// Copyright (c) 2005-2020 Intel Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. function readAllFromFile(fname) { var fso = new ActiveXObject("Scripting.FileSystemObject"); var file = null; try { file = fso.OpenTextFile(fname, 1, 0); return (file.readAll()); } finally { // Close the file in the finally section to guarantee that it will be closed in any case // (if the exception is thrown or not). file.Close(); } } function doWork() { var WshShell = WScript.CreateObject("WScript.Shell"); var tmpExec = WshShell.Run("cmd /c echo int main(){return 0;} >detect.c", 0, true); // The next block deals with GCC (MinGW) if (WScript.Arguments.Count() > 1) { var compilerPath = WScript.Arguments(1); // The RegExp matches everything up to and including the last slash (it uses a greedy approach.) var compilerName = compilerPath.replace(/^.*[\/\\]/, ""); if (compilerName.match(/gcc/i) != null) { if (WScript.Arguments(0) == "/arch") { // Get predefined macros tmpExec = WshShell.Run("cmd /C " + compilerPath + " -dM -E detect.c > detect.map", 0, true); var defs = readAllFromFile("detect.map"); //detect target architecture var intel64 = /x86_64|amd64/mgi; var ia32 = /i386/mgi; if (defs.match(intel64)) { WScript.Echo("intel64"); } else if (defs.match(ia32)) { WScript.Echo("ia32"); } else { WScript.Echo("unknown"); } } else { tmpExec = WshShell.Exec(compilerPath + " -dumpfullversion -dumpversion"); var gccVersion = tmpExec.StdOut.ReadLine(); if (WScript.Arguments(0) == "/runtime") { WScript.Echo("mingw" + gccVersion); } else if (WScript.Arguments(0) == "/minversion") { for (var i = 0; i < 3; i++) { v1 = parseInt(gccVersion.split('.')[i]); v2 = parseInt(WScript.Arguments(2).split('.')[i]); if (v1 > v2) { break; } else if (v1 < v2) { WScript.Echo("fail"); return; } } WScript.Echo("ok"); } } return; } } //Compile binary tmpExec = WshShell.Exec("cl /MD detect.c /link /MAP"); while (tmpExec.Status == 0) { WScript.Sleep(100); } //compiler banner that includes version and target arch was printed to stderr var clVersion = tmpExec.StdErr.ReadAll(); if (WScript.Arguments(0) == "/arch") { //detect target architecture var intel64 = /AMD64|EM64T|x64/mgi; var ia32 = /[80|\s]x86/mgi; var arm = /ARM/mgi; if (clVersion.match(intel64)) { WScript.Echo("intel64"); } else if (clVersion.match(ia32)) { WScript.Echo("ia32"); } else if (clVersion.match(arm)) { WScript.Echo("armv7"); } else { WScript.Echo("unknown"); } return; } if (WScript.Arguments(0) == "/runtime") { //read map-file var mapContext = readAllFromFile("detect.map"); //detect runtime var vc71 = /MSVCR71\.DLL/mgi; var vc80 = /MSVCR80\.DLL/mgi; var vc90 = /MSVCR90\.DLL/mgi; var vc100 = /MSVCR100\.DLL/mgi; var vc110 = /MSVCR110\.DLL/mgi; var vc120 = /MSVCR120\.DLL/mgi; var vc140 = /VCRUNTIME140\.DLL/mgi; var psdk = /MSVCRT\.DLL/mgi; if (mapContext.match(vc71)) { WScript.Echo("vc7.1"); } else if (mapContext.match(vc80)) { WScript.Echo("vc8"); } else if (mapContext.match(vc90)) { WScript.Echo("vc9"); } else if (mapContext.match(vc100)) { WScript.Echo("vc10"); } else if (mapContext.match(vc110)) { WScript.Echo("vc11"); } else if (mapContext.match(vc120)) { WScript.Echo("vc12"); } else if (mapContext.match(vc140)) { if (WshShell.ExpandEnvironmentStrings("%VisualStudioVersion%") == "15.0") WScript.Echo("vc14.1"); else if (WshShell.ExpandEnvironmentStrings("%VisualStudioVersion%") == "16.0") WScript.Echo("vc14.2"); else WScript.Echo("vc14"); } else { WScript.Echo("unknown"); } return; } if (WScript.Arguments(0) == "/minversion") { var compilerVersion; var compilerUpdate; if (WScript.Arguments(1) == "cl") { compilerVersion = clVersion.match(/Compiler Version ([0-9.]+)\s/mi)[1]; // compilerVersion is in xx.xx.xxxxx.xx format, i.e. a string. // It will compare well with major.minor versions where major has two digits, // which is sufficient as the versions of interest start from 13 (for VC7). } else if (WScript.Arguments(1) == "icl") { // Get predefined ICL macros tmpExec = WshShell.Run("cmd /C icl /QdM /E detect.c > detect.map", 0, true); var defs = readAllFromFile("detect.map"); // In #define __INTEL_COMPILER XXYY, XX is the major ICL version, YY is minor compilerVersion = defs.match(/__INTEL_COMPILER[ \t]*([0-9]+).*$/mi)[1] / 100; compilerUpdate = defs.match(/__INTEL_COMPILER_UPDATE[ \t]*([0-9]+).*$/mi)[1]; // compiler version is a number; it compares well with another major.minor // version number, where major has one, two, and perhaps more digits (9.1, 11, etc). } var requestedVersion = WScript.Arguments(2); var requestedUpdate = 0; if (WScript.Arguments.Count() > 3) requestedUpdate = WScript.Arguments(3); if (compilerVersion < requestedVersion) { WScript.Echo("fail"); } else if (compilerVersion == requestedVersion && compilerUpdate < requestedUpdate) { WScript.Echo("fail"); } else { WScript.Echo("ok"); } return; } } function doClean() { var fso = new ActiveXObject("Scripting.FileSystemObject"); // delete intermediate files if (fso.FileExists("detect.c")) fso.DeleteFile("detect.c", false); if (fso.FileExists("detect.obj")) fso.DeleteFile("detect.obj", false); if (fso.FileExists("detect.map")) fso.DeleteFile("detect.map", false); if (fso.FileExists("detect.exe")) fso.DeleteFile("detect.exe", false); if (fso.FileExists("detect.exe.manifest")) fso.DeleteFile("detect.exe.manifest", false); } if (WScript.Arguments.Count() > 0) { try { doWork(); } catch (error) { WScript.Echo("unknown"); } doClean(); } else { WScript.Echo("Supported options:\n" + "\t/arch [compiler]\n" + "\t/runtime [compiler]\n" + "\t/minversion compiler version"); }