📄 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 ;
import path ;
import sequence : unique ;
import common ;
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 ;-)
;
feature.subfeature toolset msvc : version
: # 6 7 7.1 # known subvalues
: propagated implicit
# versions of msvc are link-compatible
# link-incompatible
;
# Remember whether any versions have been initialized, allowing us to
# set the first initialized version as the default.
.initialized = ;
# 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.
rule init (
version ? # the msvc version which is being configured. When omitted
# the tools invoked when no explicit version is given will be configured.
: path ?
# the path to root directory of msvc installation. 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.
: vendor ? : setup ? compiler ? linker ? )
{
compiler ?= cl ;
linker ?= link ;
if $(version)
{
feature.extend <toolset>msvc version : $(version) ;
if ! $(.initialized) # The first version initialized becomes the default.
{
feature.set-default toolset-msvc:version : $(version) ;
}
}
if $(vendor) && ( $(vendor) != intel )
{
feature.extend <toolset>msvc vendor : $(vendor) ;
}
# setup will be used iff a path has been specified. If setup is
# not specified, vcvars32.bat will be used instead.
setup ?= vcvars32.bat ;
if ! $(path)
{
setup = [ locate $(setup) : $(version) : $(vendor) ] ;
}
else
{
# Don't bother with any searches. User has provided a path,
# and we assume it's correct.
# TODO: actually, it's better to check the path even in this
# case.
setup = $(path)\\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) ;
if $(version)
{
vendor = $(vendor)- ;
vendor ?= "" ;
local condition = -$(vendor)$(version) ;
condition ?= "" ;
condition = <toolset>msvc$(condition) ;
flags msvc.compile .CC $(condition) : $(prefix)$(compiler) ;
flags msvc.link .LD $(condition) : $(prefix)$(linker) ;
flags msvc.archive .LD $(condition) : $(prefix)$(linker) ;
}
else
{
# When version is not specified, we cannot form any useful
# condition. Since subfeatures don't have defaults, we can't
# use 'unspecified' as version. Therefore, just set global
# variables in this module.
.CC = $(prefix)$(compiler) ;
.LD = $(prefix)$(linker) ;
}
.initialized = true ; # remember that we've initialized at least one version of msvc
}
.CC = cl ;
.LD = LINK ;
# Attempts to find the vcvars32.bat script for the relevant version, and returns the path
# to it. If path is not found, issues an error.
# If there are several possibilities, returns arbitrary one, after issuing a
# warning message.
local rule locate ( setup : version ? : vendor ? )
{
local possible-paths ;
# Append the list of relevant default locations.
# We know default locations only for msvc, not for alternative vendors
if ! $(vendor)
{
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 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) ] ;
}
if $(version)
{
local v = [ MATCH ^(6|[^6].*) : $(version) ] ;
possible-paths += $(version-$(v)-path) ;
}
else
{
possible-paths += $(version-7.1-path) $(version-7.0-path) $(version-6-path) ;
}
# The vccars32.bat is actually in "bin" directory.
possible-paths = $(possible-paths)\\bin ;
}
# Append PATH
possible-paths += [ modules.peek : PATH Path path ] ;
# Search now
local setup = [ GLOB $(possible-paths) : $(setup) ] ;
# Try to avoid reporting ambiguity when there's several occurences
# of the same path, probably differing by case.
setup = [ unique $(setup:L) ] ;
if $(setup[2]) && ! ( --quiet in [ modules.peek : ARGV ] )
{
ECHO warning: toolset msvc $(vendor) $(version) initialization: ;
ECHO "warning: several msvc installations found." ;
ECHO "$(setup:D)" ;
ECHO "warning: using the one in $(setup[1]:D)." ;
setup = $(setup[1]) ;
}
if ! $(setup)
{
ECHO warning: toolset msvc $(vendor) $(version) initialization: ;
ECHO warning: couldn't find compiler ;
if $(.debug-configuration)
{
ECHO warning: looked in $(possible-paths) ;
}
}
if $(.debug-configuration) && $(setup)
{
ECHO "notice: msvc $(version:E=<default version>) $(vendor:E="")" ;
ECHO "notice: found at \"$(setup:D)\"" ;
}
return $(setup) ;
}
# 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 RSP : <toolset>msvc ;
generators.register-linker msvc.link.dll : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB IMPORT_LIB RSP : <toolset>msvc ;
generators.register-composing msvc.archive : OBJ : STATIC_LIB RSP : <toolset>msvc ;
generators.register-c-compiler msvc.compile.c++ : CPP : OBJ : <toolset>msvc ;
generators.register-c-compiler msvc.compile.c : C : OBJ : <toolset>msvc ;
#
# Declare flags and action for compilation
#
feature.feature debug-store : object database : propagated ;
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 <optimization>speed : /Ogity /O2 /Gs ;
flags msvc.compile CFLAGS <optimization>space : /Ogisy /O1 /Gs ;
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 <exception-handling>on : /GX ;
flags msvc.compile CFLAGS <rtti>on : /GR ;
flags msvc.compile CFLAGS <runtime-debugging>off/<link-runtime>shared : /MD ;
flags msvc.compile CFLAGS <runtime-debugging>on/<link-runtime>shared : /MDd ;
flags msvc.compile CFLAGS <runtime-debugging>off/<link-runtime>static/<threading>single : /ML ;
flags msvc.compile CFLAGS <runtime-debugging>on/<link-runtime>static/<threading>single : /MLd ;
flags msvc.compile CFLAGS <runtime-debugging>off/<link-runtime>static/<threading>multi : /MT ;
flags msvc.compile CFLAGS <runtime-debugging>on/<link-runtime>static/<threading>multi : /MTd ;
flags msvc.compile CFLAGS <base-target-type>CPP : /GX ;
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 WHATEVER <toolset-msvc:version> ;
# The actions differ only by explicit selection of input language
actions compile.c
{
$(.CC) /Zm800 -nologo -TC -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) $(USER_CFLAGS) -I"$(INCLUDES)" -c -Fo"$(<)" "$(>)"
}
actions compile.c++
{
$(.CC) /Zm800 -nologo -TP -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) $(USER_CFLAGS) -I"$(INCLUDES)" -c -Fo"$(<)" "$(>)"
}
# 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 ;
# 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.
# Declare action for creating static libraries
if [ os.name ] in NT
{
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) ] ;
}
rule archive ( targets + : sources * : properties * )
{
common.response-file $(targets) : $(sources) : $(targets[2]) : $(properties) ;
}
# If library exists, remove it before adding files. See
# http://article.gmane.org/gmane.comp.lib.boost.build/4241
# for rationale.
actions archive
{
if exist "$(<[1])" DEL "$(<[1])"
$(.LD) /lib /NOLOGO /out:"$(<[1])" @"$(<[2])"
}
}
else # CYGWIN
{
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) ;
.cygpath = "cygpath -d " ;
DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ;
}
rule archive ( targets + : sources * : properties * )
{
common.response-file $(targets) : $(sources) : $(targets[2]) : $(properties) ;
}
actions archive
{
_bbv2_out_="$(<)"
if test -f "$_bbv2_out_" ; then
_bbv2_existing_="$(<:W)"
fi
$(.LD) /lib /NOLOGO "/out:$(<:W)" $_bbv2_existing_ @"$(>:W)"
}
}
actions link bind DEF_FILE
{
$(.LD) /NOLOGO $(LINKFLAGS) /out:"$(<[1]:W)" /INCREMENTAL:NO /LIBPATH:"$(LINKPATH:W)" $(USER_LINKFLAGS) @"$(<[2]:W)"
}
actions link.dll bind DEF_FILE
{
$(.LD) /NOLOGO $(LINKFLAGS) /out:"$(<[1]:W)" /INCREMENTAL:NO /IMPLIB:"$(<[2]:W)" /LIBPATH:"$(LINKPATH:W)" /def:$(DEF_FILE) $(USER_LINKFLAGS) @"$(<[3]:W)"
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -