📄 boost-base.jam
字号:
#~ Copyright 2002-2004 Rene Rivera.
#~ Copyright 2001-2004 David Abrahams.
#~ Distributed under the Boost Software License, Version 1.0.
#~ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
# (C) Copyright David Abrahams and Carlos Pinto Coelho 2001. 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.
#
# Jamrules file by David Abrahams (abrahams@mediaone.net) and Carlos Pinto
# Coelho (cfspc@altrabroadband.com).
# Notes on the design of the system:
#
# This system is designed to support building the "same" targets with multiple
# build tool suites (e.g. msvc, gcc,...) and build variants (e.g. debug,
# release...). Although it currently varies across two dimensions, it should
# trivially support extension to three or more, e.g. in case of cross-platform
# builds. The word "same" is written in quotes above because internally,
# separate targets are generated for each unique toolset/build-variant
# combination.
#
# Specifics of build tool suites are specified in files with names of the form
# "<name>-tools.jam", where <name> is the name used to identify the tool suite.
# Workarounds for Jam limitations:
#
# 1. Jam supports something like the setting of attributes on targets using the
# syntax:
# <name> on <target> = <expression>
#
# This facility is used to control build actions for individual targets
# (target-specific variables take precedence over global ones when build
# actions # are executed). An obvious approach would be to use target
# attributes to hold # properties of build tools (e.g. where to find the
# standard includes). # Unfortunately, although you can write target
# attributes, there is no way to # read them. Instead, we take advantage of
# two properties of Jam:
#
# a. A variable name can be formed by evaluating an expression. For example,
# the following rule, appends FOOBAR to its first argument to form the
# name of a new variable, which is given the value "baz"
#
# rule X { $(1)FOOBAR = baz ; }
#
# b. Any character is allowed in a variable name. So, although they are
# actually global variables, we can form names like <name>.c++-flags thus:
#
# C++FLAGS = $($(1).c++-flags) # Get the c++-flags "attribute" from $(1)
#
# 2. There is no way to call a rule based on the value of a variable
# other than by using a switch statement. Because that approach requires
# intrusive changes to rules when the system is extended, we have avoided
# it. Instead, we have taken advantage of two "features" of Jam:
#
# a. The name of a file to be included can be computed from an
# expression. For example, the following includes a file whose name is
# formed by concatenating $(1) and "-tools.jam":
#
# include $(1)-tools.jam
#
# b. A rule can be redefined any number of times. Its latest definition is
# the one invoked. For example, the following prints "#2".
#
# rule X { ECHO #1 ; }
# rule X { ECHO #2 ; }
# X ;
#
# Together, these facts allow us to select tool-suite-specific actions for
# building specific target types by repeatedly redefining the generalized
# build actions in the various <build-tools>-tools.jam files
if $(NT)
{
TOOLS ?= vc-7_1 ;
}
else if $(UNIX)
{
switch $(JAMUNAME)
{
case Darwin* :
{
TOOLS ?= darwin ;
}
case * :
{
TOOLS ?= gcc ;
}
}
}
else
{
TOOLS ?= gcc ;
}
SHARED_TYPES = DLL ;
STATIC_TYPES = LIB ;
# detect-build-tools <tools-name> : <detection-command>
#
# Declares a pseudotarget for the specified build tools which is built by
# the given <detection-command>.
#
# Although not currently implemented, the plan is to make compilation of
# tool-specific targets dependent on this pseudotarget. That way, we will never
# even attempt to build targets for tools that don't exist.
rule detect-build-tools
{
detection-command on $(<) = $($(<).bin-directory)$(>) ;
}
# lib: generator function
#
rule library-file ( target : sources + )
{
LibraryFromObjects $(<) : [ Objects $(>) ] ;
}
# exe: generator function
#
rule executable-file ( target : sources + )
{
type-DEPENDS exe : $(<) ;
main-from-objects $(<) : [ Objects $(>) ] : EXE ;
}
# dll: generator function
#
rule dll-files ( module implib ? : sources * : target-type ? )
{
type-DEPENDS dll : $(<) ;
# Set up the import library dependency on Windows
if $(<[2])
{
INCLUDES $(<[1]) : $(<[2-]) ;
INCLUDES $(<[2-]) : $(<[1]) ;
}
target-type ?= DLL ;
if [ MATCH ^(CRAY).* : $(JAMUNAME[-1]) ] # no shared libs on cray
{
NOTFILE $(<) ;
}
else
{
main-from-objects $(<) : [ Objects $(>) ] : $(target-type) ;
}
}
# template: modifier function
#
# The target specs are modified by adding those previously specified in a template source.
# Any specs containing paths are rerooted to correctly reference the dependee locations.
#
rule template-modifier ( target : source )
{
local source-dir = [ directory-of $(source:G=) ] ;
local source-id = [ target-id-of $(source) ] ;
# Make sure it's defined.
#
if ! $(gTARGET_TYPE($(source-id)))
{
dependent-include $(source:G=) ;
}
# Copy the base specs into the target specs, adjust any paths
#
gTARGET_SOURCES($(target)) +=
[ root-paths $(gTARGET_SOURCES($(source-id))) : $(source-dir) ] ;
gTARGET_DEPS($(target)) +=
[ root-paths $(gTARGET_DEPS($(source-id))) : $(source-dir) ] ;
gTARGET_REQUIREMENTS($(target)) +=
[ fixup-path-properties $(gTARGET_REQUIREMENTS($(source-id))) : $(source-dir) ] ;
gTARGET_DEFAULT_BUILD($(target)) +=
$(gTARGET_DEFAULT_BUILD($(source-id))) ;
}
# main-from-objects exe-target : obj-target... : ("EXE"|"DLL")
#
# generate instructions to build the given "main" target from the given object
# files given in the 2nd parameter. The 3rd parameter should be EXE for an
# executable, or DLL for a shared library.
rule main-from-objects ( targets * : objects * : type )
{
# make compiled sources a dependency of target
MakeLocate $(targets) : $(LOCATE_TARGET) ;
Clean clean : $(targets) ;
MODE on $(targets) = $($(type)MODE) ;
local link-function = Link-$(type) ;
local extra-files = [ $(link-function) $(targets) : $(objects) : $(type) ] ;
Chmod $(targets[1]) ;
DEPENDS $(targets) : $(objects) ;
# locate and attach the extra files generated
if $(extra-files)
{
MakeLocate $(extra-files) : $(LOCATE_TARGET) ;
DEPENDS $(targets) : $(extra-files) ;
}
gFILES($(targets[1])) = $(targets) $(extra-files) ;
}
rule .do-link ( targets + : sources + : type )
{
# Prepare NEEDLIBS for use by the toolsets' link action (e.g. for
# invoking with-command-file)
local NEEDLIBS = [ on $(<) return $(NEEDLIBS) ] ;
return [ Link-action $(targets) : $(sources) : $(type) ] ;
}
rule Link-EXE
{
# N.B. By the time this rule is invoked, we had better have gRUN_PATH completely set.
local extra-files = [ .do-link $(<) : $(>) : EXE ] ;
RUN_PATH on $(<) = [ join [ unique $(gRUN_PATH($(<))) $(gTOOLSET_LIB_PATH) ] : $(SPLITPATH) ] ;
if $(UNIX)
{
LINK_LIBPATH on $(<) = [ join $(gRUN_LD_LIBRARY_PATH($(<))) : $(SPLITPATH) ] ;
}
return $(extra-files) ;
}
rule Link-DLL
{
gRUN_LD_LIBRARY_PATH($(<)) += $(gLOCATE($(<[1]))) $(gTOOLSET_LIB_PATH) ;
if $(UNIX)
{
LINK_LIBPATH on $(<) = [ join $(gRUN_LD_LIBRARY_PATH($(<))) : $(SPLITPATH) ] ;
}
return [ .do-link $(<) : $(>) : DLL ] ;
}
# store the shell's PATH again, just in case someone uses PATH.
# This also allows the user to customize the base path for running built
# products from the command-line
RUN_PATH ?= $(PATH) ;
if $(UNIX)
{
LINK_LIBPATH ?= $($(gSHELL_LIBPATH)) ;
gAPPEND_LD_LIBRARY_PATH = ":$"$(gSHELL_LIBPATH) ;
gAPPEND_PATH = ":$"PATH ;
}
if $(NT)
{
# Try some other likely spellings
RUN_PATH ?= $(Path) ;
RUN_PATH ?= $(path) ;
gAPPEND_LD_LIBRARY_PATH = ";%LD_LIBRARY_PATH%" ;
gAPPEND_PATH = ;\"%PATH%\" ;
}
# Now set this, just in case someone tries to use it.
PATH = $(RUN_PATH) ;
if $(UNIX)
{
$(gSHELL_LIBPATH) = $(LINK_LIBPATH) ;
}
DOLLAR = "$" ;
# bubble variable-name
#
# Helper function for sort, below
# Removes the greatest element from $(variable-name) and returns it.
rule bubble #
{
local result = ;
local last = $($(<)[1]) ;
for x in $($(<)[2-])
{
if $(last) <= $(x)
{
result += $(last) ;
last = $(x) ;
}
else
{
result += $(x) ;
}
}
$(<) = $(result) ;
return $(last) ;
}
# sort args
#
# return args sorted in lexicographic order.
rule sort
{
local _all = $(<) ;
local _result = ;
local _count ;
for _count in $(<)
{
_result = [ bubble _all ] $(_result) ;
}
return $(_result) ;
}
# min args
#
# return the lexicographic minimum element of args
rule min
{
local result = ;
local x ;
for x in $(<)
{
if ! $(result) || ( $(x) < $(result) )
{
result = $(x) ;
}
}
return $(result) ;
}
# difference listB : listA
# returns the elements of B that are not in A
rule difference
{
local result = ;
local element ;
for element in $(<)
{
if ! ( $(element) in $(>) )
{
result += $(element) ;
}
}
return $(result) ;
}
# replace list : old-value new-value
#
# returns list with occurrences of old-value replaced by new-value
rule replace
{
local result = ;
local x ;
for x in $(<)
{
if $(x) = $(>[1])
{
result += $(>[2]) ;
}
else
{
result += $(x) ;
}
}
return $(result) ;
}
# select-ungristed list...
#
# Returns the elements of list that have no grist
rule select-ungristed
{
local result x ;
for x in $(<)
{
if ! $(x:G)
{
result += $(x) ;
}
}
return $(result) ;
}
rule select-gristed ( list * )
{
local result ;
for local x in $(list)
{
if $(x:G)
{
result += $(x) ;
}
}
return $(result) ;
}
# Returns grist without "<"/">" for elements matching "<.*>",
# and ignores other elements.
rule ungrist ( names * )
{
local result ;
for local name in $(names)
{
local stripped = [ MATCH ^<(.*)>$ : $(name) ] ;
result += $(stripped) ;
}
return $(result) ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -