Boost logo

Boost-Commit :

From: jurko.gospodnetic_at_[hidden]
Date: 2008-08-24 21:47:54


Author: jurko
Date: 2008-08-24 21:47:54 EDT (Sun, 24 Aug 2008)
New Revision: 48361
URL: http://svn.boost.org/trac/boost/changeset/48361

Log:
Refactored and better commented the Boost Build msvc toolset module as it grew to be quite large and lose its structure while even more features are being planned for it. No functional changes.

Organized content into: module inclusions, public rules, class definitions, local rules and finally startup code, in that order. Rules inside a single group ordered alphabetically. Mostly standardized global variable naming style. Extracted all toolset, flag & generator registrations into a single helper rule. Extracted all the msvc version auto-detection code into a single local helper rule. toolset.flag rule now referenced by its full name. Minor stylistic changes.
Text files modified:
   trunk/tools/build/v2/tools/msvc.jam | 1420 +++++++++++++++++++++------------------
   1 files changed, 761 insertions(+), 659 deletions(-)

Modified: trunk/tools/build/v2/tools/msvc.jam
==============================================================================
--- trunk/tools/build/v2/tools/msvc.jam (original)
+++ trunk/tools/build/v2/tools/msvc.jam 2008-08-24 21:47:54 EDT (Sun, 24 Aug 2008)
@@ -4,75 +4,64 @@
 # Copyright (c) 2006 Bojan Resnik.
 # Copyright (c) 2006 Ilya Sokolov.
 # Copyright (c) 2007 Rene Rivera
+# Copyright (c) 2008 Jurko Gospodnetic
 #
 # Use, modification and distribution is subject to the Boost Software
 # License Version 1.0. (See accompanying file LICENSE_1_0.txt or
 # http://www.boost.org/LICENSE_1_0.txt)
 
+################################################################################
+#
+# MSVC Boost Build toolset module.
+# --------------------------------
+#
+# All toolset versions need to have their location either auto-detected or
+# explicitly specified except for the special 'default' version that expects the
+# environment to find the needed tools or report an error.
+#
+################################################################################
+
 import "class" : new ;
-import property ;
-import generators ;
-import os ;
-import type ;
-import toolset : flags ;
+import common ;
 import errors ;
 import feature ;
-import path ;
-import common ;
-import rc ;
-import midl ;
+import generators ;
 import mc ;
+import midl ;
+import property ;
+import os ;
+import path ;
 import pch ;
+import rc ;
+import toolset ;
+import type ;
 
-if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
-{
- .debug-configuration = true ;
-}
-
-feature.extend toolset : msvc ;
-
-feature.subfeature toolset msvc : vendor
- : intel
- : propagated optional
- # intel and msvc supposedly have link-compatible objects... remains
- # to be seen, though ;-)
- ;
-
-# List of all registered configurations
-.versions = [ new configurations ] ;
-
-# Inherit MIDL flags
-toolset.inherit-flags msvc : midl ;
-
-# Inherit MC flags
-toolset.inherit-flags msvc : mc ;
-
-# Dynamic runtime comes only in MT flavour.
-toolset.add-requirements <toolset>msvc,<runtime-link>shared:<threading>multi ;
-
-RM = [ common.rm-command ] ;
-nl = "
-" ;
 
+################################################################################
+#
+# Public rules.
+#
+################################################################################
 
-# Initialize the toolset for a specific version. As the result, path to compiler
-# and, possible, program names are set up, and will be used when that version of
-# compiler is requested. For example, you might have:
+# Initialize a specific toolset version configuration. As the result, path to
+# compiler and, possible, program names are set up, and will be used when that
+# version of compiler is requested. For example, you might have:
 #
 # using msvc : 6.5 : cl.exe ;
 # using msvc : 7.0 : Y:/foo/bar/cl.exe ;
 #
-# The version paramater can be ommited:
+# The version parameter may be ommited:
 #
 # using msvc : : Z:/foo/bar/cl.exe ;
 #
-# Two special version keywords may be supplied:
-# - all - all detected versions will be registered;
+# The following keywords have special meanings when specified as versions:
+# - all - all detected but not yet used versions will be marked as used
+# with their default options.
 # - default - this is an equivalent to an empty version.
 #
 # Depending on a supplied version, detected configurations and presence 'cl.exe'
 # in the path different results may be achieved. The following table describes
-# all possible cases:
+# the possible scenarios:
 #
 # Nothing "x.y"
 # Passed Nothing "x.y" detected, detected,
@@ -86,8 +75,9 @@
 # "x.y" - refers to a detected version;
 # "a.b" - refers to an undetected version.
 #
-# Note: for free VC7.1 tools, we do not correctly find vcvars32.bar when user
-# explicitly provides a path.
+# FIXME: Currently the command parameter and the <compiler> property parameter
+# seem to overlap in duties. Remove this duplication. This seems to be related
+# to why someone started preparing to replace init with configure rules.
 #
 rule init (
     # The msvc version being configured. When omitted the tools invoked when no
@@ -141,27 +131,34 @@
     {
         options += <command>$(command) ;
     }
-
     configure $(version) : $(options) ;
 }
 
 
 # 'configure' is a newer version of 'init'. The parameter 'command' is passed as
-# a part of the 'options' list.
+# a part of the 'options' list. See the 'init' rule comment for more detailed
+# information.
 #
 rule configure ( version ? : options * )
 {
     switch $(version)
     {
- case all :
+ case "all" :
             if $(options)
             {
- errors.error "msvc: options should be empty when 'all' is specified" ;
+ errors.error "msvc: Options should be empty when '$(version)'"
+ "is specified" ;
             }
 
- # Use all detected versions.
- for local v in [ $(.versions).all ]
- {
+ # Configure (i.e. mark as used) all registered versions.
+ local all-versions = [ $(.versions).all ] ;
+ for local v in $(all-versions)
+ {
+ # Note that there is no need to skip already configured
+ # versions here as this will request configure-really rule to
+ # configure the version using default options which will in turn
+ # cause it to simply do nothing in case the version has already
+ # been configured.
                 configure-really $(v) ;
             }
 
@@ -174,134 +171,513 @@
 }
 
 
-# Supported CPU architectures.
-.cpu-arch-i386 =
- <architecture>/<address-model>
- <architecture>/<address-model>32
- <architecture>x86/<address-model>
- <architecture>x86/<address-model>32 ;
+# Sets up flag definitions dependent on the compiler version used.
+# - 'version' is the version of compiler in N.M format.
+# - 'conditions' is the property set to be used as flag conditions.
+# - 'toolset' is the toolset for which flag settings are to be defined.
+# This makes the rule reusable for other msvc-option-compatible compilers.
+#
+rule configure-version-specific ( toolset : version : conditions )
+{
+ toolset.push-checking-for-flags-module unchecked ;
+ # Starting with versions 7.0, the msvc compiler have the /Zc:forScope and
+ # /Zc:wchar_t options that improve C++ standard conformance, but those
+ # options are off by default. If we are sure that the msvc version is at
+ # 7.*, add those options explicitly. We can be sure either if user specified
+ # version 7.* explicitly or if we auto-detected the version ourselves.
+ # above).
+ if ! [ MATCH ^(6\\.) : $(version) ]
+ {
+ toolset.flags $(toolset).compile CFLAGS $(conditions) : /Zc:forScope /Zc:wchar_t ;
+ toolset.flags $(toolset).compile.c++ C++FLAGS $(conditions) : /wd4675 ;
 
-.cpu-arch-amd64 =
- <architecture>/<address-model>64
- <architecture>x86/<address-model>64 ;
+ # Explicitly disable the 'function is deprecated' warning. Some msvc
+ # versions have a bug, causing them to emit the deprecation warning even
+ # with /W0.
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<warnings>off : /wd4996 ;
 
-.cpu-arch-ia64 =
- <architecture>ia64/<address-model>
- <architecture>ia64/<address-model>64 ;
+ if [ MATCH ^([78]\\.) : $(version) ]
+ {
+ # 64-bit compatibility warning deprecated since 9.0, see
+ # http://msdn.microsoft.com/en-us/library/yt4xw8fh.aspx
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<warnings>all : /Wp64 ;
+ }
+ }
 
+ #
+ # Processor-specific optimization.
+ #
 
-# Locates the requested setup script under the given folder and returns its full
-# path or nothing in case the script can not be found. In case multiple scripts
-# are found only the first one is returned.
+ if [ MATCH ^([67]) : $(version) ]
+ {
+ # 8.0 deprecates some of the options.
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>speed $(conditions)/<optimization>space : /Ogiy /Gs ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>speed : /Ot ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>space : /Os ;
+
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set> : /GB ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>i386 : /G3 ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>i486 : /G4 ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g5) : /G5 ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g6) : /G6 ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g7) : /G7 ;
+
+ # Improve floating-point accuracy. Otherwise, some of C++ Boost's "math"
+ # tests will fail.
+ toolset.flags $(toolset).compile CFLAGS $(conditions) : /Op ;
+
+ # 7.1 and below have single-threaded static RTL.
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>off/<runtime-link>static/<threading>single : /ML ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>on/<runtime-link>static/<threading>single : /MLd ;
+ }
+ else
+ {
+ # 8.0 and above adds some more options.
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set> : /favor:blend ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set>$(.cpu-type-em64t) : /favor:EM64T ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set>$(.cpu-type-amd64) : /favor:AMD64 ;
+
+ # 8.0 and above only has multi-threaded static RTL.
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>off/<runtime-link>static/<threading>single : /MT ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>on/<runtime-link>static/<threading>single : /MTd ;
+ }
+ toolset.pop-checking-for-flags-module ;
+}
+
+
+# Registers this toolset including all of its flags, features & generators. Does
+# nothing on repeated calls.
 #
