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 Rene Rivera
7 # Copyright (c) 2008 Jurko Gospodnetic
8 # Copyright (c) 2014 Microsoft Corporation
10 # Distributed under the Boost Software License, Version 1.0.
11 # (See accompanying file LICENSE_1_0.txt or copy at
12 # http://www.boost.org/LICENSE_1_0.txt)
14 ################################################################################
16 # MSVC Boost Build toolset module.
17 # --------------------------------
19 # All toolset versions need to have their location either auto-detected or
20 # explicitly specified except for the special 'default' version that expects the
21 # environment to find the needed tools or report an error.
23 ################################################################################
25 import "class" : new ;
41 type.register MANIFEST : manifest ;
42 feature.feature embed-manifest : on off : incidental propagated ;
43 feature.feature embed-manifest-file : : free dependency ;
45 type.register PDB : pdb ;
48 ################################################################################
52 ################################################################################
54 # Initialize a specific toolset version configuration. As the result, path to
55 # compiler and, possible, program names are set up, and will be used when that
56 # version of compiler is requested. For example, you might have:
58 # using msvc : 6.5 : cl.exe ;
59 # using msvc : 7.0 : Y:/foo/bar/cl.exe ;
61 # The version parameter may be omitted:
63 # using msvc : : Z:/foo/bar/cl.exe ;
65 # The following keywords have special meanings when specified as versions:
66 # - all - all detected but not yet used versions will be marked as used
67 # with their default options.
68 # - default - this is an equivalent to an empty version.
70 # Depending on a supplied version, detected configurations and presence 'cl.exe'
71 # in the path different results may be achieved. The following table describes
72 # the possible scenarios:
75 # Passed Nothing "x.y" detected, detected,
76 # version detected detected cl.exe in path cl.exe in path
78 # default Error Use "x.y" Create "default" Use "x.y"
79 # all None Use all None Use all
80 # x.y - Use "x.y" - Use "x.y"
81 # a.b Error Error Create "a.b" Create "a.b"
83 # "x.y" - refers to a detected version;
84 # "a.b" - refers to an undetected version.
86 # FIXME: Currently the command parameter and the <compiler> property parameter
87 # seem to overlap in duties. Remove this duplication. This seems to be related
88 # to why someone started preparing to replace init with configure rules.
91 # The msvc version being configured. When omitted the tools invoked when no
92 # explicit version is given will be configured.
95 # The command used to invoke the compiler. If not specified:
96 # - if version is given, default location for that version will be
99 # - if version is not given, default locations for MSVC 9.0, 8.0, 7.1, 7.0
100 # and 6.* will be searched
102 # - if compiler is not found in the default locations, PATH will be
106 # Options may include:
108 # All options shared by multiple toolset types as handled by the
109 # common.handle-options() rule, e.g. <cflags>, <compileflags>, <cxxflags>,
110 # <fflags> & <linkflags>.
117 # <resource-compiler>
118 # Exact tool names to be used by this msvc toolset configuration.
121 # Command through which to pipe the output of running the compiler.
122 # For example to pass the output to STLfilt.
125 # Global setup command to invoke before running any of the msvc tools.
126 # It will be passed additional option parameters depending on the actual
135 # Platform specific setup command to invoke before running any of the
136 # msvc tools used when builing a target for a specific platform, e.g.
137 # when building a 32 or 64 bit executable.
139 # <rewrite-setup-scripts>
140 # Whether to rewrite setup scripts. New scripts will be output in
141 # TEMP directory and will be used instead of originals in build actions.
143 # * on - rewrite scripts, if they do not already exist (default)
144 # * always - always rewrite scripts, even if they already exist
145 # * off - use original setup scripts
151 options += <command>$(command) ;
153 configure $(version) : $(options) ;
157 # 'configure' is a newer version of 'init'. The parameter 'command' is passed as
158 # a part of the 'options' list. See the 'init' rule comment for more detailed
161 rule configure ( version ? : options * )
169 errors.error "MSVC toolset configuration: options should be"
170 "empty when '$(version)' is specified." ;
173 # Configure (i.e. mark as used) all registered versions.
174 local all-versions = [ $(.versions).all ] ;
177 if $(.debug-configuration)
179 ECHO "notice: [msvc-cfg] Asked to configure all registered"
180 "msvc toolset versions when there are none currently"
186 for local v in $(all-versions)
188 # Note that there is no need to skip already configured
189 # versions here as this will request configure-really rule
190 # to configure the version using default options which will
191 # in turn cause it to simply do nothing in case the version
192 # has already been configured.
193 configure-really $(v) ;
198 configure-really : $(options) ;
201 configure-really $(version) : $(options) ;
206 # Sets up flag definitions dependent on the compiler version used.
207 # - 'version' is the version of compiler in N.M format.
208 # - 'conditions' is the property set to be used as flag conditions.
209 # - 'toolset' is the toolset for which flag settings are to be defined.
210 # This makes the rule reusable for other msvc-option-compatible compilers.
212 rule configure-version-specific ( toolset : version : conditions )
214 toolset.push-checking-for-flags-module unchecked ;
215 # Starting with versions 7.0, the msvc compiler have the /Zc:forScope and
216 # /Zc:wchar_t options that improve C++ standard conformance, but those
217 # options are off by default. If we are sure that the msvc version is at
218 # 7.*, add those options explicitly. We can be sure either if user specified
219 # version 7.* explicitly or if we auto-detected the version ourselves.
220 if ! [ MATCH ^(6\\.) : $(version) ]
222 toolset.flags $(toolset).compile CFLAGS $(conditions) : /Zc:forScope /Zc:wchar_t ;
223 toolset.flags $(toolset).compile.c++ C++FLAGS $(conditions) : /wd4675 ;
225 # Explicitly disable the 'function is deprecated' warning. Some msvc
226 # versions have a bug, causing them to emit the deprecation warning even
228 toolset.flags $(toolset).compile CFLAGS $(conditions)/<warnings>off : /wd4996 ;
230 if [ MATCH ^([78]\\.) : $(version) ]
232 # 64-bit compatibility warning deprecated since 9.0, see
233 # http://msdn.microsoft.com/en-us/library/yt4xw8fh.aspx
234 toolset.flags $(toolset).compile CFLAGS $(conditions)/<warnings>all : /Wp64 ;
239 # Processor-specific optimization.
242 if [ MATCH ^([67]) : $(version) ]
244 # 8.0 deprecates some of the options.
245 toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>speed $(conditions)/<optimization>space : /Ogiy /Gs ;
246 toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>speed : /Ot ;
247 toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>space : /Os ;
249 toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set> : /GB ;
250 toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>i486 : /G4 ;
251 toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g5) : /G5 ;
252 toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g6) : /G6 ;
253 toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g7) : /G7 ;
255 # Improve floating-point accuracy. Otherwise, some of C++ Boost's "math"
257 toolset.flags $(toolset).compile CFLAGS $(conditions) : /Op ;
259 # 7.1 and below have single-threaded static RTL.
260 toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>off/<runtime-link>static/<threading>single : /ML ;
261 toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>on/<runtime-link>static/<threading>single : /MLd ;
265 # 8.0 and above adds some more options.
266 toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set> : /favor:blend ;
267 toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set>$(.cpu-type-em64t) : /favor:EM64T ;
268 toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set>$(.cpu-type-amd64) : /favor:AMD64 ;
270 # 8.0 and above only has multi-threaded static RTL.
271 toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>off/<runtime-link>static/<threading>single : /MT ;
272 toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>on/<runtime-link>static/<threading>single : /MTd ;
274 # Specify target machine type so the linker will not need to guess.
275 toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-amd64) : /MACHINE:X64 ;
276 toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-i386) : /MACHINE:X86 ;
277 toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-ia64) : /MACHINE:IA64 ;
278 toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-arm) : /MACHINE:ARM ;
280 # Make sure that manifest will be generated even if there is no
281 # dependencies to put there.
282 toolset.flags $(toolset).link LINKFLAGS $(conditions) : /MANIFEST ;
285 toolset.pop-checking-for-flags-module ;
288 # Feature for handling targeting different Windows API sets.
289 feature.feature windows-api : desktop store phone : propagated composite link-incompatible ;
290 feature.compose <windows-api>store : <define>WINAPI_FAMILY=WINAPI_FAMILY_APP <define>_WIN32_WINNT=0x0602
291 <linkflags>/APPCONTAINER ;
292 feature.compose <windows-api>phone : <define>WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP <define>_WIN32_WINNT=0x0602
293 <linkflags>/APPCONTAINER <linkflags>/NODEFAULTLIB:ole32.lib <linkflags>/NODEFAULTLIB:kernel32.lib <linkflags>WindowsPhoneCore.lib ;
294 feature.set-default windows-api : desktop ;
297 # Registers this toolset including all of its flags, features & generators. Does
298 # nothing on repeated calls.
300 rule register-toolset ( )
302 if ! msvc in [ feature.values toolset ]
304 register-toolset-really ;
308 rule resolve-possible-msvc-version-alias ( version )
310 if $(.version-alias-$(version))
312 version = $(.version-alias-$(version)) ;
318 # Declare action for creating static libraries. If library exists, remove it
319 # before adding files. See
320 # http://article.gmane.org/gmane.comp.lib.boost.build/4241 for rationale.
323 # The 'DEL' command would issue a message to stdout if the file does not
324 # exist, so need a check.
327 if exist "$(<[1])" DEL "$(<[1])"
328 $(.LD) $(AROPTIONS) /out:"$(<[1])" @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
336 $(.LD) $(AROPTIONS) /out:"$(<[1])" @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
341 # For the assembler the following options are turned on by default:
343 # -Zp4 align structures to 4 bytes
344 # -Cp preserve case of user identifiers
345 # -Cx preserve case in publics, externs
349 $(.ASM) -c -Zp4 -Cp -Cx -D$(DEFINES) $(ASMFLAGS) $(USER_ASMFLAGS) -Fo "$(<:W)" "$(>:W)"
353 rule compile.c ( targets + : sources * : properties * )
355 C++FLAGS on $(targets[1]) = ;
356 get-rspline $(targets) : -TC ;
357 compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
361 rule compile.c.preprocess ( targets + : sources * : properties * )
363 C++FLAGS on $(targets[1]) = ;
364 get-rspline $(targets) : -TC ;
365 preprocess-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
369 rule compile.c.pch ( targets + : sources * : properties * )
371 C++FLAGS on $(targets[1]) = ;
372 get-rspline $(targets[1]) : -TC ;
373 get-rspline $(targets[2]) : -TC ;
374 local pch-source = [ on $(<) return $(PCH_SOURCE) ] ;
377 DEPENDS $(<) : $(pch-source) ;
378 compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ;
382 compile-c-c++-pch $(targets) : $(sources) ;
386 toolset.flags msvc YLOPTION : "-Yl" ;
388 # Action for running the C/C++ compiler without using precompiled headers.
390 # WARNING: Synchronize any changes this in action with intel-win
392 # Notes regarding PDB generation, for when we use
393 # <debug-symbols>on/<debug-store>database:
395 # 1. PDB_CFLAG is only set for <debug-symbols>on/<debug-store>database, ensuring
396 # that the /Fd flag is dropped if PDB_CFLAG is empty.
398 # 2. When compiling executables's source files, PDB_NAME is set on a per-source
399 # file basis by rule compile-c-c++. The linker will pull these into the
402 # 3. When compiling library's source files, PDB_NAME is updated to <libname>.pdb
403 # for each source file by rule archive, as in this case compiler must be used
404 # to create a single PDB for our library.
406 actions compile-c-c++ bind PDB_NAME
408 $(.CC) @"@($(<[1]:W).rsp:E="$(>[1]:W)" -Fo"$(<[1]:W)" $(PDB_CFLAG)"$(PDB_NAME)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))" $(.CC.FILTER)
411 actions preprocess-c-c++ bind PDB_NAME
413 $(.CC) @"@($(<[1]:W).rsp:E="$(>[1]:W)" -E $(PDB_CFLAG)"$(PDB_NAME)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))" >"$(<[1]:W)"
416 rule compile-c-c++ ( targets + : sources * )
418 DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_HEADER) ] ;
419 DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_FILE) ] ;
420 PDB_NAME on $(<) = $(<[1]:S=.pdb) ;
421 LOCATE on $(<[1]:S=.pdb) = [ on $(<[1]) return $(LOCATE) ] ;
424 rule preprocess-c-c++ ( targets + : sources * )
426 DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_HEADER) ] ;
427 DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_FILE) ] ;
428 PDB_NAME on $(<) = $(<:S=.pdb) ;
429 LOCATE on $(<[1]:S=.pdb) = [ on $(<[1]) return $(LOCATE) ] ;
432 # Action for running the C/C++ compiler using precompiled headers. In addition
433 # to whatever else it needs to compile, this action also adds a temporary source
434 # .cpp file used to compile the precompiled headers themselves.
436 # The global .escaped-double-quote variable is used to avoid messing up Emacs
437 # syntax highlighting in the messy N-quoted code below.
438 actions compile-c-c++-pch
440 $(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" $(YLOPTION)"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))" "@($(<[1]:W).cpp:E=#include $(.escaped-double-quote)$(>[1]:D=)$(.escaped-double-quote)$(.nl))" $(.CC.FILTER)
444 # Action for running the C/C++ compiler using precompiled headers. An already
445 # built source file for compiling the precompiled headers is expected to be
446 # given as one of the source parameters.
447 actions compile-c-c++-pch-s
449 $(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" $(YLOPTION)"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))" $(.CC.FILTER)
453 rule compile.c++ ( targets + : sources * : properties * )
455 get-rspline $(targets) : -TP ;
456 compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
459 rule compile.c++.preprocess ( targets + : sources * : properties * )
461 get-rspline $(targets) : -TP ;
462 preprocess-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
466 rule compile.c++.pch ( targets + : sources * : properties * )
468 get-rspline $(targets[1]) : -TP ;
469 get-rspline $(targets[2]) : -TP ;
470 local pch-source = [ on $(<) return $(PCH_SOURCE) ] ;
473 DEPENDS $(<) : $(pch-source) ;
474 compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ;
478 compile-c-c++-pch $(targets) : $(sources) ;
483 # See midl.jam for details.
487 $(.IDL) /nologo @"@($(<[1]:W).rsp:E=$(.nl)"$(>:W)" $(.nl)-D$(DEFINES) $(.nl)"-I$(INCLUDES:W)" $(.nl)-U$(UNDEFS) $(.nl)$(MIDLFLAGS) $(.nl)/tlb "$(<[1]:W)" $(.nl)/h "$(<[2]:W)" $(.nl)/iid "$(<[3]:W)" $(.nl)/proxy "$(<[4]:W)" $(.nl)/dlldata "$(<[5]:W)")"
488 $(.TOUCH_FILE) "$(<[4]:W)"
489 $(.TOUCH_FILE) "$(<[5]:W)"
495 $(.MC) $(MCFLAGS) -h "$(<[1]:DW)" -r "$(<[2]:DW)" "$(>:W)"
501 $(.RC) -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES:W)" -fo "$(<:W)" "$(>:W)"
505 rule link ( targets + : sources * : properties * )
507 if <embed-manifest>on in $(properties)
509 if [ feature.get-values <embed-manifest-file> : $(properties) ]
511 DEPENDS $(<) : [ on $(<) return $(EMBED_MANIFEST_FILE) ] ;
512 msvc.manifest.user $(targets) $(EMBED_MANIFEST_FILE) : $(sources) : $(properties) ;
516 msvc.manifest $(targets) : $(sources) : $(properties) ;
521 rule link.dll ( targets + : sources * : properties * )
523 DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ;
524 if <embed-manifest>on in $(properties)
526 if [ feature.get-values <embed-manifest-file> : $(properties) ]
528 DEPENDS $(<) : [ on $(<) return $(EMBED_MANIFEST_FILE) ] ;
529 msvc.manifest.dll.user $(targets) $(EMBED_MANIFEST_FILE) : $(sources) : $(properties) ;
533 msvc.manifest.dll $(targets) : $(sources) : $(properties) ;
538 # Incremental linking a DLL causes no end of problems: if the actual exports do
539 # not change, the import .lib file is never updated. Therefore, the .lib is
540 # always out-of-date and gets rebuilt every time. I am not sure that incremental
541 # linking is such a great idea in general, but in this case I am sure we do not
544 # Windows manifest is a new way to specify dependencies on managed DotNet
545 # assemblies and Windows native DLLs. The manifests are embedded as resources
546 # and are useful in any PE target (both DLL and EXE).
550 actions link bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
552 $(.LD) $(LINKFLAGS) /out:"$(<[1]:W)" /LIBPATH:"$(LINKPATH:W)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
553 if %ERRORLEVEL% NEQ 0 EXIT %ERRORLEVEL%
558 if exist "$(<[1]).manifest" (
559 $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);1"
563 actions manifest.user bind EMBED_MANIFEST_FILE
565 $(.MT) -manifest "$(EMBED_MANIFEST_FILE)" "-outputresource:$(<[1]);1"
568 actions link.dll bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
570 $(.LD) /DLL $(LINKFLAGS) /out:"$(<[1]:W)" /IMPLIB:"$(<[2]:W)" /LIBPATH:"$(LINKPATH:W)" /def:"$(DEF_FILE)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
571 if %ERRORLEVEL% NEQ 0 EXIT %ERRORLEVEL%
576 if exist "$(<[1]).manifest" (
577 $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);2"
580 actions manifest.dll.user bind EMBED_MANIFEST_FILE
582 $(.MT) -manifest "$(EMBED_MANIFEST_FILE)" "-outputresource:$(<[1]);2"
587 actions link bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
589 $(.LD) $(LINKFLAGS) /out:"$(<[1]:W)" /LIBPATH:"$(LINKPATH:W)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
594 if test -e "$(<[1]).manifest"; then
595 $(.MT) -manifest "$(<[1]:W).manifest" "-outputresource:$(<[1]:W);1"
599 actions link.dll bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
601 $(.LD) /DLL $(LINKFLAGS) /out:"$(<[1]:W)" /IMPLIB:"$(<[2]:W)" /LIBPATH:"$(LINKPATH:W)" /def:"$(DEF_FILE)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
606 if test -e "$(<[1]).manifest"; then
607 $(.MT) -manifest "$(<[1]:W).manifest" "-outputresource:$(<[1]:W);2"
611 actions manifest.dll.user bind EMBED_MANIFEST_FILE
613 $(.MT) -manifest "$(EMBED_MANIFEST_FILE)" "-outputresource:$(<[1]);2"
617 # This rule sets up the pdb file that will be used when generating static
618 # libraries and the debug-store option is database, so that the compiler puts
619 # all the debug info into a single .pdb file named after the library.
621 # Poking at source targets this way is probably not clean, but it is the
624 rule archive ( targets + : sources * : properties * )
626 PDB_NAME on $(>) = $(<[1]:S=.pdb) ;
627 LOCATE on $(<[1]:S=.pdb) = [ on $(<[1]) return $(LOCATE) ] ;
631 ################################################################################
635 ################################################################################
637 class msvc-pch-generator : pch-generator
639 import property-set ;
641 rule run-pch ( project name ? : property-set : sources * )
643 # Searching for the header and source file in the sources.
646 for local s in $(sources)
648 if [ type.is-derived [ $(s).type ] H ]
653 [ type.is-derived [ $(s).type ] CPP ] ||
654 [ type.is-derived [ $(s).type ] C ]
662 import errors : user-error : errors.user-error ;
663 errors.user-error "can not build pch without pch-header" ;
666 # If we do not have the PCH source - that is fine. We will just create a
667 # temporary .cpp file in the action.
669 local generated = [ generator.run $(project) $(name)
670 : [ property-set.create
671 # Passing of <pch-source> is a dirty trick, needed because
672 # non-composing generators with multiple inputs are subtly
673 # broken. For more detailed information see:
674 # https://zigzag.cs.msu.su:7813/boost.build/ticket/111
675 <pch-source>$(pch-source)
676 [ $(property-set).raw ] ]
680 for local g in $(generated)
682 if [ type.is-derived [ $(g).type ] PCH ]
688 return [ property-set.create <pch-header>$(pch-header)
689 <pch-file>$(pch-file) ] $(generated) ;
694 ################################################################################
698 ################################################################################
700 # Detects versions listed as '.known-versions' by checking registry information,
701 # environment variables & default paths. Supports both native Windows and
704 local rule auto-detect-toolset-versions ( )
706 if [ os.name ] in NT CYGWIN
708 # Get installation paths from the registry.
709 for local i in $(.known-versions)
711 if $(.version-$(i)-reg)
714 for local x in "" "Wow6432Node\\"
716 vc-path += [ W32_GETREG
717 "HKEY_LOCAL_MACHINE\\SOFTWARE\\"$(x)"\\Microsoft\\"$(.version-$(i)-reg)
723 vc-path = [ path.join [ path.make-NT $(vc-path[1]) ] "bin" ] ;
724 register-configuration $(i) : [ path.native $(vc-path[1]) ] ;
730 # Check environment and default installation paths.
731 for local i in $(.known-versions)
733 if ! $(i) in [ $(.versions).all ]
735 register-configuration $(i) : [ default-path $(i) ] ;
740 # Helper rule to generate a faster alternative to MSVC setup scripts.
741 # We used to call MSVC setup scripts directly in every action, however in
742 # newer MSVC versions (10.0+) they make long-lasting registry queries
743 # which have a significant impact on build time.
744 rule maybe-rewrite-setup ( toolset : setup-script : setup-options : version : rewrite-setup ? )
746 local result = $(setup-script)" "$(setup-options) ;
747 # At the moment we only know how to rewrite scripts with cmd shell.
748 if ( [ os.name ] in NT ) && ( $(rewrite-setup) != off )
750 setup-script-id = b2_$(toolset)_$(version)_$(setup-script:B) ;
751 if $(setup-options)-is-not-empty
753 setup-script-id = $(setup-script-id)_$(setup-options) ;
756 if $(.$(setup-script-id))
758 errors.error rewriting setup script for the second time ;
761 local tmpdir = [ os.environ TEMP ] ;
762 local replacement = [ path.native $(tmpdir)/$(setup-script-id).cmd ] ;
763 if ( $(rewrite-setup) = always ) || ( ! [ path.exists $(replacement) ] )
765 local original-vars = [ SPLIT_BY_CHARACTERS [ SHELL set ] : "\n" ] ;
766 local new-vars = [ SPLIT_BY_CHARACTERS [ SHELL "$(setup-script) $(setup-options)>nul && set" ] : "\n" ] ;
767 local diff-vars = [ set.difference $(new-vars) : $(original-vars) ] ;
770 local target = <new-setup-script>$(replacement) ;
771 FILE_CONTENTS on $(target) = "SET "$(diff-vars) ;
773 msvc.write-setup-script $(target) ;
774 UPDATE_NOW $(target) : : ignore-minus-n ;
775 .$(setup-script-id) = $(replacement) ;
776 result = "\""$(replacement)"\"" ;
781 result = "\""$(replacement)"\"" ;
787 actions write-setup-script
789 @($(STDOUT):E=$(FILE_CONTENTS:J=$(.nl))) > "$(<)"
793 # Local helper rule to create the vcvars setup command for given architecture
796 local rule generate-setup-cmd ( version : command : parent : options * : cpu : global-setup ? : default-global-setup-options : default-setup )
798 local setup-prefix = "call " ;
799 local setup-suffix = " >nul"$(.nl) ;
800 if ! [ os.name ] in NT
802 setup-prefix = "cmd.exe /S /C call " ;
803 setup-suffix = " \">nul\" \"&&\" " ;
806 local setup-options ;
807 local setup = [ feature.get-values <setup-$(cpu)> : $(options) ] ;
809 if ! $(setup)-is-defined
811 if $(global-setup)-is-defined
813 setup = $(global-setup) ;
815 # If needed we can easily add using configuration flags
816 # here for overriding which options get passed to the
817 # global setup command for which target platform:
818 # setup-options = [ feature.get-values <setup-options-$(c)> : $(options) ] ;
819 setup-options ?= $(default-global-setup-options) ;
823 setup = [ locate-default-setup $(command) : $(parent) : $(default-setup) ] ;
827 # Cygwin to Windows path translation.
828 setup = "\""$(setup:W)"\"" ;
830 # Append setup options to the setup name and add the final setup
832 setup-options ?= "" ;
833 local rewrite = [ feature.get-values <rewrite-setup-scripts> : $(options) ] ;
834 setup = [ maybe-rewrite-setup msvc : $(setup:J=" ") : $(setup-options:J=" ") : $(version) : $(rewrite) ] ;
835 setup = $(setup-prefix)$(setup)$(setup-suffix) ;
841 # Worker rule for toolset version configuration. Takes an explicit version id or
842 # nothing in case it should configure the default toolset version (the first
843 # registered one or a new 'default' one in case no toolset versions have been
846 local rule configure-really ( version ? : options * )
848 local v = $(version) ;
850 # Decide what the 'default' version is.
853 # Take the first registered (i.e. auto-detected) version.
854 version = [ $(.versions).all ] ;
855 version = $(version[1]) ;
858 # Note: 'version' can still be empty at this point if no versions have
859 # been auto-detected.
860 version ?= "default" ;
863 # Version alias -> real version number.
864 version = [ resolve-possible-msvc-version-alias $(version) ] ;
866 # Check whether the selected configuration is already in use.
867 if $(version) in [ $(.versions).used ]
869 # Allow multiple 'toolset.using' calls for the same configuration if the
870 # identical sets of options are used.
871 if $(options) && ( $(options) != [ $(.versions).get $(version) : options ] )
874 errors.error "MSVC toolset configuration: Toolset version"
875 "'$(version)' already configured." ;
880 # Register a new configuration.
881 $(.versions).register $(version) ;
883 # Add user-supplied to auto-detected options.
884 options = [ $(.versions).get $(version) : options ] $(options) ;
886 # Mark the configuration as 'used'.
887 $(.versions).use $(version) ;
889 # Generate conditions and save them.
890 local conditions = [ common.check-init-parameters msvc : version $(v) ]
893 $(.versions).set $(version) : conditions : $(conditions) ;
895 local command = [ feature.get-values <command> : $(options) ] ;
897 # If version is specified, we try to search first in default paths, and
899 command = [ common.get-invocation-command msvc : cl.exe : $(command) :
900 [ default-paths $(version) ] : $(version) ] ;
902 common.handle-options msvc : $(conditions) : $(command) : $(options) ;
906 # Even if version is not explicitly specified, try to detect the
907 # version from the path.
908 # FIXME: We currently detect both Microsoft Visual Studio 9.0 and
909 # 9.0express as 9.0 here.
910 if [ MATCH "(Microsoft Visual Studio 15)" : $(command) ]
914 else if [ MATCH "(Microsoft Visual Studio 14)" : $(command) ]
918 else if [ MATCH "(Microsoft Visual Studio 12)" : $(command) ]
922 else if [ MATCH "(Microsoft Visual Studio 11)" : $(command) ]
926 else if [ MATCH "(Microsoft Visual Studio 10)" : $(command) ]
930 else if [ MATCH "(Microsoft Visual Studio 9)" : $(command) ]
934 else if [ MATCH "(Microsoft Visual Studio 8)" : $(command) ]
938 else if [ MATCH "(NET 2003[\/\\]VC7)" : $(command) ]
942 else if [ MATCH "(Microsoft Visual C\\+\\+ Toolkit 2003)" :
945 version = 7.1toolkit ;
947 else if [ MATCH "(.NET[\/\\]VC7)" : $(command) ]
957 # Generate and register setup command.
959 local below-8.0 = [ MATCH ^([67]\\.) : $(version) ] ;
960 local below-11.0 = [ MATCH ^([6789]\\.|10\\.) : $(version) ] ;
962 local cpu = i386 amd64 ia64 arm ;
967 else if $(below-11.0)
969 cpu = i386 amd64 ia64 ;
976 local setup-phone-i386 ;
977 local setup-phone-arm ;
981 # TODO: Note that if we specify a non-existant toolset version then
982 # this rule may find and use a corresponding compiler executable
983 # belonging to an incorrect toolset version. For example, if you
984 # have only MSVC 7.1 installed, have its executable on the path and
985 # specify you want Boost Build to use MSVC 9.0, then you want Boost
986 # Build to report an error but this may cause it to silently use the
987 # MSVC 7.1 compiler even though it thinks it is using the msvc-9.0
989 command = [ common.get-absolute-tool-path $(command[-1]) ] ;
994 local parent = [ path.make $(command) ] ;
995 parent = [ path.parent $(parent) ] ;
996 parent = [ path.native $(parent) ] ;
998 # Setup will be used if the command name has been specified. If
999 # setup is not specified explicitly then a default setup script will
1000 # be used instead. Setup scripts may be global or architecture/
1001 # /platform/cpu specific. Setup options are used only in case of
1002 # global setup scripts.
1004 # Default setup scripts provided with different VC distributions:
1006 # VC 7.1 had only the vcvars32.bat script specific to 32 bit i386
1007 # builds. It was located in the bin folder for the regular version
1008 # and in the root folder for the free VC 7.1 tools.
1010 # Later 8.0 & 9.0 versions introduce separate platform specific
1011 # vcvars*.bat scripts (e.g. 32 bit, 64 bit AMD or 64 bit Itanium)
1012 # located in or under the bin folder. Most also include a global
1013 # vcvarsall.bat helper script located in the root folder which runs
1014 # one of the aforementioned vcvars*.bat scripts based on the options
1015 # passed to it. So far only the version coming with some PlatformSDK
1016 # distributions does not include this top level script but to
1017 # support those we need to fall back to using the worker scripts
1018 # directly in case the top level script can not be found.
1020 local global-setup = [ feature.get-values <setup> : $(options) ] ;
1021 global-setup = $(global-setup[1]) ;
1022 local global-setup-phone = $(global-setup) ;
1025 global-setup ?= [ locate-default-setup $(command) : $(parent) :
1029 local default-setup-amd64 = vcvarsx86_amd64.bat ;
1030 local default-setup-i386 = vcvars32.bat ;
1031 local default-setup-ia64 = vcvarsx86_ia64.bat ;
1032 local default-setup-arm = vcvarsx86_arm.bat ;
1033 local default-setup-phone-i386 = vcvarsphonex86.bat ;
1034 local default-setup-phone-arm = vcvarsphonex86_arm.bat ;
1036 # http://msdn2.microsoft.com/en-us/library/x4d2c09s(VS.80).aspx and
1037 # http://msdn2.microsoft.com/en-us/library/x4d2c09s(vs.90).aspx
1038 # mention an x86_IPF option, that seems to be a documentation bug
1039 # and x86_ia64 is the correct option.
1040 local default-global-setup-options-amd64 = x86_amd64 ;
1041 local default-global-setup-options-i386 = x86 ;
1042 local default-global-setup-options-ia64 = x86_ia64 ;
1043 local default-global-setup-options-arm = x86_arm ;
1045 # When using 64-bit Windows, and targeting 64-bit, it is possible to
1046 # use a native 64-bit compiler, selected by the "amd64" & "ia64"
1047 # parameters to vcvarsall.bat. There are two variables we can use --
1048 # PROCESSOR_ARCHITECTURE and PROCESSOR_IDENTIFIER. The first is
1049 # 'x86' when running 32-bit Windows, no matter which processor is
1050 # used, and 'AMD64' on 64-bit windows on x86 (either AMD64 or EM64T)
1053 if [ MATCH ^(AMD64) : [ os.environ PROCESSOR_ARCHITECTURE ] ]
1055 default-global-setup-options-amd64 = amd64 ;
1057 # When Boost.Build itself is running as a 32-bit process on 64-bit
1058 # Windows, the above test will fail (since WOW64 simulates a 32-bit
1059 # environment, including environment values). So check the WOW64
1060 # variable PROCESSOR_ARCHITEW6432 as well.
1061 if [ MATCH ^(AMD64) : [ os.environ PROCESSOR_ARCHITEW6432 ] ]
1063 default-global-setup-options-amd64 = amd64 ;
1065 # TODO: The same 'native compiler usage' should be implemented for
1066 # the Itanium platform by using the "ia64" parameter. For this
1067 # though we need someone with access to this platform who can find
1068 # out how to correctly detect this case.
1069 else if $(somehow-detect-the-itanium-platform)
1071 default-global-setup-options-ia64 = ia64 ;
1074 for local c in $(cpu)
1076 setup-$(c) = [ generate-setup-cmd $(version) : $(command) : $(parent) : $(options) : $(c) : $(global-setup) : $(default-global-setup-options-$(c)) : $(default-setup-$(c)) ] ;
1079 # Windows phone has different setup scripts, located in a different directory hierarchy.
1080 # The 11.0 toolset can target Windows Phone 8.0 and the 12.0 toolset can target Windows Phone 8.1,
1081 # each of which have a different directory for their vcvars setup scripts.
1082 local phone-parent = [ path.native [ path.join $(parent) WPSDK ] ] ;
1083 local phone-directory = $(phone-parent) ;
1084 if [ MATCH "(11.0)" : $(version) ]
1086 phone-directory = [ path.native [ path.join $(phone-directory) WP80 ] ] ;
1088 else if [ MATCH "(12.0)" : $(version) ]
1090 phone-directory = [ path.native [ path.join $(phone-directory) WP81 ] ] ;
1092 global-setup-phone ?= [ locate-default-setup $(phone-directory) : $(phone-parent) : vcvarsphoneall.bat ] ;
1094 # If can't locate default phone setup script then this VS version doesn't support Windows Phone.
1095 if $(global-setup-phone)-is-defined
1097 # i386 CPU is for the Windows Phone emulator in Visual Studio.
1098 local phone-cpu = i386 arm ;
1099 for local c in $(phone-cpu)
1101 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)) ] ;
1106 # Get tool names (if any) and finish setup.
1108 compiler = [ feature.get-values <compiler> : $(options) ] ;
1111 linker = [ feature.get-values <linker> : $(options) ] ;
1114 resource-compiler = [ feature.get-values <resource-compiler> : $(options) ] ;
1115 resource-compiler ?= rc ;
1117 # Turn on some options for i386 assembler
1118 # -coff generate COFF format object file (compatible with cl.exe output)
1119 local default-assembler-amd64 = ml64 ;
1120 local default-assembler-i386 = "ml -coff" ;
1121 local default-assembler-ia64 = ias ;
1122 local default-assembler-ia64 = armasm ;
1124 assembler = [ feature.get-values <assembler> : $(options) ] ;
1126 idl-compiler = [ feature.get-values <idl-compiler> : $(options) ] ;
1127 idl-compiler ?= midl ;
1129 mc-compiler = [ feature.get-values <mc-compiler> : $(options) ] ;
1132 manifest-tool = [ feature.get-values <manifest-tool> : $(options) ] ;
1133 manifest-tool ?= mt ;
1135 local cc-filter = [ feature.get-values <compiler-filter> : $(options) ]
1138 for local c in $(cpu)
1140 # Setup script is not required in some configurations.
1143 local cpu-conditions = $(conditions)/$(.cpu-arch-$(c)) ;
1145 if $(.debug-configuration)
1147 for local cpu-condition in $(cpu-conditions)
1149 ECHO "notice: [msvc-cfg] condition: '$(cpu-condition)', setup: '$(setup-$(c))'" ;
1153 local cpu-assembler = $(assembler) ;
1154 cpu-assembler ?= $(default-assembler-$(c)) ;
1156 toolset.flags msvc.compile .RC <windows-api>$(api)/$(cpu-conditions) : $(setup-$(c))$(resource-compiler) ;
1157 toolset.flags msvc.compile .IDL <windows-api>$(api)/$(cpu-conditions) : $(setup-$(c))$(idl-compiler) ;
1158 toolset.flags msvc.compile .MC <windows-api>$(api)/$(cpu-conditions) : $(setup-$(c))$(mc-compiler) ;
1159 toolset.flags msvc.link .MT <windows-api>$(api)/$(cpu-conditions) : $(setup-$(c))$(manifest-tool) -nologo ;
1161 for api in desktop store phone
1163 local setup-script = $(setup-$(c)) ;
1166 setup-script = $(setup-phone-$(c)) ;
1170 toolset.flags msvc.compile .CC <windows-api>$(api)/$(cpu-conditions) : $(setup-script)$(compiler) /Zm800 -nologo ;
1174 toolset.flags msvc.compile .CC <windows-api>$(api)/$(cpu-conditions) : $(setup-script)$(compiler) /Zm800 /ZW /EHsc -nologo ;
1176 toolset.flags msvc.compile .ASM <windows-api>$(api)/$(cpu-conditions) : $(setup-script)$(cpu-assembler) -nologo ;
1177 toolset.flags msvc.link .LD <windows-api>$(api)/$(cpu-conditions) : $(setup-script)$(linker) /NOLOGO /INCREMENTAL:NO ;
1178 toolset.flags msvc.archive .LD <windows-api>$(api)/$(cpu-conditions) : $(setup-script)$(linker) /lib /NOLOGO ;
1183 toolset.flags msvc .CC.FILTER $(cpu-conditions) : "|" $(cc-filter) ;
1187 # Starting with Visual Studio 2013 the CRT is split into a desktop and app dll.
1188 # If targeting WinRT and 12.0 set lib path to link against app CRT.
1189 if [ MATCH "(12)" : $(version) ]
1191 local storeLibPath = [ path.join $(parent) "lib/store" ] ;
1192 toolset.flags msvc.link LINKPATH $(conditions)/<windows-api>store/$(.cpu-arch-i386) : [ path.native $(storeLibPath) ] ;
1193 toolset.flags msvc.link LINKPATH $(conditions)/<windows-api>store/$(.cpu-arch-amd64) : [ path.native [ path.join $(storeLibPath) "amd64" ] ] ;
1194 toolset.flags msvc.link LINKPATH $(conditions)/<windows-api>store/$(.cpu-arch-arm) : [ path.native [ path.join $(storeLibPath) "arm" ] ] ;
1197 # Set version-specific flags.
1198 configure-version-specific msvc : $(version) : $(conditions) ;
1203 # Returns the default installation path for the given version.
1205 local rule default-path ( version )
1207 # Use auto-detected path if possible.
1208 local path = [ feature.get-values <command> : [ $(.versions).get $(version)
1217 # Check environment.
1218 if $(.version-$(version)-env)
1220 local vc-path = [ os.environ $(.version-$(version)-env) ] ;
1223 vc-path = [ path.make $(vc-path) ] ;
1224 vc-path = [ path.join $(vc-path) $(.version-$(version)-envpath) ] ;
1225 vc-path = [ path.native $(vc-path) ] ;
1231 # Check default path.
1232 if ! $(path) && $(.version-$(version)-path)
1234 path = [ path.native [ path.join $(.ProgramFiles) $(.version-$(version)-path) ] ] ;
1242 # Returns either the default installation path (if 'version' is not empty) or
1243 # list of all known default paths (if no version is given)
1245 local rule default-paths ( version ? )
1247 local possible-paths ;
1251 possible-paths += [ default-path $(version) ] ;
1255 for local i in $(.known-versions)
1257 possible-paths += [ default-path $(i) ] ;
1261 return $(possible-paths) ;
1265 rule get-rspline ( target : lang-opt )
1267 CC_RSPLINE on $(target) = [ on $(target) return $(lang-opt) -U$(UNDEFS)
1268 $(CFLAGS) $(C++FLAGS) $(OPTIONS) -c $(.nl)-D$(DEFINES)
1269 $(.nl)\"-I$(INCLUDES:W)\" ] ;
1272 class msvc-linking-generator : linking-generator
1274 # Calls the base version. If necessary, also create a target for the
1275 # manifest file.specifying source's name as the name of the created
1276 # target. As result, the PCH will be named whatever.hpp.gch, and not
1278 rule generated-targets ( sources + : property-set : project name ? )
1280 local result = [ linking-generator.generated-targets $(sources)
1281 : $(property-set) : $(project) $(name) ] ;
1285 local name-main = [ $(result[0]).name ] ;
1286 local action = [ $(result[0]).action ] ;
1288 if [ $(property-set).get <debug-symbols> ] = "on"
1290 # We force the exact name on PDB. The reason is tagging -- the
1291 # tag rule may reasonably special case some target types, like
1292 # SHARED_LIB. The tag rule will not catch PDBs, and it cannot
1293 # even easily figure out if a PDB is paired with a SHARED_LIB,
1294 # EXE or something else. Because PDBs always get the same name
1295 # as the main target, with .pdb as extension, just force it.
1296 local target = [ class.new file-target $(name-main:S=.pdb) exact
1297 : PDB : $(project) : $(action) ] ;
1298 local registered-target = [ virtual-target.register $(target) ]
1300 if $(target) != $(registered-target)
1302 $(action).replace-targets $(target) : $(registered-target) ;
1304 result += $(registered-target) ;
1307 if [ $(property-set).get <embed-manifest> ] = "off"
1309 # Manifest is an evil target. It has .manifest appened to the
1310 # name of the main target, including extension, e.g.
1311 # a.exe.manifest. We use the 'exact' name to achieve this
1313 local target = [ class.new file-target $(name-main).manifest
1314 exact : MANIFEST : $(project) : $(action) ] ;
1315 local registered-target = [ virtual-target.register $(target) ]
1317 if $(target) != $(registered-target)
1319 $(action).replace-targets $(target) : $(registered-target) ;
1321 result += $(registered-target) ;
1329 # Unsafe worker rule for the register-toolset() rule. Must not be called
1332 local rule register-toolset-really ( )
1334 feature.extend toolset : msvc ;
1336 # Intel and msvc supposedly have link-compatible objects.
1337 feature.subfeature toolset msvc : vendor : intel : propagated optional ;
1339 # Inherit MIDL flags.
1340 toolset.inherit-flags msvc : midl ;
1343 toolset.inherit-flags msvc : mc ;
1345 # Dynamic runtime comes only in MT flavour.
1346 toolset.add-requirements
1347 <toolset>msvc,<runtime-link>shared:<threading>multi ;
1349 # Declare msvc toolset specific features.
1351 feature.feature debug-store : object database : propagated ;
1352 feature.feature pch-source : : dependency free ;
1355 # Declare generators.
1357 # TODO: Is it possible to combine these? Make the generators
1358 # non-composing so that they do not convert each source into a separate
1360 generators.register [ new msvc-linking-generator msvc.link :
1361 OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : EXE : <toolset>msvc ] ;
1362 generators.register [ new msvc-linking-generator msvc.link.dll :
1363 OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB IMPORT_LIB :
1364 <toolset>msvc <suppress-import-lib>false ] ;
1365 generators.register [ new msvc-linking-generator msvc.link.dll :
1366 OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB :
1367 <toolset>msvc <suppress-import-lib>true ] ;
1369 generators.register-archiver msvc.archive : OBJ : STATIC_LIB : <toolset>msvc ;
1370 generators.register-c-compiler msvc.compile.c++ : CPP : OBJ : <toolset>msvc ;
1371 generators.register-c-compiler msvc.compile.c : C : OBJ : <toolset>msvc ;
1372 generators.register-c-compiler msvc.compile.c++.preprocess : CPP : PREPROCESSED_CPP : <toolset>msvc ;
1373 generators.register-c-compiler msvc.compile.c.preprocess : C : PREPROCESSED_C : <toolset>msvc ;
1375 # Using 'register-c-compiler' adds the build directory to INCLUDES.
1376 generators.register-c-compiler msvc.compile.rc : RC : OBJ(%_res) : <toolset>msvc ;
1377 generators.override msvc.compile.rc : rc.compile.resource ;
1378 generators.register-standard msvc.compile.asm : ASM : OBJ : <toolset>msvc ;
1380 generators.register-c-compiler msvc.compile.idl : IDL : MSTYPELIB H C(%_i) C(%_proxy) C(%_dlldata) : <toolset>msvc ;
1381 generators.override msvc.compile.idl : midl.compile.idl ;
1383 generators.register-standard msvc.compile.mc : MC : H RC : <toolset>msvc ;
1384 generators.override msvc.compile.mc : mc.compile ;
1386 # Note: the 'H' source type will catch both '.h' and '.hpp' headers as
1387 # the latter have their HPP type derived from H. The type of compilation
1388 # is determined entirely by the destination type.
1389 generators.register [ new msvc-pch-generator msvc.compile.c.pch : H : C_PCH OBJ : <pch>on <toolset>msvc ] ;
1390 generators.register [ new msvc-pch-generator msvc.compile.c++.pch : H : CPP_PCH OBJ : <pch>on <toolset>msvc ] ;
1392 generators.override msvc.compile.c.pch : pch.default-c-pch-generator ;
1393 generators.override msvc.compile.c++.pch : pch.default-cpp-pch-generator ;
1396 toolset.flags msvc.compile PCH_FILE <pch>on : <pch-file> ;
1397 toolset.flags msvc.compile PCH_SOURCE <pch>on : <pch-source> ;
1398 toolset.flags msvc.compile PCH_HEADER <pch>on : <pch-header> ;
1401 # Declare flags for compilation.
1404 toolset.flags msvc.compile CFLAGS <optimization>speed : /O2 ;
1405 toolset.flags msvc.compile CFLAGS <optimization>space : /O1 ;
1407 toolset.flags msvc.compile CFLAGS $(.cpu-arch-ia64)/<instruction-set>$(.cpu-type-itanium) : /G1 ;
1408 toolset.flags msvc.compile CFLAGS $(.cpu-arch-ia64)/<instruction-set>$(.cpu-type-itanium2) : /G2 ;
1410 toolset.flags msvc.compile CFLAGS <debug-symbols>on/<debug-store>object : /Z7 ;
1411 toolset.flags msvc.compile CFLAGS <debug-symbols>on/<debug-store>database : /Zi ;
1412 toolset.flags msvc.compile CFLAGS <optimization>off : /Od ;
1413 toolset.flags msvc.compile CFLAGS <inlining>off : /Ob0 ;
1414 toolset.flags msvc.compile CFLAGS <inlining>on : /Ob1 ;
1415 toolset.flags msvc.compile CFLAGS <inlining>full : /Ob2 ;
1417 toolset.flags msvc.compile CFLAGS <warnings>on : /W3 ;
1418 toolset.flags msvc.compile CFLAGS <warnings>off : /W0 ;
1419 toolset.flags msvc.compile CFLAGS <warnings>all : /W4 ;
1420 toolset.flags msvc.compile CFLAGS <warnings-as-errors>on : /WX ;
1422 toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>off/<extern-c-nothrow>off : /EHs ;
1423 toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>off/<extern-c-nothrow>on : /EHsc ;
1424 toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>on/<extern-c-nothrow>off : /EHa ;
1425 toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>on/<extern-c-nothrow>on : /EHac ;
1427 # By default 8.0 enables rtti support while prior versions disabled it. We
1428 # simply enable or disable it explicitly so we do not have to depend on this
1429 # default behaviour.
1430 toolset.flags msvc.compile CFLAGS <rtti>on : /GR ;
1431 toolset.flags msvc.compile CFLAGS <rtti>off : /GR- ;
1432 toolset.flags msvc.compile CFLAGS <runtime-debugging>off/<runtime-link>shared : /MD ;
1433 toolset.flags msvc.compile CFLAGS <runtime-debugging>on/<runtime-link>shared : /MDd ;
1435 toolset.flags msvc.compile CFLAGS <runtime-debugging>off/<runtime-link>static/<threading>multi : /MT ;
1436 toolset.flags msvc.compile CFLAGS <runtime-debugging>on/<runtime-link>static/<threading>multi : /MTd ;
1438 toolset.flags msvc.compile OPTIONS <cflags> : ;
1439 toolset.flags msvc.compile.c++ OPTIONS <cxxflags> : ;
1441 toolset.flags msvc.compile PDB_CFLAG <debug-symbols>on/<debug-store>database : /Fd ;
1443 toolset.flags msvc.compile DEFINES <define> ;
1444 toolset.flags msvc.compile UNDEFS <undef> ;
1445 toolset.flags msvc.compile INCLUDES <include> ;
1447 # Declare flags for the assembler.
1448 toolset.flags msvc.compile.asm USER_ASMFLAGS <asmflags> ;
1450 toolset.flags msvc.compile.asm ASMFLAGS <debug-symbols>on : "/Zi /Zd" ;
1452 toolset.flags msvc.compile.asm ASMFLAGS <warnings>on : /W3 ;
1453 toolset.flags msvc.compile.asm ASMFLAGS <warnings>off : /W0 ;
1454 toolset.flags msvc.compile.asm ASMFLAGS <warnings>all : /W4 ;
1455 toolset.flags msvc.compile.asm ASMFLAGS <warnings-as-errors>on : /WX ;
1457 toolset.flags msvc.compile.asm DEFINES <define> ;
1459 # Declare flags for linking.
1461 toolset.flags msvc.link PDB_LINKFLAG <debug-symbols>on/<debug-store>database : /PDB: ; # not used yet
1462 toolset.flags msvc.link LINKFLAGS <debug-symbols>on : /DEBUG ;
1463 toolset.flags msvc.link DEF_FILE <def-file> ;
1465 # The linker disables the default optimizations when using /DEBUG so we
1466 # have to enable them manually for release builds with debug symbols.
1467 toolset.flags msvc LINKFLAGS <debug-symbols>on/<runtime-debugging>off : /OPT:REF,ICF ;
1469 toolset.flags msvc LINKFLAGS <user-interface>console : /subsystem:console ;
1470 toolset.flags msvc LINKFLAGS <user-interface>gui : /subsystem:windows ;
1471 toolset.flags msvc LINKFLAGS <user-interface>wince : /subsystem:windowsce ;
1472 toolset.flags msvc LINKFLAGS <user-interface>native : /subsystem:native ;
1473 toolset.flags msvc LINKFLAGS <user-interface>auto : /subsystem:posix ;
1475 toolset.flags msvc.link OPTIONS <linkflags> ;
1476 toolset.flags msvc.link LINKPATH <library-path> ;
1478 toolset.flags msvc.link FINDLIBS_ST <find-static-library> ;
1479 toolset.flags msvc.link FINDLIBS_SA <find-shared-library> ;
1480 toolset.flags msvc.link LIBRARY_OPTION <toolset>msvc : "" : unchecked ;
1481 toolset.flags msvc.link LIBRARIES_MENTIONED_BY_FILE : <library-file> ;
1483 toolset.flags msvc.link.dll LINKFLAGS <suppress-import-lib>true : /NOENTRY ;
1486 toolset.flags msvc.archive AROPTIONS <archiveflags> ;
1490 # Locates the requested setup script under the given folder and returns its full
1491 # path or nothing in case the script can not be found. In case multiple scripts
1492 # are found only the first one is returned.
1494 # TODO: There used to exist a code comment for the msvc.init rule stating that
1495 # we do not correctly detect the location of the vcvars32.bat setup script for
1496 # the free VC7.1 tools in case user explicitly provides a path. This should be
1497 # tested or simply remove this whole comment in case this toolset version is no
1500 local rule locate-default-setup ( command : parent : setup-name )
1502 local result = [ GLOB $(command) $(parent) : $(setup-name) ] ;
1505 return $(result[1]) ;
1510 # Validates given path, registers found configuration and prints debug
1511 # information about it.
1513 local rule register-configuration ( version : path ? )
1517 local command = [ GLOB $(path) : cl.exe ] ;
1521 if $(.debug-configuration)
1523 ECHO notice: [msvc-cfg] msvc-$(version) detected, command:
1527 $(.versions).register $(version) ;
1528 $(.versions).set $(version) : options : <command>$(command) ;
1534 ################################################################################
1536 # Startup code executed when loading this module.
1538 ################################################################################
1540 if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
1542 .debug-configuration = true ;
1545 # Miscellaneous constants.
1546 .RM = [ common.rm-command ] ;
1549 .ProgramFiles = [ path.make [ common.get-program-files-dir ] ] ;
1550 .escaped-double-quote = "\"" ;
1551 .TOUCH_FILE = [ common.file-touch-command ] ;
1553 # List of all registered configurations.
1554 .versions = [ new configurations ] ;
1556 # Supported CPU architectures.
1558 <architecture>/<address-model>
1559 <architecture>/<address-model>32
1560 <architecture>x86/<address-model>
1561 <architecture>x86/<address-model>32 ;
1564 <architecture>/<address-model>64
1565 <architecture>x86/<address-model>64 ;
1568 <architecture>ia64/<address-model>
1569 <architecture>ia64/<address-model>64 ;
1572 <architecture>arm/<address-model>
1573 <architecture>arm/<address-model>32 ;
1576 # Supported CPU types (only Itanium optimization options are supported from
1577 # VC++ 2005 on). See
1578 # http://msdn2.microsoft.com/en-us/library/h66s5s0e(vs.90).aspx for more
1579 # detailed information.
1580 .cpu-type-g5 = i586 pentium pentium-mmx ;
1581 .cpu-type-g6 = i686 pentiumpro pentium2 pentium3 pentium3m pentium-m k6
1582 k6-2 k6-3 winchip-c6 winchip2 c3 c3-2 ;
1583 .cpu-type-em64t = prescott nocona core2 corei7 corei7-avx core-avx-i
1584 conroe conroe-xe conroe-l allendale merom
1585 merom-xe kentsfield kentsfield-xe penryn wolfdale
1586 yorksfield nehalem sandy-bridge ivy-bridge haswell ;
1587 .cpu-type-amd64 = k8 opteron athlon64 athlon-fx k8-sse3 opteron-sse3
1588 athlon64-sse3 amdfam10 barcelona bdver1 bdver2 bdver3
1590 .cpu-type-g7 = pentium4 pentium4m athlon athlon-tbird athlon-4 athlon-xp
1591 athlon-mp $(.cpu-type-em64t) $(.cpu-type-amd64) ;
1592 .cpu-type-itanium = itanium itanium1 merced ;
1593 .cpu-type-itanium2 = itanium2 mckinley ;
1594 .cpu-type-arm = armv2 armv2a armv3 armv3m armv4 armv4t armv5 armv5t armv5te armv6 armv6j iwmmxt ep9312
1597 # Known toolset versions, in order of preference.
1598 .known-versions = 15.0 14.0 12.0 11.0 10.0 10.0express 9.0 9.0express 8.0 8.0express 7.1
1599 7.1toolkit 7.0 6.0 ;
1602 .version-alias-6 = 6.0 ;
1603 .version-alias-6.5 = 6.0 ;
1604 .version-alias-7 = 7.0 ;
1605 .version-alias-8 = 8.0 ;
1606 .version-alias-9 = 9.0 ;
1607 .version-alias-10 = 10.0 ;
1608 .version-alias-11 = 11.0 ;
1609 .version-alias-12 = 12.0 ;
1610 .version-alias-14 = 14.0 ;
1611 .version-alias-15 = 15.0 ;
1613 # Names of registry keys containing the Visual C++ installation path (relative
1614 # to "HKEY_LOCAL_MACHINE\SOFTWARE\\Microsoft").
1615 .version-6.0-reg = "VisualStudio\\6.0\\Setup\\Microsoft Visual C++" ;
1616 .version-7.0-reg = "VisualStudio\\7.0\\Setup\\VC" ;
1617 .version-7.1-reg = "VisualStudio\\7.1\\Setup\\VC" ;
1618 .version-8.0-reg = "VisualStudio\\8.0\\Setup\\VC" ;
1619 .version-8.0express-reg = "VCExpress\\8.0\\Setup\\VC" ;
1620 .version-9.0-reg = "VisualStudio\\9.0\\Setup\\VC" ;
1621 .version-9.0express-reg = "VCExpress\\9.0\\Setup\\VC" ;
1622 .version-10.0-reg = "VisualStudio\\10.0\\Setup\\VC" ;
1623 .version-10.0express-reg = "VCExpress\\10.0\\Setup\\VC" ;
1624 .version-11.0-reg = "VisualStudio\\11.0\\Setup\\VC" ;
1625 .version-12.0-reg = "VisualStudio\\12.0\\Setup\\VC" ;
1626 .version-14.0-reg = "VisualStudio\\14.0\\Setup\\VC" ;
1627 .version-15.0-reg = "VisualStudio\\15.0\\Setup\\VC" ;
1629 # Visual C++ Toolkit 2003 does not store its installation path in the registry.
1630 # The environment variable 'VCToolkitInstallDir' and the default installation
1631 # path will be checked instead.
1632 .version-7.1toolkit-path = "Microsoft Visual C++ Toolkit 2003" "bin" ;
1633 .version-7.1toolkit-env = VCToolkitInstallDir ;
1635 # Path to the folder containing "cl.exe" relative to the value of the
1636 # corresponding environment variable.
1637 .version-7.1toolkit-envpath = "bin" ;
1640 # Auto-detect all the available msvc installations on the system.
1641 auto-detect-toolset-versions ;
1644 # And finally trigger the actual Boost Build toolset registration.