Boost logo

Boost-Build :

From: Andrey Melnikov (melnikov_at_[hidden])
Date: 2005-07-12 11:00:57


- RegEx slash escaping
- Path without \bin is created only for msvc-7.1
- 8.0 autodetection using VS80COMNTOOLS
- Windows Side-By-Side manifests aren't used on versions other than 8.0
- Windows Side-By-Side manifests are used for EXE files
- alternate grouping for pre-8.0 optimization switches
- conformance switches are used for 8.0 too

I expect someone (hopefully Vladimir Prus) to get a diff against the
latest CVS, review the changes and submit them.

Andrey
 --------------000006090106060805060305 Content-Type: text/plain;
name="msvc.jam"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="msvc.jam"

# Copyright David Abrahams 2003. Permission to copy, use,
# modify, sell and distribute this software is granted provided this
# copyright notice appears in all copies. This software is provided
# "as is" without express or implied warranty, and with no claim as
# to its suitability for any purpose.
import property ;
import generators ;
import os ;
import type ;
import toolset : flags ;
import errors : error ;
import feature : feature get-values ;
import path ;
import sequence : unique ;
import common ;

import rc ;

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 ;-)
;

RM = [ common.rm-command ] ;

# 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::
#
# using msvc : 6.5 : X:/some_dir ;
# using msvc : 7.0 : Y:/some_dir ;
# using msvc : : Z:/some_dir
#
# If you have "msvc-6.5" in build request, the version from X: drive will be used,
# and if you put only "msvc", then drive "Z:" will be used. Note that it's not possible
# the specify that by default, version 7.0 must be used --- you should use 'using'
# without version number for that effect.
#
# version --
# path --
#
# When invoking tools, we'll first run vcvars32.bat from the configured path and
# then cl/link, without path.
#
# Note: for free VC7.1 tools, we don't correctly find vcvars32.bar when user
# explicitly provides a path.
rule init (
version ? # the msvc version which is being configured. When omitted
# the tools invoked when no explicit version is given will be configured.
: command *
# the command 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 7.1, 7.0 and 6.* will
# be searched
#
# - if compiler is not found in default locations, PATH will be searched.
: options *
# options can include <setup>, <compiler>, <linker> and <resource-compiler>
)
{
# setup will be used if a path has been specified. If setup is
# not specified, vcvars32.bat will be used instead.
setup = [ get-values <setup> : $(options) ] ;
setup ?= vcvars32.bat ;
compiler = [ get-values <compiler> : $(options) ] ;
compiler ?= cl ;
linker = [ get-values <linker> : $(options) ] ;
linker ?= link ;
resource-compiler = [ get-values <resource-compiler> : $(options) ] ;
resource-compiler ?= rc ;

local condition = [ common.check-init-parameters msvc :
version $(version) ] ;

# 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 : $(condition) : $(command) : $(options) ;

if $(command)
{
command = [ common.get-absolute-tool-path $(command[-1]) ] ;
}
local root = $(command:D) ;

setup = $(root)\\bin\\$(setup) ;

# CONSIDER: What's the point of 'call'. Can we invoke the script directly?
setup = "call \""$(setup)"\" > nul " ;

if [ os.name ] = NT
{
setup = $(setup)"
" ;
}
else
{
setup = "cmd /S /C "$(setup)" \"&&\" " ;
}

# prefix with setup, or quoted path if any
local prefix = $(setup) ;

flags msvc.compile .CC $(condition) : $(prefix)$(compiler) ;
flags msvc.compile .RC $(condition) : $(prefix)$(resource-compiler) ;
flags msvc.link .LD $(condition) : $(prefix)$(linker) ;
flags msvc.archive .LD $(condition) : $(prefix)$(linker) ;

if ! $(version)
{
# Even if version is not explicitly specified, try to detect the version
# from the path.
if [ MATCH "(Microsoft Visual Studio 8)" : $(command) ]
{
version = 8.0 ;
}
else if [ MATCH "(NET 2003[\/\\\\]VC7)" : $(command) ] ||
[ MATCH "(Microsoft Visual C\\+\\+ Toolkit 2003)" : $(command) ]
{
version = 7.1 ;
}
else if [ MATCH "(.NET[\/\\\\]VC7)" : $(command) ]
{
version = 7.0 ;
}
else
{
version = 6.0 ;
}
}
# 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're 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.* (this is checked above).
if [ MATCH ^([78]\..*) : $(version) ]
{
flags msvc.compile CFLAGS $(condition) : /Zc:forScope /Zc:wchar_t ;
}

# 8.0 deprecates some of the options
if $(version) = "8.0"
{
flags msvc.link MANIFEST $(condition) : "mt -nologo -manifest " ;
flags msvc.link OUTPUTRESOURCE $(condition) : "-outputresource:" ;
}
else
{
flags msvc.compile CFLAGS $(condition)/<optimization>speed $(condition)/<optimization>space : /Ogiy /Gs ;
flags msvc.compile CFLAGS $(condition)/<optimization>speed : /Ot ;
flags msvc.compile CFLAGS $(condition)/<optimization>space : /Os ;
}
}