-local rule locate-default-setup ( command : parent : setup-name )
+rule register-toolset ( )
 {
- local result = [ GLOB $(command) $(parent) : $(setup-name) ] ;
- if $(result[1])
+ if ! msvc in [ feature.values toolset ]
     {
- return $(result[1]) ;
+ register-toolset-really ;
     }
 }
 
 
-local rule configure-really ( version ? : options * )
+# Declare action for creating static libraries. If library exists, remove it
+# before adding files. See
+# http://article.gmane.org/gmane.comp.lib.boost.build/4241 for rationale.
+if [ os.name ] in NT
 {
- local v = $(version) ;
- if ! $(v)
+ # The 'DEL' command would issue a message to stdout if the file does not
+ # exist, so need a check.
+ actions archive
     {
- # Take the first detected version.
- version = [ $(.versions).all ] ;
- version = $(version[1]) ;
- v = $(version) ;
-
- # Note: 'version' can still be empty at this point if no versions were
- # detected.
- version ?= "default" ;
+ if exist "$(<[1])" DEL "$(<[1])"
+ $(.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")"
     }
-
- # Version alias -> real version number.
- if $(.version-alias-$(version))
+}
+else
+{
+ actions archive
     {
- version = $(.version-alias-$(version)) ;
+ $(.RM) "$(<[1])"
+ $(.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")"
     }
+}
 
- # Check whether the selected configuration is already in use.
- if $(version) in [ $(.versions).used ]
+
+# For the assembler the following options are turned on by default:
+#
+# -coff generate COFF format object file (compatible with cl.exe output)
+# -Zp4 align structures to 4 bytes
+# -Cp preserve case of user identifiers
+# -Cx preserve case in publics, externs
+#
+actions compile.asm
+{
+ $(.ASM) -nologo -c -coff -Zp4 -Cp -Cx $(USER_ASMFLAGS) -Fo "$(<:W)" "$(>:W)"
+}
+
+
+rule compile.c ( targets + : sources * : properties * )
+{
+ C++FLAGS on $(targets[1]) = ;
+ get-rspline $(targets) : -TC ;
+ compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
+}
+
+
+rule compile.c.pch ( targets + : sources * : properties * )
+{
+ C++FLAGS on $(targets[1]) = ;
+ get-rspline $(targets[1]) : -TC ;
+ get-rspline $(targets[2]) : -TC ;
+ local pch-source = [ on $(<) return $(PCH_SOURCE) ] ;
+ if $(pch-source)
     {
- # Allow multiple 'toolset.using' calls for the same configuration if the
- # identical sets of options are used.
- if $(options) && ( $(options) != [ $(.versions).get $(version) : options ] )
- {
- errors.error "msvc: the toolset version '$(version)' already configured." ;
- }
+ DEPENDS $(<) : $(pch-source) ;
+ compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ;
     }
     else
     {
- # Register a new configuration.
- $(.versions).register $(version) ;
+ compile-c-c++-pch $(targets) : $(sources) ;
+ }
+}
 
- # Add user-supplied to auto-detected options.
- options = [ $(.versions).get $(version) : options ] $(options) ;
 
- # Mark the configuration as 'used'.
- $(.versions).use $(version) ;
+# Action for running the C/C++ compiler without using precompiled headers.
+#
+actions compile-c-c++
+{
+ $(.CC) @"@($(<[1]:W).rsp:E="$(>[1]:W)" -Fo"$(<[1]:W)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))" $(.CC.FILTER)
+}
 
- # Generate conditions and save them.
- local conditions = [ common.check-init-parameters msvc : version $(v) ] ;
 
- $(.versions).set $(version) : conditions : $(conditions) ;
+rule compile-c-c++ ( targets + : sources * )
+{
+ DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_HEADER) ] ;
+ DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_FILE) ] ;
+}
 
- local command = [ feature.get-values <command> : $(options) ] ;
 
- # If version is specified, we try to search first in default paths, and
- # only then in PATH.
- command = [ common.get-invocation-command msvc : cl.exe : $(command) :
- [ default-paths $(version) ] : $(version) ] ;
+# Action for running the C/C++ compiler using precompiled headers. In addition
+# to whatever else it needs to compile, this action also adds a temporary source
+# .cpp file used to compile the precompiled headers themselves.
+#
+# The global .escaped-double-quote variable is used to avoid messing up Emacs
+# syntax highlighting in the messy N-quoted code below.
+#
+actions compile-c-c++-pch
+{
+ $(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" -Yl"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))" "@($(<[1]:W).cpp:E=#include $(.escaped-double-quote)$(>[1]:D=)$(.escaped-double-quote))" $(.CC.FILTER)
+}
 
- common.handle-options msvc : $(conditions) : $(command) : $(options) ;
 
- if ! $(version)
- {
- # Even if version is not explicitly specified, try to detect the
- # version from the path.
- if [ MATCH "(Microsoft Visual Studio 9)" : $(command) ]
- {
- version = 9.0 ;
- }
- if [ MATCH "(Microsoft Visual Studio 8)" : $(command) ]
- {
- version = 8.0 ;
- }
- else if [ MATCH "(NET 2003[\/\\]VC7)" : $(command) ]
- {
- version = 7.1 ;
- }
- else if [ MATCH "(Microsoft Visual C\\+\\+ Toolkit 2003)" : $(command) ]
- {
- version = 7.1toolkit ;
- }
- else if [ MATCH "(.NET[\/\\]VC7)" : $(command) ]
- {
- version = 7.0 ;
- }
- else
- {
- version = 6.0 ;
- }
- }
+# Action for running the C/C++ compiler using precompiled headers. An already
+# built source file for compiling the precompiled headers is expected to be
+# given as one of the source parameters.
+#
+actions compile-c-c++-pch-s
+{
+ $(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" -Yl"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))" $(.CC.FILTER)
+}
 
- # Generate and register setup command.
 
- local below-8.0 = [ MATCH ^([67]\\.) : $(version) ] ;
+rule compile.c++ ( targets + : sources * : properties * )
+{
+ get-rspline $(targets) : -TP ;
+ compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
+}
 
- local cpu = i386 amd64 ia64 ;
- if $(below-8.0)
- {
- cpu = i386 ;
- }
 
- local setup-amd64 ;
- local setup-i386 ;
+rule compile.c++.pch ( targets + : sources * : properties * )
+{
+ get-rspline $(targets[1]) : -TP ;
+ get-rspline $(targets[2]) : -TP ;
+ local pch-source = [ on $(<) return $(PCH_SOURCE) ] ;
+ if $(pch-source)
+ {
+ DEPENDS $(<) : $(pch-source) ;
+ compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ;
+ }
+ else
+ {
+ compile-c-c++-pch $(targets) : $(sources) ;
+ }
+}
+
+
+# See midl.jam for details.
+#
+actions compile.idl
+{
+ $(.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)")"
+ $(.TOUCH_FILE) "$(<[4]:W)"
+ $(.TOUCH_FILE) "$(<[5]:W)"
+}
+
+
+actions compile.mc
+{
+ $(.MC) $(MCFLAGS) -h "$(<[1]:DW)" -r "$(<[2]:DW)" "$(>:W)"
+}
+
+
+actions compile.rc
+{
+ $(.RC) -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES:W)" -fo "$(<:W)" "$(>:W)"
+}
+
+
+rule link.dll ( targets + : sources * : properties * )
+{
+ DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ;
+}
+
+
+# Incremental linking a DLL causes no end of problems: if the actual exports do
+# not change, the import .lib file is never updated. Therefore, the .lib is
+# always out-of-date and gets rebuilt every time. I am not sure that incremental
+# linking is such a great idea in general, but in this case I am sure we do not
+# want it.
+
+# Windows manifest is a new way to specify dependencies on managed DotNet
+# assemblies and Windows native DLLs. The manifests are embedded as resources
+# and are useful in any PE target (both DLL and EXE).
+
+if [ os.name ] in NT
+{
+ actions link bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
+ {
+ $(.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")"
+ if %ERRORLEVEL% NEQ 0 EXIT %ERRORLEVEL%
+ if exist "$(<[1]).manifest" (
+ $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);1"
+ )
+ }
+
+ actions link.dll bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
+ {
+ $(.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")"
+ if %ERRORLEVEL% NEQ 0 EXIT %ERRORLEVEL%
+ if exist "$(<[1]).manifest" (
+ $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);2"
+ )
+ }
+}
+else
+{
+ actions link bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
+ {
+ $(.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")"
+ if test -e "$(<[1]).manifest"; then
+ $(.MT) -manifest "$(<[1]:W).manifest" "-outputresource:$(<[1]:W);1"
+ fi
+ }
+
+ actions link.dll bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
+ {
+ $(.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")"
+ if test -e "$(<[1]).manifest"; then
+ $(.MT) -manifest "$(<[1]:W).manifest" "-outputresource:$(<[1]:W);2"
+ fi
+ }
+}
+
+
+################################################################################
+#
+# Classes.
+#
+################################################################################
+
+class msvc-pch-generator : pch-generator
+{
+ import property-set ;
+
+ rule run-pch ( project name ? : property-set : sources * )
+ {
+ # Searching for the header and source file in the sources.
+ local pch-header ;
+ local pch-source ;
+ for local s in $(sources)
+ {
+ if [ type.is-derived [ $(s).type ] H ]
+ {
+ pch-header = $(s) ;
+ }
+ else if
+ [ type.is-derived [ $(s).type ] CPP ] ||
+ [ type.is-derived [ $(s).type ] C ]
+ {
+ pch-source = $(s) ;
+ }
+ }
+
+ if ! $(pch-header)
+ {
+ errors.user-error "can not build pch without pch-header" ;
+ }
+
+ # If we do not have the PCH source - that is fine. We will just create a
+ # temporary .cpp file in the action.
+
+ local generated = [ generator.run $(project) $(name)
+ : [ property-set.create
+ # Passing of <pch-source> is a dirty trick, needed because
+ # non-composing generators with multiple inputs are subtly
+ # broken. For more detailed information see:
+ # https://zigzag.cs.msu.su:7813/boost.build/ticket/111
+ <pch-source>$(pch-source)
+ [ $(property-set).raw ] ]
+ : $(pch-header) ] ;
+
+ local pch-file ;
+ for local g in $(generated)
+ {
+ if [ type.is-derived [ $(g).type ] PCH ]
+ {
+ pch-file = $(g) ;
+ }
+ }
+
+ return [ property-set.create <pch-header>$(pch-header)
+ <pch-file>$(pch-file) ] $(generated) ;
+ }
+}
+
+
+################################################################################
+#
+# Local rules.
+#
+################################################################################
+
+# Detects versions listed as '.known-versions' by checking registry information,
+# environment variables & default paths. Supports both native Windows and
+# Cygwin.
+#
+local rule auto-detect-toolset-versions ( )
+{
+ if [ os.name ] in NT CYGWIN
+ {
+ # Get installation paths from the registry.
+ for local i in $(.known-versions)
+ {
+ if $(.version-$(i)-reg)
+ {
+ local vc-path ;
+ for local x in "" "Wow6432Node\\"
+ {
+ vc-path += [ W32_GETREG
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\"$(x)"\\Microsoft\\"$(.version-$(i)-reg)
+ : "ProductDir" ] ;
+ }
+
+ if $(vc-path)
+ {
+ vc-path = [ path.join [ path.make-NT $(vc-path[1]) ] "bin" ] ;
+ register-configuration $(i) : [ path.native $(vc-path[1]) ] ;
+ }
+ }
+ }
+ }
+
+ # Check environment and default installation paths.
+ for local i in $(.known-versions)
+ {
+ if ! $(i) in [ $(.versions).all ]
+ {
+ register-configuration $(i) : [ default-path $(i) ] ;
+ }
+ }
+}
+
+
+# Worker rule for toolset version configuration. Takes an explicit version id or
+# nothing in case it should configure the default toolset version (the first
+# registered one or a new 'default' one in case no toolset versions have been
+# registered yet).
+#
+local rule configure-really ( version ? : options * )
+{
+ local v = $(version) ;
+
+ # Decide what the 'default' version is.
+ if ! $(v)
+ {
+ # Take the first registered (i.e. auto-detected) version.
+ version = [ $(.versions).all ] ;
+ version = $(version[1]) ;
+ v = $(version) ;
+
+ # Note: 'version' can still be empty at this point if no versions have
+ # been auto-detected.
+ version ?= "default" ;
+ }
+
+ # Version alias -> real version number.
+ if $(.version-alias-$(version))
+ {
+ version = $(.version-alias-$(version)) ;
+ }
+
+ # Check whether the selected configuration is already in use.
+ if $(version) in [ $(.versions).used ]
+ {
+ # Allow multiple 'toolset.using' calls for the same configuration if the
+ # identical sets of options are used.
+ if $(options) && ( $(options) != [ $(.versions).get $(version) : options ] )
+ {
+ errors.error "msvc: Toolset version '$(version)' already"
+ "configured." ;
+ }
+ }
+ else
+ {
+ # Register a new configuration.
+ $(.versions).register $(version) ;
+
+ # Add user-supplied to auto-detected options.
+ options = [ $(.versions).get $(version) : options ] $(options) ;
+
+ # Mark the configuration as 'used'.
+ $(.versions).use $(version) ;
+
+ # Generate conditions and save them.
+ local conditions = [ common.check-init-parameters msvc : version $(v) ]
+ ;
+
+ $(.versions).set $(version) : conditions : $(conditions) ;
+
+ local command = [ feature.get-values <command> : $(options) ] ;
+
+ # If version is specified, we try to search first in default paths, and
+ # only then in PATH.
+ command = [ common.get-invocation-command msvc : cl.exe : $(command) :
+ [ default-paths $(version) ] : $(version) ] ;
+
+ common.handle-options msvc : $(conditions) : $(command) : $(options) ;
+
+ if ! $(version)
+ {
+ # Even if version is not explicitly specified, try to detect the
+ # version from the path.
+ # FIXME: We currently detect both Microsoft Visual Studio 9.0 and
+ # 9.0express as 9.0 here.
+ if [ MATCH "(Microsoft Visual Studio 9)" : $(command) ]
+ {
+ version = 9.0 ;
+ }
+ if [ MATCH "(Microsoft Visual Studio 8)" : $(command) ]
+ {
+ version = 8.0 ;
+ }
+ else if [ MATCH "(NET 2003[\/\\]VC7)" : $(command) ]
+ {
+ version = 7.1 ;
+ }
+ else if [ MATCH "(Microsoft Visual C\\+\\+ Toolkit 2003)" :
+ $(command) ]
+ {
+ version = 7.1toolkit ;
+ }
+ else if [ MATCH "(.NET[\/\\]VC7)" : $(command) ]
+ {
+ version = 7.0 ;
+ }
+ else
+ {
+ version = 6.0 ;
+ }
+ }
+
+ # Generate and register setup command.
+
+ local below-8.0 = [ MATCH ^([67]\\.) : $(version) ] ;
+
+ local cpu = i386 amd64 ia64 ;
+ if $(below-8.0)
+ {
+ cpu = i386 ;
+ }
+
+ local setup-amd64 ;
+ local setup-i386 ;
         local setup-ia64 ;
 
         if $(command)
@@ -346,7 +722,8 @@
             global-setup = $(global-setup[1]) ;
             if ! $(below-8.0)
             {
- global-setup ?= [ locate-default-setup $(command) : $(parent) : vcvarsall.bat ] ;
+ global-setup ?= [ locate-default-setup $(command) : $(parent) :
+ vcvarsall.bat ] ;
             }
 
             local default-setup-amd64 = vcvarsx86_amd64.bat ;
@@ -383,7 +760,7 @@
             }
 
             local setup-prefix = "call " ;
- local setup-suffix = " >nul"$(nl) ;
+ local setup-suffix = " >nul"$(.nl) ;
             if ! [ os.name ] in NT
             {
                 setup-prefix = "cmd.exe /S /C call " ;
@@ -486,113 +863,20 @@
                 toolset.flags msvc .CC.FILTER $(cpu-conditions) : "|" $(cc-filter) ;
             }
         }
+
         # Set version-specific flags.
         configure-version-specific msvc : $(version) : $(conditions) ;
     }
 }
 
 
