diff options
Diffstat (limited to 'jam-files/boost-build/tools/msvc.jam')
-rw-r--r-- | jam-files/boost-build/tools/msvc.jam | 1392 |
1 files changed, 1392 insertions, 0 deletions
diff --git a/jam-files/boost-build/tools/msvc.jam b/jam-files/boost-build/tools/msvc.jam new file mode 100644 index 00000000..e33a66d2 --- /dev/null +++ b/jam-files/boost-build/tools/msvc.jam @@ -0,0 +1,1392 @@ +# Copyright (c) 2003 David Abrahams. +# Copyright (c) 2005 Vladimir Prus. +# Copyright (c) 2005 Alexey Pakhunov. +# 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 common ; +import errors ; +import feature ; +import generators ; +import mc ; +import midl ; +import os ; +import path ; +import pch ; +import property ; +import rc ; +import toolset ; +import type ; + + +type.register MANIFEST : manifest ; +feature.feature embed-manifest : on off : incidental propagated ; + +type.register PDB : pdb ; + +################################################################################ +# +# Public rules. +# +################################################################################ + +# 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 parameter may be ommited: +# +# using msvc : : Z:/foo/bar/cl.exe ; +# +# 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 +# the possible scenarios: +# +# Nothing "x.y" +# Passed Nothing "x.y" detected, detected, +# version detected detected cl.exe in path cl.exe in path +# +# default Error Use "x.y" Create "default" Use "x.y" +# all None Use all None Use all +# x.y - Use "x.y" - Use "x.y" +# a.b Error Error Create "a.b" Create "a.b" +# +# "x.y" - refers to a detected version; +# "a.b" - refers to an undetected version. +# +# 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 + # explicit version is given will be configured. + version ? + + # The command used to invoke the compiler. If not specified: + # - if version is given, default location for that version will be + # searched + # + # - if version is not given, default locations for MSVC 9.0, 8.0, 7.1, 7.0 + # and 6.* will be searched + # + # - if compiler is not found in the default locations, PATH will be + # searched. + : command * + + # Options may include: + # + # All options shared by multiple toolset types as handled by the + # common.handle-options() rule, e.g. <cflags>, <compileflags>, <cxxflags>, + # <fflags> & <linkflags>. + # + # <assembler> + # <compiler> + # <idl-compiler> + # <linker> + # <mc-compiler> + # <resource-compiler> + # Exact tool names to be used by this msvc toolset configuration. + # + # <compiler-filter> + # Command through which to pipe the output of running the compiler. + # For example to pass the output to STLfilt. + # + # <setup> + # Global setup command to invoke before running any of the msvc tools. + # It will be passed additional option parameters depending on the actual + # target platform. + # + # <setup-amd64> + # <setup-i386> + # <setup-ia64> + # Platform specific setup command to invoke before running any of the + # msvc tools used when builing a target for a specific platform, e.g. + # when building a 32 or 64 bit executable. + : options * +) +{ + if $(command) + { + 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. See the 'init' rule comment for more detailed +# information. +# +rule configure ( version ? : options * ) +{ + switch $(version) + { + case "all" : + if $(options) + { + errors.error "MSVC toolset configuration: options should be" + "empty when '$(version)' is specified." ; + } + + # Configure (i.e. mark as used) all registered versions. + local all-versions = [ $(.versions).all ] ; + if ! $(all-versions) + { + if $(.debug-configuration) + { + ECHO "notice: [msvc-cfg] Asked to configure all registered" + "msvc toolset versions when there are none currently" + "registered." ; + } + } + else + { + 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) ; + } + } + + case "default" : + configure-really : $(options) ; + + case * : + configure-really $(version) : $(options) ; + } +} + + +# 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. + 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 ; + + # Specify target machine type so the linker will not need to guess. + toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-amd64) : /MACHINE:X64 ; + toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-i386) : /MACHINE:X86 ; + toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-ia64) : /MACHINE:IA64 ; + + # Make sure that manifest will be generated even if there is no + # dependencies to put there. + toolset.flags $(toolset).link LINKFLAGS $(conditions)/<embed-manifest>off : /MANIFEST ; + } + toolset.pop-checking-for-flags-module ; +} + + +# Registers this toolset including all of its flags, features & generators. Does +# nothing on repeated calls. +# +rule register-toolset ( ) +{ + if ! msvc in [ feature.values toolset ] + { + register-toolset-really ; + } +} + + +# 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 +{ + actions archive + { + $(.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")" + } +} + + +# For the assembler the following options are turned on by default: +# +# -Zp4 align structures to 4 bytes +# -Cp preserve case of user identifiers +# -Cx preserve case in publics, externs +# +actions compile.asm +{ + $(.ASM) -c -Zp4 -Cp -Cx -D$(DEFINES) $(ASMFLAGS) $(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.preprocess ( targets + : sources * : properties * ) +{ + C++FLAGS on $(targets[1]) = ; + get-rspline $(targets) : -TC ; + preprocess-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) + { + DEPENDS $(<) : $(pch-source) ; + compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ; + } + else + { + compile-c-c++-pch $(targets) : $(sources) ; + } +} + +toolset.flags msvc YLOPTION : "-Yl" ; + +# Action for running the C/C++ compiler without using precompiled headers. +# +# WARNING: Synchronize any changes this in action with intel-win +# +# Notes regarding PDB generation, for when we use <debug-symbols>on/<debug-store>database +# +# 1. PDB_CFLAG is only set for <debug-symbols>on/<debug-store>database, ensuring that the /Fd flag is dropped if PDB_CFLAG is empty +# +# 2. When compiling executables's source files, PDB_NAME is set on a per-source file basis by rule compile-c-c++. +# The linker will pull these into the executable's PDB +# +# 3. When compiling library's source files, PDB_NAME is updated to <libname>.pdb for each source file by rule archive, +# as in this case the compiler must be used to create a single PDB for our library. +# +actions compile-c-c++ bind PDB_NAME +{ + $(.CC) @"@($(<[1]:W).rsp:E="$(>[1]:W)" -Fo"$(<[1]:W)" $(PDB_CFLAG)"$(PDB_NAME)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))" $(.CC.FILTER) +} + +actions preprocess-c-c++ bind PDB_NAME +{ + $(.CC) @"@($(<[1]:W).rsp:E="$(>[1]:W)" -E $(PDB_CFLAG)"$(PDB_NAME)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))" >"$(<[1]:W)" +} + +rule compile-c-c++ ( targets + : sources * ) +{ + DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_HEADER) ] ; + DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_FILE) ] ; + PDB_NAME on $(<) = $(<:S=.pdb) ; +} + +rule preprocess-c-c++ ( targets + : sources * ) +{ + DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_HEADER) ] ; + DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_FILE) ] ; + PDB_NAME on $(<) = $(<:S=.pdb) ; +} + +# 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=)" $(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) +} + + +# 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=)" $(YLOPTION)"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))" $(.CC.FILTER) +} + + +rule compile.c++ ( targets + : sources * : properties * ) +{ + get-rspline $(targets) : -TP ; + compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ; +} + +rule compile.c++.preprocess ( targets + : sources * : properties * ) +{ + get-rspline $(targets) : -TP ; + preprocess-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(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) ; + } +} + + +# 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 ( targets + : sources * : properties * ) +{ + if <embed-manifest>on in $(properties) + { + msvc.manifest $(targets) : $(sources) : $(properties) ; + } +} + +rule link.dll ( targets + : sources * : properties * ) +{ + DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ; + if <embed-manifest>on in $(properties) + { + msvc.manifest.dll $(targets) : $(sources) : $(properties) ; + } +} + +# 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% + } + + actions manifest + { + 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% + } + + actions manifest.dll + { + 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")" + } + + actions manifest + { + 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")" + } + + actions manifest.dll + { + if test -e "$(<[1]).manifest"; then + $(.MT) -manifest "$(<[1]:W).manifest" "-outputresource:$(<[1]:W);2" + fi + } +} + +# this rule sets up the pdb file that will be used when generating static +# libraries and the debug-store option is database, so that the compiler +# puts all debug info into a single .pdb file named after the library +# +# Poking at source targets this way is probably not clean, but it's the +# easiest approach. +rule archive ( targets + : sources * : properties * ) +{ + PDB_NAME on $(>) = $(<:S=.pdb) ; +} + +################################################################################ +# +# 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 configuration: 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 10)" : $(command) ] + { + version = 10.0 ; + } + else if [ MATCH "(Microsoft Visual Studio 9)" : $(command) ] + { + version = 9.0 ; + } + else 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) + { + # TODO: Note that if we specify a non-existant toolset version then + # this rule may find and use a corresponding compiler executable + # belonging to an incorrect toolset version. For example, if you + # have only MSVC 7.1 installed, have its executable on the path and + # specify you want Boost Build to use MSVC 9.0, then you want Boost + # Build to report an error but this may cause it to silently use the + # MSVC 7.1 compiler even though it thinks it is using the msvc-9.0 + # toolset version. + command = [ common.get-absolute-tool-path $(command[-1]) ] ; + } + + if $(command) + { + local parent = [ path.make $(command) ] ; + parent = [ path.parent $(parent) ] ; + parent = [ path.native $(parent) ] ; + + # Setup will be used if the command name has been specified. If + # setup is not specified explicitly then a default setup script will + # be used instead. Setup scripts may be global or arhitecture/ + # /platform/cpu specific. Setup options are used only in case of + # global setup scripts. + + # Default setup scripts provided with different VC distributions: + # + # VC 7.1 had only the vcvars32.bat script specific to 32 bit i386 + # builds. It was located in the bin folder for the regular version + # and in the root folder for the free VC 7.1 tools. + # + # Later 8.0 & 9.0 versions introduce separate platform specific + # vcvars*.bat scripts (e.g. 32 bit, 64 bit AMD or 64 bit Itanium) + # located in or under the bin folder. Most also include a global + # vcvarsall.bat helper script located in the root folder which runs + # one of the aforementioned vcvars*.bat scripts based on the options + # passed to it. So far only the version coming with some PlatformSDK + # distributions does not include this top level script but to + # support those we need to fall back to using the worker scripts + # directly in case the top level script can not be found. + + local global-setup = [ feature.get-values <setup> : $(options) ] ; + global-setup = $(global-setup[1]) ; + if ! $(below-8.0) + { + global-setup ?= [ locate-default-setup $(command) : $(parent) : + vcvarsall.bat ] ; + } + + local default-setup-amd64 = vcvarsx86_amd64.bat ; + local default-setup-i386 = vcvars32.bat ; + local default-setup-ia64 = vcvarsx86_ia64.bat ; + + # http://msdn2.microsoft.com/en-us/library/x4d2c09s(VS.80).aspx and + # http://msdn2.microsoft.com/en-us/library/x4d2c09s(vs.90).aspx + # mention an x86_IPF option, that seems to be a documentation bug + # and x86_ia64 is the correct option. + local default-global-setup-options-amd64 = x86_amd64 ; + local default-global-setup-options-i386 = x86 ; + local default-global-setup-options-ia64 = x86_ia64 ; + + # When using 64-bit Windows, and targeting 64-bit, it is possible to + # use a native 64-bit compiler, selected by the "amd64" & "ia64" + # parameters to vcvarsall.bat. There are two variables we can use -- + # PROCESSOR_ARCHITECTURE and PROCESSOR_IDENTIFIER. The first is + # 'x86' when running 32-bit Windows, no matter which processor is + # used, and 'AMD64' on 64-bit windows on x86 (either AMD64 or EM64T) + # Windows. + # + if [ MATCH ^(AMD64) : [ os.environ PROCESSOR_ARCHITECTURE ] ] + { + default-global-setup-options-amd64 = amd64 ; + } + # TODO: The same 'native compiler usage' should be implemented for + # the Itanium platform by using the "ia64" parameter. For this + # though we need someone with access to this platform who can find + # out how to correctly detect this case. + else if $(somehow-detect-the-itanium-platform) + { + default-global-setup-options-ia64 = ia64 ; + } + + local setup-prefix = "call " ; + local setup-suffix = " >nul"$(.nl) ; + if ! [ os.name ] in NT + { + setup-prefix = "cmd.exe /S /C call " ; + setup-suffix = " \">nul\" \"&&\" " ; + } + + for local c in $(cpu) + { + local setup-options ; + + setup-$(c) = [ feature.get-values <setup-$(c)> : $(options) ] ; + + if ! $(setup-$(c))-is-not-empty + { + if $(global-setup)-is-not-empty + { + setup-$(c) = $(global-setup) ; + + # If needed we can easily add using configuration flags + # here for overriding which options get passed to the + # global setup command for which target platform: + # setup-options = [ feature.get-values <setup-options-$(c)> : $(options) ] ; + + setup-options ?= $(default-global-setup-options-$(c)) ; + } + else + { + setup-$(c) = [ locate-default-setup $(command) : $(parent) : $(default-setup-$(c)) ] ; + } + } + + # Cygwin to Windows path translation. + setup-$(c) = "\""$(setup-$(c):W)"\"" ; + + # Append setup options to the setup name and add the final setup + # prefix & suffix. + setup-options ?= "" ; + setup-$(c) = $(setup-prefix)$(setup-$(c):J=" ")" "$(setup-options:J=" ")$(setup-suffix) ; + } + } + + # Get tool names (if any) and finish setup. + + compiler = [ feature.get-values <compiler> : $(options) ] ; + compiler ?= cl ; + + linker = [ feature.get-values <linker> : $(options) ] ; + linker ?= link ; + + resource-compiler = [ feature.get-values <resource-compiler> : $(options) ] ; + resource-compiler ?= rc ; + + # Turn on some options for i386 assembler + # -coff generate COFF format object file (compatible with cl.exe output) + local default-assembler-amd64 = ml64 ; + local default-assembler-i386 = "ml -coff" ; + local default-assembler-ia64 = ias ; + + assembler = [ feature.get-values <assembler> : $(options) ] ; + + idl-compiler = [ feature.get-values <idl-compiler> : $(options) ] ; + idl-compiler ?= midl ; + + mc-compiler = [ feature.get-values <mc-compiler> : $(options) ] ; + mc-compiler ?= mc ; + + manifest-tool = [ feature.get-values <manifest-tool> : $(options) ] ; + manifest-tool ?= mt ; + + local cc-filter = [ feature.get-values <compiler-filter> : $(options) ] ; + + for local c in $(cpu) + { + # Setup script is not required in some configurations. + setup-$(c) ?= "" ; + + local cpu-conditions = $(conditions)/$(.cpu-arch-$(c)) ; + + if $(.debug-configuration) + { + for local cpu-condition in $(cpu-conditions) + { + ECHO "notice: [msvc-cfg] condition: '$(cpu-condition)', setup: '$(setup-$(c))'" ; + } + } + + local cpu-assembler = $(assembler) ; + cpu-assembler ?= $(default-assembler-$(c)) ; + + toolset.flags msvc.compile .CC $(cpu-conditions) : $(setup-$(c))$(compiler) /Zm800 -nologo ; + toolset.flags msvc.compile .RC $(cpu-conditions) : $(setup-$(c))$(resource-compiler) ; + toolset.flags msvc.compile .ASM $(cpu-conditions) : $(setup-$(c))$(cpu-assembler) -nologo ; + toolset.flags msvc.link .LD $(cpu-conditions) : $(setup-$(c))$(linker) /NOLOGO /INCREMENTAL:NO ; + toolset.flags msvc.archive .LD $(cpu-conditions) : $(setup-$(c))$(linker) /lib /NOLOGO ; + toolset.flags msvc.compile .IDL $(cpu-conditions) : $(setup-$(c))$(idl-compiler) ; + toolset.flags msvc.compile .MC $(cpu-conditions) : $(setup-$(c))$(mc-compiler) ; + + toolset.flags msvc.link .MT $(cpu-conditions) : $(setup-$(c))$(manifest-tool) -nologo ; + + if $(cc-filter) + { + toolset.flags msvc .CC.FILTER $(cpu-conditions) : "|" $(cc-filter) ; + } + } + + # Set version-specific flags. + configure-version-specific msvc : $(version) : $(conditions) ; + } +} + + +# 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 ] ] ; + + if $(path) + { + path = $(path:D) ; + } + else + { + # Check environment. + if $(.version-$(version)-env) + { + local vc-path = [ os.environ $(.version-$(version)-env) ] ; + if $(vc-path) + { + 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) +# +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) ] ; + } + } + + return $(possible-paths) ; +} + + +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)\" ] ; +} + +class msvc-linking-generator : linking-generator +{ + # Calls the base version. If necessary, also create a target for the + # manifest file.specifying source's name as the name of the created + # target. As result, the PCH will be named whatever.hpp.gch, and not + # whatever.gch. + rule generated-targets ( sources + : property-set : project name ? ) + { + local result = [ linking-generator.generated-targets $(sources) + : $(property-set) : $(project) $(name) ] ; + + if $(result) + { + local name-main = [ $(result[0]).name ] ; + local action = [ $(result[0]).action ] ; + + if [ $(property-set).get <debug-symbols> ] = "on" + { + # We force exact name on PDB. The reason is tagging -- the tag rule may + # reasonably special case some target types, like SHARED_LIB. The tag rule + # will not catch PDB, and it cannot even easily figure if PDB is paired with + # SHARED_LIB or EXE or something else. Because PDB always get the + # same name as the main target, with .pdb as extension, just force it. + local target = [ class.new file-target $(name-main:S=.pdb) exact : PDB : $(project) : $(action) ] ; + local registered-target = [ virtual-target.register $(target) ] ; + if $(target) != $(registered-target) + { + $(action).replace-targets $(target) : $(registered-target) ; + } + result += $(registered-target) ; + } + + if [ $(property-set).get <embed-manifest> ] = "off" + { + # Manifest is evil target. It has .manifest appened to the name of + # main target, including extension. E.g. a.exe.manifest. We use 'exact' + # name because to achieve this effect. + local target = [ class.new file-target $(name-main).manifest exact : MANIFEST : $(project) : $(action) ] ; + local registered-target = [ virtual-target.register $(target) ] ; + if $(target) != $(registered-target) + { + $(action).replace-targets $(target) : $(registered-target) ; + } + result += $(registered-target) ; + } + } + return $(result) ; + } +} + + + +# Unsafe worker rule for the register-toolset() rule. Must not be called +# multiple times. +# +local rule register-toolset-really ( ) +{ + feature.extend toolset : msvc ; + + # Intel and msvc supposedly have link-compatible objects. + feature.subfeature toolset msvc : vendor : intel : propagated optional ; + + # 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 ; + + # Declare msvc toolset specific features. + { + feature.feature debug-store : object database : propagated ; + feature.feature pch-source : : dependency free ; + } + + # 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 [ new msvc-linking-generator + msvc.link : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : EXE : <toolset>msvc ] ; + generators.register [ new msvc-linking-generator + 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 ; + generators.register-c-compiler msvc.compile.c++.preprocess : CPP : PREPROCESSED_CPP : <toolset>msvc ; + generators.register-c-compiler msvc.compile.c.preprocess : C : PREPROCESSED_C : <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 ; + + # 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> ; + + # + # Declare flags for compilation. + # + + toolset.flags msvc.compile CFLAGS <optimization>speed : /O2 ; + toolset.flags msvc.compile CFLAGS <optimization>space : /O1 ; + + 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 ; + + 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 ; + + # 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 ; + + toolset.flags msvc.compile OPTIONS <cflags> : ; + toolset.flags msvc.compile.c++ OPTIONS <cxxflags> : ; + + toolset.flags msvc.compile PDB_CFLAG <debug-symbols>on/<debug-store>database : /Fd ; + + toolset.flags msvc.compile DEFINES <define> ; + toolset.flags msvc.compile UNDEFS <undef> ; + toolset.flags msvc.compile INCLUDES <include> ; + + # Declare flags for the assembler. + toolset.flags msvc.compile.asm USER_ASMFLAGS <asmflags> ; + + toolset.flags msvc.compile.asm ASMFLAGS <debug-symbols>on : "/Zi /Zd" ; + + toolset.flags msvc.compile.asm ASMFLAGS <warnings>on : /W3 ; + toolset.flags msvc.compile.asm ASMFLAGS <warnings>off : /W0 ; + toolset.flags msvc.compile.asm ASMFLAGS <warnings>all : /W4 ; + toolset.flags msvc.compile.asm ASMFLAGS <warnings-as-errors>on : /WX ; + + toolset.flags msvc.compile.asm DEFINES <define> ; + + # 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 ; + + 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 ; + + 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> ; + } + + toolset.flags msvc.archive AROPTIONS <archiveflags> ; +} + + +# 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 ) +{ + local result = [ GLOB $(command) $(parent) : $(setup-name) ] ; + if $(result[1]) + { + return $(result[1]) ; + } +} + + +# 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-cfg] msvc-$(version) detected, command: '$(command)'" ; + } + + $(.versions).register $(version) ; + $(.versions).set $(version) : options : <command>$(command) ; + } + } +} + + +################################################################################ +# +# Startup code executed when loading this module. +# +################################################################################ + +if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ] +{ + .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 ] ; + +# 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 ; + + +# 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 = 10.0 10.0express 9.0 9.0express 8.0 8.0express 7.1 7.1toolkit 7.0 6.0 ; + +# 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 ; +.version-alias-10 = 10.0 ; + +# 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" ; +.version-8.0-reg = "VisualStudio\\8.0\\Setup\\VC" ; +.version-8.0express-reg = "VCExpress\\8.0\\Setup\\VC" ; +.version-9.0-reg = "VisualStudio\\9.0\\Setup\\VC" ; +.version-9.0express-reg = "VCExpress\\9.0\\Setup\\VC" ; +.version-10.0-reg = "VisualStudio\\10.0\\Setup\\VC" ; +.version-10.0express-reg = "VCExpress\\10.0\\Setup\\VC" ; + +# 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" ; +.version-7.1toolkit-env = VCToolkitInstallDir ; + +# Path to the folder containing "cl.exe" relative to the value of the +# corresponding environment variable. +.version-7.1toolkit-envpath = "bin" ; + + +# Auto-detect all the available msvc installations on the system. +auto-detect-toolset-versions ; + + +# And finally trigger the actual Boost Build toolset registration. +register-toolset ; |