rule default-paths ( version ? )
{
local possible-paths ;

local ProgramFiles = [ modules.peek : ProgramFiles ] ;
if $(ProgramFiles)
{
ProgramFiles = "$(ProgramFiles:J= )" ;
}
else
{
ProgramFiles = "c:\\Program Files" ;
}

local version-6-path = $(ProgramFiles)"\\Microsoft Visual Studio\\VC98" ;
local version-7-path = $(ProgramFiles)"\\Microsoft Visual Studio .NET\\VC7" ;
local version-7.0-path = $(version-7-path) ;
local version-7.1-path = $(ProgramFiles)"\\Microsoft Visual Studio .NET 2003\\VC7" ;
local version-8.0-path = $(ProgramFiles)"\\Microsoft Visual Studio 8" ;

local VS71COMNTOOLS = [ modules.peek : VS71COMNTOOLS ] ;
if $(VS71COMNTOOLS)
{
# VS71COMNTOOLS is set by VS .NET 2003 to <VSDIR>\Common7\Tools
version-7.1-path = [ path.make "$(VS71COMNTOOLS:J= )" ] ;
version-7.1-path = [ path.parent $(version-7.1-path) ] ;
version-7.1-path = [ path.parent $(version-7.1-path) ] ;
version-7.1-path = [ path.join $(version-7.1-path) "VC7" ] ;
version-7.1-path = [ path.native $(version-7.1-path) ] ;
}

local VS80COMNTOOLS = [ modules.peek : VS80COMNTOOLS ] ;

if $(VS80COMNTOOLS)
{
# VS80COMNTOOLS is set by VS .NET 2005 to <VSDIR>\Common7\Tools
version-8.0-path = [ path.make "$(VS80COMNTOOLS:J= )" ] ;
version-8.0-path = [ path.parent $(version-8.0-path) ] ;
version-8.0-path = [ path.parent $(version-8.0-path) ] ;
version-8.0-path = [ path.join $(version-8.0-path) "VC" ] ;
version-8.0-path = [ path.native $(version-8.0-path) ] ;

}

# Change by Andrey Melnikov
# Fixed so we don't add paths without \\bin to all versions.
# Path without 7.1

if $(version)
{
local v = [ MATCH ^(6|[^6].*) : $(version) ] ;
possible-paths += $(version-$(v)-path) ;
}
else
{
possible-paths += $(version-8.0-path) $(version-7.1-path) $(version-7.0-path) $(version-6-path) ;
}

# The vccars32.bat is actually in "bin" directory.
# (except for free VC7.1 tools)
possible-paths = $(possible-paths)\\bin ;

local VCToolkitInstallDir = [ modules.peek : VCToolkitInstallDir ] ;
if $(VCToolkitInstallDir)
{

if $(version) = "7.1"
{
VCToolkitInstallDir = [ path.native [ path.make "$(VCToolkitInstallDir:J= )" ] ] ;
# NOTE it's impossible to switch between Toolkit and VS.
# I wonder is toolkit and VS can be installed together?

possible-paths += ;
}
if ! $(version)
{
possible-paths += [ path.make "$(VCToolkitInstallDir:J= )" ] ;
}

}
else
{
possible-paths += [ path.parent $(version-7.1-path) ] ;
}

return $(possible-paths) ;
}

# Declare generators

# is it possible to combine these?
# make the generators non-composing, so that they don't convert each source
# into 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 ;
generators.register-standard msvc.compile.rc : RC : OBJ(%_res) : <toolset>msvc ;
generators.override msvc.compile.rc : rc.resource-compile ;

