]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | # Copyright (c) 2003 David Abrahams |
2 | # Copyright (c) 2005 Vladimir Prus | |
3 | # Copyright (c) 2005 Alexey Pakhunov | |
4 | # Copyright (c) 2006 Bojan Resnik | |
5 | # Copyright (c) 2006 Ilya Sokolov | |
b32b8144 | 6 | # Copyright (c) 2007-2017 Rene Rivera |
7c673cae FG |
7 | # Copyright (c) 2008 Jurko Gospodnetic |
8 | # Copyright (c) 2014 Microsoft Corporation | |
9 | # | |
10 | # Distributed under the Boost Software License, Version 1.0. | |
11 | # (See accompanying file LICENSE_1_0.txt or copy at | |
12 | # http://www.boost.org/LICENSE_1_0.txt) | |
13 | ||
14 | ################################################################################ | |
15 | # | |
16 | # MSVC Boost Build toolset module. | |
17 | # -------------------------------- | |
18 | # | |
19 | # All toolset versions need to have their location either auto-detected or | |
20 | # explicitly specified except for the special 'default' version that expects the | |
21 | # environment to find the needed tools or report an error. | |
22 | # | |
23 | ################################################################################ | |
24 | ||
25 | import "class" : new ; | |
26 | import common ; | |
27 | import feature ; | |
28 | import generators ; | |
29 | import mc ; | |
30 | import midl ; | |
31 | import os ; | |
32 | import path ; | |
33 | import pch ; | |
34 | import property ; | |
35 | import rc ; | |
36 | import set ; | |
37 | import toolset ; | |
38 | import type ; | |
39 | ||
40 | ||
41 | type.register MANIFEST : manifest ; | |
42 | feature.feature embed-manifest : on off : incidental propagated ; | |
43 | feature.feature embed-manifest-file : : free dependency ; | |
44 | ||
45 | type.register PDB : pdb ; | |
46 | ||
47 | ||
48 | ################################################################################ | |
49 | # | |
50 | # Public rules. | |
51 | # | |
52 | ################################################################################ | |
53 | ||
54 | # Initialize a specific toolset version configuration. As the result, path to | |
55 | # compiler and, possible, program names are set up, and will be used when that | |
56 | # version of compiler is requested. For example, you might have: | |
57 | # | |
58 | # using msvc : 6.5 : cl.exe ; | |
59 | # using msvc : 7.0 : Y:/foo/bar/cl.exe ; | |
60 | # | |
61 | # The version parameter may be omitted: | |
62 | # | |
63 | # using msvc : : Z:/foo/bar/cl.exe ; | |
64 | # | |
65 | # The following keywords have special meanings when specified as versions: | |
66 | # - all - all detected but not yet used versions will be marked as used | |
67 | # with their default options. | |
68 | # - default - this is an equivalent to an empty version. | |
69 | # | |
70 | # Depending on a supplied version, detected configurations and presence 'cl.exe' | |
71 | # in the path different results may be achieved. The following table describes | |
72 | # the possible scenarios: | |
73 | # | |
74 | # Nothing "x.y" | |
75 | # Passed Nothing "x.y" detected, detected, | |
76 | # version detected detected cl.exe in path cl.exe in path | |
77 | # | |
78 | # default Error Use "x.y" Create "default" Use "x.y" | |
79 | # all None Use all None Use all | |
80 | # x.y - Use "x.y" - Use "x.y" | |
81 | # a.b Error Error Create "a.b" Create "a.b" | |
82 | # | |
83 | # "x.y" - refers to a detected version; | |
84 | # "a.b" - refers to an undetected version. | |
85 | # | |
86 | # FIXME: Currently the command parameter and the <compiler> property parameter | |
87 | # seem to overlap in duties. Remove this duplication. This seems to be related | |
88 | # to why someone started preparing to replace init with configure rules. | |
89 | # | |
90 | rule init ( | |
91 | # The msvc version being configured. When omitted the tools invoked when no | |
92 | # explicit version is given will be configured. | |
93 | version ? | |
94 | ||
95 | # The command used to invoke the compiler. If not specified: | |
96 | # - if version is given, default location for that version will be | |
97 | # searched | |
98 | # | |
99 | # - if version is not given, default locations for MSVC 9.0, 8.0, 7.1, 7.0 | |
100 | # and 6.* will be searched | |
101 | # | |
102 | # - if compiler is not found in the default locations, PATH will be | |
103 | # searched. | |
104 | : command * | |
105 | ||
106 | # Options may include: | |
107 | # | |
108 | # All options shared by multiple toolset types as handled by the | |
109 | # common.handle-options() rule, e.g. <cflags>, <compileflags>, <cxxflags>, | |
110 | # <fflags> & <linkflags>. | |
111 | # | |
112 | # <assembler> | |
113 | # <compiler> | |
114 | # <idl-compiler> | |
115 | # <linker> | |
116 | # <mc-compiler> | |
117 | # <resource-compiler> | |
118 | # Exact tool names to be used by this msvc toolset configuration. | |
119 | # | |
120 | # <compiler-filter> | |
121 | # Command through which to pipe the output of running the compiler. | |
122 | # For example to pass the output to STLfilt. | |
123 | # | |
124 | # <setup> | |
125 | # Global setup command to invoke before running any of the msvc tools. | |
126 | # It will be passed additional option parameters depending on the actual | |
127 | # target platform. | |
128 | # | |
129 | # <setup-amd64> | |
130 | # <setup-i386> | |
131 | # <setup-ia64> | |
132 | # <setup-arm> | |
133 | # <setup-phone-i386> | |
134 | # <setup-phone-arm> | |
135 | # Platform specific setup command to invoke before running any of the | |
136 | # msvc tools used when builing a target for a specific platform, e.g. | |
137 | # when building a 32 or 64 bit executable. | |
138 | # | |
139 | # <rewrite-setup-scripts> | |
140 | # Whether to rewrite setup scripts. New scripts will be output in | |
141 | # TEMP directory and will be used instead of originals in build actions. | |
142 | # Possible values: | |
143 | # * on - rewrite scripts, if they do not already exist (default) | |
144 | # * always - always rewrite scripts, even if they already exist | |
145 | # * off - use original setup scripts | |
146 | : options * | |
147 | ) | |
148 | { | |
149 | if $(command) | |
150 | { | |
151 | options += <command>$(command) ; | |
152 | } | |
153 | configure $(version) : $(options) ; | |
154 | } | |
155 | ||
156 | ||
157 | # 'configure' is a newer version of 'init'. The parameter 'command' is passed as | |
158 | # a part of the 'options' list. See the 'init' rule comment for more detailed | |
159 | # information. | |
160 | # | |
161 | rule configure ( version ? : options * ) | |
162 | { | |
163 | switch $(version) | |
164 | { | |
165 | case "all" : | |
166 | if $(options) | |
167 | { | |
168 | import errors ; | |
169 | errors.error "MSVC toolset configuration: options should be" | |
170 | "empty when '$(version)' is specified." ; | |
171 | } | |
172 | ||
173 | # Configure (i.e. mark as used) all registered versions. | |
174 | local all-versions = [ $(.versions).all ] ; | |
175 | if ! $(all-versions) | |
176 | { | |
177 | if $(.debug-configuration) | |
178 | { | |
179 | ECHO "notice: [msvc-cfg] Asked to configure all registered" | |
180 | "msvc toolset versions when there are none currently" | |
181 | "registered." ; | |
182 | } | |
183 | } | |
184 | else | |
185 | { | |
186 | for local v in $(all-versions) | |
187 | { | |
188 | # Note that there is no need to skip already configured | |
189 | # versions here as this will request configure-really rule | |
190 | # to configure the version using default options which will | |
191 | # in turn cause it to simply do nothing in case the version | |
192 | # has already been configured. | |
193 | configure-really $(v) ; | |
194 | } | |
195 | } | |
196 | ||
197 | case "default" : | |
198 | configure-really : $(options) ; | |
199 | ||
200 | case * : | |
201 | configure-really $(version) : $(options) ; | |
202 | } | |
203 | } | |
204 | ||
205 | ||
206 | # Sets up flag definitions dependent on the compiler version used. | |
207 | # - 'version' is the version of compiler in N.M format. | |
208 | # - 'conditions' is the property set to be used as flag conditions. | |
209 | # - 'toolset' is the toolset for which flag settings are to be defined. | |
210 | # This makes the rule reusable for other msvc-option-compatible compilers. | |
211 | # | |
212 | rule configure-version-specific ( toolset : version : conditions ) | |
213 | { | |
214 | toolset.push-checking-for-flags-module unchecked ; | |
215 | # Starting with versions 7.0, the msvc compiler have the /Zc:forScope and | |
216 | # /Zc:wchar_t options that improve C++ standard conformance, but those | |
217 | # options are off by default. If we are sure that the msvc version is at | |
218 | # 7.*, add those options explicitly. We can be sure either if user specified | |
219 | # version 7.* explicitly or if we auto-detected the version ourselves. | |
220 | if ! [ MATCH ^(6\\.) : $(version) ] | |
221 | { | |
222 | toolset.flags $(toolset).compile CFLAGS $(conditions) : /Zc:forScope /Zc:wchar_t ; | |
223 | toolset.flags $(toolset).compile.c++ C++FLAGS $(conditions) : /wd4675 ; | |
224 | ||
225 | # Explicitly disable the 'function is deprecated' warning. Some msvc | |
226 | # versions have a bug, causing them to emit the deprecation warning even | |
227 | # with /W0. | |
228 | toolset.flags $(toolset).compile CFLAGS $(conditions)/<warnings>off : /wd4996 ; | |
229 | ||
230 | if [ MATCH ^([78]\\.) : $(version) ] | |
231 | { | |
232 | # 64-bit compatibility warning deprecated since 9.0, see | |
233 | # http://msdn.microsoft.com/en-us/library/yt4xw8fh.aspx | |
234 | toolset.flags $(toolset).compile CFLAGS $(conditions)/<warnings>all : /Wp64 ; | |
235 | } | |
236 | } | |
237 | ||
238 | # | |
239 | # Processor-specific optimization. | |
240 | # | |
241 | ||
242 | if [ MATCH ^([67]) : $(version) ] | |
243 | { | |
244 | # 8.0 deprecates some of the options. | |
245 | toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>speed $(conditions)/<optimization>space : /Ogiy /Gs ; | |
246 | toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>speed : /Ot ; | |
247 | toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>space : /Os ; | |
248 | ||
249 | toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set> : /GB ; | |
250 | toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>i486 : /G4 ; | |
251 | toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g5) : /G5 ; | |
252 | toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g6) : /G6 ; | |
253 | toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g7) : /G7 ; | |
254 | ||
255 | # Improve floating-point accuracy. Otherwise, some of C++ Boost's "math" | |
256 | # tests will fail. | |
257 | toolset.flags $(toolset).compile CFLAGS $(conditions) : /Op ; | |
258 | ||
259 | # 7.1 and below have single-threaded static RTL. | |
260 | toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>off/<runtime-link>static/<threading>single : /ML ; | |
261 | toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>on/<runtime-link>static/<threading>single : /MLd ; | |
262 | } | |
263 | else | |
264 | { | |
265 | # 8.0 and above adds some more options. | |
266 | toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set> : /favor:blend ; | |
267 | toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set>$(.cpu-type-em64t) : /favor:EM64T ; | |
268 | toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set>$(.cpu-type-amd64) : /favor:AMD64 ; | |
269 | ||
270 | # 8.0 and above only has multi-threaded static RTL. | |
271 | toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>off/<runtime-link>static/<threading>single : /MT ; | |
272 | toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>on/<runtime-link>static/<threading>single : /MTd ; | |
273 | ||
274 | # Specify target machine type so the linker will not need to guess. | |
275 | toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-amd64) : /MACHINE:X64 ; | |
276 | toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-i386) : /MACHINE:X86 ; | |
277 | toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-ia64) : /MACHINE:IA64 ; | |
278 | toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-arm) : /MACHINE:ARM ; | |
279 | ||
280 | # Make sure that manifest will be generated even if there is no | |
281 | # dependencies to put there. | |
282 | toolset.flags $(toolset).link LINKFLAGS $(conditions) : /MANIFEST ; | |
283 | } | |
284 | ||
285 | toolset.pop-checking-for-flags-module ; | |
286 | } | |
287 | ||
288 | # Feature for handling targeting different Windows API sets. | |
289 | feature.feature windows-api : desktop store phone : propagated composite link-incompatible ; | |
290 | feature.compose <windows-api>store : <define>WINAPI_FAMILY=WINAPI_FAMILY_APP <define>_WIN32_WINNT=0x0602 | |
291 | <linkflags>/APPCONTAINER ; | |
292 | feature.compose <windows-api>phone : <define>WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP <define>_WIN32_WINNT=0x0602 | |
293 | <linkflags>/APPCONTAINER <linkflags>/NODEFAULTLIB:ole32.lib <linkflags>/NODEFAULTLIB:kernel32.lib <linkflags>WindowsPhoneCore.lib ; | |
294 | feature.set-default windows-api : desktop ; | |
295 | ||
296 | ||
297 | # Registers this toolset including all of its flags, features & generators. Does | |
298 | # nothing on repeated calls. | |
299 | # | |
300 | rule register-toolset ( ) | |
301 | { | |
302 | if ! msvc in [ feature.values toolset ] | |
303 | { | |
304 | register-toolset-really ; | |
305 | } | |
306 | } | |
307 | ||
308 | rule resolve-possible-msvc-version-alias ( version ) | |
309 | { | |
310 | if $(.version-alias-$(version)) | |
311 | { | |
312 | version = $(.version-alias-$(version)) ; | |
313 | } | |
314 | return $(version) ; | |
315 | } | |
316 | ||
317 | ||
318 | # Declare action for creating static libraries. If library exists, remove it | |
319 | # before adding files. See | |
320 | # http://article.gmane.org/gmane.comp.lib.boost.build/4241 for rationale. | |
321 | if [ os.name ] in NT | |
322 | { | |
323 | # The 'DEL' command would issue a message to stdout if the file does not | |
324 | # exist, so need a check. | |
325 | actions archive | |
326 | { | |
327 | if exist "$(<[1])" DEL "$(<[1])" | |
328 | $(.LD) $(AROPTIONS) /out:"$(<[1])" @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")" | |
329 | } | |
330 | } | |
331 | else | |
332 | { | |
333 | actions archive | |
334 | { | |
335 | $(.RM) "$(<[1])" | |
336 | $(.LD) $(AROPTIONS) /out:"$(<[1])" @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")" | |
337 | } | |
338 | } | |
339 | ||
340 | ||
341 | # For the assembler the following options are turned on by default: | |
342 | # | |
343 | # -Zp4 align structures to 4 bytes | |
344 | # -Cp preserve case of user identifiers | |
345 | # -Cx preserve case in publics, externs | |
346 | # | |
347 | actions compile.asm | |
348 | { | |
349 | $(.ASM) -c -Zp4 -Cp -Cx -D$(DEFINES) $(ASMFLAGS) $(USER_ASMFLAGS) -Fo "$(<:W)" "$(>:W)" | |
350 | } | |
351 | ||
352 | ||
353 | rule compile.c ( targets + : sources * : properties * ) | |
354 | { | |
355 | C++FLAGS on $(targets[1]) = ; | |
356 | get-rspline $(targets) : -TC ; | |
357 | compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ; | |
358 | } | |
359 | ||
360 | ||
361 | rule compile.c.preprocess ( targets + : sources * : properties * ) | |
362 | { | |
363 | C++FLAGS on $(targets[1]) = ; | |
364 | get-rspline $(targets) : -TC ; | |
365 | preprocess-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ; | |
366 | } | |
367 | ||
368 | ||
369 | rule compile.c.pch ( targets + : sources * : properties * ) | |
370 | { | |
371 | C++FLAGS on $(targets[1]) = ; | |
372 | get-rspline $(targets[1]) : -TC ; | |
373 | get-rspline $(targets[2]) : -TC ; | |
374 | local pch-source = [ on $(<) return $(PCH_SOURCE) ] ; | |
375 | if $(pch-source) | |
376 | { | |
377 | DEPENDS $(<) : $(pch-source) ; | |
378 | compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ; | |
379 | } | |
380 | else | |
381 | { | |
382 | compile-c-c++-pch $(targets) : $(sources) ; | |
383 | } | |
384 | } | |
385 | ||
386 | toolset.flags msvc YLOPTION : "-Yl" ; | |
387 | ||
388 | # Action for running the C/C++ compiler without using precompiled headers. | |
389 | # | |
390 | # WARNING: Synchronize any changes this in action with intel-win | |
391 | # | |
392 | # Notes regarding PDB generation, for when we use | |
393 | # <debug-symbols>on/<debug-store>database: | |
394 | # | |
395 | # 1. PDB_CFLAG is only set for <debug-symbols>on/<debug-store>database, ensuring | |
396 | # that the /Fd flag is dropped if PDB_CFLAG is empty. | |
397 | # | |
398 | # 2. When compiling executables's source files, PDB_NAME is set on a per-source | |
399 | # file basis by rule compile-c-c++. The linker will pull these into the | |
400 | # executable's PDB. | |
401 | # | |
402 | # 3. When compiling library's source files, PDB_NAME is updated to <libname>.pdb | |
403 | # for each source file by rule archive, as in this case compiler must be used | |
404 | # to create a single PDB for our library. | |
405 | # | |
406 | actions compile-c-c++ bind PDB_NAME | |
407 | { | |
408 | $(.CC) @"@($(<[1]:W).rsp:E="$(>[1]:W)" -Fo"$(<[1]:W)" $(PDB_CFLAG)"$(PDB_NAME)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))" $(.CC.FILTER) | |
409 | } | |
410 | ||
411 | actions preprocess-c-c++ bind PDB_NAME | |
412 | { | |
413 | $(.CC) @"@($(<[1]:W).rsp:E="$(>[1]:W)" -E $(PDB_CFLAG)"$(PDB_NAME)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))" >"$(<[1]:W)" | |
414 | } | |
415 | ||
416 | rule compile-c-c++ ( targets + : sources * ) | |
417 | { | |
418 | DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_HEADER) ] ; | |
419 | DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_FILE) ] ; | |
420 | PDB_NAME on $(<) = $(<[1]:S=.pdb) ; | |
421 | LOCATE on $(<[1]:S=.pdb) = [ on $(<[1]) return $(LOCATE) ] ; | |
422 | } | |
423 | ||
424 | rule preprocess-c-c++ ( targets + : sources * ) | |
425 | { | |
426 | DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_HEADER) ] ; | |
427 | DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_FILE) ] ; | |
428 | PDB_NAME on $(<) = $(<:S=.pdb) ; | |
429 | LOCATE on $(<[1]:S=.pdb) = [ on $(<[1]) return $(LOCATE) ] ; | |
430 | } | |
431 | ||
432 | # Action for running the C/C++ compiler using precompiled headers. In addition | |
433 | # to whatever else it needs to compile, this action also adds a temporary source | |
434 | # .cpp file used to compile the precompiled headers themselves. | |
435 | # | |
436 | # The global .escaped-double-quote variable is used to avoid messing up Emacs | |
437 | # syntax highlighting in the messy N-quoted code below. | |
438 | actions compile-c-c++-pch | |
439 | { | |
440 | $(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" $(YLOPTION)"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))" "@($(<[1]:W).cpp:E=#include $(.escaped-double-quote)$(>[1]:D=)$(.escaped-double-quote)$(.nl))" $(.CC.FILTER) | |
441 | } | |
442 | ||
443 | ||
444 | # Action for running the C/C++ compiler using precompiled headers. An already | |
445 | # built source file for compiling the precompiled headers is expected to be | |
446 | # given as one of the source parameters. | |
447 | actions compile-c-c++-pch-s | |
448 | { | |
449 | $(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" $(YLOPTION)"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))" $(.CC.FILTER) | |
450 | } | |
451 | ||
452 | ||
453 | rule compile.c++ ( targets + : sources * : properties * ) | |
454 | { | |
455 | get-rspline $(targets) : -TP ; | |
456 | compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ; | |
457 | } | |
458 | ||
459 | rule compile.c++.preprocess ( targets + : sources * : properties * ) | |
460 | { | |
461 | get-rspline $(targets) : -TP ; | |
462 | preprocess-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ; | |
463 | } | |
464 | ||
465 | ||
466 | rule compile.c++.pch ( targets + : sources * : properties * ) | |
467 | { | |
468 | get-rspline $(targets[1]) : -TP ; | |
469 | get-rspline $(targets[2]) : -TP ; | |
470 | local pch-source = [ on $(<) return $(PCH_SOURCE) ] ; | |
471 | if $(pch-source) | |
472 | { | |
473 | DEPENDS $(<) : $(pch-source) ; | |
474 | compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ; | |
475 | } | |
476 | else | |
477 | { | |
478 | compile-c-c++-pch $(targets) : $(sources) ; | |
479 | } | |
480 | } | |
481 | ||
482 | ||
483 | # See midl.jam for details. | |
484 | # | |
485 | actions compile.idl | |
486 | { | |
487 | $(.IDL) /nologo @"@($(<[1]:W).rsp:E=$(.nl)"$(>:W)" $(.nl)-D$(DEFINES) $(.nl)"-I$(INCLUDES:W)" $(.nl)-U$(UNDEFS) $(.nl)$(MIDLFLAGS) $(.nl)/tlb "$(<[1]:W)" $(.nl)/h "$(<[2]:W)" $(.nl)/iid "$(<[3]:W)" $(.nl)/proxy "$(<[4]:W)" $(.nl)/dlldata "$(<[5]:W)")" | |
488 | $(.TOUCH_FILE) "$(<[4]:W)" | |
489 | $(.TOUCH_FILE) "$(<[5]:W)" | |
490 | } | |
491 | ||
492 | ||
493 | actions compile.mc | |
494 | { | |
495 | $(.MC) $(MCFLAGS) -h "$(<[1]:DW)" -r "$(<[2]:DW)" "$(>:W)" | |
496 | } | |
497 | ||
498 | ||
499 | actions compile.rc | |
500 | { | |
501 | $(.RC) -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES:W)" -fo "$(<:W)" "$(>:W)" | |
502 | } | |
503 | ||
504 | ||
505 | rule link ( targets + : sources * : properties * ) | |
506 | { | |
507 | if <embed-manifest>on in $(properties) | |
508 | { | |
509 | if [ feature.get-values <embed-manifest-file> : $(properties) ] | |
510 | { | |
511 | DEPENDS $(<) : [ on $(<) return $(EMBED_MANIFEST_FILE) ] ; | |
512 | msvc.manifest.user $(targets) $(EMBED_MANIFEST_FILE) : $(sources) : $(properties) ; | |
513 | } | |
514 | else | |
515 | { | |
516 | msvc.manifest $(targets) : $(sources) : $(properties) ; | |
517 | } | |
518 | } | |
519 | } | |
520 | ||
521 | rule link.dll ( targets + : sources * : properties * ) | |
522 | { | |
523 | DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ; | |
524 | if <embed-manifest>on in $(properties) | |
525 | { | |
526 | if [ feature.get-values <embed-manifest-file> : $(properties) ] | |
527 | { | |
528 | DEPENDS $(<) : [ on $(<) return $(EMBED_MANIFEST_FILE) ] ; | |
529 | msvc.manifest.dll.user $(targets) $(EMBED_MANIFEST_FILE) : $(sources) : $(properties) ; | |
530 | } | |
531 | else | |
532 | { | |
533 | msvc.manifest.dll $(targets) : $(sources) : $(properties) ; | |
534 | } | |
535 | } | |
536 | } | |
537 | ||
538 | # Incremental linking a DLL causes no end of problems: if the actual exports do | |
539 | # not change, the import .lib file is never updated. Therefore, the .lib is | |
540 | # always out-of-date and gets rebuilt every time. I am not sure that incremental | |
541 | # linking is such a great idea in general, but in this case I am sure we do not | |
542 | # want it. | |
543 | ||
544 | # Windows manifest is a new way to specify dependencies on managed DotNet | |
545 | # assemblies and Windows native DLLs. The manifests are embedded as resources | |
546 | # and are useful in any PE target (both DLL and EXE). | |
547 | ||
548 | if [ os.name ] in NT | |
549 | { | |
550 | actions link bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE | |
551 | { | |
552 | $(.LD) $(LINKFLAGS) /out:"$(<[1]:W)" /LIBPATH:"$(LINKPATH:W)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")" | |
553 | if %ERRORLEVEL% NEQ 0 EXIT %ERRORLEVEL% | |
554 | } | |
555 | ||
556 | actions manifest | |
557 | { | |
558 | if exist "$(<[1]).manifest" ( | |
559 | $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);1" | |
560 | ) | |
561 | } | |
562 | ||
563 | actions manifest.user bind EMBED_MANIFEST_FILE | |
564 | { | |
565 | $(.MT) -manifest "$(EMBED_MANIFEST_FILE)" "-outputresource:$(<[1]);1" | |
566 | } | |
567 | ||
568 | actions link.dll bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE | |
569 | { | |
570 | $(.LD) /DLL $(LINKFLAGS) /out:"$(<[1]:W)" /IMPLIB:"$(<[2]:W)" /LIBPATH:"$(LINKPATH:W)" /def:"$(DEF_FILE)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")" | |
571 | if %ERRORLEVEL% NEQ 0 EXIT %ERRORLEVEL% | |
572 | } | |
573 | ||
574 | actions manifest.dll | |
575 | { | |
576 | if exist "$(<[1]).manifest" ( | |
577 | $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);2" | |
578 | ) | |
579 | } | |
580 | actions manifest.dll.user bind EMBED_MANIFEST_FILE | |
581 | { | |
582 | $(.MT) -manifest "$(EMBED_MANIFEST_FILE)" "-outputresource:$(<[1]);2" | |
583 | } | |
584 | } | |
585 | else | |
586 | { | |
587 | actions link bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE | |
588 | { | |
589 | $(.LD) $(LINKFLAGS) /out:"$(<[1]:W)" /LIBPATH:"$(LINKPATH:W)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")" | |
590 | } | |
591 | ||
592 | actions manifest | |
593 | { | |
594 | if test -e "$(<[1]).manifest"; then | |
595 | $(.MT) -manifest "$(<[1]:W).manifest" "-outputresource:$(<[1]:W);1" | |
596 | fi | |
597 | } | |
598 | ||
599 | actions link.dll bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE | |
600 | { | |
601 | $(.LD) /DLL $(LINKFLAGS) /out:"$(<[1]:W)" /IMPLIB:"$(<[2]:W)" /LIBPATH:"$(LINKPATH:W)" /def:"$(DEF_FILE)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")" | |
602 | } | |
603 | ||
604 | actions manifest.dll | |
605 | { | |
606 | if test -e "$(<[1]).manifest"; then | |
607 | $(.MT) -manifest "$(<[1]:W).manifest" "-outputresource:$(<[1]:W);2" | |
608 | fi | |
609 | } | |
610 | ||
611 | actions manifest.dll.user bind EMBED_MANIFEST_FILE | |
612 | { | |
613 | $(.MT) -manifest "$(EMBED_MANIFEST_FILE)" "-outputresource:$(<[1]);2" | |
614 | } | |
615 | } | |
616 | ||
617 | # This rule sets up the pdb file that will be used when generating static | |
618 | # libraries and the debug-store option is database, so that the compiler puts | |
619 | # all the debug info into a single .pdb file named after the library. | |
620 | # | |
621 | # Poking at source targets this way is probably not clean, but it is the | |
622 | # easiest approach. | |
623 | # | |
624 | rule archive ( targets + : sources * : properties * ) | |
625 | { | |
626 | PDB_NAME on $(>) = $(<[1]:S=.pdb) ; | |
627 | LOCATE on $(<[1]:S=.pdb) = [ on $(<[1]) return $(LOCATE) ] ; | |
628 | } | |
629 | ||
630 | ||
631 | ################################################################################ | |
632 | # | |
633 | # Classes. | |
634 | # | |
635 | ################################################################################ | |
636 | ||
637 | class msvc-pch-generator : pch-generator | |
638 | { | |
639 | import property-set ; | |
640 | ||
641 | rule run-pch ( project name ? : property-set : sources * ) | |
642 | { | |
643 | # Searching for the header and source file in the sources. | |
644 | local pch-header ; | |
645 | local pch-source ; | |
646 | for local s in $(sources) | |
647 | { | |
648 | if [ type.is-derived [ $(s).type ] H ] | |
649 | { | |
650 | pch-header = $(s) ; | |
651 | } | |
652 | else if | |
653 | [ type.is-derived [ $(s).type ] CPP ] || | |
654 | [ type.is-derived [ $(s).type ] C ] | |
655 | { | |
656 | pch-source = $(s) ; | |
657 | } | |
658 | } | |
659 | ||
660 | if ! $(pch-header) | |
661 | { | |
662 | import errors : user-error : errors.user-error ; | |
663 | errors.user-error "can not build pch without pch-header" ; | |
664 | } | |
665 | ||
666 | # If we do not have the PCH source - that is fine. We will just create a | |
667 | # temporary .cpp file in the action. | |
668 | ||
669 | local generated = [ generator.run $(project) $(name) | |
670 | : [ property-set.create | |
671 | # Passing of <pch-source> is a dirty trick, needed because | |
672 | # non-composing generators with multiple inputs are subtly | |
673 | # broken. For more detailed information see: | |
674 | # https://zigzag.cs.msu.su:7813/boost.build/ticket/111 | |
675 | <pch-source>$(pch-source) | |
676 | [ $(property-set).raw ] ] | |
677 | : $(pch-header) ] ; | |
678 | ||
679 | local pch-file ; | |
680 | for local g in $(generated) | |
681 | { | |
682 | if [ type.is-derived [ $(g).type ] PCH ] | |
683 | { | |
684 | pch-file = $(g) ; | |
685 | } | |
686 | } | |
687 | ||
688 | return [ property-set.create <pch-header>$(pch-header) | |
689 | <pch-file>$(pch-file) ] $(generated) ; | |
690 | } | |
691 | } | |
692 | ||
693 | ||
694 | ################################################################################ | |
695 | # | |
696 | # Local rules. | |
697 | # | |
698 | ################################################################################ | |
699 | ||
700 | # Detects versions listed as '.known-versions' by checking registry information, | |
701 | # environment variables & default paths. Supports both native Windows and | |
702 | # Cygwin. | |
703 | # | |
704 | local rule auto-detect-toolset-versions ( ) | |
705 | { | |
706 | if [ os.name ] in NT CYGWIN | |
707 | { | |
708 | # Get installation paths from the registry. | |
709 | for local i in $(.known-versions) | |
710 | { | |
711 | if $(.version-$(i)-reg) | |
712 | { | |
713 | local vc-path ; | |
714 | for local x in "" "Wow6432Node\\" | |
715 | { | |
716 | vc-path += [ W32_GETREG | |
717 | "HKEY_LOCAL_MACHINE\\SOFTWARE\\"$(x)"\\Microsoft\\"$(.version-$(i)-reg) | |
718 | : "ProductDir" ] ; | |
719 | } | |
720 | ||
721 | if $(vc-path) | |
722 | { | |
723 | vc-path = [ path.join [ path.make-NT $(vc-path[1]) ] "bin" ] ; | |
724 | register-configuration $(i) : [ path.native $(vc-path[1]) ] ; | |
725 | } | |
726 | } | |
727 | } | |
728 | } | |
729 | ||
730 | # Check environment and default installation paths. | |
731 | for local i in $(.known-versions) | |
732 | { | |
733 | if ! $(i) in [ $(.versions).all ] | |
734 | { | |
735 | register-configuration $(i) : [ default-path $(i) ] ; | |
736 | } | |
737 | } | |
738 | } | |
739 | ||
740 | # Helper rule to generate a faster alternative to MSVC setup scripts. | |
741 | # We used to call MSVC setup scripts directly in every action, however in | |
742 | # newer MSVC versions (10.0+) they make long-lasting registry queries | |
743 | # which have a significant impact on build time. | |
744 | rule maybe-rewrite-setup ( toolset : setup-script : setup-options : version : rewrite-setup ? ) | |
745 | { | |
746 | local result = $(setup-script)" "$(setup-options) ; | |
747 | # At the moment we only know how to rewrite scripts with cmd shell. | |
748 | if ( [ os.name ] in NT ) && ( $(rewrite-setup) != off ) | |
749 | { | |
750 | setup-script-id = b2_$(toolset)_$(version)_$(setup-script:B) ; | |
751 | if $(setup-options)-is-not-empty | |
752 | { | |
753 | setup-script-id = $(setup-script-id)_$(setup-options) ; | |
754 | } | |
755 | ||
756 | if $(.$(setup-script-id)) | |
757 | { | |
758 | errors.error rewriting setup script for the second time ; | |
759 | } | |
760 | ||
761 | local tmpdir = [ os.environ TEMP ] ; | |
762 | local replacement = [ path.native $(tmpdir)/$(setup-script-id).cmd ] ; | |
763 | if ( $(rewrite-setup) = always ) || ( ! [ path.exists $(replacement) ] ) | |
764 | { | |
765 | local original-vars = [ SPLIT_BY_CHARACTERS [ SHELL set ] : "\n" ] ; | |
766 | local new-vars = [ SPLIT_BY_CHARACTERS [ SHELL "$(setup-script) $(setup-options)>nul && set" ] : "\n" ] ; | |
767 | local diff-vars = [ set.difference $(new-vars) : $(original-vars) ] ; | |
768 | if $(diff-vars) | |
769 | { | |
770 | local target = <new-setup-script>$(replacement) ; | |
771 | FILE_CONTENTS on $(target) = "SET "$(diff-vars) ; | |
772 | ALWAYS $(target) ; | |
773 | msvc.write-setup-script $(target) ; | |
774 | UPDATE_NOW $(target) : : ignore-minus-n ; | |
775 | .$(setup-script-id) = $(replacement) ; | |
776 | result = "\""$(replacement)"\"" ; | |
777 | } | |
778 | } | |
779 | else | |
780 | { | |
781 | result = "\""$(replacement)"\"" ; | |
782 | } | |
783 | } | |
784 | return $(result) ; | |
785 | } | |
786 | ||
787 | actions write-setup-script | |
788 | { | |
789 | @($(STDOUT):E=$(FILE_CONTENTS:J=$(.nl))) > "$(<)" | |
790 | } | |
791 | ||
792 | ||
793 | # Local helper rule to create the vcvars setup command for given architecture | |
794 | # and options. | |
795 | # | |
796 | local rule generate-setup-cmd ( version : command : parent : options * : cpu : global-setup ? : default-global-setup-options : default-setup ) | |
797 | { | |
798 | local setup-prefix = "call " ; | |
799 | local setup-suffix = " >nul"$(.nl) ; | |
800 | if ! [ os.name ] in NT | |
801 | { | |
802 | setup-prefix = "cmd.exe /S /C call " ; | |
803 | setup-suffix = " \">nul\" \"&&\" " ; | |
804 | } | |
805 | ||
806 | local setup-options ; | |
807 | local setup = [ feature.get-values <setup-$(cpu)> : $(options) ] ; | |
808 | ||
809 | if ! $(setup)-is-defined | |
810 | { | |
811 | if $(global-setup)-is-defined | |
812 | { | |
813 | setup = $(global-setup) ; | |
814 | ||
815 | # If needed we can easily add using configuration flags | |
816 | # here for overriding which options get passed to the | |
817 | # global setup command for which target platform: | |
818 | # setup-options = [ feature.get-values <setup-options-$(c)> : $(options) ] ; | |
819 | setup-options ?= $(default-global-setup-options) ; | |
820 | } | |
821 | else | |
822 | { | |
b32b8144 FG |
823 | if [ MATCH "(14.1)" : $(version) ] |
824 | { | |
825 | if $(.debug-configuration) | |
826 | { | |
827 | ECHO 'notice: [generate-setup-cmd] $(version) is 14.1' ; | |
828 | } | |
829 | parent = [ path.native [ path.join $(parent) "..\\..\\..\\..\\..\\Auxiliary\\Build" ] ] ; | |
830 | } | |
7c673cae | 831 | setup = [ locate-default-setup $(command) : $(parent) : $(default-setup) ] ; |
b32b8144 | 832 | setup ?= [ path.join $(parent) "vcvarsall.bat" ] ; |
7c673cae FG |
833 | } |
834 | } | |
835 | ||
836 | # Cygwin to Windows path translation. | |
837 | setup = "\""$(setup:W)"\"" ; | |
838 | ||
839 | # Append setup options to the setup name and add the final setup | |
840 | # prefix & suffix. | |
841 | setup-options ?= "" ; | |
842 | local rewrite = [ feature.get-values <rewrite-setup-scripts> : $(options) ] ; | |
843 | setup = [ maybe-rewrite-setup msvc : $(setup:J=" ") : $(setup-options:J=" ") : $(version) : $(rewrite) ] ; | |
844 | setup = $(setup-prefix)$(setup)$(setup-suffix) ; | |
845 | ||
846 | return $(setup) ; | |
847 | } | |
848 | ||
849 | ||
850 | # Worker rule for toolset version configuration. Takes an explicit version id or | |
851 | # nothing in case it should configure the default toolset version (the first | |
852 | # registered one or a new 'default' one in case no toolset versions have been | |
853 | # registered yet). | |
854 | # | |
855 | local rule configure-really ( version ? : options * ) | |
856 | { | |
857 | local v = $(version) ; | |
858 | ||
859 | # Decide what the 'default' version is. | |
860 | if ! $(v) | |
861 | { | |
b32b8144 | 862 | # Take the best registered (i.e. auto-detected) version. |
7c673cae | 863 | version = [ $(.versions).all ] ; |
b32b8144 FG |
864 | for local known in $(.known-versions) |
865 | { | |
866 | if $(known) in $(version) | |
867 | { | |
868 | version = $(known) ; | |
869 | break ; | |
870 | } | |
871 | } | |
7c673cae FG |
872 | version = $(version[1]) ; |
873 | v = $(version) ; | |
874 | ||
875 | # Note: 'version' can still be empty at this point if no versions have | |
876 | # been auto-detected. | |
877 | version ?= "default" ; | |
878 | } | |
879 | ||
880 | # Version alias -> real version number. | |
881 | version = [ resolve-possible-msvc-version-alias $(version) ] ; | |
882 | ||
883 | # Check whether the selected configuration is already in use. | |
884 | if $(version) in [ $(.versions).used ] | |
885 | { | |
886 | # Allow multiple 'toolset.using' calls for the same configuration if the | |
887 | # identical sets of options are used. | |
888 | if $(options) && ( $(options) != [ $(.versions).get $(version) : options ] ) | |
889 | { | |
890 | import errors ; | |
891 | errors.error "MSVC toolset configuration: Toolset version" | |
892 | "'$(version)' already configured." ; | |
893 | } | |
894 | } | |
895 | else | |
896 | { | |
897 | # Register a new configuration. | |
898 | $(.versions).register $(version) ; | |
899 | ||
900 | # Add user-supplied to auto-detected options. | |
901 | options = [ $(.versions).get $(version) : options ] $(options) ; | |
902 | ||
903 | # Mark the configuration as 'used'. | |
904 | $(.versions).use $(version) ; | |
905 | ||
906 | # Generate conditions and save them. | |
907 | local conditions = [ common.check-init-parameters msvc : version $(v) ] | |
908 | ; | |
909 | ||
910 | $(.versions).set $(version) : conditions : $(conditions) ; | |
911 | ||
912 | local command = [ feature.get-values <command> : $(options) ] ; | |
913 | ||
b32b8144 FG |
914 | # For 14.1 we need the exact version as MS is planning rolling updates |
915 | # that will cause our `setup-cmd` to become invalid | |
916 | exact-version = [ MATCH "(14\.10\.[0-9\.]+)" : $(command) ] ; | |
917 | ||
7c673cae FG |
918 | # If version is specified, we try to search first in default paths, and |
919 | # only then in PATH. | |
920 | command = [ common.get-invocation-command msvc : cl.exe : $(command) : | |
921 | [ default-paths $(version) ] : $(version) ] ; | |
922 | ||
b32b8144 FG |
923 | if ( ! $(version) || $(version) = "default" ) && ! $(command:D) |
924 | { | |
925 | ECHO ; | |
926 | ECHO warning: | |
927 | "Did not find command for MSVC toolset." | |
928 | "If you have Visual Studio 2017 installed you will need to" | |
929 | "specify the full path to the command," | |
930 | "set VS150COMNTOOLS for your installation," | |
931 | "or" | |
932 | "build from the 'Visual Studio Command Prompt for VS 2017'." | |
933 | ; | |
934 | ECHO ; | |
935 | } | |
936 | ||
7c673cae FG |
937 | common.handle-options msvc : $(conditions) : $(command) : $(options) ; |
938 | ||
939 | if ! $(version) | |
940 | { | |
941 | # Even if version is not explicitly specified, try to detect the | |
942 | # version from the path. | |
943 | # FIXME: We currently detect both Microsoft Visual Studio 9.0 and | |
944 | # 9.0express as 9.0 here. | |
b32b8144 | 945 | if [ MATCH "(MSVC\\14.1)" : $(command) ] |
7c673cae | 946 | { |
b32b8144 | 947 | version = 14.1 ; |
7c673cae FG |
948 | } |
949 | else if [ MATCH "(Microsoft Visual Studio 14)" : $(command) ] | |
950 | { | |
951 | version = 14.0 ; | |
952 | } | |
953 | else if [ MATCH "(Microsoft Visual Studio 12)" : $(command) ] | |
954 | { | |
955 | version = 12.0 ; | |
956 | } | |
957 | else if [ MATCH "(Microsoft Visual Studio 11)" : $(command) ] | |
958 | { | |
959 | version = 11.0 ; | |
960 | } | |
961 | else if [ MATCH "(Microsoft Visual Studio 10)" : $(command) ] | |
962 | { | |
963 | version = 10.0 ; | |
964 | } | |
965 | else if [ MATCH "(Microsoft Visual Studio 9)" : $(command) ] | |
966 | { | |
967 | version = 9.0 ; | |
968 | } | |
969 | else if [ MATCH "(Microsoft Visual Studio 8)" : $(command) ] | |
970 | { | |
971 | version = 8.0 ; | |
972 | } | |
973 | else if [ MATCH "(NET 2003[\/\\]VC7)" : $(command) ] | |
974 | { | |
975 | version = 7.1 ; | |
976 | } | |
977 | else if [ MATCH "(Microsoft Visual C\\+\\+ Toolkit 2003)" : | |
978 | $(command) ] | |
979 | { | |
980 | version = 7.1toolkit ; | |
981 | } | |
982 | else if [ MATCH "(.NET[\/\\]VC7)" : $(command) ] | |
983 | { | |
984 | version = 7.0 ; | |
985 | } | |
986 | else | |
987 | { | |
988 | version = 6.0 ; | |
989 | } | |
990 | } | |
991 | ||
992 | # Generate and register setup command. | |
993 | ||
994 | local below-8.0 = [ MATCH ^([67]\\.) : $(version) ] ; | |
995 | local below-11.0 = [ MATCH ^([6789]\\.|10\\.) : $(version) ] ; | |
996 | ||
997 | local cpu = i386 amd64 ia64 arm ; | |
998 | if $(below-8.0) | |
999 | { | |
1000 | cpu = i386 ; | |
1001 | } | |
1002 | else if $(below-11.0) | |
1003 | { | |
1004 | cpu = i386 amd64 ia64 ; | |
1005 | } | |
1006 | ||
1007 | local setup-amd64 ; | |
1008 | local setup-i386 ; | |
1009 | local setup-ia64 ; | |
1010 | local setup-arm ; | |
1011 | local setup-phone-i386 ; | |
1012 | local setup-phone-arm ; | |
1013 | ||
1014 | if $(command) | |
1015 | { | |
1016 | # TODO: Note that if we specify a non-existant toolset version then | |
1017 | # this rule may find and use a corresponding compiler executable | |
1018 | # belonging to an incorrect toolset version. For example, if you | |
1019 | # have only MSVC 7.1 installed, have its executable on the path and | |
1020 | # specify you want Boost Build to use MSVC 9.0, then you want Boost | |
1021 | # Build to report an error but this may cause it to silently use the | |
1022 | # MSVC 7.1 compiler even though it thinks it is using the msvc-9.0 | |
1023 | # toolset version. | |
1024 | command = [ common.get-absolute-tool-path $(command[-1]) ] ; | |
1025 | } | |
1026 | ||
1027 | if $(command) | |
1028 | { | |
1029 | local parent = [ path.make $(command) ] ; | |
1030 | parent = [ path.parent $(parent) ] ; | |
1031 | parent = [ path.native $(parent) ] ; | |
1032 | ||
1033 | # Setup will be used if the command name has been specified. If | |
1034 | # setup is not specified explicitly then a default setup script will | |
1035 | # be used instead. Setup scripts may be global or architecture/ | |
1036 | # /platform/cpu specific. Setup options are used only in case of | |
1037 | # global setup scripts. | |
1038 | ||
1039 | # Default setup scripts provided with different VC distributions: | |
1040 | # | |
1041 | # VC 7.1 had only the vcvars32.bat script specific to 32 bit i386 | |
1042 | # builds. It was located in the bin folder for the regular version | |
1043 | # and in the root folder for the free VC 7.1 tools. | |
1044 | # | |
1045 | # Later 8.0 & 9.0 versions introduce separate platform specific | |
1046 | # vcvars*.bat scripts (e.g. 32 bit, 64 bit AMD or 64 bit Itanium) | |
1047 | # located in or under the bin folder. Most also include a global | |
1048 | # vcvarsall.bat helper script located in the root folder which runs | |
1049 | # one of the aforementioned vcvars*.bat scripts based on the options | |
1050 | # passed to it. So far only the version coming with some PlatformSDK | |
1051 | # distributions does not include this top level script but to | |
1052 | # support those we need to fall back to using the worker scripts | |
1053 | # directly in case the top level script can not be found. | |
1054 | ||
1055 | local global-setup = [ feature.get-values <setup> : $(options) ] ; | |
1056 | global-setup = $(global-setup[1]) ; | |
1057 | local global-setup-phone = $(global-setup) ; | |
1058 | if ! $(below-8.0) | |
1059 | { | |
1060 | global-setup ?= [ locate-default-setup $(command) : $(parent) : | |
1061 | vcvarsall.bat ] ; | |
1062 | } | |
1063 | ||
1064 | local default-setup-amd64 = vcvarsx86_amd64.bat ; | |
1065 | local default-setup-i386 = vcvars32.bat ; | |
1066 | local default-setup-ia64 = vcvarsx86_ia64.bat ; | |
1067 | local default-setup-arm = vcvarsx86_arm.bat ; | |
1068 | local default-setup-phone-i386 = vcvarsphonex86.bat ; | |
1069 | local default-setup-phone-arm = vcvarsphonex86_arm.bat ; | |
1070 | ||
1071 | # http://msdn2.microsoft.com/en-us/library/x4d2c09s(VS.80).aspx and | |
1072 | # http://msdn2.microsoft.com/en-us/library/x4d2c09s(vs.90).aspx | |
1073 | # mention an x86_IPF option, that seems to be a documentation bug | |
1074 | # and x86_ia64 is the correct option. | |
1075 | local default-global-setup-options-amd64 = x86_amd64 ; | |
1076 | local default-global-setup-options-i386 = x86 ; | |
1077 | local default-global-setup-options-ia64 = x86_ia64 ; | |
1078 | local default-global-setup-options-arm = x86_arm ; | |
1079 | ||
1080 | # When using 64-bit Windows, and targeting 64-bit, it is possible to | |
1081 | # use a native 64-bit compiler, selected by the "amd64" & "ia64" | |
1082 | # parameters to vcvarsall.bat. There are two variables we can use -- | |
1083 | # PROCESSOR_ARCHITECTURE and PROCESSOR_IDENTIFIER. The first is | |
1084 | # 'x86' when running 32-bit Windows, no matter which processor is | |
1085 | # used, and 'AMD64' on 64-bit windows on x86 (either AMD64 or EM64T) | |
1086 | # Windows. | |
1087 | # | |
1088 | if [ MATCH ^(AMD64) : [ os.environ PROCESSOR_ARCHITECTURE ] ] | |
1089 | { | |
1090 | default-global-setup-options-amd64 = amd64 ; | |
1091 | } | |
1092 | # When Boost.Build itself is running as a 32-bit process on 64-bit | |
1093 | # Windows, the above test will fail (since WOW64 simulates a 32-bit | |
1094 | # environment, including environment values). So check the WOW64 | |
1095 | # variable PROCESSOR_ARCHITEW6432 as well. | |
1096 | if [ MATCH ^(AMD64) : [ os.environ PROCESSOR_ARCHITEW6432 ] ] | |
1097 | { | |
1098 | default-global-setup-options-amd64 = amd64 ; | |
1099 | } | |
1100 | # TODO: The same 'native compiler usage' should be implemented for | |
1101 | # the Itanium platform by using the "ia64" parameter. For this | |
1102 | # though we need someone with access to this platform who can find | |
1103 | # out how to correctly detect this case. | |
1104 | else if $(somehow-detect-the-itanium-platform) | |
1105 | { | |
1106 | default-global-setup-options-ia64 = ia64 ; | |
1107 | } | |
1108 | ||
1109 | for local c in $(cpu) | |
1110 | { | |
b32b8144 FG |
1111 | exact-version ?= $(version) ; |
1112 | setup-$(c) = [ generate-setup-cmd $(exact-version) : $(command) : $(parent) : $(options) : $(c) : $(global-setup) : $(default-global-setup-options-$(c)) : $(default-setup-$(c)) ] ; | |
7c673cae FG |
1113 | } |
1114 | ||
1115 | # Windows phone has different setup scripts, located in a different directory hierarchy. | |
1116 | # The 11.0 toolset can target Windows Phone 8.0 and the 12.0 toolset can target Windows Phone 8.1, | |
1117 | # each of which have a different directory for their vcvars setup scripts. | |
1118 | local phone-parent = [ path.native [ path.join $(parent) WPSDK ] ] ; | |
1119 | local phone-directory = $(phone-parent) ; | |
1120 | if [ MATCH "(11.0)" : $(version) ] | |
1121 | { | |
1122 | phone-directory = [ path.native [ path.join $(phone-directory) WP80 ] ] ; | |
1123 | } | |
1124 | else if [ MATCH "(12.0)" : $(version) ] | |
1125 | { | |
1126 | phone-directory = [ path.native [ path.join $(phone-directory) WP81 ] ] ; | |
1127 | } | |
1128 | global-setup-phone ?= [ locate-default-setup $(phone-directory) : $(phone-parent) : vcvarsphoneall.bat ] ; | |
1129 | ||
1130 | # If can't locate default phone setup script then this VS version doesn't support Windows Phone. | |
1131 | if $(global-setup-phone)-is-defined | |
1132 | { | |
1133 | # i386 CPU is for the Windows Phone emulator in Visual Studio. | |
1134 | local phone-cpu = i386 arm ; | |
1135 | for local c in $(phone-cpu) | |
1136 | { | |
1137 | setup-phone-$(c) = [ generate-setup-cmd $(version) : $(phone-directory) : $(phone-parent) : $(options) : $(c) : $(global-setup-phone) : $(default-global-setup-options-$(c)) : $(default-setup-phone-$(c)) ] ; | |
1138 | } | |
1139 | } | |
1140 | } | |
1141 | ||
1142 | # Get tool names (if any) and finish setup. | |
1143 | ||
1144 | compiler = [ feature.get-values <compiler> : $(options) ] ; | |
1145 | compiler ?= cl ; | |
1146 | ||
1147 | linker = [ feature.get-values <linker> : $(options) ] ; | |
1148 | linker ?= link ; | |
1149 | ||
1150 | resource-compiler = [ feature.get-values <resource-compiler> : $(options) ] ; | |
1151 | resource-compiler ?= rc ; | |
1152 | ||
1153 | # Turn on some options for i386 assembler | |
1154 | # -coff generate COFF format object file (compatible with cl.exe output) | |
1155 | local default-assembler-amd64 = ml64 ; | |
1156 | local default-assembler-i386 = "ml -coff" ; | |
1157 | local default-assembler-ia64 = ias ; | |
1158 | local default-assembler-ia64 = armasm ; | |
1159 | ||
1160 | assembler = [ feature.get-values <assembler> : $(options) ] ; | |
1161 | ||
1162 | idl-compiler = [ feature.get-values <idl-compiler> : $(options) ] ; | |
1163 | idl-compiler ?= midl ; | |
1164 | ||
1165 | mc-compiler = [ feature.get-values <mc-compiler> : $(options) ] ; | |
1166 | mc-compiler ?= mc ; | |
1167 | ||
1168 | manifest-tool = [ feature.get-values <manifest-tool> : $(options) ] ; | |
1169 | manifest-tool ?= mt ; | |
1170 | ||
1171 | local cc-filter = [ feature.get-values <compiler-filter> : $(options) ] | |
1172 | ; | |
1173 | ||
1174 | for local c in $(cpu) | |
1175 | { | |
1176 | # Setup script is not required in some configurations. | |
1177 | setup-$(c) ?= "" ; | |
1178 | ||
1179 | local cpu-conditions = $(conditions)/$(.cpu-arch-$(c)) ; | |
1180 | ||
1181 | if $(.debug-configuration) | |
1182 | { | |
1183 | for local cpu-condition in $(cpu-conditions) | |
1184 | { | |
1185 | ECHO "notice: [msvc-cfg] condition: '$(cpu-condition)', setup: '$(setup-$(c))'" ; | |
1186 | } | |
1187 | } | |
1188 | ||
1189 | local cpu-assembler = $(assembler) ; | |
1190 | cpu-assembler ?= $(default-assembler-$(c)) ; | |
1191 | ||
1192 | toolset.flags msvc.compile .RC <windows-api>$(api)/$(cpu-conditions) : $(setup-$(c))$(resource-compiler) ; | |
1193 | toolset.flags msvc.compile .IDL <windows-api>$(api)/$(cpu-conditions) : $(setup-$(c))$(idl-compiler) ; | |
1194 | toolset.flags msvc.compile .MC <windows-api>$(api)/$(cpu-conditions) : $(setup-$(c))$(mc-compiler) ; | |
1195 | toolset.flags msvc.link .MT <windows-api>$(api)/$(cpu-conditions) : $(setup-$(c))$(manifest-tool) -nologo ; | |
1196 | ||
1197 | for api in desktop store phone | |
1198 | { | |
1199 | local setup-script = $(setup-$(c)) ; | |
1200 | if $(api) = phone | |
1201 | { | |
1202 | setup-script = $(setup-phone-$(c)) ; | |
1203 | } | |
1204 | if $(api) = desktop | |
1205 | { | |
1206 | toolset.flags msvc.compile .CC <windows-api>$(api)/$(cpu-conditions) : $(setup-script)$(compiler) /Zm800 -nologo ; | |
1207 | } | |
1208 | else | |
1209 | { | |
1210 | toolset.flags msvc.compile .CC <windows-api>$(api)/$(cpu-conditions) : $(setup-script)$(compiler) /Zm800 /ZW /EHsc -nologo ; | |
1211 | } | |
1212 | toolset.flags msvc.compile .ASM <windows-api>$(api)/$(cpu-conditions) : $(setup-script)$(cpu-assembler) -nologo ; | |
1213 | toolset.flags msvc.link .LD <windows-api>$(api)/$(cpu-conditions) : $(setup-script)$(linker) /NOLOGO /INCREMENTAL:NO ; | |
1214 | toolset.flags msvc.archive .LD <windows-api>$(api)/$(cpu-conditions) : $(setup-script)$(linker) /lib /NOLOGO ; | |
1215 | } | |
1216 | ||
1217 | if $(cc-filter) | |
1218 | { | |
1219 | toolset.flags msvc .CC.FILTER $(cpu-conditions) : "|" $(cc-filter) ; | |
1220 | } | |
1221 | } | |
1222 | ||
1223 | # Starting with Visual Studio 2013 the CRT is split into a desktop and app dll. | |
1224 | # If targeting WinRT and 12.0 set lib path to link against app CRT. | |
1225 | if [ MATCH "(12)" : $(version) ] | |
1226 | { | |
1227 | local storeLibPath = [ path.join $(parent) "lib/store" ] ; | |
1228 | toolset.flags msvc.link LINKPATH $(conditions)/<windows-api>store/$(.cpu-arch-i386) : [ path.native $(storeLibPath) ] ; | |
1229 | toolset.flags msvc.link LINKPATH $(conditions)/<windows-api>store/$(.cpu-arch-amd64) : [ path.native [ path.join $(storeLibPath) "amd64" ] ] ; | |
1230 | toolset.flags msvc.link LINKPATH $(conditions)/<windows-api>store/$(.cpu-arch-arm) : [ path.native [ path.join $(storeLibPath) "arm" ] ] ; | |
1231 | } | |
1232 | ||
1233 | # Set version-specific flags. | |
1234 | configure-version-specific msvc : $(version) : $(conditions) ; | |
1235 | } | |
1236 | } | |
1237 | ||
1238 | ||
1239 | # Returns the default installation path for the given version. | |
1240 | # | |
1241 | local rule default-path ( version ) | |
1242 | { | |
1243 | # Use auto-detected path if possible. | |
b32b8144 | 1244 | local result = [ feature.get-values <command> : [ $(.versions).get $(version) |
7c673cae FG |
1245 | : options ] ] ; |
1246 | ||
b32b8144 | 1247 | if $(result) |
7c673cae | 1248 | { |
b32b8144 | 1249 | result = $(result:D) ; |
7c673cae FG |
1250 | } |
1251 | else | |
1252 | { | |
b32b8144 FG |
1253 | # try to use vswhere |
1254 | local pseudo_env_VS150 ; | |
1255 | if $(version) = 14.1 || $(version) = "default" | |
7c673cae | 1256 | { |
b32b8144 FG |
1257 | local req = "-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64" ; |
1258 | local prop = "-property installationPath" ; | |
1259 | local limit = "-version \"[15.0,16.0)\"" ; | |
1260 | local root = [ os.environ "ProgramFiles(x86)" ] ; | |
1261 | if ( ! $(root) ) | |
7c673cae | 1262 | { |
b32b8144 FG |
1263 | root = [ os.environ "ProgramFiles" ] ; |
1264 | } | |
1265 | local vswhere = "$(root)\\Microsoft Visual Studio\\Installer\\vswhere.exe" ; | |
1266 | if ( [ path.exists $(vswhere) ] ) | |
1267 | { | |
1268 | local vmwhere_cmd = "\"$(vswhere)\" -latest -products * $(req) $(prop) $(limit)" ; | |
1269 | local shell_ret = [ SPLIT_BY_CHARACTERS [ SHELL $(vmwhere_cmd) ] : "\n" ] ; | |
1270 | pseudo_env_VS150 = [ path.native [ path.join $(shell_ret) "\\Common7\\Tools" ] ] ; | |
7c673cae FG |
1271 | } |
1272 | } | |
1273 | ||
b32b8144 FG |
1274 | # Check environment or previous path_VS150 |
1275 | for local env in $(.version-$(version)-env) | |
7c673cae | 1276 | { |
b32b8144 FG |
1277 | local env-path ; |
1278 | if ( $(pseudo_env_VS150) && [ path.exists $(pseudo_env_VS150) ] ) | |
1279 | { | |
1280 | env-path = $(pseudo_env_VS150) ; | |
1281 | } | |
1282 | else | |
1283 | { | |
1284 | env-path = [ os.environ $(env) ] ; | |
1285 | } | |
1286 | if $(env-path) && $(.version-$(version)-path) | |
1287 | { | |
1288 | for local bin-path in $(.version-$(version)-path) | |
1289 | { | |
1290 | result = [ path.glob [ path.make $(env-path) ] : $(bin-path) ] ; | |
1291 | if $(result) | |
1292 | { | |
1293 | result = [ path.native $(result[1]) ] ; | |
1294 | break ; | |
1295 | } | |
1296 | } | |
1297 | } | |
1298 | if $(result) | |
1299 | { | |
1300 | break ; | |
1301 | } | |
7c673cae FG |
1302 | } |
1303 | } | |
1304 | ||
b32b8144 | 1305 | return $(result) ; |
7c673cae FG |
1306 | } |
1307 | ||
1308 | ||
1309 | # Returns either the default installation path (if 'version' is not empty) or | |
1310 | # list of all known default paths (if no version is given) | |
1311 | # | |
1312 | local rule default-paths ( version ? ) | |
1313 | { | |
1314 | local possible-paths ; | |
1315 | ||
1316 | if $(version) | |
1317 | { | |
1318 | possible-paths += [ default-path $(version) ] ; | |
1319 | } | |
1320 | else | |
1321 | { | |
1322 | for local i in $(.known-versions) | |
1323 | { | |
1324 | possible-paths += [ default-path $(i) ] ; | |
1325 | } | |
1326 | } | |
1327 | ||
1328 | return $(possible-paths) ; | |
1329 | } | |
1330 | ||
1331 | ||
1332 | rule get-rspline ( target : lang-opt ) | |
1333 | { | |
1334 | CC_RSPLINE on $(target) = [ on $(target) return $(lang-opt) -U$(UNDEFS) | |
1335 | $(CFLAGS) $(C++FLAGS) $(OPTIONS) -c $(.nl)-D$(DEFINES) | |
1336 | $(.nl)\"-I$(INCLUDES:W)\" ] ; | |
1337 | } | |
1338 | ||
1339 | class msvc-linking-generator : linking-generator | |
1340 | { | |
1341 | # Calls the base version. If necessary, also create a target for the | |
1342 | # manifest file.specifying source's name as the name of the created | |
1343 | # target. As result, the PCH will be named whatever.hpp.gch, and not | |
1344 | # whatever.gch. | |
1345 | rule generated-targets ( sources + : property-set : project name ? ) | |
1346 | { | |
1347 | local result = [ linking-generator.generated-targets $(sources) | |
1348 | : $(property-set) : $(project) $(name) ] ; | |
1349 | ||
1350 | if $(result) | |
1351 | { | |
1352 | local name-main = [ $(result[0]).name ] ; | |
1353 | local action = [ $(result[0]).action ] ; | |
1354 | ||
1355 | if [ $(property-set).get <debug-symbols> ] = "on" | |
1356 | { | |
1357 | # We force the exact name on PDB. The reason is tagging -- the | |
1358 | # tag rule may reasonably special case some target types, like | |
1359 | # SHARED_LIB. The tag rule will not catch PDBs, and it cannot | |
1360 | # even easily figure out if a PDB is paired with a SHARED_LIB, | |
1361 | # EXE or something else. Because PDBs always get the same name | |
1362 | # as the main target, with .pdb as extension, just force it. | |
1363 | local target = [ class.new file-target $(name-main:S=.pdb) exact | |
1364 | : PDB : $(project) : $(action) ] ; | |
1365 | local registered-target = [ virtual-target.register $(target) ] | |
1366 | ; | |
1367 | if $(target) != $(registered-target) | |
1368 | { | |
1369 | $(action).replace-targets $(target) : $(registered-target) ; | |
1370 | } | |
1371 | result += $(registered-target) ; | |
1372 | } | |
1373 | ||
1374 | if [ $(property-set).get <embed-manifest> ] = "off" | |
1375 | { | |
1376 | # Manifest is an evil target. It has .manifest appened to the | |
1377 | # name of the main target, including extension, e.g. | |
1378 | # a.exe.manifest. We use the 'exact' name to achieve this | |
1379 | # effect. | |
1380 | local target = [ class.new file-target $(name-main).manifest | |
1381 | exact : MANIFEST : $(project) : $(action) ] ; | |
1382 | local registered-target = [ virtual-target.register $(target) ] | |
1383 | ; | |
1384 | if $(target) != $(registered-target) | |
1385 | { | |
1386 | $(action).replace-targets $(target) : $(registered-target) ; | |
1387 | } | |
1388 | result += $(registered-target) ; | |
1389 | } | |
1390 | } | |
1391 | return $(result) ; | |
1392 | } | |
1393 | } | |
1394 | ||
1395 | ||
1396 | # Unsafe worker rule for the register-toolset() rule. Must not be called | |
1397 | # multiple times. | |
1398 | # | |
1399 | local rule register-toolset-really ( ) | |
1400 | { | |
1401 | feature.extend toolset : msvc ; | |
1402 | ||
1403 | # Intel and msvc supposedly have link-compatible objects. | |
1404 | feature.subfeature toolset msvc : vendor : intel : propagated optional ; | |
1405 | ||
1406 | # Inherit MIDL flags. | |
1407 | toolset.inherit-flags msvc : midl ; | |
1408 | ||
1409 | # Inherit MC flags. | |
1410 | toolset.inherit-flags msvc : mc ; | |
1411 | ||
1412 | # Dynamic runtime comes only in MT flavour. | |
1413 | toolset.add-requirements | |
1414 | <toolset>msvc,<runtime-link>shared:<threading>multi ; | |
1415 | ||
1416 | # Declare msvc toolset specific features. | |
1417 | { | |
1418 | feature.feature debug-store : object database : propagated ; | |
1419 | feature.feature pch-source : : dependency free ; | |
1420 | } | |
1421 | ||
1422 | # Declare generators. | |
1423 | { | |
1424 | # TODO: Is it possible to combine these? Make the generators | |
1425 | # non-composing so that they do not convert each source into a separate | |
1426 | # .rsp file. | |
1427 | generators.register [ new msvc-linking-generator msvc.link : | |
1428 | OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : EXE : <toolset>msvc ] ; | |
1429 | generators.register [ new msvc-linking-generator msvc.link.dll : | |
1430 | OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB IMPORT_LIB : | |
1431 | <toolset>msvc <suppress-import-lib>false ] ; | |
1432 | generators.register [ new msvc-linking-generator msvc.link.dll : | |
1433 | OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB : | |
1434 | <toolset>msvc <suppress-import-lib>true ] ; | |
1435 | ||
1436 | generators.register-archiver msvc.archive : OBJ : STATIC_LIB : <toolset>msvc ; | |
1437 | generators.register-c-compiler msvc.compile.c++ : CPP : OBJ : <toolset>msvc ; | |
1438 | generators.register-c-compiler msvc.compile.c : C : OBJ : <toolset>msvc ; | |
1439 | generators.register-c-compiler msvc.compile.c++.preprocess : CPP : PREPROCESSED_CPP : <toolset>msvc ; | |
1440 | generators.register-c-compiler msvc.compile.c.preprocess : C : PREPROCESSED_C : <toolset>msvc ; | |
1441 | ||
1442 | # Using 'register-c-compiler' adds the build directory to INCLUDES. | |
1443 | generators.register-c-compiler msvc.compile.rc : RC : OBJ(%_res) : <toolset>msvc ; | |
1444 | generators.override msvc.compile.rc : rc.compile.resource ; | |
1445 | generators.register-standard msvc.compile.asm : ASM : OBJ : <toolset>msvc ; | |
1446 | ||
1447 | generators.register-c-compiler msvc.compile.idl : IDL : MSTYPELIB H C(%_i) C(%_proxy) C(%_dlldata) : <toolset>msvc ; | |
1448 | generators.override msvc.compile.idl : midl.compile.idl ; | |
1449 | ||
1450 | generators.register-standard msvc.compile.mc : MC : H RC : <toolset>msvc ; | |
1451 | generators.override msvc.compile.mc : mc.compile ; | |
1452 | ||
1453 | # Note: the 'H' source type will catch both '.h' and '.hpp' headers as | |
1454 | # the latter have their HPP type derived from H. The type of compilation | |
1455 | # is determined entirely by the destination type. | |
1456 | generators.register [ new msvc-pch-generator msvc.compile.c.pch : H : C_PCH OBJ : <pch>on <toolset>msvc ] ; | |
1457 | generators.register [ new msvc-pch-generator msvc.compile.c++.pch : H : CPP_PCH OBJ : <pch>on <toolset>msvc ] ; | |
1458 | ||
1459 | generators.override msvc.compile.c.pch : pch.default-c-pch-generator ; | |
1460 | generators.override msvc.compile.c++.pch : pch.default-cpp-pch-generator ; | |
1461 | } | |
1462 | ||
1463 | toolset.flags msvc.compile PCH_FILE <pch>on : <pch-file> ; | |
1464 | toolset.flags msvc.compile PCH_SOURCE <pch>on : <pch-source> ; | |
1465 | toolset.flags msvc.compile PCH_HEADER <pch>on : <pch-header> ; | |
1466 | ||
1467 | # | |
1468 | # Declare flags for compilation. | |
1469 | # | |
1470 | ||
1471 | toolset.flags msvc.compile CFLAGS <optimization>speed : /O2 ; | |
1472 | toolset.flags msvc.compile CFLAGS <optimization>space : /O1 ; | |
1473 | ||
1474 | toolset.flags msvc.compile CFLAGS $(.cpu-arch-ia64)/<instruction-set>$(.cpu-type-itanium) : /G1 ; | |
1475 | toolset.flags msvc.compile CFLAGS $(.cpu-arch-ia64)/<instruction-set>$(.cpu-type-itanium2) : /G2 ; | |
1476 | ||
1477 | toolset.flags msvc.compile CFLAGS <debug-symbols>on/<debug-store>object : /Z7 ; | |
1478 | toolset.flags msvc.compile CFLAGS <debug-symbols>on/<debug-store>database : /Zi ; | |
1479 | toolset.flags msvc.compile CFLAGS <optimization>off : /Od ; | |
1480 | toolset.flags msvc.compile CFLAGS <inlining>off : /Ob0 ; | |
1481 | toolset.flags msvc.compile CFLAGS <inlining>on : /Ob1 ; | |
1482 | toolset.flags msvc.compile CFLAGS <inlining>full : /Ob2 ; | |
1483 | ||
1484 | toolset.flags msvc.compile CFLAGS <warnings>on : /W3 ; | |
1485 | toolset.flags msvc.compile CFLAGS <warnings>off : /W0 ; | |
1486 | toolset.flags msvc.compile CFLAGS <warnings>all : /W4 ; | |
1487 | toolset.flags msvc.compile CFLAGS <warnings-as-errors>on : /WX ; | |
1488 | ||
1489 | toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>off/<extern-c-nothrow>off : /EHs ; | |
1490 | toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>off/<extern-c-nothrow>on : /EHsc ; | |
1491 | toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>on/<extern-c-nothrow>off : /EHa ; | |
1492 | toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>on/<extern-c-nothrow>on : /EHac ; | |
1493 | ||
b32b8144 FG |
1494 | toolset.flags msvc.compile C++FLAGS <cxxstd>14 : /std:c++14 ; |
1495 | toolset.flags msvc.compile C++FLAGS <cxxstd>17 : /std:c++17 ; | |
1496 | toolset.flags msvc.compile C++FLAGS <cxxstd>latest : /std:c++latest ; | |
1497 | ||
7c673cae FG |
1498 | # By default 8.0 enables rtti support while prior versions disabled it. We |
1499 | # simply enable or disable it explicitly so we do not have to depend on this | |
1500 | # default behaviour. | |
1501 | toolset.flags msvc.compile CFLAGS <rtti>on : /GR ; | |
1502 | toolset.flags msvc.compile CFLAGS <rtti>off : /GR- ; | |
1503 | toolset.flags msvc.compile CFLAGS <runtime-debugging>off/<runtime-link>shared : /MD ; | |
1504 | toolset.flags msvc.compile CFLAGS <runtime-debugging>on/<runtime-link>shared : /MDd ; | |
1505 | ||
1506 | toolset.flags msvc.compile CFLAGS <runtime-debugging>off/<runtime-link>static/<threading>multi : /MT ; | |
1507 | toolset.flags msvc.compile CFLAGS <runtime-debugging>on/<runtime-link>static/<threading>multi : /MTd ; | |
1508 | ||
1509 | toolset.flags msvc.compile OPTIONS <cflags> : ; | |
1510 | toolset.flags msvc.compile.c++ OPTIONS <cxxflags> : ; | |
1511 | ||
1512 | toolset.flags msvc.compile PDB_CFLAG <debug-symbols>on/<debug-store>database : /Fd ; | |
1513 | ||
1514 | toolset.flags msvc.compile DEFINES <define> ; | |
1515 | toolset.flags msvc.compile UNDEFS <undef> ; | |
1516 | toolset.flags msvc.compile INCLUDES <include> ; | |
1517 | ||
1518 | # Declare flags for the assembler. | |
1519 | toolset.flags msvc.compile.asm USER_ASMFLAGS <asmflags> ; | |
1520 | ||
1521 | toolset.flags msvc.compile.asm ASMFLAGS <debug-symbols>on : "/Zi /Zd" ; | |
1522 | ||
1523 | toolset.flags msvc.compile.asm ASMFLAGS <warnings>on : /W3 ; | |
1524 | toolset.flags msvc.compile.asm ASMFLAGS <warnings>off : /W0 ; | |
1525 | toolset.flags msvc.compile.asm ASMFLAGS <warnings>all : /W4 ; | |
1526 | toolset.flags msvc.compile.asm ASMFLAGS <warnings-as-errors>on : /WX ; | |
1527 | ||
1528 | toolset.flags msvc.compile.asm DEFINES <define> ; | |
1529 | ||
1530 | # Declare flags for linking. | |
1531 | { | |
1532 | toolset.flags msvc.link PDB_LINKFLAG <debug-symbols>on/<debug-store>database : /PDB: ; # not used yet | |
1533 | toolset.flags msvc.link LINKFLAGS <debug-symbols>on : /DEBUG ; | |
1534 | toolset.flags msvc.link DEF_FILE <def-file> ; | |
1535 | ||
1536 | # The linker disables the default optimizations when using /DEBUG so we | |
1537 | # have to enable them manually for release builds with debug symbols. | |
1538 | toolset.flags msvc LINKFLAGS <debug-symbols>on/<runtime-debugging>off : /OPT:REF,ICF ; | |
1539 | ||
1540 | toolset.flags msvc LINKFLAGS <user-interface>console : /subsystem:console ; | |
1541 | toolset.flags msvc LINKFLAGS <user-interface>gui : /subsystem:windows ; | |
1542 | toolset.flags msvc LINKFLAGS <user-interface>wince : /subsystem:windowsce ; | |
1543 | toolset.flags msvc LINKFLAGS <user-interface>native : /subsystem:native ; | |
1544 | toolset.flags msvc LINKFLAGS <user-interface>auto : /subsystem:posix ; | |
1545 | ||
1546 | toolset.flags msvc.link OPTIONS <linkflags> ; | |
1547 | toolset.flags msvc.link LINKPATH <library-path> ; | |
1548 | ||
1549 | toolset.flags msvc.link FINDLIBS_ST <find-static-library> ; | |
1550 | toolset.flags msvc.link FINDLIBS_SA <find-shared-library> ; | |
1551 | toolset.flags msvc.link LIBRARY_OPTION <toolset>msvc : "" : unchecked ; | |
1552 | toolset.flags msvc.link LIBRARIES_MENTIONED_BY_FILE : <library-file> ; | |
1553 | ||
1554 | toolset.flags msvc.link.dll LINKFLAGS <suppress-import-lib>true : /NOENTRY ; | |
1555 | } | |
1556 | ||
1557 | toolset.flags msvc.archive AROPTIONS <archiveflags> ; | |
1558 | } | |
1559 | ||
1560 | ||
1561 | # Locates the requested setup script under the given folder and returns its full | |
1562 | # path or nothing in case the script can not be found. In case multiple scripts | |
1563 | # are found only the first one is returned. | |
1564 | # | |
1565 | # TODO: There used to exist a code comment for the msvc.init rule stating that | |
1566 | # we do not correctly detect the location of the vcvars32.bat setup script for | |
1567 | # the free VC7.1 tools in case user explicitly provides a path. This should be | |
1568 | # tested or simply remove this whole comment in case this toolset version is no | |
1569 | # longer important. | |
1570 | # | |
1571 | local rule locate-default-setup ( command : parent : setup-name ) | |
1572 | { | |
1573 | local result = [ GLOB $(command) $(parent) : $(setup-name) ] ; | |
1574 | if $(result[1]) | |
1575 | { | |
1576 | return $(result[1]) ; | |
1577 | } | |
1578 | } | |
1579 | ||
1580 | ||
1581 | # Validates given path, registers found configuration and prints debug | |
1582 | # information about it. | |
1583 | # | |
1584 | local rule register-configuration ( version : path ? ) | |
1585 | { | |
1586 | if $(path) | |
1587 | { | |
1588 | local command = [ GLOB $(path) : cl.exe ] ; | |
1589 | ||
1590 | if $(command) | |
1591 | { | |
1592 | if $(.debug-configuration) | |
1593 | { | |
1594 | ECHO notice: [msvc-cfg] msvc-$(version) detected, command: | |
1595 | '$(command)' ; | |
1596 | } | |
1597 | ||
1598 | $(.versions).register $(version) ; | |
1599 | $(.versions).set $(version) : options : <command>$(command) ; | |
1600 | } | |
1601 | } | |
1602 | } | |
1603 | ||
1604 | ||
1605 | ################################################################################ | |
1606 | # | |
1607 | # Startup code executed when loading this module. | |
1608 | # | |
1609 | ################################################################################ | |
1610 | ||
1611 | if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ] | |
1612 | { | |
1613 | .debug-configuration = true ; | |
1614 | } | |
1615 | ||
1616 | # Miscellaneous constants. | |
1617 | .RM = [ common.rm-command ] ; | |
1618 | .nl = " | |
1619 | " ; | |
1620 | .ProgramFiles = [ path.make [ common.get-program-files-dir ] ] ; | |
1621 | .escaped-double-quote = "\"" ; | |
1622 | .TOUCH_FILE = [ common.file-touch-command ] ; | |
1623 | ||
1624 | # List of all registered configurations. | |
1625 | .versions = [ new configurations ] ; | |
1626 | ||
1627 | # Supported CPU architectures. | |
1628 | .cpu-arch-i386 = | |
1629 | <architecture>/<address-model> | |
1630 | <architecture>/<address-model>32 | |
1631 | <architecture>x86/<address-model> | |
1632 | <architecture>x86/<address-model>32 ; | |
1633 | ||
1634 | .cpu-arch-amd64 = | |
1635 | <architecture>/<address-model>64 | |
1636 | <architecture>x86/<address-model>64 ; | |
1637 | ||
1638 | .cpu-arch-ia64 = | |
1639 | <architecture>ia64/<address-model> | |
1640 | <architecture>ia64/<address-model>64 ; | |
1641 | ||
1642 | .cpu-arch-arm = | |
1643 | <architecture>arm/<address-model> | |
1644 | <architecture>arm/<address-model>32 ; | |
1645 | ||
1646 | ||
1647 | # Supported CPU types (only Itanium optimization options are supported from | |
1648 | # VC++ 2005 on). See | |
1649 | # http://msdn2.microsoft.com/en-us/library/h66s5s0e(vs.90).aspx for more | |
1650 | # detailed information. | |
1651 | .cpu-type-g5 = i586 pentium pentium-mmx ; | |
1652 | .cpu-type-g6 = i686 pentiumpro pentium2 pentium3 pentium3m pentium-m k6 | |
1653 | k6-2 k6-3 winchip-c6 winchip2 c3 c3-2 ; | |
1654 | .cpu-type-em64t = prescott nocona core2 corei7 corei7-avx core-avx-i | |
1655 | conroe conroe-xe conroe-l allendale merom | |
1656 | merom-xe kentsfield kentsfield-xe penryn wolfdale | |
b32b8144 FG |
1657 | yorksfield nehalem sandy-bridge ivy-bridge haswell |
1658 | broadwell skylake skylake-avx512 cannonlake ; | |
7c673cae FG |
1659 | .cpu-type-amd64 = k8 opteron athlon64 athlon-fx k8-sse3 opteron-sse3 |
1660 | athlon64-sse3 amdfam10 barcelona bdver1 bdver2 bdver3 | |
b32b8144 | 1661 | bdver4 btver1 btver2 znver1 ; |
7c673cae FG |
1662 | .cpu-type-g7 = pentium4 pentium4m athlon athlon-tbird athlon-4 athlon-xp |
1663 | athlon-mp $(.cpu-type-em64t) $(.cpu-type-amd64) ; | |
1664 | .cpu-type-itanium = itanium itanium1 merced ; | |
1665 | .cpu-type-itanium2 = itanium2 mckinley ; | |
1666 | .cpu-type-arm = armv2 armv2a armv3 armv3m armv4 armv4t armv5 armv5t armv5te armv6 armv6j iwmmxt ep9312 | |
1667 | armv7 armv7s ; | |
1668 | ||
1669 | # Known toolset versions, in order of preference. | |
b32b8144 | 1670 | .known-versions = 14.1 14.0 12.0 11.0 10.0 10.0express 9.0 9.0express 8.0 8.0express 7.1 |
7c673cae FG |
1671 | 7.1toolkit 7.0 6.0 ; |
1672 | ||
1673 | # Version aliases. | |
1674 | .version-alias-6 = 6.0 ; | |
1675 | .version-alias-6.5 = 6.0 ; | |
1676 | .version-alias-7 = 7.0 ; | |
1677 | .version-alias-8 = 8.0 ; | |
1678 | .version-alias-9 = 9.0 ; | |
1679 | .version-alias-10 = 10.0 ; | |
1680 | .version-alias-11 = 11.0 ; | |
1681 | .version-alias-12 = 12.0 ; | |
1682 | .version-alias-14 = 14.0 ; | |
b32b8144 | 1683 | .version-alias-14.1 = 14.1 ; |
7c673cae FG |
1684 | |
1685 | # Names of registry keys containing the Visual C++ installation path (relative | |
1686 | # to "HKEY_LOCAL_MACHINE\SOFTWARE\\Microsoft"). | |
1687 | .version-6.0-reg = "VisualStudio\\6.0\\Setup\\Microsoft Visual C++" ; | |
1688 | .version-7.0-reg = "VisualStudio\\7.0\\Setup\\VC" ; | |
1689 | .version-7.1-reg = "VisualStudio\\7.1\\Setup\\VC" ; | |
1690 | .version-8.0-reg = "VisualStudio\\8.0\\Setup\\VC" ; | |
1691 | .version-8.0express-reg = "VCExpress\\8.0\\Setup\\VC" ; | |
1692 | .version-9.0-reg = "VisualStudio\\9.0\\Setup\\VC" ; | |
1693 | .version-9.0express-reg = "VCExpress\\9.0\\Setup\\VC" ; | |
1694 | .version-10.0-reg = "VisualStudio\\10.0\\Setup\\VC" ; | |
1695 | .version-10.0express-reg = "VCExpress\\10.0\\Setup\\VC" ; | |
1696 | .version-11.0-reg = "VisualStudio\\11.0\\Setup\\VC" ; | |
1697 | .version-12.0-reg = "VisualStudio\\12.0\\Setup\\VC" ; | |
1698 | .version-14.0-reg = "VisualStudio\\14.0\\Setup\\VC" ; | |
7c673cae FG |
1699 | |
1700 | # Visual C++ Toolkit 2003 does not store its installation path in the registry. | |
1701 | # The environment variable 'VCToolkitInstallDir' and the default installation | |
1702 | # path will be checked instead. | |
b32b8144 | 1703 | .version-7.1toolkit-path = "Microsoft Visual C++ Toolkit 2003/bin" ; |
7c673cae | 1704 | .version-7.1toolkit-env = VCToolkitInstallDir ; |
b32b8144 FG |
1705 | # Visual Studio 2017 doesn't use a registry at all. And the suggested methods |
1706 | # of discovery involve having a compiled program. So as a fallback we search | |
1707 | # paths for VS2017 (aka msvc >= 14.1). | |
1708 | .version-14.1-path = | |
1709 | "../../VC/Tools/MSVC/*/bin/Host*/*" | |
1710 | "Microsoft Visual Studio/2017/*/VC/Tools/MSVC/*/bin/Host*/*" | |
1711 | ; | |
1712 | .version-14.1-env = VS150COMNTOOLS ProgramFiles ProgramFiles(x86) ; | |
7c673cae FG |
1713 | |
1714 | # Auto-detect all the available msvc installations on the system. | |
1715 | auto-detect-toolset-versions ; | |
1716 | ||
1717 | ||
1718 | # And finally trigger the actual Boost Build toolset registration. | |
1719 | register-toolset ; |