-# Supported CPU types (only Itanium optimization options are supported from
-# VC++ 2005 on). See http://msdn2.microsoft.com/en-us/library/h66s5s0e(vs.90).aspx
-cpu-type-g5 = i586 pentium pentium-mmx ;
-cpu-type-g6 =
- i686 pentiumpro pentium2 pentium3 pentium3m pentium-m k6 k6-2 k6-3
- winchip-c6 winchip2 c3 c3-2 ;
-
-cpu-type-em64t = prescott nocona
- conroe conroe-xe conroe-l allendale mermon mermon-xe kentsfield kentsfield-xe
- penryn wolfdale yorksfield nehalem ;
-cpu-type-amd64 = k8 opteron athlon64 athlon-fx ;
-
-cpu-type-g7 =
- pentium4 pentium4m athlon athlon-tbird athlon-4 athlon-xp athlon-mp
- $(cpu-type-em64t) $(cpu-type-amd64) ;
-
-cpu-type-itanium = itanium itanium1 merced ;
-cpu-type-itanium2 = itanium2 mckinley ;
-
-
-# Sets up flag definitions dependent on the compiler version used.
-# - 'version' is the version of compiler in N.M format.
-# - 'conditions' is the property set to be used as flag conditions.
-# - 'toolset' is the toolset for which flag settings are to be defined.
-# This makes the rule reusable for other msvc-option-compatible compilers.
-#
-rule configure-version-specific ( toolset : version : conditions )
-{
- toolset.push-checking-for-flags-module unchecked ;
- # Starting with versions 7.0, the msvc compiler have the /Zc:forScope and
- # /Zc:wchar_t options that improve C++ standard conformance, but those
- # options are off by default. If we are sure that msvc version is at 7.*,
- # add those options explicitly. We can be sure either if user specified
- # version 7.* explicitly, or if the installation path contain 7.* (checked
- # above).
- if ! [ MATCH ^(6\\.) : $(version) ]
- {
- toolset.flags $(toolset).compile CFLAGS $(conditions) : /Zc:forScope /Zc:wchar_t ;
- toolset.flags $(toolset).compile.c++ C++FLAGS $(conditions) : /wd4675 ;
-
- # Explicitly disable the 'function is deprecated' warning. Some msvc
- # versions have a bug, causing them to emit the deprecation warning even
- # with /W0.
- toolset.flags $(toolset).compile CFLAGS $(conditions)/<warnings>off : /wd4996 ;
-
- if [ MATCH ^([78]\\.) : $(version) ]
- {
- # 64-bit compatibility warning deprecated since 9.0, see
- # http://msdn.microsoft.com/en-us/library/yt4xw8fh.aspx
- toolset.flags $(toolset).compile CFLAGS $(conditions)/<warnings>all : /Wp64 ;
- }
- }
-
- #
- # Processor-specific optimization.
- #
-
- if [ MATCH ^([67]) : $(version) ]
- {
- # 8.0 deprecates some of the options.
- toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>speed $(conditions)/<optimization>space : /Ogiy /Gs ;
- toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>speed : /Ot ;
- toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>space : /Os ;
-
- toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set> : /GB ;
- toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>i386 : /G3 ;
- toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>i486 : /G4 ;
- toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(cpu-type-g5) : /G5 ;
- toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(cpu-type-g6) : /G6 ;
- toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(cpu-type-g7) : /G7 ;
-
- # Improve floating-point accuracy. Otherwise, some of C++ Boost's "math"
- # tests will fail.
- toolset.flags $(toolset).compile CFLAGS $(conditions) : /Op ;
-
- # 7.1 and below have single-threaded static RTL.
- toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>off/<runtime-link>static/<threading>single : /ML ;
- toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>on/<runtime-link>static/<threading>single : /MLd ;
- }
- else
- {
- # 8.0 and above adds some more options.
- toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set> : /favor:blend ;
- toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set>$(cpu-type-em64t) : /favor:EM64T ;
- toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set>$(cpu-type-amd64) : /favor:AMD64 ;
-
- # 8.0 and above only has multi-threaded static RTL.
- toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>off/<runtime-link>static/<threading>single : /MT ;
- toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>on/<runtime-link>static/<threading>single : /MTd ;
- }
- toolset.pop-checking-for-flags-module ;
-}
-
-
 # Returns the default installation path for the given version.
 #
 local rule default-path ( version )
 {
     # Use auto-detected path if possible.
- local path = [ feature.get-values <command> :
- [ $(.versions).get $(version) : options ] ] ;
+ local path = [ feature.get-values <command> : [ $(.versions).get $(version)
+ : options ] ] ;
 
     if $(path)
     {
@@ -608,440 +892,304 @@
             {
                 vc-path = [ path.make $(vc-path) ] ;
                 vc-path = [ path.join $(vc-path) $(.version-$(version)-envpath) ] ;
- vc-path = [ path.native $(vc-path) ] ;
-
- path = $(vc-path) ;
- }
- }
-
- # Check default path.
- if ! $(path) && $(.version-$(version)-path)
- {
- path = [ path.native [ path.join $(.ProgramFiles) $(.version-$(version)-path) ] ] ;
- }
- }
-
- return $(path) ;
-}
-
-
-# Returns either the default installation path (if 'version' is not empty) or
-# list of all known default paths (if no version is given)
-#
-rule default-paths ( version ? )
-{
- local possible-paths ;
-
- if $(version)
- {
- possible-paths += [ default-path $(version) ] ;
- }
- else
- {
- for local i in $(.known-versions)
- {
- possible-paths += [ default-path $(i) ] ;
- }
- }
-
- return $(possible-paths) ;
-}
-
-
-# Declare generators.
-
-# TODO: Is it possible to combine these? Make the generators non-composing so
-# that they do not convert each source into a separate .rsp file.
-generators.register-linker msvc.link : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : EXE : <toolset>msvc ;
-generators.register-linker msvc.link.dll : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB IMPORT_LIB : <toolset>msvc ;
-
-generators.register-archiver msvc.archive : OBJ : STATIC_LIB : <toolset>msvc ;
-generators.register-c-compiler msvc.compile.c++ : CPP : OBJ : <toolset>msvc ;
-generators.register-c-compiler msvc.compile.c : C : OBJ : <toolset>msvc ;
-
-# Using 'register-c-compiler' adds the build directory to INCLUDES.
-generators.register-c-compiler msvc.compile.rc : RC : OBJ(%_res) : <toolset>msvc ;
-generators.override msvc.compile.rc : rc.compile.resource ;
-generators.register-standard msvc.compile.asm : ASM : OBJ : <toolset>msvc ;
-
-generators.register-c-compiler msvc.compile.idl : IDL : MSTYPELIB H C(%_i) C(%_proxy) C(%_dlldata) : <toolset>msvc ;
-generators.override msvc.compile.idl : midl.compile.idl ;
-
-generators.register-standard msvc.compile.mc : MC : H RC : <toolset>msvc ;
-generators.override msvc.compile.mc : mc.compile ;
-
-# pch support
-
-feature.feature pch-source : : free dependency ;
-
-class msvc-pch-generator : pch-generator
-{
- import property-set ;
-
- rule run-pch ( project name ? : property-set : sources * )
- {
- # Searching for the header and source file in the sources.
- local pch-header ;
- local pch-source ;
- for local s in $(sources)
- {
- if [ type.is-derived [ $(s).type ] H ]
- {
- pch-header = $(s) ;
- }
- else if
- [ type.is-derived [ $(s).type ] CPP ]
- || [ type.is-derived [ $(s).type ] C ]
- {
- pch-source = $(s) ;
- }
- }
-
- if ! $(pch-header)
- {
- errors.user-error "can not build pch without pch-header" ;
- }
-
- # If we do not have the PCH source - that is fine. We will just create a
- # temporary .cpp file in the action.
-
- local generated = [ generator.run $(project) $(name)
- : [ property-set.create
- # Passing of <pch-source> is a dirty trick, needed because
- # non-composing generators with multiple inputs are subtly
- # broken. For more detailed information see:
- # https://zigzag.cs.msu.su:7813/boost.build/ticket/111
- <pch-source>$(pch-source)
- [ $(property-set).raw ] ]
- : $(pch-header) ] ;
-
- local pch-file ;
- for local g in $(generated)
- {
- if [ type.is-derived [ $(g).type ] PCH ]
- {
- pch-file = $(g) ;
- }
- }
-
- return [ property-set.create <pch-header>$(pch-header)
- <pch-file>$(pch-file) ] $(generated) ;
- }
-}
-
-
-# Note: the 'H' source type will catch both '.h' header and '.hpp' header. The
-# latter have HPP type, but HPP type is derived from H. The type of compilation
-# is determined entirely by the destination type.
-generators.register [ new msvc-pch-generator msvc.compile.c.pch : H : C_PCH OBJ : <pch>on <toolset>msvc ] ;
-generators.register [ new msvc-pch-generator msvc.compile.c++.pch : H : CPP_PCH OBJ : <pch>on <toolset>msvc ] ;
-
-generators.override msvc.compile.c.pch : pch.default-c-pch-generator ;
-generators.override msvc.compile.c++.pch : pch.default-cpp-pch-generator ;
-
-flags msvc.compile PCH_FILE <pch>on : <pch-file> ;
-flags msvc.compile PCH_SOURCE <pch>on : <pch-source> ;
-flags msvc.compile PCH_HEADER <pch>on : <pch-header> ;
-
-#
-# Declare flags and action for compilation
-#
-feature.feature debug-store : object database : propagated ;
-
-flags msvc.compile CFLAGS <optimization>speed : /O2 ;
-flags msvc.compile CFLAGS <optimization>space : /O1 ;
-
-flags msvc.compile CFLAGS $(.cpu-arch-ia64)/<instruction-set>$(cpu-type-itanium) : /G1 ;
-flags msvc.compile CFLAGS $(.cpu-arch-ia64)/<instruction-set>$(cpu-type-itanium2) : /G2 ;
-
-flags msvc.compile CFLAGS <debug-symbols>on/<debug-store>object : /Z7 ;
-flags msvc.compile CFLAGS <debug-symbols>on/<debug-store>database : /Zi ;
-flags msvc.compile CFLAGS <optimization>off : /Od ;
-flags msvc.compile CFLAGS <inlining>off : /Ob0 ;
-flags msvc.compile CFLAGS <inlining>on : /Ob1 ;
-flags msvc.compile CFLAGS <inlining>full : /Ob2 ;
-
-flags msvc.compile CFLAGS <warnings>on : /W3 ;
-flags msvc.compile CFLAGS <warnings>off : /W0 ;
-flags msvc.compile CFLAGS <warnings>all : /W4 ;
-flags msvc.compile CFLAGS <warnings-as-errors>on : /WX ;
-
-flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>off/<extern-c-nothrow>off : /EHs ;
-flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>off/<extern-c-nothrow>on : /EHsc ;
-flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>on/<extern-c-nothrow>off : /EHa ;
-flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>on/<extern-c-nothrow>on : /EHac ;
+ vc-path = [ path.native $(vc-path) ] ;
 
