1 #include <msp/builder/builder.h>
2 #include <msp/builder/component.h>
3 #include <msp/builder/csourcefile.h>
4 #include <msp/builder/objectfile.h>
5 #include <msp/builder/sourcepackage.h>
6 #include <msp/core/environ.h>
7 #include <msp/core/maputils.h>
8 #include <msp/fs/utils.h>
9 #include <msp/strings/format.h>
10 #include <msp/strings/utils.h>
11 #include "microsofttools.h"
12 #include "msvccompiler.h"
17 MsvcCompiler::MsvcCompiler(Builder &b, const Architecture &a, const string &t, const MicrosoftTools &m):
23 input_suffixes.push_back(".c");
24 aux_suffixes.push_back(".h");
28 input_suffixes.push_back(".cpp");
29 input_suffixes.push_back(".cc");
30 aux_suffixes.push_back(".hpp");
33 throw invalid_argument("MsvcCompiler::MsvcCompiler");
35 set_command((ms_tools.get_vc_bin_dir()/"cl.exe").str(), false);
36 set_run_external(_run);
39 Target *MsvcCompiler::create_source(const Component &comp, const FS::Path &path) const
41 return new CSourceFile(builder, comp, path);
44 Target *MsvcCompiler::create_source(const FS::Path &path) const
46 return new CSourceFile(builder, path);
49 Target *MsvcCompiler::create_target(const vector<Target *> &sources, const string &)
52 throw invalid_argument("MsvcCompiler::create_target");
53 SourceFile &source = dynamic_cast<SourceFile &>(*sources.front());
54 ObjectFile *obj = new ObjectFile(builder, *source.get_component(), source);
59 string MsvcCompiler::create_build_signature(const BuildInfo &binfo) const
61 string result = Tool::create_build_signature(binfo);
68 result += (binfo.optimize<0 ? '1' : binfo.optimize==1 ? 'x' : '2');
70 if(binfo.libmode<=BuildInfo::STATIC)
75 void MsvcCompiler::do_prepare(ToolData &tool) const
77 const std::string &tool_tag = static_cast<Tool &>(tool).get_tag();
79 const FS::Path &vc_base_dir = ms_tools.get_vc_base_dir();
80 tool.system_path.push_back(vc_base_dir/"include");
82 const FS::Path &win_sdk_dir = ms_tools.get_windows_sdk_dir();
83 const string &win_sdk_ver = ms_tools.get_windows_sdk_version();
84 tool.system_path.push_back(win_sdk_dir/"include"/win_sdk_ver/"ucrt");
85 tool.system_path.push_back(win_sdk_dir/"include"/win_sdk_ver/"shared");
86 tool.system_path.push_back(win_sdk_dir/"include"/win_sdk_ver/"um");
89 for(const FS::Path &p: tool.system_path)
91 append(path, ";", p.str());
92 builder.get_logger().log("tools", "Got %s system path: %s", tool_tag, p);
95 setenv("INCLUDE", path);
98 ExternalTask::Arguments MsvcCompiler::_run(const ObjectFile &object, FS::Path &work_dir)
100 const Tool &tool = *object.get_tool();
102 ExternalTask::Arguments argv;
103 argv.push_back(tool.get_executable()->get_path().str());
104 argv.push_back("/nologo");
105 argv.push_back("/c");
108 object.collect_build_info(binfo);
110 if(binfo.standards.count(tool.get_tag()))
112 const BuildInfo::LanguageStandard &std = get_item(binfo.standards, tool.get_tag());
113 if((tool.get_tag()=="CXX" && std.year>2011) || (tool.get_tag()=="CC" && std.year>1999))
114 argv.push_back("/std:"+std.str());
117 if(binfo.warning_level>=1)
119 argv.push_back(format("/W%d", binfo.warning_level));
120 if(binfo.fatal_warnings)
121 argv.push_back("/WX");
122 if(binfo.warning_level>=3)
123 argv.push_back("/permissive-");
125 argv.push_back("/wd4068"); // Unknown pragma
126 if(binfo.warning_level<4)
128 argv.push_back("/wd4244"); // Narrowing conversion on arg or return
129 argv.push_back("/wd4267"); // Narrowing conversion
133 argv.push_back("/w");
135 for(const FS::Path &p: binfo.local_incpath)
137 argv.push_back("/I");
138 argv.push_back(p.str());
140 for(const FS::Path &p: binfo.incpath)
142 argv.push_back("/I");
143 argv.push_back(p.str());
146 for(const auto &kvp: binfo.defines)
148 argv.push_back("/D");
149 if(kvp.second.empty())
150 argv.push_back(kvp.first);
152 argv.push_back(format("%s=%s", kvp.first, kvp.second));
156 argv.push_back("/Z7");
160 argv.push_back("/O1");
161 else if(binfo.optimize==1)
162 argv.push_back("/Ox");
164 argv.push_back("/O2");
167 if(binfo.libmode<=BuildInfo::STATIC)
168 argv.push_back(binfo.debug ? "/MTd" : "/MT");
170 argv.push_back(binfo.debug ? "/MDd" : "/MD");
172 argv.push_back("/EHsc");
174 FS::Path obj_path = object.get_path();
175 FS::Path src_path = object.get_source().get_path();
177 argv.push_back("/Fo"+relative(obj_path, work_dir).str());
178 argv.push_back(relative(src_path, work_dir).str());