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
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)
18 [[bbv2.reference.tools.compiler.msvc]]
19 = Microsoft Visual C++
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:
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
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
43 .\b2 toolset=msvc-14.2 target
46 The `msvc` module is initialized using the following syntax:
49 using msvc : [version] : [c++-compile-command] : [compiler options] ;
52 This statement may be repeated several times, if you want to configure
53 several versions of the compiler.
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.
62 The compiler command should be specified using forward slashes, and
65 The following options can be provided, using
66 _`<option-name>option-value syntax`_:
69 Specifies additional compiler flags that will be used when compiling C
73 Specifies additional compiler flags that will be used when compiling C++
77 Specifies additional compiler flags that will be used when compiling both C
81 Specifies additional command line options that will be passed to the linker.
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.
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.
94 Command through which to pipe the output of running the compiler. For
95 example to pass the output to STLfilt.
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.
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.
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.
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.
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`.
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.
131 [[bbv2.reference.tools.compiler.msvc.64]]
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):
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
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.
153 To use 64-bit compilation you should:
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
159 2. When compiling, use `address-model=64`, to generate AMD64 code.
160 3. To generate IA64 code, use `architecture=ia64`
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.
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.
173 [[bbv2.reference.tools.compiler.msvc.winrt]]
174 == Windows Runtime support
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.
182 When using `store` or `phone` the specified toolset determines what
183 Windows version is targeted. The following options are available:
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
190 For example use the following to build for Windows Store 8.1 with the
194 .\b2 toolset=msvc-12.0 windows-api=store architecture=arm
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].
204 ################################################################################
206 # MSVC Boost Build toolset module.
207 # --------------------------------
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.
213 ################################################################################
215 import "class" : new ;
226 import property-set ;
233 import virtual-target ;
237 type.register MANIFEST : manifest ;
241 [[bbv2.builtin.features.embed-manifest]]`embed-manifest`::
242 *Allowed values:* `on`, `off`.
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.
250 |# # end::embed-doc[]
252 feature.feature embed-manifest : on off : incidental propagated ;
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.
263 |# # end::embed-doc[]
265 feature.feature embed-manifest-file : : free dependency ;
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.
273 |# # end::embed-doc[]
275 feature.feature embed-manifest-via : mt linker : incidental propagated ;
277 type.register PDB : pdb ;
280 ################################################################################
284 ################################################################################
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:
290 # using msvc : 6.5 : cl.exe ;
291 # using msvc : 7.0 : Y:/foo/bar/cl.exe ;
293 # The version parameter may be omitted:
295 # using msvc : : Z:/foo/bar/cl.exe ;
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.
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:
307 # Passed Nothing "x.y" detected, detected,
308 # version detected detected cl.exe in path cl.exe in path
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"
315 # "x.y" - refers to a detected version;
316 # "a.b" - refers to an undetected version.
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.
323 # The msvc version being configured. When omitted the tools invoked when no
324 # explicit version is given will be configured.
327 # The command used to invoke the compiler. If not specified:
328 # - if version is given, default location for that version will be
331 # - if version is not given, default locations for MSVC 9.0, 8.0, 7.1, 7.0
332 # and 6.* will be searched
334 # - if compiler is not found in the default locations, PATH will be
338 # Options may include:
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>.
349 # <resource-compiler>
350 # Exact tool names to be used by this msvc toolset configuration.
353 # Command through which to pipe the output of running the compiler.
354 # For example to pass the output to STLfilt.
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
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.
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.
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
383 options += <command>$(command) ;
385 configure $(version) : $(options) ;
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
393 rule configure ( version ? : options * )
401 errors.error "MSVC toolset configuration: options should be"
402 "empty when '$(version)' is specified." ;
405 # Configure (i.e. mark as used) all registered versions.
406 local all-versions = [ $(.versions).all ] ;
409 if $(.debug-configuration)
411 ECHO "notice: [msvc-cfg] Asked to configure all registered"
412 "msvc toolset versions when there are none currently"
418 for local v in $(all-versions)
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) ;
430 configure-really : $(options) ;
433 configure-really $(version) : $(options) ;
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.
444 rule configure-version-specific ( toolset : version : conditions )
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) ]
454 toolset.flags $(toolset).compile OPTIONS $(conditions) : "/Zc:forScope" "/Zc:wchar_t" ;
455 toolset.flags $(toolset).compile.c++ C++FLAGS $(conditions) : /wd4675 ;
457 # Explicitly disable the 'function is deprecated' warning. Some msvc
458 # versions have a bug, causing them to emit the deprecation warning even
460 toolset.flags $(toolset).compile OPTIONS $(conditions)/<warnings>off : /wd4996 ;
462 if [ MATCH "^([78]\\.)" : $(version) ]
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 ;
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 ]
475 toolset.flags $(toolset).compile OPTIONS $(conditions) : "/Zc:inline" ;
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 ;
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 ]
485 toolset.flags $(toolset).compile C++FLAGS $(conditions) : "/Zc:throwingNew" ;
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 ]
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
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" ;
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" ;
560 # Processor-specific optimization.
563 if [ MATCH "^([67])" : $(version) ]
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 ;
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 ;
576 # Improve floating-point accuracy. Otherwise, some of C++ Boost's "math"
578 toolset.flags $(toolset).compile OPTIONS $(conditions) : /Op ;
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 ;
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" ;
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 ;
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" ;
602 if [ version.version-less [ SPLIT_BY_CHARACTERS [ MATCH "^([0123456789.]+)" : $(version) ] : . ] : 11 ]
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 ;
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" ;
614 local conditionx = [ feature.split $(conditions) ] ;
615 toolset.add-defaults $(conditionx:J=,)\:<embed-manifest-via>linker ;
619 toolset.pop-checking-for-flags-module ;
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 ;
631 # Registers this toolset including all of its flags, features & generators. Does
632 # nothing on repeated calls.
634 rule register-toolset ( )
636 if ! msvc in [ feature.values toolset ]
638 register-toolset-really ;
642 rule resolve-possible-msvc-version-alias ( version )
644 if $(.version-alias-$(version))
646 version = $(.version-alias-$(version)) ;
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.
657 # The 'DEL' command would issue a message to stdout if the file does not
658 # exist, so need a check.
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")
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")
674 rule compile.asm ( targets + : sources * : properties * )
676 set-setup-command $(targets) : $(properties) ;
681 $(.SETUP) $(.ASM) -D$(ASMDEFINES) $(ASMFLAGS) $(USER_ASMFLAGS) $(.ASM_OUTPUT) "$(<:W)" "$(>:W)"
685 rule compile.c ( targets + : sources * : properties * )
687 set-setup-command $(targets) : $(properties) ;
688 get-rspline $(targets) : -TC CFLAGS ;
689 compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
693 rule compile.c.preprocess ( targets + : sources * : properties * )
695 set-setup-command $(targets) : $(properties) ;
696 get-rspline $(targets) : -TC CFLAGS ;
697 preprocess-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
701 rule compile.c.pch ( targets + : sources * : properties * )
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) ] ;
709 DEPENDS $(<) : $(pch-source) ;
710 compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ;
714 compile-c-c++-pch $(targets) : $(sources) ;
718 toolset.flags msvc YLOPTION : "-Yl" ;
720 # Action for running the C/C++ compiler without using precompiled headers.
722 # WARNING: Synchronize any changes this in action with intel-win
724 # Notes regarding PDB generation, for when we use
725 # <debug-symbols>on/<debug-store>database:
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.
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
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.
738 actions compile-c-c++ bind PDB_NAME PCH_HEADER
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)
743 actions preprocess-c-c++ bind PDB_NAME PCH_HEADER
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))
748 rule compile-c-c++ ( targets + : sources * )
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) ] ;
756 rule preprocess-c-c++ ( targets + : sources * )
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) ] ;
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.
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
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)
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
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)
785 rule compile.c++ ( targets + : sources * : properties * )
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) ] ;
792 rule compile.c++.preprocess ( targets + : sources * : properties * )
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) ] ;
800 rule compile.c++.pch ( targets + : sources * : properties * )
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) ] ;
808 DEPENDS $(<) : $(pch-source) ;
809 compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ;
813 compile-c-c++-pch $(targets) : $(sources) ;
817 rule compile.idl ( targets + : sources * : properties * )
819 set-setup-command $(targets) : $(properties) ;
822 # See midl.jam for details.
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)"
831 rule compile.mc ( targets + : sources * : properties * )
833 set-setup-command $(targets) : $(properties) ;
838 $(.SETUP) $(.MC) $(MCFLAGS) -h "$(<[1]:DW)" -r "$(<[2]:DW)" "$(>:W)"
842 rule compile.rc ( targets + : sources * : properties * )
844 set-setup-command $(targets) : $(properties) ;
849 $(.SETUP) $(.RC) /nologo -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES:W)" -fo "$(<:W)" "$(>:W)"
852 toolset.uses-features msvc.link : <embed-manifest> <embed-manifest-file> ;
854 rule link ( targets + : sources * : properties * )
856 set-setup-command $(targets) : $(properties) ;
857 if <embed-manifest>on in $(properties) && <embed-manifest-via>mt in $(properties)
859 if [ feature.get-values <embed-manifest-file> : $(properties) ]
861 DEPENDS $(<) : [ on $(<) return $(EMBED_MANIFEST_FILE) ] ;
862 msvc.manifest.user $(targets) $(EMBED_MANIFEST_FILE) : $(sources) : $(properties) ;
866 msvc.manifest $(targets) : $(sources) : $(properties) ;
871 rule link.dll ( targets + : sources * : properties * )
873 set-setup-command $(targets) : $(properties) ;
874 DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ;
876 if ! <suppress-import-lib>true in $(properties)
878 import-lib = $(targets[2]) ;
879 IMPORT_LIB on $(targets) = $(import-lib) ;
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)
893 if [ feature.get-values <embed-manifest-file> : $(properties) ]
895 DEPENDS $(<) : [ on $(<) return $(EMBED_MANIFEST_FILE) ] ;
896 msvc.manifest.dll.user $(targets) $(EMBED_MANIFEST_FILE) : $(sources) : $(properties) ;
900 msvc.manifest.dll $(targets) : $(sources) : $(properties) ;
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
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).
916 actions link bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE MANIFEST_FILE
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)"
923 $(.SETUP) $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);1"
926 actions manifest.user bind EMBED_MANIFEST_FILE
928 $(.SETUP) $(.MT) -manifest "$(EMBED_MANIFEST_FILE)" "-outputresource:$(<[1]);1"
931 actions link.dll bind IMPORT_LIB DEF_FILE LIBRARIES_MENTIONED_BY_FILE MANIFEST_FILE
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)"
938 $(.SETUP) $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);2"
941 actions manifest.dll.user bind EMBED_MANIFEST_FILE
943 $(.SETUP) $(.MT) -manifest "$(EMBED_MANIFEST_FILE)" "-outputresource:$(<[1]);2"
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.
951 # Poking at source targets this way is probably not clean, but it is the
954 rule archive ( targets + : sources * : properties * )
956 set-setup-command $(targets) : $(properties) ;
957 PDB_NAME on $(>) = $(<[1]:S=.pdb) ;
958 LOCATE on $(<[1]:S=.pdb) = [ on $(<[1]) return $(LOCATE) ] ;
962 ################################################################################
966 ################################################################################
968 class msvc-pch-generator : pch-generator
970 import property-set ;
972 rule run-pch ( project name ? : property-set : sources * )
974 # Searching for the header and source file in the sources.
977 for local s in $(sources)
979 if [ type.is-derived [ $(s).type ] H ]
984 [ type.is-derived [ $(s).type ] CPP ] ||
985 [ type.is-derived [ $(s).type ] C ]
993 import errors : user-error : errors.user-error ;
994 errors.user-error "can not build pch without pch-header" ;
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 ] ]
1011 for local g in $(generated[2-])
1013 if [ type.is-derived [ $(g).type ] PCH ]
1019 return [ $(generated[1]).add-raw <pch-header>$(pch-header)
1020 <pch-file>$(pch-file) ] $(generated[2-]) ;
1025 ################################################################################
1029 ################################################################################
1031 # Detects versions listed as '.known-versions' by checking registry information,
1032 # environment variables & default paths. Supports both native Windows and
1035 local rule auto-detect-toolset-versions ( )
1037 if [ os.name ] in NT CYGWIN
1039 # Get installation paths from the registry.
1040 for local i in $(.known-versions)
1042 if $(.version-$(i)-reg)
1045 for local x in "" "Wow6432Node\\"
1047 vc-path += [ W32_GETREG
1048 "HKEY_LOCAL_MACHINE\\SOFTWARE\\"$(x)"\\Microsoft\\"$(.version-$(i)-reg)
1054 vc-path = [ path.join [ path.make-NT $(vc-path[1]) ] "bin" ] ;
1055 register-configuration $(i) : [ path.native $(vc-path[1]) ] ;
1061 # Check environment and default installation paths.
1062 for local i in $(.known-versions)
1064 if ! $(i) in [ $(.versions).all ]
1066 register-configuration $(i) : [ default-path $(i) ] ;
1071 actions write-setup-script
1073 @($(STDOUT):E=$(FILE_CONTENTS:J=$(.nl))) > "$(<)"
1078 local rule call-batch-script ( command )
1080 return "call $(command) >nul$(.nl)" ;
1085 # On cygwin, we need to run both the batch script
1086 # and the following command in the same instance
1088 local rule call-batch-script ( command )
1090 return "cmd.exe /S /C call $(command) \">nul\" \"&&\" " ;
1094 # Local helper rule to create the vcvars setup command for given architecture
1097 local rule generate-setup-cmd ( version : command : parent : options * : cpu : global-setup ? : default-global-setup-options : default-setup )
1099 local setup-options ;
1100 local setup = [ feature.get-values <setup-$(cpu)> : $(options) ] ;
1102 if ! $(setup)-is-defined
1104 if $(global-setup)-is-defined
1106 setup = $(global-setup) ;
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) ;
1116 if [ MATCH "(14.3)" : $(version) ]
1118 if $(.debug-configuration)
1120 ECHO "notice: [generate-setup-cmd] $(version) is 14.3" ;
1122 parent = [ path.native [ path.join $(parent) "..\\..\\..\\..\\..\\Auxiliary\\Build" ] ] ;
1124 else if [ MATCH "(14.2)" : $(version) ]
1126 if $(.debug-configuration)
1128 ECHO "notice: [generate-setup-cmd] $(version) is 14.2" ;
1130 parent = [ path.native [ path.join $(parent) "..\\..\\..\\..\\..\\Auxiliary\\Build" ] ] ;
1132 else if [ MATCH "(14.1)" : $(version) ]
1134 if $(.debug-configuration)
1136 ECHO "notice: [generate-setup-cmd] $(version) is 14.1" ;
1138 parent = [ path.native [ path.join $(parent) "..\\..\\..\\..\\..\\Auxiliary\\Build" ] ] ;
1140 setup = [ locate-default-setup $(command) : $(parent) : $(default-setup) ] ;
1141 setup ?= [ path.join $(parent) "vcvarsall.bat" ] ;
1145 return $(setup) "$(setup-options:J= )" ;
1148 # Worker for set-setup-command. Usable in a virtual-target.action.
1149 rule adjust-setup-command ( new-setup : setup : properties * )
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) ;
1163 # This doesn't actually do anything. It's merely
1164 # used as a trigger for __ACTION_RULE__.
1165 actions quietly read-setup { }
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 : * )
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) ] ;
1179 FILE_CONTENTS on $(new-setup) = "REM $(command)" "SET "$(diff-vars) ;
1183 IMPORT msvc : rewrite-setup : : msvc.rewrite-setup ;
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 * )
1191 if ! [ on $(targets) return $(.SETUP) ]
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)
1199 local setup-options = [ on $(targets) return $(.SETUP-OPTIONS) ] ;
1200 local key = .setup-command-$(setup-script:E=)-$(setup-options:E=) ;
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) ]
1219 $(key) = [ call-batch-script "\"$(command:WG=:R=$(path))\" $(setup-options:E=)" ] $(block-update) ;
1221 DEPENDS $(targets) : $($(key)[2]) ;
1222 .SETUP on $(targets) = $($(key)[1]) ;
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
1231 local rule configure-really ( version ? : options * )
1233 local command = [ feature.get-values <command> : $(options) ] ;
1235 if ! $(version) && ! $(command)
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)
1245 if $(known) in $(version)
1247 version = $(known) ;
1251 # version might still have multiple elements if no versions
1252 # were auto-detected, but an unknown version was configured
1254 version = $(version[1]) ;
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 ] )
1262 local found-command = [ common.get-invocation-command-nodefault msvc : cl.exe : $(command) ] ;
1266 command = $(found-command) ;
1269 local path = [ common.get-absolute-tool-path $(command) ] ;
1270 command = $(command:R=$(path)) ;
1275 # If we still failed to find cl.exe, bail out.
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,"
1283 "build from the 'Visual Studio Command Prompt for VS 2017'."
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) ]
1299 else if [ MATCH "(MSVC\\\\14.2)" : $(command) ]
1303 else if [ MATCH "(MSVC\\\\14.1)" : $(command) ]
1307 else if [ MATCH "(Microsoft Visual Studio 14)" : $(command) ]
1311 else if [ MATCH "(Microsoft Visual Studio 12)" : $(command) ]
1315 else if [ MATCH "(Microsoft Visual Studio 11)" : $(command) ]
1319 else if [ MATCH "(Microsoft Visual Studio 10)" : $(command) ]
1323 else if [ MATCH "(Microsoft Visual Studio 9)" : $(command) ]
1327 else if [ MATCH "(Microsoft Visual Studio 8)" : $(command) ]
1331 else if [ MATCH "(NET 2003[\/\\]VC7)" : $(command) ]
1335 else if [ MATCH "(Microsoft Visual C\\+\\+ Toolkit 2003)" :
1338 version = 7.1toolkit ;
1340 else if [ MATCH "(.NET[\/\\]VC7)" : $(command) ]
1351 # Version alias -> real version number.
1352 version = [ resolve-possible-msvc-version-alias $(version) ] ;
1354 # Check whether the selected configuration is already in use.
1355 if $(version) in [ $(.versions).used ]
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 ] )
1362 errors.user-error "MSVC toolset configuration: Toolset version"
1363 "'$(version)' already configured." ;
1368 # Register a new configuration.
1369 $(.versions).register $(version) ;
1370 $(.versions).set $(version) : options : $(options) ;
1372 # Mark the configuration as 'used'.
1373 $(.versions).use $(version) ;
1375 # Generate conditions and save them.
1376 local conditions = [ common.check-init-parameters msvc : version $(version) ] ;
1378 $(.versions).set $(version) : conditions : $(conditions) ;
1380 command ?= [ $(.versions).get $(version) : default-command ] ;
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) ] ;
1386 common.handle-options msvc : $(conditions) : $(command) : $(options) ;
1388 # Generate and register setup command.
1390 local below-8.0 = [ MATCH "^([67]\\.)" : $(version) ] ;
1391 local below-11.0 = [ MATCH "^([6789]\\.|10\\.)" : $(version) ] ;
1393 local cpu = i386 amd64 ia64 arm arm64 ;
1398 else if $(below-11.0)
1400 cpu = i386 amd64 ia64 ;
1408 local setup-phone-i386 ;
1409 local setup-phone-arm ;
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
1421 command = [ common.get-absolute-tool-path $(command[-1]) ] ;
1426 local parent = [ path.make $(command) ] ;
1427 parent = [ path.parent $(parent) ] ;
1428 parent = [ path.native $(parent) ] ;
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.
1436 # Default setup scripts provided with different VC distributions:
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.
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.
1452 local global-setup = [ feature.get-values <setup> : $(options) ] ;
1453 global-setup = $(global-setup[1]) ;
1454 local global-setup-phone = $(global-setup) ;
1457 global-setup ?= [ locate-default-setup $(command) : $(parent) :
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 ;
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 ;
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)
1487 if [ MATCH ^(AMD64) : [ os.environ PROCESSOR_ARCHITECTURE ] ]
1489 default-global-setup-options-amd64 = amd64 ;
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 ] ]
1497 default-global-setup-options-amd64 = amd64 ;
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)
1505 default-global-setup-options-ia64 = ia64 ;
1508 for local c in $(cpu)
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)) ] ;
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) ]
1521 phone-directory = [ path.native [ path.join $(phone-directory) WP80 ] ] ;
1523 else if [ MATCH "(12.0)" : $(version) ]
1525 phone-directory = [ path.native [ path.join $(phone-directory) WP81 ] ] ;
1527 global-setup-phone ?= [ locate-default-setup $(phone-directory) : $(phone-parent) : vcvarsphoneall.bat ] ;
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
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)
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)) ] ;
1541 # Get tool names (if any) and finish setup.
1543 compiler = [ feature.get-values <compiler> : $(options) ] ;
1546 linker = [ feature.get-values <linker> : $(options) ] ;
1549 resource-compiler = [ feature.get-values <resource-compiler> : $(options) ] ;
1550 resource-compiler ?= rc ;
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 ;
1560 # For the assembler the following options are turned on by default:
1562 # -Zp4 align structures to 4 bytes
1563 # -Cp preserve case of user identifiers
1564 # -Cx preserve case in publics, externs
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 = "" ;
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 ;
1578 assembler = [ feature.get-values <assembler> : $(options) ] ;
1580 idl-compiler = [ feature.get-values <idl-compiler> : $(options) ] ;
1581 idl-compiler ?= midl ;
1583 mc-compiler = [ feature.get-values <mc-compiler> : $(options) ] ;
1586 manifest-tool = [ feature.get-values <manifest-tool> : $(options) ] ;
1587 manifest-tool ?= mt ;
1589 local cc-filter = [ feature.get-values <compiler-filter> : $(options) ]
1592 for local c in $(cpu)
1594 # Setup script is not required in some configurations.
1597 local cpu-conditions = $(conditions)/$(.cpu-arch-$(c)) ;
1599 if $(.debug-configuration)
1601 for local cpu-condition in $(cpu-conditions)
1603 ECHO "notice: [msvc-cfg] condition: '$(cpu-condition)', setup: '$(setup-$(c):J= )'" ;
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)) ;
1612 for local api in desktop store phone
1614 local setup-script = $(setup-$(c)) ;
1617 setup-script = $(setup-phone-$(c)) ;
1620 if <rewrite-setup-scripts>always in $(options)
1622 toolset.flags msvc .REWRITE-SETUP <windows-api>$(api)/$(cpu-conditions) : true ;
1625 if ! $(setup-script)
1627 # Should we try to set up some error handling or fallbacks here?
1629 else if <rewrite-setup-scripts>off in $(options) || [ os.name ] != NT
1631 toolset.flags msvc .SETUP <windows-api>$(api)/$(cpu-conditions) : [ call-batch-script "\"$(setup-script[1]:W)\" $(setup-script[2-]:E=)" ] ;
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-]) ;
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 ;
1646 toolset.flags msvc.compile .CC <windows-api>$(api)/$(cpu-conditions) : $(compiler) /Zm800 -nologo ;
1650 toolset.flags msvc.compile .CC <windows-api>$(api)/$(cpu-conditions) : $(compiler) /Zm800 /ZW /EHsc -nologo ;
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 ;
1660 toolset.flags msvc .CC.FILTER $(cpu-conditions) : "|" $(cc-filter) ;
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) ]
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" ] ] ;
1675 toolset.flags msvc.compile OPTIONS $(conditions)/<lto>on : /GL ;
1676 toolset.flags msvc.link LINKFLAGS $(conditions)/<lto>on : /LTCG ;
1678 # Set version-specific flags.
1679 configure-version-specific msvc : $(version) : $(conditions) ;
1684 # Returns the default installation path for the given version.
1686 local rule default-path ( version )
1690 # try to use vswhere
1691 local pseudo_env_VSCOMNTOOLS ;
1692 local all-env-paths ;
1693 local root = [ os.environ "ProgramFiles(x86)" ] ;
1696 root = [ os.environ "ProgramFiles" ] ;
1698 if ( ! $(root) ) && [ os.name ] in CYGWIN
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
1707 root = [ SHELL "cygpath -w -F 38" : strip-eol ] ; # CSIDL_PROGRAM_FILES
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) ]
1718 local req = "-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64" ;
1719 local prop = "-property installationPath" ;
1722 if $(version) = 14.3
1724 limit = "-version \"[17.0,18.0)\" -prerelease" ;
1726 else if $(version) = 14.2 || $(version) = "default"
1728 limit = "-version \"[16.0,17.0)\"" ;
1730 else if $(version) = 14.1
1732 limit = "-version \"[15.0,16.0)\"" ;
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) ]
1742 return ; # Not found. If we have vswhere, assume that it works.
1744 all-env-paths = $(pseudo_env_VSCOMNTOOLS) ;
1748 all-env-paths = [ sequence.transform os.environ
1749 : $(.version-$(version)-env) ] ;
1752 # Check environment or previous path_VS150
1753 for local env-path in $(all-env-paths)
1755 if $(env-path) && $(.version-$(version)-path)
1757 for local bin-path in $(.version-$(version)-path)
1759 result = [ path.glob [ path.make $(env-path) ] : $(bin-path) ] ;
1762 result = [ path.native $(result[1]) ] ;
1779 rule get-rspline ( target : lang-opt lang-flags )
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)\" ] ;
1786 class msvc-linking-generator : linking-generator
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
1792 rule generated-targets ( sources + : property-set : project name ? )
1794 local result = [ linking-generator.generated-targets $(sources)
1795 : $(property-set) : $(project) $(name) ] ;
1799 local name-main = [ $(result[1]).name ] ;
1800 local action = [ $(result[1]).action ] ;
1802 if [ $(property-set).get <debug-symbols> ] = "on"
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) ]
1814 if $(target) != $(registered-target)
1816 $(action).replace-targets $(target) : $(registered-target) ;
1818 result += $(registered-target) ;
1821 if [ $(property-set).get <embed-manifest> ] = "off"
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
1827 local target = [ class.new file-target $(name-main).manifest
1828 exact : MANIFEST : $(project) : $(action) ] ;
1829 local registered-target = [ virtual-target.register $(target) ]
1831 if $(target) != $(registered-target)
1833 $(action).replace-targets $(target) : $(registered-target) ;
1835 result += $(registered-target) ;
1843 # Unsafe worker rule for the register-toolset() rule. Must not be called
1846 local rule register-toolset-really ( )
1848 feature.extend toolset : msvc ;
1850 # Intel and msvc supposedly have link-compatible objects.
1851 feature.subfeature toolset msvc : vendor : intel : propagated optional ;
1853 # Inherit MIDL flags.
1854 toolset.inherit-flags msvc : midl ;
1857 toolset.inherit-flags msvc : mc ;
1859 # Dynamic runtime comes only in MT flavour.
1860 toolset.add-requirements
1861 <toolset>msvc,<runtime-link>shared:<threading>multi ;
1863 # Declare msvc toolset specific features.
1865 feature.feature debug-store : object database : propagated ;
1866 feature.feature pch-source : : dependency free ;
1869 # Declare generators.
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
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 ] ;
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 ;
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 ;
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 ;
1897 generators.register-standard msvc.compile.mc : MC : H RC : <toolset>msvc ;
1898 generators.override msvc.compile.mc : mc.compile ;
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 ] ;
1906 generators.override msvc.compile.c.pch : pch.default-c-pch-generator ;
1907 generators.override msvc.compile.c++.pch : pch.default-cpp-pch-generator ;
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> ;
1915 # Declare flags for compilation.
1918 toolset.flags msvc.compile OPTIONS <optimization>speed : /O2 ;
1919 toolset.flags msvc.compile OPTIONS <optimization>space : /O1 ;
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 ;
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 ;
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 ;
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 ;
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" ;
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 ;
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 ;
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> : ;
1963 toolset.flags msvc.compile PDB_CFLAG <debug-symbols>on/<debug-store>database : /Fd ;
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> ;
1970 # Declare flags for the assembler.
1971 toolset.flags msvc.compile.asm USER_ASMFLAGS <asmflags> ;
1973 toolset.flags msvc.compile.asm ASMFLAGS <architecture>x86/<debug-symbols>on : "/Zi /Zd" ;
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 ;
1980 toolset.flags msvc.compile.asm ASMDEFINES <architecture>x86 : <define> ;
1982 # Declare flags for linking.
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> ;
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" ;
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" ;
1999 toolset.flags msvc.link LINKFLAGS <linkflags> ;
2000 toolset.flags msvc.link LINKPATH <library-path> ;
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> ;
2008 toolset.flags msvc.archive AROPTIONS <archiveflags> ;
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 ;
2015 # Create a project to allow building the setup scripts
2016 project.initialize $(__name__) ;
2017 .project = [ project.current ] ;
2020 feature.feature msvc.setup-options : : free ;
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.
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
2034 local rule locate-default-setup ( command : parent : setup-name )
2036 local result = [ GLOB $(command) $(parent) : $(setup-name) ] ;
2039 return $(result[1]) ;
2044 # Validates given path, registers found configuration and prints debug
2045 # information about it.
2047 local rule register-configuration ( version : path ? )
2051 local command = [ GLOB $(path) : cl.exe ] ;
2055 if $(.debug-configuration)
2057 ECHO notice\: "[msvc-cfg]" msvc-$(version) detected, command\:
2061 $(.versions).register $(version) ;
2062 $(.versions).set $(version) : default-command : $(command) ;
2068 ################################################################################
2070 # Startup code executed when loading this module.
2072 ################################################################################
2074 if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
2076 .debug-configuration = true ;
2079 # Miscellaneous constants.
2080 .RM = [ common.rm-command ] ;
2084 .ProgramFiles = [ path.make [ common.get-program-files-dir ] ] ;
2085 .escaped-double-quote = "\"" ;
2087 .TOUCH_FILE = [ common.file-touch-command ] ;
2089 # List of all registered configurations.
2090 .versions = [ new configurations ] ;
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 ;
2099 # Fill explicit architecture and address model values
2100 for local cpu in [ MATCH "^\\.cpu-arch-info-(.*)" : [ VARNAMES $(__name__) ] ]
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]) ;
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)
2113 case x86 : .default-cpu-arch = i386 ;
2114 case em64t : .default-cpu-arch = amd64 ;
2117 for local cpu in $(.cpus-on-$(.cpu-arch-info-$(.default-cpu-arch)[1]))
2119 .cpu-arch-$(cpu) += <architecture>/<address-model>$(.cpu-arch-info-$(cpu)[2]) ;
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> ;
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__) ] ]
2128 if ! $(.cpus-on-$(arch)[2-]) && $(.cpus-on-$(arch)[1]) != $(.default-cpu-arch)
2130 .cpu-arch-$(.cpus-on-$(arch)) += <architecture>$(arch)/<address-model> ;
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
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 ;
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 ;
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" ;
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*/*"
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*/*"
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*/*"
2210 .version-14.3-env = VS170COMNTOOLS ProgramFiles ProgramFiles(x86) ;
2212 # Auto-detect all the available msvc installations on the system.
2213 auto-detect-toolset-versions ;
2216 # And finally trigger the actual Boost Build toolset registration.