-# By default 8.0 enables rtti support while prior versions disabled it. We
-# simply enable or disable it expliclty so we do not have to depend on this
-# default behaviour.
-flags msvc.compile CFLAGS <rtti>on : /GR ;
-flags msvc.compile CFLAGS <rtti>off : /GR- ;
-flags msvc.compile CFLAGS <runtime-debugging>off/<runtime-link>shared : /MD ;
-flags msvc.compile CFLAGS <runtime-debugging>on/<runtime-link>shared : /MDd ;
+ path = $(vc-path) ;
+ }
+ }
 
-flags msvc.compile CFLAGS <runtime-debugging>off/<runtime-link>static/<threading>multi : /MT ;
-flags msvc.compile CFLAGS <runtime-debugging>on/<runtime-link>static/<threading>multi : /MTd ;
+ # Check default path.
+ if ! $(path) && $(.version-$(version)-path)
+ {
+ path = [ path.native [ path.join $(.ProgramFiles) $(.version-$(version)-path) ] ] ;
+ }
+ }
 
-flags msvc.compile.c OPTIONS <cflags> : ;
-flags msvc.compile.c++ OPTIONS <cxxflags> : ;
+ return $(path) ;
+}
 
-flags msvc.compile PDB_CFLAG <debug-symbols>on/<debug-store>database : /Fd ; # not used yet
 
