]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/build/src/tools/msvc.jam
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / tools / build / src / tools / msvc.jam
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
6 # Copyright (c) 2007-2017 Rene Rivera
7 # Copyright (c) 2008 Jurko Gospodnetic
8 # Copyright (c) 2014 Microsoft Corporation
9 # Copyright (c) 2019 Michał Janiszewski
10 # Copyright (c) 2020 Nikita Kniazev
11 #
12 # Distributed under the Boost Software License, Version 1.0.
13 # (See accompanying file LICENSE.txt or copy at
14 # https://www.bfgroup.xyz/b2/LICENSE.txt)
15
16 #| tag::doc[]
17
18 [[bbv2.reference.tools.compiler.msvc]]
19 = Microsoft Visual C++
20
21 The `msvc` module supports the
22 http://msdn.microsoft.com/visualc/[Microsoft Visual C++] command-line
23 tools on Microsoft Windows. The supported products and versions of
24 command line tools are listed below:
25
26 * Visual Studio 2019-14.2
27 * Visual Studio 2017—14.1
28 * Visual Studio 2015—14.0
29 * Visual Studio 2013—12.0
30 * Visual Studio 2012—11.0
31 * Visual Studio 2010—10.0
32 * Visual Studio 2008—9.0
33 * Visual Studio 2005—8.0
34 * Visual Studio .NET 2003—7.1
35 * Visual Studio .NET—7.0
36 * Visual Studio 6.0, Service Pack 5--6.5
37
38 The user would then call the boost build executable with the toolset set
39 equal to `msvc-[version number]` for example to build with Visual Studio
40 2019 one could run:
41
42 ----
43 .\b2 toolset=msvc-14.2 target
44 ----
45
46 The `msvc` module is initialized using the following syntax:
47
48 ----
49 using msvc : [version] : [c++-compile-command] : [compiler options] ;
50 ----
51
52 This statement may be repeated several times, if you want to configure
53 several versions of the compiler.
54
55 If the version is not explicitly specified, the most recent version
56 found in the registry will be used instead. If the special value `all`
57 is passed as the version, all versions found in the registry will be
58 configured. If a version is specified, but the command is not, the
59 compiler binary will be searched in standard installation paths for that
60 version, followed by PATH.
61
62 The compiler command should be specified using forward slashes, and
63 quoted.
64
65 The following options can be provided, using
66 _`<option-name>option-value syntax`_:
67
68 `cflags`::
69 Specifies additional compiler flags that will be used when compiling C
70 sources.
71
72 `cxxflags`::
73 Specifies additional compiler flags that will be used when compiling C++
74 sources.
75
76 `compileflags`::
77 Specifies additional compiler flags that will be used when compiling both C
78 and C++ sources.
79
80 `linkflags`::
81 Specifies additional command line options that will be passed to the linker.
82
83 `assembler`::
84 The command that compiles assembler sources. If not specified, `ml`
85 will be used. The command will be invoked after the setup script was
86 executed and adjusted the PATH variable.
87
88 `compiler`::
89 The command that compiles C and C++ sources. If not specified, `cl`
90 will be used. The command will be invoked after the setup script was
91 executed and adjusted the PATH variable.
92
93 `compiler-filter`::
94 Command through which to pipe the output of running the compiler. For
95 example to pass the output to STLfilt.
96
97 `idl-compiler`::
98 The command that compiles Microsoft COM interface definition files. If
99 not specified, `midl` will be used. The command will be invoked after
100 the setup script was executed and adjusted the PATH variable.
101
102 `linker`::
103 The command that links executables and dynamic libraries. If not
104 specified, `link` will be used. The command will be invoked after the
105 setup script was executed and adjusted the PATH variable.
106
107 `mc-compiler`::
108 The command that compiles Microsoft message catalog files. If not
109 specified, `mc` will be used. The command will be invoked after the
110 setup script was executed and adjusted the PATH variable.
111
112 `resource-compiler`::
113 The command that compiles resource files. If not specified, `rc` will
114 be used. The command will be invoked after the setup script was
115 executed and adjusted the PATH variable.
116
117 `setup`::
118 The filename of the global environment setup script to run before
119 invoking any of the tools defined in this toolset. Will not be used in
120 case a target platform specific script has been explicitly specified
121 for the current target platform. Used setup script will be passed the
122 target platform identifier (x86, x86_amd64, x86_ia64, amd64 or ia64)
123 as a parameter. If not specified a default script is chosen based on
124 the used compiler binary, e.g. `vcvars32.bat` or `vsvars32.bat`.
125
126 `setup-amd64`; `setup-i386`; `setup-ia64`::
127 The filename of the target platform specific environment setup script
128 to run before invoking any of the tools defined in this toolset. If
129 not specified the global environment setup script is used.
130
131 [[bbv2.reference.tools.compiler.msvc.64]]
132 == 64-bit support
133
134 Starting with version 8.0, Microsoft Visual Studio can generate binaries
135 for 64-bit processor, both 64-bit flavours of x86 (codenamed
136 AMD64/EM64T), and Itanium (codenamed IA64). In addition, compilers that
137 are itself run in 64-bit mode, for better performance, are provided. The
138 complete list of compiler configurations are as follows (we abbreviate
139 AMD64/EM64T to just AMD64):
140
141 * 32-bit x86 host, 32-bit x86 target
142 * 32-bit x86 host, 64-bit AMD64 target
143 * 32-bit x86 host, 64-bit IA64 target
144 * 64-bit AMD64 host, 64-bit AMD64 target
145 * 64-bit IA64 host, 64-bit IA64 target
146
147 The 32-bit host compilers can be always used, even on 64-bit Windows. On
148 the contrary, 64-bit host compilers require both 64-bit host processor
149 and 64-bit Windows, but can be faster. By default, only 32-bit host,
150 32-bit target compiler is installed, and additional compilers need to be
151 installed explicitly.
152
153 To use 64-bit compilation you should:
154
155 1. Configure you compiler as usual. If you provide a path to the
156 compiler explicitly, provide the path to the 32-bit compiler. If you try
157 to specify the path to any of 64-bit compilers, configuration will not
158 work.
159 2. When compiling, use `address-model=64`, to generate AMD64 code.
160 3. To generate IA64 code, use `architecture=ia64`
161
162 The (AMD64 host, AMD64 target) compiler will be used automatically when
163 you are generating AMD64 code and are running 64-bit Windows on AMD64.
164 The (IA64 host, IA64 target) compiler will never be used, since nobody
165 has an IA64 machine to test.
166
167 It is believed that AMD64 and EM64T targets are essentially compatible.
168 The compiler options `/favor:AMD64` and `/favor:EM64T`, which are
169 accepted only by AMD64 targeting compilers, cause the generated code to
170 be tuned to a specific flavor of 64-bit x86. B2 will make use
171 of those options depending on the value of the`instruction-set` feature.
172
173 [[bbv2.reference.tools.compiler.msvc.winrt]]
174 == Windows Runtime support
175
176 Starting with version 11.0, Microsoft Visual Studio can produce binaries
177 for Windows Store and Phone in addition to traditional Win32 desktop. To
178 specify which Windows API set to target, use the `windows-api` feature.
179 Available options are `desktop`, `store`, or `phone`. If not specified,
180 `desktop` will be used.
181
182 When using `store` or `phone` the specified toolset determines what
183 Windows version is targeted. The following options are available:
184
185 * Windows 8.0: toolset=msvc-11.0 windows-api=store
186 * Windows 8.1: toolset=msvc-12.0 windows-api=store
187 * Windows Phone 8.0: toolset=msvc-11.0 windows-api=phone
188 * Windows Phone 8.1: toolset=msvc-12.0 windows-api=phone
189
190 For example use the following to build for Windows Store 8.1 with the
191 ARM architecture:
192
193 ----
194 .\b2 toolset=msvc-12.0 windows-api=store architecture=arm
195 ----
196
197 Note that when targeting Windows Phone 8.1, version 12.0 didn't include
198 the vcvars phone setup scripts. They can be separately downloaded from
199 http://blogs.msdn.com/b/vcblog/archive/2014/07/18/using-boost-libraries-in-windows-store-and-phone-applications.aspx[here].
200
201 |# # end::doc[]
202
203
204 ################################################################################
205 #
206 # MSVC Boost Build toolset module.
207 # --------------------------------
208 #
209 # All toolset versions need to have their location either auto-detected or
210 # explicitly specified except for the special 'default' version that expects the
211 # environment to find the needed tools or report an error.
212 #
213 ################################################################################
214
215 import "class" : new ;
216 import common ;
217 import feature ;
218 import generators ;
219 import mc ;
220 import midl ;
221 import os ;
222 import path ;
223 import pch ;
224 import project ;
225 import property ;
226 import property-set ;
227 import rc ;
228 import sequence ;
229 import set ;
230 import testing ;
231 import toolset ;
232 import type ;
233 import virtual-target ;
234 import version ;
235
236
237 type.register MANIFEST : manifest ;
238
239 #| tag::embed-doc[]
240
241 [[bbv2.builtin.features.embed-manifest]]`embed-manifest`::
242 *Allowed values:* `on`, `off`.
243 +
244 This feature is specific to the `msvc` toolset (see <<Microsoft Visual C++>>),
245 and controls whether the manifest files should be embedded inside executables
246 and shared libraries, or placed alongside them. This feature corresponds to the
247 IDE option found in the project settings dialog, under Configuration Properties
248 -> Manifest Tool -> Input and Output -> Embed manifest.
249
250 |# # end::embed-doc[]
251
252 feature.feature embed-manifest : on off : incidental propagated ;
253
254 #| tag::embed-doc[]
255
256 [[bbv2.builtin.features.embed-manifest-file]]`embed-manifest-file`::
257 This feature is specific to the `msvc` toolset (see <<Microsoft Visual C++>>),
258 and controls which manifest files should be embedded inside executables and
259 shared libraries. This feature corresponds to the IDE option found in the
260 project settings dialog, under Configuration Properties -> Manifest Tool ->
261 Input and Output -> Additional Manifest Files.
262
263 |# # end::embed-doc[]
264
265 feature.feature embed-manifest-file : : free dependency ;
266
267 #| tag::embed-doc[]
268
269 [[bbv2.builtin.features.embed-manifest-via]]`embed-manifest-via`::
270 This feature is specific to the `msvc` toolset (see <<Microsoft Visual C++>>),
271 and controls whether a manifest should be embedded via linker or manifest tool.
272
273 |# # end::embed-doc[]
274
275 feature.feature embed-manifest-via : mt linker : incidental propagated ;
276
277 type.register PDB : pdb ;
278
279
280 ################################################################################
281 #
282 # Public rules.
283 #
284 ################################################################################
285
286 # Initialize a specific toolset version configuration. As the result, path to
287 # compiler and, possible, program names are set up, and will be used when that
288 # version of compiler is requested. For example, you might have:
289 #
290 # using msvc : 6.5 : cl.exe ;
291 # using msvc : 7.0 : Y:/foo/bar/cl.exe ;
292 #
293 # The version parameter may be omitted:
294 #
295 # using msvc : : Z:/foo/bar/cl.exe ;
296 #
297 # The following keywords have special meanings when specified as versions:
298 # - all - all detected but not yet used versions will be marked as used
299 # with their default options.
300 # - default - this is an equivalent to an empty version.
301 #
302 # Depending on a supplied version, detected configurations and presence 'cl.exe'
303 # in the path different results may be achieved. The following table describes
304 # the possible scenarios:
305 #
306 # Nothing "x.y"
307 # Passed Nothing "x.y" detected, detected,
308 # version detected detected cl.exe in path cl.exe in path
309 #
310 # default Error Use "x.y" Create "default" Use "x.y"
311 # all None Use all None Use all
312 # x.y - Use "x.y" - Use "x.y"
313 # a.b Error Error Create "a.b" Create "a.b"
314 #
315 # "x.y" - refers to a detected version;
316 # "a.b" - refers to an undetected version.
317 #
318 # FIXME: Currently the command parameter and the <compiler> property parameter
319 # seem to overlap in duties. Remove this duplication. This seems to be related
320 # to why someone started preparing to replace init with configure rules.
321 #
322 rule init (
323 # The msvc version being configured. When omitted the tools invoked when no
324 # explicit version is given will be configured.
325 version ?
326
327 # The command used to invoke the compiler. If not specified:
328 # - if version is given, default location for that version will be
329 # searched
330 #
331 # - if version is not given, default locations for MSVC 9.0, 8.0, 7.1, 7.0
332 # and 6.* will be searched
333 #
334 # - if compiler is not found in the default locations, PATH will be
335 # searched.
336 : command *
337
338 # Options may include:
339 #
340 # All options shared by multiple toolset types as handled by the
341 # common.handle-options() rule, e.g. <cflags>, <compileflags>, <cxxflags>,
342 # <fflags> & <linkflags>.
343 #
344 # <assembler>
345 # <compiler>
346 # <idl-compiler>
347 # <linker>
348 # <mc-compiler>
349 # <resource-compiler>
350 # Exact tool names to be used by this msvc toolset configuration.
351 #
352 # <compiler-filter>
353 # Command through which to pipe the output of running the compiler.
354 # For example to pass the output to STLfilt.
355 #
356 # <setup>
357 # Global setup command to invoke before running any of the msvc tools.
358 # It will be passed additional option parameters depending on the actual
359 # target platform.
360 #
361 # <setup-amd64>
362 # <setup-i386>
363 # <setup-ia64>
364 # <setup-arm>
365 # <setup-phone-i386>
366 # <setup-phone-arm>
367 # Platform specific setup command to invoke before running any of the
368 # msvc tools used when builing a target for a specific platform, e.g.
369 # when building a 32 or 64 bit executable.
370 #
371 # <rewrite-setup-scripts>
372 # Whether to rewrite setup scripts. New scripts will be output in
373 # build tree and will be used instead of originals in build actions.
374 # Possible values:
375 # * on - rewrite scripts, if they do not already exist (default)
376 # * always - always rewrite scripts, even if they already exist
377 # * off - use original setup scripts
378 : options *
379 )
380 {
381 if $(command)
382 {
383 options += <command>$(command) ;
384 }
385 configure $(version) : $(options) ;
386 }
387
388
389 # 'configure' is a newer version of 'init'. The parameter 'command' is passed as
390 # a part of the 'options' list. See the 'init' rule comment for more detailed
391 # information.
392 #
393 rule configure ( version ? : options * )
394 {
395 switch $(version)
396 {
397 case "all" :
398 if $(options)
399 {
400 import errors ;
401 errors.error "MSVC toolset configuration: options should be"
402 "empty when '$(version)' is specified." ;
403 }
404
405 # Configure (i.e. mark as used) all registered versions.
406 local all-versions = [ $(.versions).all ] ;
407 if ! $(all-versions)
408 {
409 if $(.debug-configuration)
410 {
411 ECHO "notice: [msvc-cfg] Asked to configure all registered"
412 "msvc toolset versions when there are none currently"
413 "registered." ;
414 }
415 }
416 else
417 {
418 for local v in $(all-versions)
419 {
420 # Note that there is no need to skip already configured
421 # versions here as this will request configure-really rule
422 # to configure the version using default options which will
423 # in turn cause it to simply do nothing in case the version
424 # has already been configured.
425 configure-really $(v) ;
426 }
427 }
428
429 case "default" :
430 configure-really : $(options) ;
431
432 case * :
433 configure-really $(version) : $(options) ;
434 }
435 }
436
437
438 # Sets up flag definitions dependent on the compiler version used.
439 # - 'version' is the version of compiler in N.M format.
440 # - 'conditions' is the property set to be used as flag conditions.
441 # - 'toolset' is the toolset for which flag settings are to be defined.
442 # This makes the rule reusable for other msvc-option-compatible compilers.
443 #
444 rule configure-version-specific ( toolset : version : conditions )
445 {
446 toolset.push-checking-for-flags-module unchecked ;
447 # Starting with versions 7.0, the msvc compiler have the /Zc:forScope and
448 # /Zc:wchar_t options that improve C++ standard conformance, but those
449 # options are off by default. If we are sure that the msvc version is at
450 # 7.*, add those options explicitly. We can be sure either if user specified
451 # version 7.* explicitly or if we auto-detected the version ourselves.
452 if ! [ MATCH ^(6\\.) : $(version) ]
453 {
454 toolset.flags $(toolset).compile OPTIONS $(conditions) : "/Zc:forScope" "/Zc:wchar_t" ;
455 toolset.flags $(toolset).compile.c++ C++FLAGS $(conditions) : /wd4675 ;
456
457 # Explicitly disable the 'function is deprecated' warning. Some msvc
458 # versions have a bug, causing them to emit the deprecation warning even
459 # with /W0.
460 toolset.flags $(toolset).compile OPTIONS $(conditions)/<warnings>off : /wd4996 ;
461
462 if [ MATCH "^([78]\\.)" : $(version) ]
463 {
464 # 64-bit compatibility warning deprecated since 9.0, see
465 # http://msdn.microsoft.com/en-us/library/yt4xw8fh.aspx
466 toolset.flags $(toolset).compile OPTIONS $(conditions)/<warnings>all : /Wp64 ;
467 }
468 }
469
470 # 12.0 (VS2013 Update 2) introduced /Zc:inline opt-in standard conformance
471 # compiler flag that also similar to linker /opt:ref removes unreferenced
472 # variables and functions that have internal linkage
473 if ! [ version.version-less [ SPLIT_BY_CHARACTERS [ MATCH "^([0123456789.]+)" : $(version) ] : . ] : 12 ]
474 {
475 toolset.flags $(toolset).compile OPTIONS $(conditions) : "/Zc:inline" ;
476
477 # /Gy analog for variables: https://devblogs.microsoft.com/cppblog/introducing-gw-compiler-switch/
478 toolset.flags $(toolset).compile OPTIONS $(conditions)/<optimization>speed $(conditions)/<optimization>space : /Gw ;
479 }
480
481 # 14.0 introduced /Zc:throwingNew opt-in flag that disables a workaround
482 # for not throwing operator new in VC up to 6.0
483 if ! [ version.version-less [ SPLIT_BY_CHARACTERS [ MATCH "^([0123456789.]+)" : $(version) ] : . ] : 14 ]
484 {
485 toolset.flags $(toolset).compile C++FLAGS $(conditions) : "/Zc:throwingNew" ;
486 }
487
488 # 14.27 (VS2019 Version 16.7) introduced support for ASAN on x86 and x64 CPUs
489 # This check however now only tests for 14.2 (which is 16.0) as msvc.jam doesn't distinguish between minor versions (e.g. 14.21..14.28 etc)
490 if ! [ version.version-less [ SPLIT_BY_CHARACTERS [ MATCH "^([0123456789.]+)" : $(version) ] : . ] : 14 2 ]
491 {
492 # General asan compile and link options.
493 toolset.flags $(toolset).compile OPTIONS
494 $(conditions)/<address-sanitizer>on
495 : /fsanitize=address /FS ;
496 toolset.flags $(toolset).link LINKFLAGS
497 $(conditions)/<address-sanitizer>on
498 : -incremental\:no ;
499
500 # The various 64 bit runtime asan support libraries and related flags.
501 toolset.flags $(toolset).link FINDLIBS_SA
502 $(conditions)/<address-sanitizer>on/<address-model>/<runtime-link>shared
503 $(conditions)/<address-sanitizer>on/<address-model>64/<runtime-link>shared
504 : clang_rt.asan_dynamic-x86_64
505 clang_rt.asan_dynamic_runtime_thunk-x86_64 ;
506 toolset.flags $(toolset).link LINKFLAGS
507 $(conditions)/<address-sanitizer>on/<address-model>/<runtime-link>shared
508 $(conditions)/<address-sanitizer>on/<address-model>64/<runtime-link>shared
509 : /wholearchive\:"clang_rt.asan_dynamic-x86_64.lib"
510 /wholearchive\:"clang_rt.asan_dynamic_runtime_thunk-x86_64.lib" ;
511 toolset.flags $(toolset).link FINDLIBS_SA
512 $(conditions)/<address-sanitizer>on/<address-model>/<runtime-link>static/<main-target-type>EXE
513 $(conditions)/<address-sanitizer>on/<address-model>/<runtime-link>static/<main-target-type>UNIT_TEST
514 $(conditions)/<address-sanitizer>on/<address-model>64/<runtime-link>static/<main-target-type>EXE
515 $(conditions)/<address-sanitizer>on/<address-model>64/<runtime-link>static/<main-target-type>UNIT_TEST
516 : clang_rt.asan-x86_64
517 clang_rt.asan_cxx-x86_64 ;
518 toolset.flags $(toolset).link LINKFLAGS
519 $(conditions)/<address-sanitizer>on/<address-model>/<runtime-link>static/<main-target-type>EXE
520 $(conditions)/<address-sanitizer>on/<address-model>/<runtime-link>static/<main-target-type>UNIT_TEST
521 $(conditions)/<address-sanitizer>on/<address-model>64/<runtime-link>static/<main-target-type>EXE
522 $(conditions)/<address-sanitizer>on/<address-model>64/<runtime-link>static/<main-target-type>UNIT_TEST
523 : /wholearchive\:"clang_rt.asan-x86_64.lib"
524 /wholearchive\:"clang_rt.asan_cxx-x86_64.lib" ;
525 toolset.flags $(toolset).link.dll FINDLIBS_SA
526 $(conditions)/<address-sanitizer>on/<address-model>/<runtime-link>static
527 $(conditions)/<address-sanitizer>on/<address-model>64/<runtime-link>static
528 : clang_rt.asan_dll_thunk-x86_64 ;
529 toolset.flags $(toolset).link.dll LINKFLAGS
530 $(conditions)/<address-sanitizer>on/<address-model>/<runtime-link>static
531 $(conditions)/<address-sanitizer>on/<address-model>64/<runtime-link>static
532 : /wholearchive\:"clang_rt.asan_dll_thunk-x86_64.lib" ;
533
534 # The various 32 bit runtime asan support libraries and related flags.
535 toolset.flags $(toolset).link FINDLIBS_SA
536 $(conditions)/<address-sanitizer>on/<address-model>32/<runtime-link>shared
537 : clang_rt.asan_dynamic-i386 clang_rt.asan_dynamic_runtime_thunk-i386 ;
538 toolset.flags $(toolset).link LINKFLAGS
539 $(conditions)/<address-sanitizer>on/<address-model>32/<runtime-link>shared
540 : /wholearchive\:"clang_rt.asan_dynamic-i386.lib"
541 /wholearchive\:"clang_rt.asan_dynamic_runtime_thunk-i386.lib" ;
542 toolset.flags $(toolset).link FINDLIBS_SA
543 $(conditions)/<address-sanitizer>on/<address-model>32/<runtime-link>static/<main-target-type>EXE
544 $(conditions)/<address-sanitizer>on/<address-model>32/<runtime-link>static/<main-target-type>UNIT_TEST
545 : clang_rt.asan-i386 clang_rt.asan_cxx-i386 ;
546 toolset.flags $(toolset).link LINKFLAGS
547 $(conditions)/<address-sanitizer>on/<address-model>32/<runtime-link>static/<main-target-type>EXE
548 $(conditions)/<address-sanitizer>on/<address-model>32/<runtime-link>static/<main-target-type>UNIT_TEST
549 : /wholearchive\:"clang_rt.asan-i386.lib"
550 /wholearchive\:"clang_rt.asan_cxx-i386.lib" ;
551 toolset.flags $(toolset).link.dll FINDLIBS_SA
552 $(conditions)/<address-sanitizer>on/<address-model>32/<runtime-link>static/<main-target-type>LIB/<link>shared
553 : clang_rt.asan_dll_thunk-i386 ;
554 toolset.flags $(toolset).link.dll LINKFLAGS
555 $(conditions)/<address-sanitizer>on/<address-model>32/<runtime-link>static/<main-target-type>LIB/<link>shared
556 : /wholearchive\:"clang_rt.asan_dll_thunk-i386.lib" ;
557 }
558
559 #
560 # Processor-specific optimization.
561 #
562
563 if [ MATCH "^([67])" : $(version) ]
564 {
565 # 8.0 deprecates some of the options.
566 toolset.flags $(toolset).compile OPTIONS $(conditions)/<optimization>speed $(conditions)/<optimization>space : /Ogiy /Gs ;
567 toolset.flags $(toolset).compile OPTIONS $(conditions)/<optimization>speed : /Ot ;
568 toolset.flags $(toolset).compile OPTIONS $(conditions)/<optimization>space : /Os ;
569
570 toolset.flags $(toolset).compile OPTIONS $(conditions)/$(.cpu-arch-i386)/<instruction-set> : /GB ;
571 toolset.flags $(toolset).compile OPTIONS $(conditions)/$(.cpu-arch-i386)/<instruction-set>i486 : /G4 ;
572 toolset.flags $(toolset).compile OPTIONS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g5) : /G5 ;
573 toolset.flags $(toolset).compile OPTIONS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g6) : /G6 ;
574 toolset.flags $(toolset).compile OPTIONS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g7) : /G7 ;
575
576 # Improve floating-point accuracy. Otherwise, some of C++ Boost's "math"
577 # tests will fail.
578 toolset.flags $(toolset).compile OPTIONS $(conditions) : /Op ;
579
580 # 7.1 and below have single-threaded static RTL.
581 toolset.flags $(toolset).compile OPTIONS $(conditions)/<runtime-debugging>off/<runtime-link>static/<threading>single : /ML ;
582 toolset.flags $(toolset).compile OPTIONS $(conditions)/<runtime-debugging>on/<runtime-link>static/<threading>single : /MLd ;
583 }
584 else
585 {
586 # 8.0 and above adds some more options.
587 toolset.flags $(toolset).compile OPTIONS $(conditions)/$(.cpu-arch-amd64)/<instruction-set> : "/favor:blend" ;
588 toolset.flags $(toolset).compile OPTIONS $(conditions)/$(.cpu-arch-amd64)/<instruction-set>$(.cpu-type-em64t) : "/favor:EM64T" ;
589 toolset.flags $(toolset).compile OPTIONS $(conditions)/$(.cpu-arch-amd64)/<instruction-set>$(.cpu-type-amd64) : "/favor:AMD64" ;
590
591 # 8.0 and above only has multi-threaded static RTL.
592 toolset.flags $(toolset).compile OPTIONS $(conditions)/<runtime-debugging>off/<runtime-link>static/<threading>single : /MT ;
593 toolset.flags $(toolset).compile OPTIONS $(conditions)/<runtime-debugging>on/<runtime-link>static/<threading>single : /MTd ;
594
595 # Specify target machine type so the linker will not need to guess.
596 toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-amd64) : "/MACHINE:X64" ;
597 toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-i386) : "/MACHINE:X86" ;
598 toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-ia64) : "/MACHINE:IA64" ;
599 toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-arm) : "/MACHINE:ARM" ;
600 toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-arm64) : "/MACHINE:ARM64" ;
601
602 if [ version.version-less [ SPLIT_BY_CHARACTERS [ MATCH "^([0123456789.]+)" : $(version) ] : . ] : 11 ]
603 {
604 # Make sure that manifest will be generated even if there is no
605 # dependencies to put there.
606 toolset.flags $(toolset).link LINKFLAGS $(conditions) : /MANIFEST ;
607 }
608 else
609 {
610 toolset.flags $(toolset).link LINKFLAGS $(conditions)/<embed-manifest-via>mt : /MANIFEST ;
611 toolset.flags $(toolset).link LINKFLAGS $(conditions)/<embed-manifest-via>linker/<embed-manifest>off : /MANIFEST ;
612 toolset.flags $(toolset).link LINKFLAGS $(conditions)/<embed-manifest-via>linker/<embed-manifest>on : "/MANIFEST:EMBED" ;
613
614 local conditionx = [ feature.split $(conditions) ] ;
615 toolset.add-defaults $(conditionx:J=,)\:<embed-manifest-via>linker ;
616 }
617 }
618
619 toolset.pop-checking-for-flags-module ;
620 }
621
622 # Feature for handling targeting different Windows API sets.
623 feature.feature windows-api : desktop store phone : propagated composite link-incompatible ;
624 feature.compose <windows-api>store : <define>WINAPI_FAMILY=WINAPI_FAMILY_APP <define>_WIN32_WINNT=0x0602
625 <linkflags>/APPCONTAINER ;
626 feature.compose <windows-api>phone : <define>WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP <define>_WIN32_WINNT=0x0602
627 <linkflags>/APPCONTAINER <linkflags>"/NODEFAULTLIB:ole32.lib" <linkflags>"/NODEFAULTLIB:kernel32.lib" <linkflags>WindowsPhoneCore.lib ;
628 feature.set-default windows-api : desktop ;
629
630
631 # Registers this toolset including all of its flags, features & generators. Does
632 # nothing on repeated calls.
633 #
634 rule register-toolset ( )
635 {
636 if ! msvc in [ feature.values toolset ]
637 {
638 register-toolset-really ;
639 }
640 }
641
642 rule resolve-possible-msvc-version-alias ( version )
643 {
644 if $(.version-alias-$(version))
645 {
646 version = $(.version-alias-$(version)) ;
647 }
648 return $(version) ;
649 }
650
651
652 # Declare action for creating static libraries. If library exists, remove it
653 # before adding files. See
654 # http://article.gmane.org/gmane.comp.lib.boost.build/4241 for rationale.
655 if [ os.name ] in NT
656 {
657 # The 'DEL' command would issue a message to stdout if the file does not
658 # exist, so need a check.
659 actions archive
660 {
661 if exist "$(<[1])" DEL "$(<[1])"
662 $(.SETUP) $(.LD) $(AROPTIONS) /out:"$(<[1])" @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>)" $(LIBRARIES_MENTIONED_BY_FILE) "$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" "$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")
663 }
664 }
665 else
666 {
667 actions archive
668 {
669 $(.RM) "$(<[1])"
670 $(.SETUP) $(.LD) $(AROPTIONS) /out:"$(<[1])" @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>)" $(LIBRARIES_MENTIONED_BY_FILE) "$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" "$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")
671 }
672 }
673
674 rule compile.asm ( targets + : sources * : properties * )
675 {
676 set-setup-command $(targets) : $(properties) ;
677 }
678
679 actions compile.asm
680 {
681 $(.SETUP) $(.ASM) -D$(ASMDEFINES) $(ASMFLAGS) $(USER_ASMFLAGS) $(.ASM_OUTPUT) "$(<:W)" "$(>:W)"
682 }
683
684
685 rule compile.c ( targets + : sources * : properties * )
686 {
687 set-setup-command $(targets) : $(properties) ;
688 get-rspline $(targets) : -TC CFLAGS ;
689 compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
690 }
691
692
693 rule compile.c.preprocess ( targets + : sources * : properties * )
694 {
695 set-setup-command $(targets) : $(properties) ;
696 get-rspline $(targets) : -TC CFLAGS ;
697 preprocess-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
698 }
699
700
701 rule compile.c.pch ( targets + : sources * : properties * )
702 {
703 set-setup-command $(targets) : $(properties) ;
704 get-rspline $(targets[1]) : -TC CFLAGS ;
705 get-rspline $(targets[2]) : -TC CFLAGS ;
706 local pch-source = [ on $(<) return $(PCH_SOURCE) ] ;
707 if $(pch-source)
708 {
709 DEPENDS $(<) : $(pch-source) ;
710 compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ;
711 }
712 else
713 {
714 compile-c-c++-pch $(targets) : $(sources) ;
715 }
716 }
717
718 toolset.flags msvc YLOPTION : "-Yl" ;
719
720 # Action for running the C/C++ compiler without using precompiled headers.
721 #
722 # WARNING: Synchronize any changes this in action with intel-win
723 #
724 # Notes regarding PDB generation, for when we use
725 # <debug-symbols>on/<debug-store>database:
726 #
727 # 1. PDB_CFLAG is only set for <debug-symbols>on/<debug-store>database, ensuring
728 # that the /Fd flag is dropped if PDB_CFLAG is empty.
729 #
730 # 2. When compiling executables's source files, PDB_NAME is set on a per-source
731 # file basis by rule compile-c-c++. The linker will pull these into the
732 # executable's PDB.
733 #
734 # 3. When compiling library's source files, PDB_NAME is updated to <libname>.pdb
735 # for each source file by rule archive, as in this case compiler must be used
736 # to create a single PDB for our library.
737 #
738 actions compile-c-c++ bind PDB_NAME PCH_HEADER
739 {
740 $(.SETUP) $(.CC) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>[1]:W)" -c -Fo"$(<[1]:W)" $(PDB_CFLAG)"$(PDB_NAME)" -FI"$(PCH_HEADER)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE)) $(.CC.FILTER)
741 }
742
743 actions preprocess-c-c++ bind PDB_NAME PCH_HEADER
744 {
745 $(.SETUP) $(.CC) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>[1]:W)" -P -Fi"$(<[1]:W)" $(PDB_CFLAG)"$(PDB_NAME)" -FI"$(PCH_HEADER)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))
746 }
747
748 rule compile-c-c++ ( targets + : sources * )
749 {
750 DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_HEADER) ] ;
751 DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_FILE) ] ;
752 PDB_NAME on $(<) = $(<[1]:S=.pdb) ;
753 LOCATE on $(<[1]:S=.pdb) = [ on $(<[1]) return $(LOCATE) ] ;
754 }
755
756 rule preprocess-c-c++ ( targets + : sources * )
757 {
758 DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_HEADER) ] ;
759 DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_FILE) ] ;
760 PDB_NAME on $(<) = $(<:S=.pdb) ;
761 LOCATE on $(<[1]:S=.pdb) = [ on $(<[1]) return $(LOCATE) ] ;
762 }
763
764 # Action for running the C/C++ compiler using precompiled headers. In addition
765 # to whatever else it needs to compile, this action also adds a temporary source
766 # .cpp file used to compile the precompiled headers themselves.
767 #
768 # The global .escaped-double-quote variable is used to avoid messing up Emacs
769 # syntax highlighting in the messy N-quoted code below.
770 actions compile-c-c++-pch
771 {
772 $(.SETUP) $(.CC) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>[2]:W)" -c -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" $(YLOPTION)"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE)) @($(<[1]:W).cpp:<=":>=":E=$(.hash)include $(.escaped-double-quote)$(>[1]:D=)$(.escaped-double-quote)$(.nl)) $(.CC.FILTER)
773 }
774
775
776 # Action for running the C/C++ compiler using precompiled headers. An already
777 # built source file for compiling the precompiled headers is expected to be
778 # given as one of the source parameters.
779 actions compile-c-c++-pch-s
780 {
781 $(.SETUP) $(.CC) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>[2]:W)" -c -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" $(YLOPTION)"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE)) $(.CC.FILTER)
782 }
783
784
785 rule compile.c++ ( targets + : sources * : properties * )
786 {
787 set-setup-command $(targets) : $(properties) ;
788 get-rspline $(targets) : -TP C++FLAGS ;
789 compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
790 }
791
792 rule compile.c++.preprocess ( targets + : sources * : properties * )
793 {
794 set-setup-command $(targets) : $(properties) ;
795 get-rspline $(targets) : -TP C++FLAGS ;
796 preprocess-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
797 }
798
799
800 rule compile.c++.pch ( targets + : sources * : properties * )
801 {
802 set-setup-command $(targets) : $(properties) ;
803 get-rspline $(targets[1]) : -TP C++FLAGS ;
804 get-rspline $(targets[2]) : -TP C++FLAGS ;
805 local pch-source = [ on $(<) return $(PCH_SOURCE) ] ;
806 if $(pch-source)
807 {
808 DEPENDS $(<) : $(pch-source) ;
809 compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ;
810 }
811 else
812 {
813 compile-c-c++-pch $(targets) : $(sources) ;
814 }
815 }
816
817 rule compile.idl ( targets + : sources * : properties * )
818 {
819 set-setup-command $(targets) : $(properties) ;
820 }
821
822 # See midl.jam for details.
823 #
824 actions compile.idl
825 {
826 $(.SETUP) $(.IDL) /nologo @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>:W)" -D$(DEFINES) "-I$(INCLUDES:W)" -U$(UNDEFS) $(MIDLFLAGS) /tlb "$(<[1]:W)" /h "$(<[2]:W)" /iid "$(<[3]:W)" /proxy "$(<[4]:W)" /dlldata "$(<[5]:W)")
827 $(.TOUCH_FILE) "$(<[4]:W)"
828 $(.TOUCH_FILE) "$(<[5]:W)"
829 }
830
831 rule compile.mc ( targets + : sources * : properties * )
832 {
833 set-setup-command $(targets) : $(properties) ;
834 }
835
836 actions compile.mc
837 {
838 $(.SETUP) $(.MC) $(MCFLAGS) -h "$(<[1]:DW)" -r "$(<[2]:DW)" "$(>:W)"
839 }
840
841
842 rule compile.rc ( targets + : sources * : properties * )
843 {
844 set-setup-command $(targets) : $(properties) ;
845 }
846
847 actions compile.rc
848 {
849 $(.SETUP) $(.RC) /nologo -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES:W)" -fo "$(<:W)" "$(>:W)"
850 }
851
852 toolset.uses-features msvc.link : <embed-manifest> <embed-manifest-file> ;
853
854 rule link ( targets + : sources * : properties * )
855 {
856 set-setup-command $(targets) : $(properties) ;
857 if <embed-manifest>on in $(properties) && <embed-manifest-via>mt in $(properties)
858 {
859 if [ feature.get-values <embed-manifest-file> : $(properties) ]
860 {
861 DEPENDS $(<) : [ on $(<) return $(EMBED_MANIFEST_FILE) ] ;
862 msvc.manifest.user $(targets) $(EMBED_MANIFEST_FILE) : $(sources) : $(properties) ;
863 }
864 else
865 {
866 msvc.manifest $(targets) : $(sources) : $(properties) ;
867 }
868 }
869 }
870
871 rule link.dll ( targets + : sources * : properties * )
872 {
873 set-setup-command $(targets) : $(properties) ;
874 DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ;
875 local import-lib ;
876 if ! <suppress-import-lib>true in $(properties)
877 {
878 import-lib = $(targets[2]) ;
879 IMPORT_LIB on $(targets) = $(import-lib) ;
880 }
881 # On msvc-14.1, the linker might not touch the import library
882 # if the exports do not change. (Apparently this could also
883 # happen for incremental linking, which is why we disable it,
884 # but that no longer seems to be enough).
885 # Therefore, don't update the import library just because
886 # it's out-dated. It will be force updated, when the dll
887 # is updated. Also, make it so that anything that depends
888 # on it depends on the dll as well.
889 NOUPDATE $(import-lib) ;
890 INCLUDES $(import-lib) : $(targets[1]) ;
891 if <embed-manifest>on in $(properties) && <embed-manifest-via>mt in $(properties)
892 {
893 if [ feature.get-values <embed-manifest-file> : $(properties) ]
894 {
895 DEPENDS $(<) : [ on $(<) return $(EMBED_MANIFEST_FILE) ] ;
896 msvc.manifest.dll.user $(targets) $(EMBED_MANIFEST_FILE) : $(sources) : $(properties) ;
897 }
898 else
899 {
900 msvc.manifest.dll $(targets) : $(sources) : $(properties) ;
901 }
902 }
903 }
904
905 # Incremental linking a DLL causes no end of problems: if the actual exports do
906 # not change, the import .lib file is never updated. Therefore, the .lib is
907 # always out-of-date and gets rebuilt every time. I am not sure that incremental
908 # linking is such a great idea in general, but in this case I am sure we do not
909 # want it.
910
911 # Windows manifest is a new way to specify dependencies on managed DotNet
912 # assemblies and Windows native DLLs. The manifests are embedded as resources
913 # and are useful in any PE target (both DLL and EXE).
914
915 {
916 actions link bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE MANIFEST_FILE
917 {
918 $(.SETUP) $(.LD) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>)" $(LIBRARIES_MENTIONED_BY_FILE) $(LIBRARIES) "$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" "$(LIBRARY_OPTION)$(FINDLIBS_SA).lib") $(LINKOPT) $(LINKFLAGS) /out:"$(<[1]:W)" /LIBPATH:"$(LINKPATH:W)" /MANIFESTINPUT:"$(MANIFEST_FILE)"
919 }
920
921 actions manifest
922 {
923 $(.SETUP) $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);1"
924 }
925
926 actions manifest.user bind EMBED_MANIFEST_FILE
927 {
928 $(.SETUP) $(.MT) -manifest "$(EMBED_MANIFEST_FILE)" "-outputresource:$(<[1]);1"
929 }
930
931 actions link.dll bind IMPORT_LIB DEF_FILE LIBRARIES_MENTIONED_BY_FILE MANIFEST_FILE
932 {
933 $(.SETUP) $(.LD) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>)" $(LIBRARIES_MENTIONED_BY_FILE) $(LIBRARIES) "$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" "$(LIBRARY_OPTION)$(FINDLIBS_SA).lib") $(LINKOPT) $(LINKFLAGS) /out:"$(<[1]:W)" /LIBPATH:"$(LINKPATH:W)" /MANIFESTINPUT:"$(MANIFEST_FILE)" /DLL /IMPLIB:"$(IMPORT_LIB:W)" /def:"$(DEF_FILE)"
934 }
935
936 actions manifest.dll
937 {
938 $(.SETUP) $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);2"
939 }
940
941 actions manifest.dll.user bind EMBED_MANIFEST_FILE
942 {
943 $(.SETUP) $(.MT) -manifest "$(EMBED_MANIFEST_FILE)" "-outputresource:$(<[1]);2"
944 }
945 }
946
947 # This rule sets up the pdb file that will be used when generating static
948 # libraries and the debug-store option is database, so that the compiler puts
949 # all the debug info into a single .pdb file named after the library.
950 #
951 # Poking at source targets this way is probably not clean, but it is the
952 # easiest approach.
953 #
954 rule archive ( targets + : sources * : properties * )
955 {
956 set-setup-command $(targets) : $(properties) ;
957 PDB_NAME on $(>) = $(<[1]:S=.pdb) ;
958 LOCATE on $(<[1]:S=.pdb) = [ on $(<[1]) return $(LOCATE) ] ;
959 }
960
961
962 ################################################################################
963 #
964 # Classes.
965 #
966 ################################################################################
967
968 class msvc-pch-generator : pch-generator
969 {
970 import property-set ;
971
972 rule run-pch ( project name ? : property-set : sources * )
973 {
974 # Searching for the header and source file in the sources.
975 local pch-header ;
976 local pch-source ;
977 for local s in $(sources)
978 {
979 if [ type.is-derived [ $(s).type ] H ]
980 {
981 pch-header = $(s) ;
982 }
983 else if
984 [ type.is-derived [ $(s).type ] CPP ] ||
985 [ type.is-derived [ $(s).type ] C ]
986 {
987 pch-source = $(s) ;
988 }
989 }
990
991 if ! $(pch-header)
992 {
993 import errors : user-error : errors.user-error ;
994 errors.user-error "can not build pch without pch-header" ;
995 }
996
997 # If we do not have the PCH source - that is fine. We will just create a
998 # temporary .cpp file in the action.
999 local pch-header-dir = [ $(pch-header).path ] ;
1000 local generated = [ generator.run $(project) $(name)
1001 : [ property-set.create
1002 # Passing of <pch-source> is a dirty trick, needed because
1003 # non-composing generators with multiple inputs are subtly
1004 # broken. For more detailed information see:
1005 # https://zigzag.cs.msu.su:7813/boost.build/ticket/111
1006 <pch-source>$(pch-source) "<include>$(pch-header-dir)"
1007 [ $(property-set).raw ] ]
1008 : $(pch-header) ] ;
1009
1010 local pch-file ;
1011 for local g in $(generated[2-])
1012 {
1013 if [ type.is-derived [ $(g).type ] PCH ]
1014 {
1015 pch-file = $(g) ;
1016 }
1017 }
1018
1019 return [ $(generated[1]).add-raw <pch-header>$(pch-header)
1020 <pch-file>$(pch-file) ] $(generated[2-]) ;
1021 }
1022 }
1023
1024
1025 ################################################################################
1026 #
1027 # Local rules.
1028 #
1029 ################################################################################
1030
1031 # Detects versions listed as '.known-versions' by checking registry information,
1032 # environment variables & default paths. Supports both native Windows and
1033 # Cygwin.
1034 #
1035 local rule auto-detect-toolset-versions ( )
1036 {
1037 if [ os.name ] in NT CYGWIN
1038 {
1039 # Get installation paths from the registry.
1040 for local i in $(.known-versions)
1041 {
1042 if $(.version-$(i)-reg)
1043 {
1044 local vc-path ;
1045 for local x in "" "Wow6432Node\\"
1046 {
1047 vc-path += [ W32_GETREG
1048 "HKEY_LOCAL_MACHINE\\SOFTWARE\\"$(x)"\\Microsoft\\"$(.version-$(i)-reg)
1049 : "ProductDir" ] ;
1050 }
1051
1052 if $(vc-path)
1053 {
1054 vc-path = [ path.join [ path.make-NT $(vc-path[1]) ] "bin" ] ;
1055 register-configuration $(i) : [ path.native $(vc-path[1]) ] ;
1056 }
1057 }
1058 }
1059 }
1060
1061 # Check environment and default installation paths.
1062 for local i in $(.known-versions)
1063 {
1064 if ! $(i) in [ $(.versions).all ]
1065 {
1066 register-configuration $(i) : [ default-path $(i) ] ;
1067 }
1068 }
1069 }
1070
1071 actions write-setup-script
1072 {
1073 @($(STDOUT):E=$(FILE_CONTENTS:J=$(.nl))) > "$(<)"
1074 }
1075
1076 if [ os.name ] = NT
1077 {
1078 local rule call-batch-script ( command )
1079 {
1080 return "call $(command) >nul$(.nl)" ;
1081 }
1082 }
1083 else
1084 {
1085 # On cygwin, we need to run both the batch script
1086 # and the following command in the same instance
1087 # of cmd.exe.
1088 local rule call-batch-script ( command )
1089 {
1090 return "cmd.exe /S /C call $(command) \">nul\" \"&&\" " ;
1091 }
1092 }
1093
1094 # Local helper rule to create the vcvars setup command for given architecture
1095 # and options.
1096 #
1097 local rule generate-setup-cmd ( version : command : parent : options * : cpu : global-setup ? : default-global-setup-options : default-setup )
1098 {
1099 local setup-options ;
1100 local setup = [ feature.get-values <setup-$(cpu)> : $(options) ] ;
1101
1102 if ! $(setup)-is-defined
1103 {
1104 if $(global-setup)-is-defined
1105 {
1106 setup = $(global-setup) ;
1107
1108 # If needed we can easily add using configuration flags
1109 # here for overriding which options get passed to the
1110 # global setup command for which target platform:
1111 # setup-options = [ feature.get-values <setup-options-$(c)> : $(options) ] ;
1112 setup-options ?= $(default-global-setup-options) ;
1113 }
1114 else
1115 {
1116 if [ MATCH "(14.3)" : $(version) ]
1117 {
1118 if $(.debug-configuration)
1119 {
1120 ECHO "notice: [generate-setup-cmd] $(version) is 14.3" ;
1121 }
1122 parent = [ path.native [ path.join $(parent) "..\\..\\..\\..\\..\\Auxiliary\\Build" ] ] ;
1123 }
1124 else if [ MATCH "(14.2)" : $(version) ]
1125 {
1126 if $(.debug-configuration)
1127 {
1128 ECHO "notice: [generate-setup-cmd] $(version) is 14.2" ;
1129 }
1130 parent = [ path.native [ path.join $(parent) "..\\..\\..\\..\\..\\Auxiliary\\Build" ] ] ;
1131 }
1132 else if [ MATCH "(14.1)" : $(version) ]
1133 {
1134 if $(.debug-configuration)
1135 {
1136 ECHO "notice: [generate-setup-cmd] $(version) is 14.1" ;
1137 }
1138 parent = [ path.native [ path.join $(parent) "..\\..\\..\\..\\..\\Auxiliary\\Build" ] ] ;
1139 }
1140 setup = [ locate-default-setup $(command) : $(parent) : $(default-setup) ] ;
1141 setup ?= [ path.join $(parent) "vcvarsall.bat" ] ;
1142 }
1143 }
1144
1145 return $(setup) "$(setup-options:J= )" ;
1146 }
1147
1148 # Worker for set-setup-command. Usable in a virtual-target.action.
1149 rule adjust-setup-command ( new-setup : setup : properties * )
1150 {
1151 local internal = $(new-setup:S=.read) ;
1152 NOTFILE $(internal) ;
1153 local setup-options = [ property.select <msvc.setup-options> : $(properties) ] ;
1154 setup-options = $(setup-options:G=:E=) ;
1155 DEPENDS $(internal) : $(setup) ;
1156 DEPENDS $(new-setup) : $(internal) ;
1157 REBUILDS $(new-setup) : $(internal) ;
1158 msvc.read-setup $(internal) : $(setup) ;
1159 msvc.write-setup-script $(new-setup) : $(setup) ;
1160 __ACTION_RULE__ on $(internal) = msvc.rewrite-setup $(setup) $(setup-options) $(new-setup) ;
1161 }
1162
1163 # This doesn't actually do anything. It's merely
1164 # used as a trigger for __ACTION_RULE__.
1165 actions quietly read-setup { }
1166
1167 # Calculates the changes to the environment make by setup-script
1168 # Should be used as a callback for __ACTION_RULE__
1169 local rule rewrite-setup ( setup-script setup-options new-setup : target : * )
1170 {
1171 local setup-path = [ on $(setup-script) return $(LOCATE) $(SEARCH) ] ;
1172 setup-path = $(setup-path[1]) ;
1173 local command = "\"$(setup-script:G=:R=$(setup-path))\" $(setup-options)" ;
1174 local original-vars = [ SPLIT_BY_CHARACTERS [ SHELL set ] : "\n" ] ;
1175 local new-vars = [ SPLIT_BY_CHARACTERS [ SHELL "$(command) >nul && set" ] : "\n" ] ;
1176 local diff-vars = [ set.difference $(new-vars) : $(original-vars) ] ;
1177 if $(diff-vars)
1178 {
1179 FILE_CONTENTS on $(new-setup) = "REM $(command)" "SET "$(diff-vars) ;
1180 }
1181 }
1182
1183 IMPORT msvc : rewrite-setup : : msvc.rewrite-setup ;
1184
1185 # Helper rule to generate a faster alternative to MSVC setup scripts.
1186 # We used to call MSVC setup scripts directly in every action, however in
1187 # newer MSVC versions (10.0+) they make long-lasting registry queries
1188 # which have a significant impact on build time.
1189 local rule set-setup-command ( targets * : properties * )
1190 {
1191 if ! [ on $(targets) return $(.SETUP) ]
1192 {
1193 local setup-script = [ on $(targets) return $(.SETUP-SCRIPT) ] ;
1194 # If no setup script was given, then we don't need to do anything.
1195 if ! $(setup-script)
1196 {
1197 return ;
1198 }
1199 local setup-options = [ on $(targets) return $(.SETUP-OPTIONS) ] ;
1200 local key = .setup-command-$(setup-script:E=)-$(setup-options:E=) ;
1201 if ! $($(key))
1202 {
1203 properties = [ feature.expand $(properties) ] ;
1204 properties = [ property.select <toolset> <toolset-msvc:version> <architecture> <address-model> <windows-api> <relevant> : $(properties) ] ;
1205 local ps = [ property-set.create $(properties) <msvc.setup-options>$(setup-options) ] ;
1206 local original = [ virtual-target.from-file $(setup-script) : [ path.pwd ] : $(.project) ] ;
1207 local action = [ new non-scanning-action $(original) : msvc.adjust-setup-command : $(ps) ] ;
1208 local new-setup = [ virtual-target.register [ new file-target msvc-setup.bat exact : : $(.project) : $(action) ] ] ;
1209 local command = [ $(new-setup).actualize ] ;
1210 local path = [ on $(command) return $(LOCATE) ] ;
1211 local block-update = $(command:S=.nup) ;
1212 NOUPDATE $(block-update) ;
1213 NOTFILE $(block-update) ;
1214 DEPENDS $(block-update) : $(command) ;
1215 if [ on $(targets) return $(.REWRITE-SETUP) ]
1216 {
1217 ALWAYS $(command) ;
1218 }
1219 $(key) = [ call-batch-script "\"$(command:WG=:R=$(path))\" $(setup-options:E=)" ] $(block-update) ;
1220 }
1221 DEPENDS $(targets) : $($(key)[2]) ;
1222 .SETUP on $(targets) = $($(key)[1]) ;
1223 }
1224 }
1225
1226 # Worker rule for toolset version configuration. Takes an explicit version id or
1227 # nothing in case it should configure the default toolset version (the first
1228 # registered one or a new 'default' one in case no toolset versions have been
1229 # registered yet).
1230 #
1231 local rule configure-really ( version ? : options * )
1232 {
1233 local command = [ feature.get-values <command> : $(options) ] ;
1234
1235 if ! $(version) && ! $(command)
1236 {
1237 # We were given neither a command, nor a version.
1238 # Take the best registered (i.e. auto-detected) version.
1239 # FIXME: consider whether an explicitly specified setup script
1240 # should disable this logic. We already won't get here if
1241 # there is a user specified command.
1242 version = [ $(.versions).all ] ;
1243 for local known in $(.known-versions)
1244 {
1245 if $(known) in $(version)
1246 {
1247 version = $(known) ;
1248 break ;
1249 }
1250 }
1251 # version might still have multiple elements if no versions
1252 # were auto-detected, but an unknown version was configured
1253 # manually.
1254 version = $(version[1]) ;
1255 }
1256
1257 # Handle a user-provided command, and deduce the version if necessary.
1258 # If the user-requested version was not autodetected and no command
1259 # was given, attempt to find it in PATH
1260 if $(command) || ! ( $(version:E=default) in [ $(.versions).all ] )
1261 {
1262 local found-command = [ common.get-invocation-command-nodefault msvc : cl.exe : $(command) ] ;
1263
1264 if $(found-command)
1265 {
1266 command = $(found-command) ;
1267 if ! $(command:D)
1268 {
1269 local path = [ common.get-absolute-tool-path $(command) ] ;
1270 command = $(command:R=$(path)) ;
1271 }
1272 }
1273 else
1274 {
1275 # If we still failed to find cl.exe, bail out.
1276 ECHO ;
1277 ECHO warning\:
1278 "Did not find command for MSVC toolset."
1279 "If you have Visual Studio 2017 installed you will need to"
1280 "specify the full path to the command,"
1281 "set VS150COMNTOOLS for your installation,"
1282 "or"
1283 "build from the 'Visual Studio Command Prompt for VS 2017'."
1284 ;
1285 ECHO ;
1286 command ?= cl.exe ;
1287 }
1288
1289 if ! $(version)
1290 {
1291 # Even if version is not explicitly specified, try to detect the
1292 # version from the path.
1293 # FIXME: We currently detect both Microsoft Visual Studio 9.0 and
1294 # 9.0express as 9.0 here.
1295 if [ MATCH "(MSVC\\\\14.3)" : $(command) ]
1296 {
1297 version = 14.3 ;
1298 }
1299 else if [ MATCH "(MSVC\\\\14.2)" : $(command) ]
1300 {
1301 version = 14.2 ;
1302 }
1303 else if [ MATCH "(MSVC\\\\14.1)" : $(command) ]
1304 {
1305 version = 14.1 ;
1306 }
1307 else if [ MATCH "(Microsoft Visual Studio 14)" : $(command) ]
1308 {
1309 version = 14.0 ;
1310 }
1311 else if [ MATCH "(Microsoft Visual Studio 12)" : $(command) ]
1312 {
1313 version = 12.0 ;
1314 }
1315 else if [ MATCH "(Microsoft Visual Studio 11)" : $(command) ]
1316 {
1317 version = 11.0 ;
1318 }
1319 else if [ MATCH "(Microsoft Visual Studio 10)" : $(command) ]
1320 {
1321 version = 10.0 ;
1322 }
1323 else if [ MATCH "(Microsoft Visual Studio 9)" : $(command) ]
1324 {
1325 version = 9.0 ;
1326 }
1327 else if [ MATCH "(Microsoft Visual Studio 8)" : $(command) ]
1328 {
1329 version = 8.0 ;
1330 }
1331 else if [ MATCH "(NET 2003[\/\\]VC7)" : $(command) ]
1332 {
1333 version = 7.1 ;
1334 }
1335 else if [ MATCH "(Microsoft Visual C\\+\\+ Toolkit 2003)" :
1336 $(command) ]
1337 {
1338 version = 7.1toolkit ;
1339 }
1340 else if [ MATCH "(.NET[\/\\]VC7)" : $(command) ]
1341 {
1342 version = 7.0 ;
1343 }
1344 else
1345 {
1346 version = 6.0 ;
1347 }
1348 }
1349 }
1350
1351 # Version alias -> real version number.
1352 version = [ resolve-possible-msvc-version-alias $(version) ] ;
1353
1354 # Check whether the selected configuration is already in use.
1355 if $(version) in [ $(.versions).used ]
1356 {
1357 # Allow multiple 'toolset.using' calls for the same configuration if the
1358 # identical sets of options are used.
1359 if $(options) && ( $(options) != [ $(.versions).get $(version) : options ] )
1360 {
1361 import errors ;
1362 errors.user-error "MSVC toolset configuration: Toolset version"
1363 "'$(version)' already configured." ;
1364 }
1365 }
1366 else
1367 {
1368 # Register a new configuration.
1369 $(.versions).register $(version) ;
1370 $(.versions).set $(version) : options : $(options) ;
1371
1372 # Mark the configuration as 'used'.
1373 $(.versions).use $(version) ;
1374
1375 # Generate conditions and save them.
1376 local conditions = [ common.check-init-parameters msvc : version $(version) ] ;
1377
1378 $(.versions).set $(version) : conditions : $(conditions) ;
1379
1380 command ?= [ $(.versions).get $(version) : default-command ] ;
1381
1382 # For 14.1+ we need the exact version as MS is planning rolling updates
1383 # that will cause our `setup-cmd` to become invalid
1384 exact-version = [ MATCH "(14\.[1-9][0-9]\.[0-9\.]+)" : $(command) ] ;
1385
1386 common.handle-options msvc : $(conditions) : $(command) : $(options) ;
1387
1388 # Generate and register setup command.
1389
1390 local below-8.0 = [ MATCH "^([67]\\.)" : $(version) ] ;
1391 local below-11.0 = [ MATCH "^([6789]\\.|10\\.)" : $(version) ] ;
1392
1393 local cpu = i386 amd64 ia64 arm arm64 ;
1394 if $(below-8.0)
1395 {
1396 cpu = i386 ;
1397 }
1398 else if $(below-11.0)
1399 {
1400 cpu = i386 amd64 ia64 ;
1401 }
1402
1403 local setup-amd64 ;
1404 local setup-i386 ;
1405 local setup-ia64 ;
1406 local setup-arm ;
1407 local setup-arm64 ;
1408 local setup-phone-i386 ;
1409 local setup-phone-arm ;
1410
1411 if $(command)
1412 {
1413 # TODO: Note that if we specify a non-existant toolset version then
1414 # this rule may find and use a corresponding compiler executable
1415 # belonging to an incorrect toolset version. For example, if you
1416 # have only MSVC 7.1 installed, have its executable on the path and
1417 # specify you want Boost Build to use MSVC 9.0, then you want Boost
1418 # Build to report an error but this may cause it to silently use the
1419 # MSVC 7.1 compiler even though it thinks it is using the msvc-9.0
1420 # toolset version.
1421 command = [ common.get-absolute-tool-path $(command[-1]) ] ;
1422 }
1423
1424 if $(command)
1425 {
1426 local parent = [ path.make $(command) ] ;
1427 parent = [ path.parent $(parent) ] ;
1428 parent = [ path.native $(parent) ] ;
1429
1430 # Setup will be used if the command name has been specified. If
1431 # setup is not specified explicitly then a default setup script will
1432 # be used instead. Setup scripts may be global or architecture/
1433 # /platform/cpu specific. Setup options are used only in case of
1434 # global setup scripts.
1435
1436 # Default setup scripts provided with different VC distributions:
1437 #
1438 # VC 7.1 had only the vcvars32.bat script specific to 32 bit i386
1439 # builds. It was located in the bin folder for the regular version
1440 # and in the root folder for the free VC 7.1 tools.
1441 #
1442 # Later 8.0 & 9.0 versions introduce separate platform specific
1443 # vcvars*.bat scripts (e.g. 32 bit, 64 bit AMD or 64 bit Itanium)
1444 # located in or under the bin folder. Most also include a global
1445 # vcvarsall.bat helper script located in the root folder which runs
1446 # one of the aforementioned vcvars*.bat scripts based on the options
1447 # passed to it. So far only the version coming with some PlatformSDK
1448 # distributions does not include this top level script but to
1449 # support those we need to fall back to using the worker scripts
1450 # directly in case the top level script can not be found.
1451
1452 local global-setup = [ feature.get-values <setup> : $(options) ] ;
1453 global-setup = $(global-setup[1]) ;
1454 local global-setup-phone = $(global-setup) ;
1455 if ! $(below-8.0)
1456 {
1457 global-setup ?= [ locate-default-setup $(command) : $(parent) :
1458 vcvarsall.bat ] ;
1459 }
1460
1461 local default-setup-amd64 = vcvars64.bat ;
1462 local default-setup-i386 = vcvars32.bat ;
1463 local default-setup-ia64 = vcvarsx86_ia64.bat ;
1464 local default-setup-arm = vcvarsx86_arm.bat ;
1465 local default-setup-arm64 = vcvarsx86_arm64.bat ;
1466 local default-setup-phone-i386 = vcvarsphonex86.bat ;
1467 local default-setup-phone-arm = vcvarsphonex86_arm.bat ;
1468
1469 # http://msdn2.microsoft.com/en-us/library/x4d2c09s(VS.80).aspx and
1470 # http://msdn2.microsoft.com/en-us/library/x4d2c09s(vs.90).aspx
1471 # mention an x86_IPF option, that seems to be a documentation bug
1472 # and x86_ia64 is the correct option.
1473 local default-global-setup-options-amd64 = x86_amd64 ;
1474 local default-global-setup-options-i386 = x86 ;
1475 local default-global-setup-options-ia64 = x86_ia64 ;
1476 local default-global-setup-options-arm = x86_arm ;
1477 local default-global-setup-options-arm64 = x86_arm64 ;
1478
1479 # When using 64-bit Windows, and targeting 64-bit, it is possible to
1480 # use a native 64-bit compiler, selected by the "amd64" & "ia64"
1481 # parameters to vcvarsall.bat. There are two variables we can use --
1482 # PROCESSOR_ARCHITECTURE and PROCESSOR_IDENTIFIER. The first is
1483 # 'x86' when running 32-bit Windows, no matter which processor is
1484 # used, and 'AMD64' on 64-bit windows on x86 (either AMD64 or EM64T)
1485 # Windows.
1486 #
1487 if [ MATCH ^(AMD64) : [ os.environ PROCESSOR_ARCHITECTURE ] ]
1488 {
1489 default-global-setup-options-amd64 = amd64 ;
1490 }
1491 # When B2 itself is running as a 32-bit process on 64-bit
1492 # Windows, the above test will fail (since WOW64 simulates a 32-bit
1493 # environment, including environment values). So check the WOW64
1494 # variable PROCESSOR_ARCHITEW6432 as well.
1495 if [ MATCH ^(AMD64) : [ os.environ PROCESSOR_ARCHITEW6432 ] ]
1496 {
1497 default-global-setup-options-amd64 = amd64 ;
1498 }
1499 # TODO: The same 'native compiler usage' should be implemented for
1500 # the Itanium platform by using the "ia64" parameter. For this
1501 # though we need someone with access to this platform who can find
1502 # out how to correctly detect this case.
1503 else if $(somehow-detect-the-itanium-platform)
1504 {
1505 default-global-setup-options-ia64 = ia64 ;
1506 }
1507
1508 for local c in $(cpu)
1509 {
1510 exact-version ?= $(version) ;
1511 setup-$(c) = [ generate-setup-cmd $(exact-version) : $(command) : $(parent) : $(options) : $(c) : $(global-setup) : $(default-global-setup-options-$(c)) : $(default-setup-$(c)) ] ;
1512 }
1513
1514 # Windows phone has different setup scripts, located in a different directory hierarchy.
1515 # The 11.0 toolset can target Windows Phone 8.0 and the 12.0 toolset can target Windows Phone 8.1,
1516 # each of which have a different directory for their vcvars setup scripts.
1517 local phone-parent = [ path.native [ path.join $(parent) WPSDK ] ] ;
1518 local phone-directory = $(phone-parent) ;
1519 if [ MATCH "(11.0)" : $(version) ]
1520 {
1521 phone-directory = [ path.native [ path.join $(phone-directory) WP80 ] ] ;
1522 }
1523 else if [ MATCH "(12.0)" : $(version) ]
1524 {
1525 phone-directory = [ path.native [ path.join $(phone-directory) WP81 ] ] ;
1526 }
1527 global-setup-phone ?= [ locate-default-setup $(phone-directory) : $(phone-parent) : vcvarsphoneall.bat ] ;
1528
1529 # If can't locate default phone setup script then this VS version doesn't support Windows Phone.
1530 if $(global-setup-phone)-is-defined
1531 {
1532 # i386 CPU is for the Windows Phone emulator in Visual Studio.
1533 local phone-cpu = i386 arm ;
1534 for local c in $(phone-cpu)
1535 {
1536 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)) ] ;
1537 }
1538 }
1539 }
1540
1541 # Get tool names (if any) and finish setup.
1542
1543 compiler = [ feature.get-values <compiler> : $(options) ] ;
1544 compiler ?= cl ;
1545
1546 linker = [ feature.get-values <linker> : $(options) ] ;
1547 linker ?= link ;
1548
1549 resource-compiler = [ feature.get-values <resource-compiler> : $(options) ] ;
1550 resource-compiler ?= rc ;
1551
1552 # Turn on some options for i386 assembler
1553 # -coff generate COFF format object file (compatible with cl.exe output)
1554 local default-assembler-amd64 = ml64 ;
1555 local default-assembler-i386 = "ml -coff" ;
1556 local default-assembler-ia64 = ias ;
1557 local default-assembler-arm = armasm ;
1558 local default-assembler-arm64 = armasm64 ;
1559
1560 # For the assembler the following options are turned on by default:
1561 #
1562 # -Zp4 align structures to 4 bytes
1563 # -Cp preserve case of user identifiers
1564 # -Cx preserve case in publics, externs
1565 #
1566 local assembler-flags-amd64 = "-c -Zp4 -Cp -Cx" ;
1567 local assembler-flags-i386 = "-c -Zp4 -Cp -Cx" ;
1568 local assembler-flags-ia64 = "-c -Zp4 -Cp -Cx" ;
1569 local assembler-flags-arm = "" ;
1570 local assembler-flags-arm64 = "" ;
1571
1572 local assembler-output-flag-amd64 = -Fo ;
1573 local assembler-output-flag-i386 = -Fo ;
1574 local assembler-output-flag-ia64 = -Fo ;
1575 local assembler-output-flag-arm = -o ;
1576 local assembler-output-flag-arm64 = -o ;
1577
1578 assembler = [ feature.get-values <assembler> : $(options) ] ;
1579
1580 idl-compiler = [ feature.get-values <idl-compiler> : $(options) ] ;
1581 idl-compiler ?= midl ;
1582
1583 mc-compiler = [ feature.get-values <mc-compiler> : $(options) ] ;
1584 mc-compiler ?= mc ;
1585
1586 manifest-tool = [ feature.get-values <manifest-tool> : $(options) ] ;
1587 manifest-tool ?= mt ;
1588
1589 local cc-filter = [ feature.get-values <compiler-filter> : $(options) ]
1590 ;
1591
1592 for local c in $(cpu)
1593 {
1594 # Setup script is not required in some configurations.
1595 setup-$(c) ?= "" ;
1596
1597 local cpu-conditions = $(conditions)/$(.cpu-arch-$(c)) ;
1598
1599 if $(.debug-configuration)
1600 {
1601 for local cpu-condition in $(cpu-conditions)
1602 {
1603 ECHO "notice: [msvc-cfg] condition: '$(cpu-condition)', setup: '$(setup-$(c):J= )'" ;
1604 }
1605 }
1606
1607 local cpu-assembler = $(assembler) ;
1608 cpu-assembler ?= $(default-assembler-$(c)) ;
1609 local assembler-flags = $(assembler-flags-$(c)) ;
1610 local assembler-output-flag = $(assembler-output-flag-$(c)) ;
1611
1612 for local api in desktop store phone
1613 {
1614 local setup-script = $(setup-$(c)) ;
1615 if $(api) = phone
1616 {
1617 setup-script = $(setup-phone-$(c)) ;
1618 }
1619
1620 if <rewrite-setup-scripts>always in $(options)
1621 {
1622 toolset.flags msvc .REWRITE-SETUP <windows-api>$(api)/$(cpu-conditions) : true ;
1623 }
1624
1625 if ! $(setup-script)
1626 {
1627 # Should we try to set up some error handling or fallbacks here?
1628 }
1629 else if <rewrite-setup-scripts>off in $(options) || [ os.name ] != NT
1630 {
1631 toolset.flags msvc .SETUP <windows-api>$(api)/$(cpu-conditions) : [ call-batch-script "\"$(setup-script[1]:W)\" $(setup-script[2-]:E=)" ] ;
1632 }
1633 else
1634 {
1635 toolset.flags msvc .SETUP-SCRIPT <windows-api>$(api)/$(cpu-conditions) : $(setup-script[1]) ;
1636 toolset.flags msvc .SETUP-OPTIONS <windows-api>$(api)/$(cpu-conditions) : $(setup-script[2-]) ;
1637 }
1638
1639 toolset.flags msvc.compile .RC <windows-api>$(api)/$(cpu-conditions) : $(resource-compiler) ;
1640 toolset.flags msvc.compile .IDL <windows-api>$(api)/$(cpu-conditions) : $(idl-compiler) ;
1641 toolset.flags msvc.compile .MC <windows-api>$(api)/$(cpu-conditions) : $(mc-compiler) ;
1642 toolset.flags msvc.link .MT <windows-api>$(api)/$(cpu-conditions) : $(manifest-tool) -nologo ;
1643
1644 if $(api) = desktop
1645 {
1646 toolset.flags msvc.compile .CC <windows-api>$(api)/$(cpu-conditions) : $(compiler) /Zm800 -nologo ;
1647 }
1648 else
1649 {
1650 toolset.flags msvc.compile .CC <windows-api>$(api)/$(cpu-conditions) : $(compiler) /Zm800 /ZW /EHsc -nologo ;
1651 }
1652 toolset.flags msvc.compile .ASM <windows-api>$(api)/$(cpu-conditions) : $(cpu-assembler) $(assembler-flags) -nologo ;
1653 toolset.flags msvc.compile .ASM_OUTPUT <windows-api>$(api)/$(cpu-conditions) : $(assembler-output-flag) ;
1654 toolset.flags msvc.link .LD <windows-api>$(api)/$(cpu-conditions) : $(linker) /NOLOGO "/INCREMENTAL:NO" ;
1655 toolset.flags msvc.archive .LD <windows-api>$(api)/$(cpu-conditions) : $(linker) /lib /NOLOGO ;
1656 }
1657
1658 if $(cc-filter)
1659 {
1660 toolset.flags msvc .CC.FILTER $(cpu-conditions) : "|" $(cc-filter) ;
1661 }
1662 }
1663
1664 # Starting with Visual Studio 2013 the CRT is split into a desktop and app dll.
1665 # If targeting WinRT and 12.0 set lib path to link against app CRT.
1666 if [ MATCH "(12)" : $(version) ]
1667 {
1668 local storeLibPath = [ path.join $(parent) "lib/store" ] ;
1669 toolset.flags msvc.link LINKPATH $(conditions)/<windows-api>store/$(.cpu-arch-i386) : [ path.native $(storeLibPath) ] ;
1670 toolset.flags msvc.link LINKPATH $(conditions)/<windows-api>store/$(.cpu-arch-amd64) : [ path.native [ path.join $(storeLibPath) "amd64" ] ] ;
1671 toolset.flags msvc.link LINKPATH $(conditions)/<windows-api>store/$(.cpu-arch-arm) : [ path.native [ path.join $(storeLibPath) "arm" ] ] ;
1672 }
1673
1674 # LTO
1675 toolset.flags msvc.compile OPTIONS $(conditions)/<lto>on : /GL ;
1676 toolset.flags msvc.link LINKFLAGS $(conditions)/<lto>on : /LTCG ;
1677
1678 # Set version-specific flags.
1679 configure-version-specific msvc : $(version) : $(conditions) ;
1680 }
1681 }
1682
1683
1684 # Returns the default installation path for the given version.
1685 #
1686 local rule default-path ( version )
1687 {
1688 local result ;
1689 {
1690 # try to use vswhere
1691 local pseudo_env_VSCOMNTOOLS ;
1692 local all-env-paths ;
1693 local root = [ os.environ "ProgramFiles(x86)" ] ;
1694 if ( ! $(root) )
1695 {
1696 root = [ os.environ "ProgramFiles" ] ;
1697 }
1698 if ( ! $(root) ) && [ os.name ] in CYGWIN
1699 {
1700 # We probably are in an 'env -i' Cygwin session, where the user
1701 # was unable restore the "ProgramFiles(x86)" environment variable,
1702 # because it is an invalid environment variable name in Cygwin.
1703 # However, we can try to query cygpath instead.
1704 root = [ SHELL "cygpath -w -F 42" : strip-eol ] ; # CSIDL_PROGRAM_FILESX86
1705 if ( ! $(root) )
1706 {
1707 root = [ SHELL "cygpath -w -F 38" : strip-eol ] ; # CSIDL_PROGRAM_FILES
1708 }
1709 }
1710 # When we are a Cygwin build, [ SHELL ] does execute using "/bin/sh -c".
1711 # When /bin/sh does find a forward slash, no PATH search is performed,
1712 # causing [ SHELL "C:\\...\\Installer/vswhere.exe" ] to succeed.
1713 # And fortunately, forward slashes do also work in native Windows.
1714 local vswhere = "$(root)/Microsoft Visual Studio/Installer/vswhere.exe" ;
1715 # The check for $(root) is to avoid a segmentation fault if not found.
1716 if $(version) in 14.1 14.2 14.3 default && $(root) && [ path.exists $(vswhere) ]
1717 {
1718 local req = "-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64" ;
1719 local prop = "-property installationPath" ;
1720 local limit ;
1721
1722 if $(version) = 14.3
1723 {
1724 limit = "-version \"[17.0,18.0)\" -prerelease" ;
1725 }
1726 else if $(version) = 14.2 || $(version) = "default"
1727 {
1728 limit = "-version \"[16.0,17.0)\"" ;
1729 }
1730 else if $(version) = 14.1
1731 {
1732 limit = "-version \"[15.0,16.0)\"" ;
1733 }
1734
1735 # Quoting the "*" is for when we are a Cygwin build, to bypass /bin/sh.
1736 local vswhere_cmd = "\"$(vswhere)\" -latest -products \"*\" $(req) $(prop) $(limit)" ;
1737 # The split character "\r" is for when we are a Cygwin build.
1738 local shell_ret = [ SPLIT_BY_CHARACTERS [ SHELL $(vswhere_cmd) ] : "\r\n" ] ;
1739 pseudo_env_VSCOMNTOOLS = [ path.native [ path.join $(shell_ret) "\\Common7\\Tools" ] ] ;
1740 if ! [ path.exists $(pseudo_env_VSCOMNTOOLS) ]
1741 {
1742 return ; # Not found. If we have vswhere, assume that it works.
1743 }
1744 all-env-paths = $(pseudo_env_VSCOMNTOOLS) ;
1745 }
1746 else
1747 {
1748 all-env-paths = [ sequence.transform os.environ
1749 : $(.version-$(version)-env) ] ;
1750 }
1751
1752 # Check environment or previous path_VS150
1753 for local env-path in $(all-env-paths)
1754 {
1755 if $(env-path) && $(.version-$(version)-path)
1756 {
1757 for local bin-path in $(.version-$(version)-path)
1758 {
1759 result = [ path.glob [ path.make $(env-path) ] : $(bin-path) ] ;
1760 if $(result)
1761 {
1762 result = [ path.native $(result[1]) ] ;
1763 break ;
1764 }
1765 }
1766 }
1767 if $(result)
1768 {
1769 break ;
1770 }
1771 }
1772 }
1773
1774 return $(result) ;
1775 }
1776
1777
1778
1779 rule get-rspline ( target : lang-opt lang-flags )
1780 {
1781 CC_RSPLINE on $(target) = [ on $(target) return $(lang-opt) -U$(UNDEFS)
1782 $($(lang-flags)) $(OPTIONS) $(USER_COMPILEFLAGS) $(USER_$(lang-flags)) -D$(DEFINES)
1783 \"-I$(INCLUDES:W)\" \"-FI$(FORCE_INCLUDES:W)\" ] ;
1784 }
1785
1786 class msvc-linking-generator : linking-generator
1787 {
1788 # Calls the base version. If necessary, also create a target for the
1789 # manifest file.specifying source's name as the name of the created
1790 # target. As result, the PCH will be named whatever.hpp.gch, and not
1791 # whatever.gch.
1792 rule generated-targets ( sources + : property-set : project name ? )
1793 {
1794 local result = [ linking-generator.generated-targets $(sources)
1795 : $(property-set) : $(project) $(name) ] ;
1796
1797 if $(result)
1798 {
1799 local name-main = [ $(result[1]).name ] ;
1800 local action = [ $(result[1]).action ] ;
1801
1802 if [ $(property-set).get <debug-symbols> ] = "on"
1803 {
1804 # We force the exact name on PDB. The reason is tagging -- the
1805 # tag rule may reasonably special case some target types, like
1806 # SHARED_LIB. The tag rule will not catch PDBs, and it cannot
1807 # even easily figure out if a PDB is paired with a SHARED_LIB,
1808 # EXE or something else. Because PDBs always get the same name
1809 # as the main target, with .pdb as extension, just force it.
1810 local target = [ class.new file-target $(name-main:S=.pdb) exact
1811 : PDB : $(project) : $(action) ] ;
1812 local registered-target = [ virtual-target.register $(target) ]
1813 ;
1814 if $(target) != $(registered-target)
1815 {
1816 $(action).replace-targets $(target) : $(registered-target) ;
1817 }
1818 result += $(registered-target) ;
1819 }
1820
1821 if [ $(property-set).get <embed-manifest> ] = "off"
1822 {
1823 # Manifest is an evil target. It has .manifest appened to the
1824 # name of the main target, including extension, e.g.
1825 # a.exe.manifest. We use the 'exact' name to achieve this
1826 # effect.
1827 local target = [ class.new file-target $(name-main).manifest
1828 exact : MANIFEST : $(project) : $(action) ] ;
1829 local registered-target = [ virtual-target.register $(target) ]
1830 ;
1831 if $(target) != $(registered-target)
1832 {
1833 $(action).replace-targets $(target) : $(registered-target) ;
1834 }
1835 result += $(registered-target) ;
1836 }
1837 }
1838 return $(result) ;
1839 }
1840 }
1841
1842
1843 # Unsafe worker rule for the register-toolset() rule. Must not be called
1844 # multiple times.
1845 #
1846 local rule register-toolset-really ( )
1847 {
1848 feature.extend toolset : msvc ;
1849
1850 # Intel and msvc supposedly have link-compatible objects.
1851 feature.subfeature toolset msvc : vendor : intel : propagated optional ;
1852
1853 # Inherit MIDL flags.
1854 toolset.inherit-flags msvc : midl ;
1855
1856 # Inherit MC flags.
1857 toolset.inherit-flags msvc : mc ;
1858
1859 # Dynamic runtime comes only in MT flavour.
1860 toolset.add-requirements
1861 <toolset>msvc,<runtime-link>shared:<threading>multi ;
1862
1863 # Declare msvc toolset specific features.
1864 {
1865 feature.feature debug-store : object database : propagated ;
1866 feature.feature pch-source : : dependency free ;
1867 }
1868
1869 # Declare generators.
1870 {
1871 # TODO: Is it possible to combine these? Make the generators
1872 # non-composing so that they do not convert each source into a separate
1873 # .rsp file.
1874 generators.register [ new msvc-linking-generator msvc.link :
1875 OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : EXE : <toolset>msvc ] ;
1876 generators.register [ new msvc-linking-generator msvc.link.dll :
1877 OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB IMPORT_LIB :
1878 <toolset>msvc <suppress-import-lib>false ] ;
1879 generators.register [ new msvc-linking-generator msvc.link.dll :
1880 OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB :
1881 <toolset>msvc <suppress-import-lib>true ] ;
1882
1883 generators.register-archiver msvc.archive : OBJ : STATIC_LIB : <toolset>msvc ;
1884 generators.register-c-compiler msvc.compile.c++ : CPP : OBJ : <toolset>msvc ;
1885 generators.register-c-compiler msvc.compile.c : C : OBJ : <toolset>msvc ;
1886 generators.register-c-compiler msvc.compile.c++.preprocess : CPP : PREPROCESSED_CPP : <toolset>msvc ;
1887 generators.register-c-compiler msvc.compile.c.preprocess : C : PREPROCESSED_C : <toolset>msvc ;
1888
1889 # Using 'register-c-compiler' adds the build directory to INCLUDES.
1890 generators.register-c-compiler msvc.compile.rc : RC : OBJ(%_res) : <toolset>msvc ;
1891 generators.override msvc.compile.rc : rc.compile.resource ;
1892 generators.register-standard msvc.compile.asm : ASM : OBJ : <toolset>msvc ;
1893
1894 generators.register-c-compiler msvc.compile.idl : IDL : MSTYPELIB H C(%_i) C(%_proxy) C(%_dlldata) : <toolset>msvc ;
1895 generators.override msvc.compile.idl : midl.compile.idl ;
1896
1897 generators.register-standard msvc.compile.mc : MC : H RC : <toolset>msvc ;
1898 generators.override msvc.compile.mc : mc.compile ;
1899
1900 # Note: the 'H' source type will catch both '.h' and '.hpp' headers as
1901 # the latter have their HPP type derived from H. The type of compilation
1902 # is determined entirely by the destination type.
1903 generators.register [ new msvc-pch-generator msvc.compile.c.pch : H : C_PCH OBJ : <pch>on <toolset>msvc ] ;
1904 generators.register [ new msvc-pch-generator msvc.compile.c++.pch : H : CPP_PCH OBJ : <pch>on <toolset>msvc ] ;
1905
1906 generators.override msvc.compile.c.pch : pch.default-c-pch-generator ;
1907 generators.override msvc.compile.c++.pch : pch.default-cpp-pch-generator ;
1908 }
1909
1910 toolset.flags msvc.compile PCH_FILE <pch>on : <pch-file> ;
1911 toolset.flags msvc.compile PCH_SOURCE <pch>on : <pch-source> ;
1912 toolset.flags msvc.compile PCH_HEADER <pch>on : <pch-header> ;
1913
1914 #
1915 # Declare flags for compilation.
1916 #
1917
1918 toolset.flags msvc.compile OPTIONS <optimization>speed : /O2 ;
1919 toolset.flags msvc.compile OPTIONS <optimization>space : /O1 ;
1920
1921 toolset.flags msvc.compile OPTIONS $(.cpu-arch-ia64)/<instruction-set>$(.cpu-type-itanium) : /G1 ;
1922 toolset.flags msvc.compile OPTIONS $(.cpu-arch-ia64)/<instruction-set>$(.cpu-type-itanium2) : /G2 ;
1923
1924 toolset.flags msvc.compile OPTIONS <debug-symbols>on/<debug-store>object : /Z7 ;
1925 toolset.flags msvc.compile OPTIONS <debug-symbols>on/<debug-store>database : /Zi ;
1926 toolset.flags msvc.compile OPTIONS <optimization>off : /Od ;
1927 toolset.flags msvc.compile OPTIONS <inlining>off : /Ob0 ;
1928 toolset.flags msvc.compile OPTIONS <inlining>on : /Ob1 ;
1929 toolset.flags msvc.compile OPTIONS <inlining>full : /Ob2 ;
1930
1931 toolset.flags msvc.compile OPTIONS <warnings>on : /W3 ;
1932 toolset.flags msvc.compile OPTIONS <warnings>off : /W0 ;
1933 toolset.flags msvc.compile OPTIONS <warnings>all : /W4 ;
1934 toolset.flags msvc.compile OPTIONS <warnings>extra : /W4 ;
1935 toolset.flags msvc.compile OPTIONS <warnings>pedantic : /W4 ;
1936 toolset.flags msvc.compile OPTIONS <warnings-as-errors>on : /WX ;
1937
1938 toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>off/<extern-c-nothrow>off : /EHs ;
1939 toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>off/<extern-c-nothrow>on : /EHsc ;
1940 toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>on/<extern-c-nothrow>off : /EHa ;
1941 toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>on/<extern-c-nothrow>on : /EHac ;
1942
1943 toolset.flags msvc.compile C++FLAGS <cxxstd>14 : "/std:c++14" ;
1944 toolset.flags msvc.compile C++FLAGS <cxxstd>17 : "/std:c++17" ;
1945 toolset.flags msvc.compile C++FLAGS <cxxstd>20 : "/std:c++20" ;
1946 toolset.flags msvc.compile C++FLAGS <cxxstd>latest : "/std:c++latest" ;
1947
1948 # By default 8.0 enables rtti support while prior versions disabled it. We
1949 # simply enable or disable it explicitly so we do not have to depend on this
1950 # default behaviour.
1951 toolset.flags msvc.compile C++FLAGS <rtti>on : /GR ;
1952 toolset.flags msvc.compile C++FLAGS <rtti>off : /GR- ;
1953 toolset.flags msvc.compile OPTIONS <runtime-debugging>off/<runtime-link>shared : /MD ;
1954 toolset.flags msvc.compile OPTIONS <runtime-debugging>on/<runtime-link>shared : /MDd ;
1955
1956 toolset.flags msvc.compile OPTIONS <runtime-debugging>off/<runtime-link>static/<threading>multi : /MT ;
1957 toolset.flags msvc.compile OPTIONS <runtime-debugging>on/<runtime-link>static/<threading>multi : /MTd ;
1958
1959 toolset.flags msvc.compile USER_CFLAGS <cflags> : ;
1960 toolset.flags msvc.compile.c++ USER_C++FLAGS <cxxflags> : ;
1961 toolset.flags msvc.compile.c++ USER_COMPILEFLAGS <compileflags> : ;
1962
1963 toolset.flags msvc.compile PDB_CFLAG <debug-symbols>on/<debug-store>database : /Fd ;
1964
1965 toolset.flags msvc.compile DEFINES <define> ;
1966 toolset.flags msvc.compile UNDEFS <undef> ;
1967 toolset.flags msvc.compile INCLUDES <include> ;
1968 toolset.flags msvc.compile FORCE_INCLUDES <force-include> ;
1969
1970 # Declare flags for the assembler.
1971 toolset.flags msvc.compile.asm USER_ASMFLAGS <asmflags> ;
1972
1973 toolset.flags msvc.compile.asm ASMFLAGS <architecture>x86/<debug-symbols>on : "/Zi /Zd" ;
1974
1975 toolset.flags msvc.compile.asm ASMFLAGS <architecture>x86/<warnings>on : /W3 ;
1976 toolset.flags msvc.compile.asm ASMFLAGS <architecture>x86/<warnings>off : /W0 ;
1977 toolset.flags msvc.compile.asm ASMFLAGS <architecture>x86/<warnings>all : /W4 ;
1978 toolset.flags msvc.compile.asm ASMFLAGS <architecture>x86/<warnings-as-errors>on : /WX ;
1979
1980 toolset.flags msvc.compile.asm ASMDEFINES <architecture>x86 : <define> ;
1981
1982 # Declare flags for linking.
1983 {
1984 toolset.flags msvc.link PDB_LINKFLAG <debug-symbols>on/<debug-store>database : "/PDB:" ; # not used yet
1985 toolset.flags msvc.link LINKFLAGS <debug-symbols>on : /DEBUG ;
1986 toolset.flags msvc.link DEF_FILE <def-file> ;
1987 toolset.flags msvc.link MANIFEST_FILE <embed-manifest-via>linker : <embed-manifest-file> ;
1988
1989 # The linker disables the default optimizations when using /DEBUG so we
1990 # have to enable them manually for release builds with debug symbols.
1991 toolset.flags msvc LINKFLAGS <debug-symbols>on/<runtime-debugging>off : "/OPT:REF,ICF" ;
1992
1993 toolset.flags msvc LINKFLAGS <user-interface>console : "/subsystem:console" ;
1994 toolset.flags msvc LINKFLAGS <user-interface>gui : "/subsystem:windows" ;
1995 toolset.flags msvc LINKFLAGS <user-interface>wince : "/subsystem:windowsce" ;
1996 toolset.flags msvc LINKFLAGS <user-interface>native : "/subsystem:native" ;
1997 toolset.flags msvc LINKFLAGS <user-interface>auto : "/subsystem:posix" ;
1998
1999 toolset.flags msvc.link LINKFLAGS <linkflags> ;
2000 toolset.flags msvc.link LINKPATH <library-path> ;
2001
2002 toolset.flags msvc.link FINDLIBS_ST <find-static-library> ;
2003 toolset.flags msvc.link FINDLIBS_SA <find-shared-library> ;
2004 toolset.flags msvc.link LIBRARY_OPTION <toolset>msvc : "" : unchecked ;
2005 toolset.flags msvc.link LIBRARIES_MENTIONED_BY_FILE : <library-file> ;
2006 }
2007
2008 toolset.flags msvc.archive AROPTIONS <archiveflags> ;
2009
2010 # Enable response file control
2011 toolset.flags msvc RESPONSE_FILE_SUB <response-file>auto : a ;
2012 toolset.flags msvc RESPONSE_FILE_SUB <response-file>file : f ;
2013 toolset.flags msvc RESPONSE_FILE_SUB <response-file>contents : c ;
2014
2015 # Create a project to allow building the setup scripts
2016 project.initialize $(__name__) ;
2017 .project = [ project.current ] ;
2018 project msvc ;
2019
2020 feature.feature msvc.setup-options : : free ;
2021 }
2022
2023
2024 # Locates the requested setup script under the given folder and returns its full
2025 # path or nothing in case the script can not be found. In case multiple scripts
2026 # are found only the first one is returned.
2027 #
2028 # TODO: There used to exist a code comment for the msvc.init rule stating that
2029 # we do not correctly detect the location of the vcvars32.bat setup script for
2030 # the free VC7.1 tools in case user explicitly provides a path. This should be
2031 # tested or simply remove this whole comment in case this toolset version is no
2032 # longer important.
2033 #
2034 local rule locate-default-setup ( command : parent : setup-name )
2035 {
2036 local result = [ GLOB $(command) $(parent) : $(setup-name) ] ;
2037 if $(result[1])
2038 {
2039 return $(result[1]) ;
2040 }
2041 }
2042
2043
2044 # Validates given path, registers found configuration and prints debug
2045 # information about it.
2046 #
2047 local rule register-configuration ( version : path ? )
2048 {
2049 if $(path)
2050 {
2051 local command = [ GLOB $(path) : cl.exe ] ;
2052
2053 if $(command)
2054 {
2055 if $(.debug-configuration)
2056 {
2057 ECHO notice\: "[msvc-cfg]" msvc-$(version) detected, command\:
2058 '$(command)' ;
2059 }
2060
2061 $(.versions).register $(version) ;
2062 $(.versions).set $(version) : default-command : $(command) ;
2063 }
2064 }
2065 }
2066
2067
2068 ################################################################################
2069 #
2070 # Startup code executed when loading this module.
2071 #
2072 ################################################################################
2073
2074 if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
2075 {
2076 .debug-configuration = true ;
2077 }
2078
2079 # Miscellaneous constants.
2080 .RM = [ common.rm-command ] ;
2081 .nl = "
2082 " ;
2083 _ = " " ;
2084 .ProgramFiles = [ path.make [ common.get-program-files-dir ] ] ;
2085 .escaped-double-quote = "\"" ;
2086 .hash = "\#" ;
2087 .TOUCH_FILE = [ common.file-touch-command ] ;
2088
2089 # List of all registered configurations.
2090 .versions = [ new configurations ] ;
2091
2092 # Supported CPU architectures.
2093 .cpu-arch-info-i386 = x86 32 ;
2094 .cpu-arch-info-amd64 = x86 64 ;
2095 .cpu-arch-info-ia64 = ia64 64 ;
2096 .cpu-arch-info-arm = arm 32 ;
2097 .cpu-arch-info-arm64 = arm 64 ;
2098
2099 # Fill explicit architecture and address model values
2100 for local cpu in [ MATCH "^\\.cpu-arch-info-(.*)" : [ VARNAMES $(__name__) ] ]
2101 {
2102 local arch = $(.cpu-arch-info-$(cpu)[1]) ;
2103 .cpus-on-$(arch) += $(cpu) ;
2104 .cpu-arch-$(cpu) = <architecture>$(arch)/<address-model>$(.cpu-arch-info-$(cpu)[2]) ;
2105 }
2106
2107 # Match implicit architecture and address model based on the current platform
2108 .default-cpu-arch = [ os.environ PROCESSOR_ARCHITEW6432 ] ;
2109 .default-cpu-arch ?= [ os.environ PROCESSOR_ARCHITECTURE ] ;
2110 .default-cpu-arch = $(.default-cpu-arch:L) ;
2111 switch $(.default-cpu-arch)
2112 {
2113 case x86 : .default-cpu-arch = i386 ;
2114 case em64t : .default-cpu-arch = amd64 ;
2115 }
2116
2117 for local cpu in $(.cpus-on-$(.cpu-arch-info-$(.default-cpu-arch)[1]))
2118 {
2119 .cpu-arch-$(cpu) += <architecture>/<address-model>$(.cpu-arch-info-$(cpu)[2]) ;
2120 }
2121
2122 .cpu-arch-$(.default-cpu-arch) += <architecture>$(.cpu-arch-info-$(.default-cpu-arch)[1])/<address-model> ;
2123 .cpu-arch-$(.default-cpu-arch) += <architecture>/<address-model> ;
2124
2125 # If there is only one address model for an architecture we allow to ommit it
2126 for local arch in [ MATCH "^\\.cpus-on-(.*)" : [ VARNAMES $(__name__) ] ]
2127 {
2128 if ! $(.cpus-on-$(arch)[2-]) && $(.cpus-on-$(arch)[1]) != $(.default-cpu-arch)
2129 {
2130 .cpu-arch-$(.cpus-on-$(arch)) += <architecture>$(arch)/<address-model> ;
2131 }
2132 }
2133
2134
2135 # Supported CPU types (only Itanium optimization options are supported from
2136 # VC++ 2005 on). See
2137 # http://msdn2.microsoft.com/en-us/library/h66s5s0e(vs.90).aspx for more
2138 # detailed information.
2139 .cpu-type-g5 = i586 pentium pentium-mmx ;
2140 .cpu-type-g6 = i686 pentiumpro pentium2 pentium3 pentium3m pentium-m k6
2141 k6-2 k6-3 winchip-c6 winchip2 c3 c3-2 c7 ;
2142 .cpu-type-em64t = prescott nocona core2 corei7 corei7-avx core-avx-i
2143 conroe conroe-xe conroe-l allendale merom
2144 merom-xe kentsfield kentsfield-xe penryn wolfdale
2145 yorksfield nehalem sandy-bridge ivy-bridge haswell
2146 broadwell skylake skylake-avx512 cannonlake icelake-client
2147 icelake-server cascadelake cooperlake tigerlake ;
2148 .cpu-type-amd64 = k8 opteron athlon64 athlon-fx k8-sse3 opteron-sse3
2149 athlon64-sse3 amdfam10 barcelona bdver1 bdver2 bdver3
2150 bdver4 btver1 btver2 znver1 znver2 ;
2151 .cpu-type-g7 = pentium4 pentium4m athlon athlon-tbird athlon-4 athlon-xp
2152 athlon-mp $(.cpu-type-em64t) $(.cpu-type-amd64) ;
2153 .cpu-type-itanium = itanium itanium1 merced ;
2154 .cpu-type-itanium2 = itanium2 mckinley ;
2155 .cpu-type-arm = armv2 armv2a armv3 armv3m armv4 armv4t armv5 armv5t armv5te armv6 armv6j iwmmxt ep9312
2156 armv7 armv7s ;
2157
2158 # Known toolset versions, in order of preference.
2159 .known-versions = 14.3 14.2 14.1 14.0 12.0 11.0 10.0 10.0express 9.0 9.0express 8.0 8.0express 7.1
2160 7.1toolkit 7.0 6.0 ;
2161
2162 # Version aliases.
2163 .version-alias-6 = 6.0 ;
2164 .version-alias-6.5 = 6.0 ;
2165 .version-alias-7 = 7.0 ;
2166 .version-alias-8 = 8.0 ;
2167 .version-alias-9 = 9.0 ;
2168 .version-alias-10 = 10.0 ;
2169 .version-alias-11 = 11.0 ;
2170 .version-alias-12 = 12.0 ;
2171 .version-alias-14 = 14.0 ;
2172
2173 # Names of registry keys containing the Visual C++ installation path (relative
2174 # to "HKEY_LOCAL_MACHINE\SOFTWARE\\Microsoft").
2175 .version-6.0-reg = "VisualStudio\\6.0\\Setup\\Microsoft Visual C++" ;
2176 .version-7.0-reg = "VisualStudio\\7.0\\Setup\\VC" ;
2177 .version-7.1-reg = "VisualStudio\\7.1\\Setup\\VC" ;
2178 .version-8.0-reg = "VisualStudio\\8.0\\Setup\\VC" ;
2179 .version-8.0express-reg = "VCExpress\\8.0\\Setup\\VC" ;
2180 .version-9.0-reg = "VisualStudio\\9.0\\Setup\\VC" ;
2181 .version-9.0express-reg = "VCExpress\\9.0\\Setup\\VC" ;
2182 .version-10.0-reg = "VisualStudio\\10.0\\Setup\\VC" ;
2183 .version-10.0express-reg = "VCExpress\\10.0\\Setup\\VC" ;
2184 .version-11.0-reg = "VisualStudio\\11.0\\Setup\\VC" ;
2185 .version-12.0-reg = "VisualStudio\\12.0\\Setup\\VC" ;
2186 .version-14.0-reg = "VisualStudio\\14.0\\Setup\\VC" ;
2187
2188 # Visual C++ Toolkit 2003 does not store its installation path in the registry.
2189 # The environment variable 'VCToolkitInstallDir' and the default installation
2190 # path will be checked instead.
2191 .version-7.1toolkit-path = "Microsoft Visual C++ Toolkit 2003/bin" ;
2192 .version-7.1toolkit-env = VCToolkitInstallDir ;
2193 # Visual Studio 2017 doesn't use a registry at all. And the suggested methods
2194 # of discovery involve having a compiled program. So as a fallback we search
2195 # paths for VS2017 (aka msvc >= 14.1).
2196 .version-14.1-path =
2197 "../../VC/Tools/MSVC/*/bin/Host*/*"
2198 "Microsoft Visual Studio/2017/*/VC/Tools/MSVC/*/bin/Host*/*"
2199 ;
2200 .version-14.1-env = VS150COMNTOOLS ProgramFiles ProgramFiles(x86) ;
2201 .version-14.2-path =
2202 "../../VC/Tools/MSVC/*/bin/Host*/*"
2203 "Microsoft Visual Studio/2019/*/VC/Tools/MSVC/*/bin/Host*/*"
2204 ;
2205 .version-14.2-env = VS160COMNTOOLS ProgramFiles ProgramFiles(x86) ;
2206 .version-14.3-path =
2207 "../../VC/Tools/MSVC/*/bin/Host*/*"
2208 "Microsoft Visual Studio/2022/*/VC/Tools/MSVC/*/bin/Host*/*"
2209 ;
2210 .version-14.3-env = VS170COMNTOOLS ProgramFiles ProgramFiles(x86) ;
2211
2212 # Auto-detect all the available msvc installations on the system.
2213 auto-detect-toolset-versions ;
2214
2215
2216 # And finally trigger the actual Boost Build toolset registration.
2217 register-toolset ;