1 /// Wrapper which accepts DMC command-line syntax 2 /// and passes the transformed options to a MSVC cl.exe. 3 module msvc_dmc; 4 5 import std.algorithm.searching; 6 import std.array; 7 import std.file; 8 import std.path; 9 import std.process; 10 import std.stdio; 11 12 int main(string[] args) 13 { 14 import std.conv: to; 15 import std.format: format; 16 17 enum defaultVSVersion = "10.0"; 18 auto cl = environment.get("MSVC_CC", 19 environment.get("VCINSTALLDIR", 20 `\Program Files (x86)\Microsoft Visual Studio %s\VC\`.format(defaultVSVersion)) 21 .buildPath("bin", "amd64", "cl.exe")); 22 string[] newArgs = [cl]; 23 newArgs ~= "/nologo"; 24 newArgs ~= `/Ivcbuild`; 25 newArgs ~= `/Idmd\root`; 26 newArgs ~= `/FIwarnings.h`; 27 28 if (environment.get("VisualStudioVersion", defaultVSVersion).to!double >= 14.0) 29 { 30 // either this or /EHsc due to 'noexcept' in system headers 31 newArgs ~= `/D_HAS_EXCEPTIONS=0`; 32 // disable narrowing conversion warnings 33 newArgs ~= `/Wv:18`; 34 } 35 bool compilingOnly; 36 37 foreach (arg; args[1..$]) 38 { 39 switch (arg) 40 { 41 case "-Ae": // "enable exception handling" 42 newArgs ~= "/EHa"; 43 break; 44 case "-c": // "skip the link, do compile only" 45 newArgs ~= "/c"; 46 compilingOnly = true; 47 break; 48 case "-cpp": // "source files are C++" 49 newArgs ~= "/TP"; 50 break; 51 case "-D": // "define macro DEBUG" 52 newArgs ~= "/DDEBUG"; 53 break; 54 case "-e": // "show results of preprocessor" 55 break; 56 case "-g": // "generate debug info" 57 case "-gl": // "debug line numbers only" 58 newArgs ~= "/Zi"; 59 break; 60 case "-o": // "optimize for program speed" 61 newArgs ~= "/O2"; 62 break; 63 case "-wx": // "treat warnings as errors" 64 newArgs ~= "/WX"; 65 break; 66 default: 67 if (arg.startsWith("-I")) // "#include file search path" 68 { 69 foreach (path; arg[2..$].split(";")) 70 if (path != `\dm\include`) 71 newArgs ~= "/I" ~ path; 72 } 73 else 74 if (arg.startsWith("-o")) // "output filename" 75 newArgs ~= "/F" ~ (compilingOnly ? "o" : "e") ~ arg[2..$]; 76 else 77 if (arg[0] != '/' && arg[0] != '-' && !exists(arg) && exists(arg ~ ".c")) 78 newArgs ~= arg ~ ".c"; 79 else 80 newArgs ~= arg; 81 break; 82 } 83 } 84 stderr.writeln(escapeShellCommand(newArgs)); 85 return spawnProcess(newArgs).wait(); 86 }