-flags msvc.compile DEFINES <define> ;
-flags msvc.compile UNDEFS <undef> ;
-flags msvc.compile INCLUDES <include> ;
+# Returns either the default installation path (if 'version' is not empty) or
+# list of all known default paths (if no version is given)
+#
+local rule default-paths ( version ? )
+{
+ local possible-paths ;
 
+ if $(version)
+ {
+ possible-paths += [ default-path $(version) ] ;
+ }
+ else
+ {
+ for local i in $(.known-versions)
+ {
+ possible-paths += [ default-path $(i) ] ;
+ }
+ }
 
-rule get-rspline ( target : lang-opt )
-{
- CC_RSPLINE on $(target) = [ on $(target) return $(lang-opt) -U$(UNDEFS) $(CFLAGS) $(C++FLAGS) $(OPTIONS) -c $(nl)-D$(DEFINES) $(nl)\"-I$(INCLUDES:W)\" ] ;
+ return $(possible-paths) ;
 }
 
 
-rule compile-c-c++ ( targets + : sources * )
+local rule get-rspline ( target : lang-opt )
 {
- DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_HEADER) ] ;
- DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_FILE) ] ;
+ CC_RSPLINE on $(target) = [ on $(target) return $(lang-opt) -U$(UNDEFS)
+ $(CFLAGS) $(C++FLAGS) $(OPTIONS) -c $(.nl)-D$(DEFINES)
+ $(.nl)\"-I$(INCLUDES:W)\" ] ;
 }
 
 
-actions compile-c-c++
+# Unsafe worker rule for the register-toolset() rule. Must not be called
+# multiple times.
+#
+local rule register-toolset-really ( )
 {
- $(.CC) @"@($(<[1]:W).rsp:E="$(>[1]:W)" -Fo"$(<[1]:W)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))" $(.CC.FILTER)
-}
+ feature.extend toolset : msvc ;
 
+ # Intel and msvc supposedly have link-compatible objects.
+ feature.subfeature toolset msvc : vendor : intel : propagated optional ;
 
-rule compile.c ( targets + : sources * : properties * )
-{
- C++FLAGS on $(targets[1]) = ;
- get-rspline $(targets) : -TC ;
- compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
-}
+ # Inherit MIDL flags.
+ toolset.inherit-flags msvc : midl ;
 
+ # Inherit MC flags.
+ toolset.inherit-flags msvc : mc ;
 
-rule compile.c++ ( targets + : sources * : properties * )
-{
- get-rspline $(targets) : -TP ;
- compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
-}
+ # Dynamic runtime comes only in MT flavour.
+ toolset.add-requirements
+ <toolset>msvc,<runtime-link>shared:<threading>multi ;
 
+ # Precompiled header (PCH) support feature.
+ feature.feature pch-source : : free dependency ;
 
-actions compile-c-c++-pch-s
-{
- $(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" -Yl"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))" $(.CC.FILTER)
-}
+ # Declare generators.
+ {
+ # TODO: Is it possible to combine these? Make the generators
+ # non-composing so that they do not convert each source into a separate
+ # .rsp file.
+ generators.register-linker msvc.link : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : EXE : <toolset>msvc ;
+ generators.register-linker msvc.link.dll : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB IMPORT_LIB : <toolset>msvc ;
 
+ generators.register-archiver msvc.archive : OBJ : STATIC_LIB : <toolset>msvc ;
+ generators.register-c-compiler msvc.compile.c++ : CPP : OBJ : <toolset>msvc ;
+ generators.register-c-compiler msvc.compile.c : C : OBJ : <toolset>msvc ;
 
-# Needed only to avoid messing up Emacs syntax highlighting in the messy
-# N-quoted code below.
-quote = "\"" ;
+ # Using 'register-c-compiler' adds the build directory to INCLUDES.
+ generators.register-c-compiler msvc.compile.rc : RC : OBJ(%_res) : <toolset>msvc ;
+ generators.override msvc.compile.rc : rc.compile.resource ;
+ generators.register-standard msvc.compile.asm : ASM : OBJ : <toolset>msvc ;
 
-actions compile-c-c++-pch
-{
- $(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" -Yl"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))" "@($(<[1]:W).cpp:E=#include $(quote)$(>[1]:D=)$(quote))" $(.CC.FILTER)
-}
+ generators.register-c-compiler msvc.compile.idl : IDL : MSTYPELIB H C(%_i) C(%_proxy) C(%_dlldata) : <toolset>msvc ;
+ generators.override msvc.compile.idl : midl.compile.idl ;
 
+ generators.register-standard msvc.compile.mc : MC : H RC : <toolset>msvc ;
+ generators.override msvc.compile.mc : mc.compile ;
 
-rule compile.c.pch ( targets + : sources * : properties * )
-{
- C++FLAGS on $(targets[1]) = ;
- get-rspline $(targets[1]) : -TC ;
- get-rspline $(targets[2]) : -TC ;
- local pch-source = [ on $(<) return $(PCH_SOURCE) ] ;
- if $(pch-source)
- {
- DEPENDS $(<) : $(pch-source) ;
- compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ;
- }
- else
- {
- compile-c-c++-pch $(targets) : $(sources) ;
+ # Note: the 'H' source type will catch both '.h' and '.hpp' headers as
+ # the latter have their HPP type derived from H. The type of compilation
+ # is determined entirely by the destination type.
+ generators.register [ new msvc-pch-generator msvc.compile.c.pch : H : C_PCH OBJ : <pch>on <toolset>msvc ] ;
+ generators.register [ new msvc-pch-generator msvc.compile.c++.pch : H : CPP_PCH OBJ : <pch>on <toolset>msvc ] ;
+
+ generators.override msvc.compile.c.pch : pch.default-c-pch-generator ;
+ generators.override msvc.compile.c++.pch : pch.default-cpp-pch-generator ;
     }
-}
 
+ toolset.flags msvc.compile PCH_FILE <pch>on : <pch-file> ;
+ toolset.flags msvc.compile PCH_SOURCE <pch>on : <pch-source> ;
+ toolset.flags msvc.compile PCH_HEADER <pch>on : <pch-header> ;
 
-rule compile.c++.pch ( targets + : sources * : properties * )
-{
- get-rspline $(targets[1]) : -TP ;
- get-rspline $(targets[2]) : -TP ;
- local pch-source = [ on $(<) return $(PCH_SOURCE) ] ;
- if $(pch-source)
- {
- DEPENDS $(<) : $(pch-source) ;
- compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ;
- }
- else
- {
- compile-c-c++-pch $(targets) : $(sources) ;
- }
-}
+ #
+ # Declare flags for compilation.
+ #
+ feature.feature debug-store : object database : propagated ;
 
+ toolset.flags msvc.compile CFLAGS <optimization>speed : /O2 ;
+ toolset.flags msvc.compile CFLAGS <optimization>space : /O1 ;
 
-actions compile.rc
-{
- $(.RC) -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES:W)" -fo "$(<:W)" "$(>:W)"
-}
+ toolset.flags msvc.compile CFLAGS $(.cpu-arch-ia64)/<instruction-set>$(.cpu-type-itanium) : /G1 ;
+ toolset.flags msvc.compile CFLAGS $(.cpu-arch-ia64)/<instruction-set>$(.cpu-type-itanium2) : /G2 ;
 
+ toolset.flags msvc.compile CFLAGS <debug-symbols>on/<debug-store>object : /Z7 ;
+ toolset.flags msvc.compile CFLAGS <debug-symbols>on/<debug-store>database : /Zi ;
+ toolset.flags msvc.compile CFLAGS <optimization>off : /Od ;
+ toolset.flags msvc.compile CFLAGS <inlining>off : /Ob0 ;
+ toolset.flags msvc.compile CFLAGS <inlining>on : /Ob1 ;
+ toolset.flags msvc.compile CFLAGS <inlining>full : /Ob2 ;
 
