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 }
Suggestion Box / Bug Report