#
# 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 <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 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 ;

flags msvc.compile CFLAGS <rtti>on : /GR ;
flags msvc.compile CFLAGS <runtime-debugging>off/<runtime-link>shared : /MD ;
flags msvc.compile CFLAGS <runtime-debugging>on/<runtime-link>shared : /MDd ;

flags msvc.compile CFLAGS <runtime-debugging>off/<runtime-link>static/<threading>single : /ML ;
flags msvc.compile CFLAGS <runtime-debugging>on/<runtime-link>static/<threading>single : /MLd ;
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 ;

flags msvc.compile USER_CFLAGS <cflags> : ;
flags msvc.compile.c++ USER_CFLAGS <cxxflags> : ;

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> ;

flags msvc.compile.c++ C++FLAGS : /wd4675 ;

# The actions differ only by explicit selection of input language
actions compile.c bind RSP
{
$(.CC) /Zm800 -nologo -TC -U$(UNDEFS) $(CFLAGS) $(USER_CFLAGS) @"$(RSP:W)" -c -Fo"$(<[1]:W)" && $(RM) "$(RSP)"
}
actions compile.c++ bind RSP
{
$(.CC) /Zm800 -nologo -TP -U$(UNDEFS) $(CFLAGS) $(C++FLAGS) $(USER_CFLAGS) @"$(RSP:W)" -c -Fo"$(<[1]:W)" && $(RM) "$(RSP)"
}

actions compile.rc
{
$(.RC) -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES)" -fo "$(<:W)" "$(>:W)"
}

# 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. Whe 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 LINKFLAGS <main-target-type>LIB/<link>shared : /DLL ;

toolset.flags msvc.link USER_LINKFLAGS <linkflags> ;
toolset.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 ;

rule archive ( targets + : sources * : properties * )
{
common.response-file $(targets) : $(sources) : $(targets[2]) : $(properties) ;
}

rule link ( targets + : sources * : properties * )
{
common.response-file $(targets) : $(sources) : $(targets[2])
: $(properties) ;
}

rule link.dll ( targets + : sources * : properties * )
{
common.response-file $(targets) : $(sources) : $(targets[3]) : $(properties) ;
DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ;
}

# 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 bind RSP
{
if exist "$(<[1])" DEL "$(<[1])"
$(.LD) /lib /NOLOGO /out:"$(<[1])" @"$(RSP)" && $(RM) "$(RSP)"
}
}
else
{
actions archive bind RSP
{
$(RM) "$(<[1])"
$(.LD) /lib /NOLOGO /out:"$(<[1])" @"$(RSP)" && $(RM) "$(RSP)"
}
}

# incremental linking a DLL causes no end of problems: if the
# actual exports don't change, the import .lib file is never
# updated. Therefore, the .lib is always out-of-date and gets
# rebuilt every time. I'm not sure that incremental linking is
# such a great idea in general, but in this case I'm sure we
# don't want it.
actions link bind DEF_FILE RSP
{
$(.LD) /NOLOGO $(LINKFLAGS) /out:"$(<[1]:W)" /INCREMENTAL:NO /LIBPATH:"$(LINKPATH:W)" $(USER_LINKFLAGS) @"$(RSP:W)" && $(RM) "$(RSP)"
$(MANIFEST)$(<[1]).manifest $(OUTPUTRESOURCE)$(<[1]);#2
}

actions link.dll bind DEF_FILE RSP
{

$(.LD) /NOLOGO $(LINKFLAGS) /out:"$(<[1]:W)" /INCREMENTAL:NO /IMPLIB:"$(<[2]:W)" /LIBPATH:"$(LINKPATH:W)" /def:$(DEF_FILE) $(USER_LINKFLAGS) @"$(RSP:W)" && $(RM) "$(RSP)"
$(MANIFEST)$(<[1]).manifest $(OUTPUTRESOURCE)$(<[1]);#2
}

rule compile.c++ ( targets + : sources * : properties * )
{
common.response-file $(targets) : $(sources) : $(response-file) : $(properties) ;
}

rule compile.c ( targets + : sources * : properties * )
{
common.response-file $(targets) : $(sources) : $(targets[2]) : $(properties) ;
}

 --------------000006090106060805060305--


Boost-Build 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