-# See midl.jam for details.
-TOUCH_FILE = [ common.file-touch-command ] ;
+ toolset.flags msvc.compile CFLAGS <warnings>on : /W3 ;
+ toolset.flags msvc.compile CFLAGS <warnings>off : /W0 ;
+ toolset.flags msvc.compile CFLAGS <warnings>all : /W4 ;
+ toolset.flags msvc.compile CFLAGS <warnings-as-errors>on : /WX ;
 
+ toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>off/<extern-c-nothrow>off : /EHs ;
+ toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>off/<extern-c-nothrow>on : /EHsc ;
+ toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>on/<extern-c-nothrow>off : /EHa ;
+ toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>on/<extern-c-nothrow>on : /EHac ;
 
-actions compile.idl
-{
- $(.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)")"
- $(TOUCH_FILE) "$(<[4]:W)"
- $(TOUCH_FILE) "$(<[5]:W)"
-}
+ # By default 8.0 enables rtti support while prior versions disabled it. We
+ # simply enable or disable it explicitly so we do not have to depend on this
+ # default behaviour.
+ toolset.flags msvc.compile CFLAGS <rtti>on : /GR ;
+ toolset.flags msvc.compile CFLAGS <rtti>off : /GR- ;
+ toolset.flags msvc.compile CFLAGS <runtime-debugging>off/<runtime-link>shared : /MD ;
+ toolset.flags msvc.compile CFLAGS <runtime-debugging>on/<runtime-link>shared : /MDd ;
 
+ toolset.flags msvc.compile CFLAGS <runtime-debugging>off/<runtime-link>static/<threading>multi : /MT ;
+ toolset.flags msvc.compile CFLAGS <runtime-debugging>on/<runtime-link>static/<threading>multi : /MTd ;
 
-# Declare flags and action for the assembler
+ toolset.flags msvc.compile.c OPTIONS <cflags> : ;
+ toolset.flags msvc.compile.c++ OPTIONS <cxxflags> : ;
 
-flags msvc.compile.asm USER_ASMFLAGS <asmflags> : ;
+ toolset.flags msvc.compile PDB_CFLAG <debug-symbols>on/<debug-store>database : /Fd ; # not used yet
 
+ toolset.flags msvc.compile DEFINES <define> ;
+ toolset.flags msvc.compile UNDEFS <undef> ;
+ toolset.flags msvc.compile INCLUDES <include> ;
 
-# For the assembler the following options are turned on by default:
-#
-# -coff generate COFF format object file (compatible with cl.exe output)
-# -Zp4 align structures to 4 bytes
-# -Cp preserve case of user identifiers
-# -Cx preserve case in publics, externs
+ # Declare flags for the assembler.
+ toolset.flags msvc.compile.asm USER_ASMFLAGS <asmflags> ;
 
-actions compile.asm
-{
- $(.ASM) -nologo -c -coff -Zp4 -Cp -Cx $(USER_ASMFLAGS) -Fo "$(<:W)" "$(>:W)"
-}
+ # Declare flags for linking.
+ {
+ toolset.flags msvc.link PDB_LINKFLAG <debug-symbols>on/<debug-store>database : /PDB: ; # not used yet
+ toolset.flags msvc.link LINKFLAGS <debug-symbols>on : /DEBUG ;
+ toolset.flags msvc.link DEF_FILE <def-file> ;
 
+ # The linker disables the default optimizations when using /DEBUG so we
+ # have to enable them manually for release builds with debug symbols.
+ toolset.flags msvc LINKFLAGS <debug-symbols>on/<runtime-debugging>off : /OPT:REF,ICF ;
 
-# Declare flags and action for linking.
-flags msvc.link PDB_LINKFLAG <debug-symbols>on/<debug-store>database : /PDB: ; # not used yet
-flags msvc.link LINKFLAGS <debug-symbols>on : /DEBUG ;
-flags msvc.link DEF_FILE <def-file> ;
-# The linker disables the default optimizations when using /DEBUG. We have to
-# enable them manually for release builds with debug symbols.
-flags msvc LINKFLAGS <debug-symbols>on/<runtime-debugging>off : /OPT:REF,ICF ;
-
-flags msvc LINKFLAGS <user-interface>console : /subsystem:console ;
-flags msvc LINKFLAGS <user-interface>gui : /subsystem:windows ;
-flags msvc LINKFLAGS <user-interface>wince : /subsystem:windowsce ;
-flags msvc LINKFLAGS <user-interface>native : /subsystem:native ;
-flags msvc LINKFLAGS <user-interface>auto : /subsystem:posix ;
-
-flags msvc.link OPTIONS <linkflags> ;
-flags msvc.link LINKPATH <library-path> ;
-
-flags msvc.link FINDLIBS_ST <find-static-library> ;
-flags msvc.link FINDLIBS_SA <find-shared-library> ;
-flags msvc.link LIBRARY_OPTION <toolset>msvc : "" : unchecked ;
-flags msvc.link LIBRARIES_MENTIONED_BY_FILE : <library-file> ;
+ toolset.flags msvc LINKFLAGS <user-interface>console : /subsystem:console ;
+ toolset.flags msvc LINKFLAGS <user-interface>gui : /subsystem:windows ;
+ toolset.flags msvc LINKFLAGS <user-interface>wince : /subsystem:windowsce ;
+ toolset.flags msvc LINKFLAGS <user-interface>native : /subsystem:native ;
+ toolset.flags msvc LINKFLAGS <user-interface>auto : /subsystem:posix ;
 
-flags msvc.archive AROPTIONS <archiveflags> ;
+ toolset.flags msvc.link OPTIONS <linkflags> ;
+ toolset.flags msvc.link LINKPATH <library-path> ;
 
+ toolset.flags msvc.link FINDLIBS_ST <find-static-library> ;
+ toolset.flags msvc.link FINDLIBS_SA <find-shared-library> ;
+ toolset.flags msvc.link LIBRARY_OPTION <toolset>msvc : "" : unchecked ;
+ toolset.flags msvc.link LIBRARIES_MENTIONED_BY_FILE : <library-file> ;
+ }
 
-rule link.dll ( targets + : sources * : properties * )
-{
- DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ;
+ toolset.flags msvc.archive AROPTIONS <archiveflags> ;
 }
 
 
-# Declare action for creating static libraries. If library exists, remove it
-# before adding files. See
-# http://article.gmane.org/gmane.comp.lib.boost.build/4241 for rationale.
-if [ os.name ] in NT
-{
- # The 'DEL' command would issue a message to stdout if the file does not
- # exist, so need a check.
- actions archive
- {
- if exist "$(<[1])" DEL "$(<[1])"
- $(.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")"
- }
-}
-else
+# Locates the requested setup script under the given folder and returns its full
+# path or nothing in case the script can not be found. In case multiple scripts
+# are found only the first one is returned.
+#
+# TODO: There used to exist a code comment for the msvc.init rule stating that
+# we do not correctly detect the location of the vcvars32.bat setup script for
+# the free VC7.1 tools in case user explicitly provides a path. This should be
+# tested or simply remove this whole comment in case this toolset version is no
+# longer important.
+#
+local rule locate-default-setup ( command : parent : setup-name )
 {
- actions archive
+ local result = [ GLOB $(command) $(parent) : $(setup-name) ] ;
+ if $(result[1])
     {
- $(RM) "$(<[1])"
- $(.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")"
+ return $(result[1]) ;
     }
 }
 
 
-# Incremental linking a DLL causes no end of problems: if the actual exports do
-# not change, the import .lib file is never updated. Therefore, the .lib is
-# always out-of-date and gets rebuilt every time. I am not sure that incremental
-# linking is such a great idea in general, but in this case I am sure we do not
-# want it.
-
-# Windows manifest is a new way to specify dependencies on managed DotNet
-# assemblies and Windows native DLLs. The manifests are embedded as resources
-# and are useful in any PE target (both DLL and EXE).
-
-if [ os.name ] in NT
+# Validates given path, registers found configuration and prints debug
+# information about it.
+#
+local rule register-configuration ( version : path ? )
 {
- actions link bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
+ if $(path)
     {
- $(.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")"
- if %ERRORLEVEL% NEQ 0 EXIT %ERRORLEVEL%
- if exist "$(<[1]).manifest" (
- $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);1"
- )
- }
+ local command = [ GLOB $(path) : cl.exe ] ;
 
- actions link.dll bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
- {
- $(.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")"
- if %ERRORLEVEL% NEQ 0 EXIT %ERRORLEVEL%
- if exist "$(<[1]).manifest" (
- $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);2"
- )
- }
-}
-else
-{
- actions link bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
- {
- $(.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")"
- if test -e "$(<[1]).manifest"; then
- $(.MT) -manifest "$(<[1]:W).manifest" "-outputresource:$(<[1]:W);1"
- fi
- }
+ if $(command)
+ {
+ if $(.debug-configuration)
+ {
+ ECHO "notice: msvc-$(version) detected, command: '$(command)'" ;
+ }
 
- actions link.dll bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
- {
- $(.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")"
- if test -e "$(<[1]).manifest"; then
- $(.MT) -manifest "$(<[1]:W).manifest" "-outputresource:$(<[1]:W);2"
- fi
+ $(.versions).register $(version) ;
+ $(.versions).set $(version) : options : <command>$(command) ;
+ }
     }
 }
 
 
-actions compile.mc
+################################################################################
+#
+# Startup code executed when loading this module.
+#
+################################################################################
+
+if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
 {
- $(.MC) $(MCFLAGS) -h "$(<[1]:DW)" -r "$(<[2]:DW)" "$(>:W)"
+ .debug-configuration = true ;
 }
 
+# Miscellaneous constants.
+.RM = [ common.rm-command ] ;
+.nl = "
+" ;
+.ProgramFiles = [ path.make [ common.get-program-files-dir ] ] ;
+.escaped-double-quote = "\"" ;
+.TOUCH_FILE = [ common.file-touch-command ] ;
+
+# List of all registered configurations.
+.versions = [ new configurations ] ;
 
-#
-# Autodetection code
-# detects versions listed as '.known-versions' using registry, environment
-# and checking default paths. Supports both native Windows and Cygwin.
-#
+# Supported CPU architectures.
+.cpu-arch-i386 =
+ <architecture>/<address-model>
+ <architecture>/<address-model>32
+ <architecture>x86/<address-model>
+ <architecture>x86/<address-model>32 ;
+
+.cpu-arch-amd64 =
+ <architecture>/<address-model>64
+ <architecture>x86/<address-model>64 ;
+
+.cpu-arch-ia64 =
+ <architecture>ia64/<address-model>
+ <architecture>ia64/<address-model>64 ;
 
-.ProgramFiles = [ path.make [ common.get-program-files-dir ] ] ;
 
+# Supported CPU types (only Itanium optimization options are supported from
+# VC++ 2005 on). See
+# http://msdn2.microsoft.com/en-us/library/h66s5s0e(vs.90).aspx for more
+# detailed information.
+.cpu-type-g5 = i586 pentium pentium-mmx ;
+.cpu-type-g6 = i686 pentiumpro pentium2 pentium3 pentium3m pentium-m k6
+ k6-2 k6-3 winchip-c6 winchip2 c3 c3-2 ;
+.cpu-type-em64t = prescott nocona conroe conroe-xe conroe-l allendale mermon
+ mermon-xe kentsfield kentsfield-xe penryn wolfdale
+ yorksfield nehalem ;
+.cpu-type-amd64 = k8 opteron athlon64 athlon-fx ;
+.cpu-type-g7 = pentium4 pentium4m athlon athlon-tbird athlon-4 athlon-xp
+ athlon-mp $(.cpu-type-em64t) $(.cpu-type-amd64) ;
+.cpu-type-itanium = itanium itanium1 merced ;
+.cpu-type-itanium2 = itanium2 mckinley ;
+
+
+# Known toolset versions, in order of preference.
 .known-versions = 9.0 9.0express 8.0 8.0express 7.1 7.1toolkit 7.0 6.0 ;
 
-# Version aliases
+# Version aliases.
 .version-alias-6 = 6.0 ;
 .version-alias-6.5 = 6.0 ;
 .version-alias-7 = 7.0 ;
 .version-alias-8 = 8.0 ;
 .version-alias-9 = 9.0 ;
 
-# Name of the registry key that contains Visual C++ installation path
-# (relative to "HKEY_LOCAL_MACHINE\SOFTWARE\\Microsoft").
+# Names of registry keys containing the Visual C++ installation path (relative
+# to "HKEY_LOCAL_MACHINE\SOFTWARE\\Microsoft").
 .version-6.0-reg = "VisualStudio\\6.0\\Setup\\Microsoft Visual C++" ;
 .version-7.0-reg = "VisualStudio\\7.0\\Setup\\VC" ;
 .version-7.1-reg = "VisualStudio\\7.1\\Setup\\VC" ;
@@ -1050,7 +1198,7 @@
 .version-9.0-reg = "VisualStudio\\9.0\\Setup\\VC" ;
 .version-9.0express-reg = "VCExpress\\9.0\\Setup\\VC" ;
 
-# Visual C++ Toolkit 2003 do not store its installation path in the registry.
+# Visual C++ Toolkit 2003 does not store its installation path in the registry.
 # The environment variable 'VCToolkitInstallDir' and the default installation
 # path will be checked instead.
 .version-7.1toolkit-path = "Microsoft Visual C++ Toolkit 2003" "bin" ;
@@ -1061,59 +1209,13 @@
 .version-7.1toolkit-envpath = "bin" ;
 
 
-# Validates given path, registers found configuration and prints debug
-# information about it.
-#
-local rule register-configuration ( version : path ? )
-{
- if $(path)
- {
- local command = [ GLOB $(path) : cl.exe ] ;
-
- if $(command)
- {
- if $(.debug-configuration)
- {
- ECHO "notice: msvc-$(version) detected, command: '$(command)'" ;
- }
-
- $(.versions).register $(version) ;
- $(.versions).set $(version) : options : <command>$(command) ;
- }
- }
-}
-
-if [ os.name ] in NT CYGWIN
-{
- # Get installation paths from the registry.
- for local i in $(.known-versions)
- {
- if $(.version-$(i)-reg)
- {
- local vc-path ;
- for local x in "" "Wow6432Node\\"
- {
- vc-path += [ W32_GETREG
- "HKEY_LOCAL_MACHINE\\SOFTWARE\\"$(x)"\\Microsoft\\"$(.version-$(i)-reg)
- : "ProductDir" ] ;
- }
-
- if $(vc-path)
- {
- vc-path = [ path.native [ path.join [ path.make-NT $(vc-path[1]) ] "bin" ] ] ;
- register-configuration $(i) : $(vc-path[1]) ;
- }
- }
- }
-}
-
+# We try to auto-detect all the available msvc installations on the system
+# directly on module import.
+auto-detect-toolset-versions ;
 
-# Check environment and default installation paths.
 
-for local i in $(.known-versions)
-{
- if ! $(i) in [ $(.versions).all ]
- {
- register-configuration $(i) : [ default-path $(i) ] ;
- }
-}
+# And finally trigger the actual Boost Build toolset registration.
+#
+# TODO: This should later be triggered lazily to avoid registering the toolset
+# in case none of its versions have been configured successfully.
+register-toolset ;


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk