Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Overview 概覽

Boost.Jam Language  Boost.Jam語言
Configuration 配置
Invocation 調用
Declaring Targets 聲明目標
Projects 工程
The Build Process 構建過程

This section will provide the information necessary to create your own projects using Boost.Build. The information provided here is relatively high-level, and the section called 「Detailed reference」 as well as the on-line help system must be used to obtain low-level documentation (see --help).
這個章節為你提供了使用 Boost.Build 創建工程所需的信息。這裡所提供的信息相對比較高層次,要獲得底層的信息,則必須使用 「詳細參考」一節 以及在線幫助系統。(請見 --help)。

Boost.Build actually consists of two parts - Boost.Jam, a build engine with its own interpreted language, and Boost.Build itself, implemented in Boost.Jam's language. The chain of events when you type bjam on the command line is:
Boost.Build 實際上包含兩部分 - Boost.Jam,一個帶有解釋性語言的構建引擎,和用 Boost.Jam 的語言實現的 Boost.Build 本身。當你在命令行敲入 bjam 時,發生的事件如下:

  1. Boost.Jam tries to find Boost.Build and loads the top-level module. The exact process is described in the section called 「Initialization」
    Boost.Jam 嘗試查找 Boost.Build 並裝入頂層模塊。精確的過程在 「初始化」一節 中描述。

  2. The top-level module loads user-defined configuration files, user-config.jam and site-config.jam, which define available toolsets.
    頂層模塊裝入用戶自定義配置文件,user-config.jamsite-config.jam,它們定義了可用的工具集。

  3. The Jamfile in the current directory is read. That in turn might cause reading of further Jamfiles. As a result, a tree of projects is created, with targets inside projects.
    讀入當前目錄中的 Jamfile。然後可能會讀入更多的 Jamfiles。結果,一棵由工程中各個目標所組成的工程樹被創建。

  4. Finally, using the build request specified on the command line, Boost.Build decides which targets should be built, and how. That information is passed back to Boost.Jam, which takes care of actually running commands.
    最後,使用在命令行中指定的構建請求,Boost.Build 決定要構建哪些目標以及如何構建。這些信息被回傳給 Boost.Jam,後者負責實際運行命令。

So, to be able to successfully use Boost.Build, you need to know only four things:
所以,要成功地使用 Boost.Build,你只需要知道以下四件事情:

Boost.Jam Language  Boost.Jam語言

This section will describe the basics of the Boost.Jam language—just enough for writing Jamfiles. For more information, please see the Boost.Jam documentation.
本節描述 Boost.Jam 語言的基礎—僅夠用於編寫 Jamfiles。更多的信息,請參見 Boost.Jam 文檔。

Boost.Jam has an interpreted, procedural language. On the lowest level, a Boost.Jam program consists of variables and rules (the Jam term for function). They are grouped in modules—there's one global module and a number of named modules. Besides that, a Boost.Jam program contains classes and class instances.
Boost.Jam 有一個解釋性的過程語言。在最底層,Boost.Jam 程序由變量和 規則 ("函數"一詞在 Jam 中的術語)組成。它們組成各個模塊—有一個全局模塊和多個命名模塊。此外,Boost.Jam 程序還包含類和類實例。

Syntantically, a Boost.Jam program consists of two kind of elements—keywords (which have a special meaning to Boost.Jam) and literals. Consider this code:
在語法上,Boost.Jam 程序由兩類元素組成—關鍵字(對於 Boost.Jam 來說具有特殊的意義) 和普通文字。考慮以下代碼:

a = b ;

which assigns the value b to the variable a. Here, = and ; are keywords, while a and b are literals.
它將值 b 賦給變量 a。這裡,=; 是關鍵字,而 ab 是普通文字。

[Warning] Warning 警告

All syntax elements, even keywords, must be separated by spaces. For example, omitting the space character before ; will lead to a syntax error.

所有語法元素,包括關鍵字,都必須用空格分隔。例如,省略 ; 前面的空格將導致語法錯誤。

If you want to use a literal value that is the same as some keyword, the value can be quoted:
如果你想使用一個與某個關鍵字相同的文字,就要把它用引號引起來:

a = "=" ;

All variables in Boost.Jam have the same type—list of strings. To define a variable one assigns a value to it, like in the previous example. An undefined variable is the same as a variable with an empty value. Variables can be accessed using the $(variable) syntax. For example:
Boost.Jam 中的所有變量都具有相同的類型—字符串列表。要定義一個變量同時賦值給它,就像前面的例子那樣。一個未定義的變量和一個具有空值的變量一樣。變量可以用 $(variable) 語法來訪問。例如:

a = $(b) $(c) ;

Rules are defined by specifying the rule name, the parameter names, and the allowed size of the list value for each parameter.
規則通過指定規則名、參數名及各個參數所允許的列表值大小來定義。

rule example
     (
         parameter1 :
parameter2 ? :
parameter3 + :
parameter4 * ) { // body }

When this rule is called, the list passed as the first argument must have exactly one value. The list passed as the second argument can either have one value of be empty. The two remaining arguments can be arbitrarily long, but the third argument may not be empty.
在調用這個規則時,傳入的第一個參數的列表必須剛好包含一個值。第二個參數的列表則可以有一個值或者為空。其餘兩個參數可以是變長的,但第三個參數不能為空。

The overview of Boost.Jam language statements is given below:
以下是 Boost.Jam 語言的語句的一個概覽:

helper 1 : 2 : 3 ;
x = [ helper 1 : 2 : 3 ] ;

This code calls the named rule with the specified arguments. When the result of the call must be used inside some expression, you need to add brackets around the call, like shown on the second line.
這段代碼以給定的參數調用命名規則。當調用的結果要在某個表達式中使用時,你必須用方括號把調用括起來,就像前面第二行語句那樣。

if cond { statements } [ else { statements } ]

This is a regular if-statement. The condition is composed of:
這是一個普通的 if-語句。條件由以下組成:

  • Literals (true if at least one string is not empty)
    普通文字(當至少一個字符串非空時為真)

  • Comparisons: a operator b where operator is one of =, !=, <, >, <=, >=. The comparison is done pairwise between each string in the left and the right arguments.
    比較操作:a operator b ,其中 operator=, !=, <, >, <=, >= 之一。比較操作是在左參數和右參數的各個字符串之間成對地進行的。

  • Logical operations: ! a, a && b, a || b
    邏輯操作:! a, a && b, a || b

  • Grouping: ( cond )
    分組操作:( cond )

for var in list { statements }

Executes statements for each element in list, setting the variable var to the element value.
對 list 中的各個元素執行 statements,將變量 var 設為各個元素的值。

while cond { statements }

Repeatedly execute statements while cond remains true upon entry.
當 cond 在每次進入時保持為真時重複執行 statements。

return values ;

This statement should be used only inside a rule and assigns values to the return value of the rule.
這個語句只應在某個規則的內部使用,它將 values 賦為該規則的返回值。

[Warning] Warning 警告

The return statement does not exit the rule. For example:

return 語句不會退出規則。例如:

rule test ( )
{
if 1 = 1 {
return "reasonable" ;
}
return "strange" ;
}

will return strange, not reasonable.
將返回 strange, 而不是 reasonable.

import module ;
import module : rule ;

The first form imports the specified bjam module. All rules from that module are made available using the qualified name: module.rule. The second form imports the specified rules only, and they can be called using unqualified names.
第一種形式導入指定的 bjam 模塊。該模塊的所有規則都可以通過限定名稱 module.rule 使用。第二種形式僅導入指定的規則,該規則可以通過非限定名稱調用。

Sometimes, you'd need to specify the actual command lines to be used when creating targets. In jam language, you use named actions to do this. For example:
有時候,你需要在構建目標時指定真實的命令行。在 jam 語言中,你可以用命名動作來實現。例如:

actions create-file-from-another
{
create-file-from-another $(<) $(>)
}

This specifies a named action called create-file-from-another. The text inside braces is the command to invoke. The $(<) variable will be expanded to a list of generated files, and the $(>) variable will be expanded to a list of source files.
它指定了一個名為 create-file-from-another 的命名動作。在大括號中的文本是要調用的命令。變量 $(<) 將被展開為被生成文件的列表,而變量 $(>) 則被展開為源文件的列表。

To flexibly adjust command line, you can define a rule with the same name as the action, and taking three parameters -- targets, sources and properties. For example:
為了靈活調整命令行,你可以定義一個和該動作同名的規則,它接受三個參數 -- 目標、源和屬性。例如:

rule create-file-from-another ( targets * : sources * : properties * )
{
if <variant>debug in $(properties)
{
OPTIONS on $(targets) = --debug ;
}
}
actions create-file-from-another
{
create-file-from-another $(OPTIONS) $(<) $(>)
}

In this example, the rule checks if certain build property is specified. If so, it sets variable OPIONS that is then used inside the action. Note that the variables set "on a target" will be visible only inside actions building that target, not globally. Were they set globally, using variable named OPTIONS in two unrelated actions would be impossible.
在這個例子中,規則會檢查是否指定了特定的構建屬性。如果有,則設置變量 OPIONS 然後在動作中使用它。注意,被設置"在特定目標上"的變量僅在構建該目標的動作內可見,而不是全局的。如果它被設為全局的,那麼在兩個無關的動作中使用名為 OPTIONS 的變量就不可能了。

More details can be found in Jam reference, the section called 「 Rules」
更多細節可以在 Jam 參考手冊的 「規則」一節 中找到

Configuration 配置

The Boost.Build configuration is specified in the file user-config.jam. You can edit the one in the top-level directory of Boost.Build installation or create a copy in your home directory and edit that. (See Table 28.2, 「Search paths for configuration files」 for the exact search paths.) The primary function of that file is to declare which compilers and other tools are available. The simplest syntax to configure a tool is:
Boost.Build 的配置是在文件 user-config.jam 中指定的。你可以編輯位於 Boost.Build 安裝的頂層目錄中的那個文件,或者在你的主目錄中創建一個拷貝並編輯它。(精確的查找路徑請見 表 28.2, 「配置文件的查找路徑」)。該文件的主要功能是聲明有哪些編譯器和工具可用。配置一個工具的最簡單語法是:

using tool-name ;

The using rule is given a name of tool, and will make that tool available to Boost.Build. For example, using gcc ; will make the gcc compiler available.
規則 using 給定工具的名字,並使得該工具對 Boost.Build 可用。例如,using gcc ; 將使得 gcc 編譯器可用。

Since nothing but a tool name is specified, Boost.Build will pick some default settings. For example, it will use the gcc executable found in the PATH, or look in some known installation locations. In most cases, this strategy works automatically. In case you have several versions of a compiler, it's installed in some unusual location, or you need to tweak its configuration, you'll need to pass additional parameters to the using rule. The parameters to using can be different for each tool. You can obtain specific documentation for any tool's configuration parameters by invoking
由於只給出了工具名,所以 Boost.Build 將選取一些缺省的設置。例如,它將使用在 PATH 或某些已知的安裝位置中找到的 gcc 可執行文件。多數情況下,這一策略可自動工作。如果你有某個編譯器的多個版本,它們被安裝在某個與眾不同的位置,或者你想要優化編譯器的配置,那麼你就需要傳遞其它參數給 using 規則。給 using 的參數可以對每個工具各不一樣。你可以通過調用以下命令獲得關於任一工具的配置參數的文檔:

bjam --help tool-name.init

That said, for all the compiler toolsets Boost.Build supports out-of-the-box, the list of parameters to using is the same: toolset-name, version, invocation-command, and options.
即是說,對於 Boost.Build 缺省配置就支持的所有編譯器工具集,給 using 的參數列表都是一樣的:toolset-name, version, invocation-command, 和 options.

The version parameter identifies the toolset version, in case you have several installed. It can have any form you like, but it is recommended that you use a numeric identifier like 7.1.
參數 version 標識了工具集的版本,如果你安裝了多個版本。它可以有你喜歡的任意格式,不過建議你使用數字標識,如 7.1.

The invocation-command parameter is the command that must be executed to run the compiler. This parameter can usually be omitted if the compiler executable
參數 invocation-command 是運行該編譯器所必須執行的命令。該參數通常可以省略,如果編譯器的可執行文件

  • has its 「usual name」 and is in the PATH, or
    具有"正常名字"且位於 PATH 中,或者

  • was installed in a standard 「installation directory」, or
    被安裝在標準的"安裝目錄"下,或者

  • can be found using a global system like the Windows registry.
    可以用全局系統,如 Windows 註冊表,查找得到。

For example:
例如:

using msvc : 7.1 ;
using gcc ;

If the compiler can be found in the PATH but only by a nonstandard name, you can just supply that name:
如果編譯器可以在 PATH 中找到,但是用了一個非標準的名字,那麼你只要給定這個名字就行了:

using gcc : : g++-3.2 ;

Otherwise, it might be necessary to supply the complete path to the compiler executable:
否則,就可能需要提供這個編譯器的可執行文件的完整路徑:

using msvc : : "Z:/Programs/Microsoft Visual Studio/vc98/bin/cl" ;

Some Boost.Build toolsets will use that path to take additional actions required before invoking the compiler, such as calling vendor-supplied scripts to set up its required environment variables. When compiler executables for C and C++ are different, path to the C++ compiler executable must be specified. The 「invocation command」 can be any command allowed by the operating system. For example:
有些 Boost.Build 工具集要在調用編譯器之前用這個路徑來進行其它必要的動作,如調用一個廠家提供的腳本來設置所需的環境變量。如果用於 C 和 C++ 的編譯程序是不同的,那麼必須指定 C++ 編譯程序的路徑。「invocation command」可以是操作系統允許的任何命令。例如:

using msvc : : echo Compiling && foo/bar/baz/cl ;

will work.
也可以工作。

To configure several versions of a toolset, simply invoke the using rule multiple times:
要配置一個工具集的多個版本,只要多次調用 using 規則即可。

using gcc : 3.3 ;
using gcc : 3.4 : g++-3.4 ;
using gcc : 3.2 : g++-3.2 ;

Note that in the first call to using, the compiler found in the PATH will be used, and there's no need to explicitly specify the command.
注意,在調用第一個 using 時,會使用在 PATH 中找到的編譯器,無需明確指定相關命令。

As shown above, both the version and invocation-command parameters are optional, but there's an important restriction: if you configure the same toolset more than once, you must pass the version parameter every time. For example, the following is not allowed:
如上所示,參數 versioninvocation-command 都是可選的,但是有一個重要的限制:如果你超過一次配置同一個工具集,你必須在每次傳遞 version 參數。例如,以下是不可以的:

using gcc ;
using gcc : 3.4 : g++-3.4 ;

because the first using call does not specify a version.
因為第一個 using 調用沒有指定 version.

The options parameter is used to fine-tune the configuration. All of Boost.Build's standard compiler toolsets accept properties of the four builtin features cflags, cxxflags, compileflags and linkflags as options specifying flags that will be always passed to the corresponding tools. Values of the cflags feature are passed directly to the C compiler, values of the cxxflags feature are passed directly to the C++ compiler, and values of the compileflags feature are passed to both. For example, to configure a gcc toolset so that it always generates 64-bit code you could write:
參數 options 用於對配置進行調整。所有 Boost.Build 的標準編譯器工具集都用 options 接受四個內建特性 cflags, cxxflags, compileflagslinkflags 的屬性,以指定傳遞給對應工具的選項。cflags 特性的值會直接傳遞給 C 編譯器,cxxflags 特性的值則直接傳遞給 C++ 編譯器,而 compileflags 特性的值則傳給兩者。例如,要將 gcc 工具集進行配置以使之一直生成64位代碼,你可以寫:

using gcc : 3.4 : : <compileflags>-m64 <linkflags>-m64 ;

Invocation 調用

This section describes how invoke Boost.Build from the command line
本節描述如何從命令行調用 Boost.Build。

To build all targets defined in Jamfile in the current directory with default properties, run:
要以缺省屬性構建當前目錄的 Jamfile 中的所有目標,運行:

bjam

To build specific targets, specify them on the command line:
要構建特定目標,則在命令行中指定它們:

bjam lib1 subproject//lib2

To request a certain value for some property, add property=value to the command line:
要為某些屬性指定特定值,則在命令行中加入 property=value

bjam toolset=gcc variant=debug optimization=space

For often used features, like toolset and variant you can omit the feature name, so the above can be written as:
對於經常使用的特性,如 toolsetvariant,你可以省略特性名,所以上例也可以寫成:

bjam optimization=space

Boost.Build recognizes the following command line options.
Boost.Build 使用以下命令行選項:

--clean

Cleans all targets in the current directory and in any subprojects. Note that unlike the clean target in make, you can use --clean together with target names to clean specific targets.
清除當前目錄及所有子工程中的目標。注意,與 make 中的 clean 目標不同,你可以將 --clean 和目標名一起使用以清除指定目標。

--clean-all

Cleans all targets, no matter where they are defined. In particular, it will clean targets in parent Jamfiles, and targets defined under other project roots.
清除所有目標,不管它們在哪裡定義。特定地,它將清除在父 Jamfiles 中的目標以及定義在其它工程根下的目標。

--build-dir

Changes build directories for all project roots being built. When this option is specified, all Jamroot files should declare project name. The build directory for the project root will be computed by concatanating the value of the --build-dir option, the project name specified in Jamroot, and the build dir specified in Jamroot (or bin, if none is specified).
為被構建的所有工程根修改構建目錄。如果指定了這一選項,所有 Jamroot 文件都應聲明工程名。工程根的構建目錄通過將 --build-dir 選項的值與在 Jamroot 中指定的工程名以及在 Jamroot 中指定的構建目錄(如果沒有指定則為 bin)相聯接得到,

The option is primarily useful when building from read-only media, when you can't modify Jamroot.
該選項主要在從只讀介質進行構建時使用,這時你不能修改 Jamroot。

--version

Prints information on Boost.Build and Boost.Jam versions.
打印 Boost.Build 和 Boost.Jam 的版本信息。

--help

Invokes the online help system. This prints general information on how to use the help system with additional --help* options.
調用在線幫助系統。以額外的 --help* 選項打印如何使用幫助系統的信息。

--debug-configuration

Produces debug information about loading of Boost.Build and toolset files.
產生關於 Boost.Build 和工具集文件裝入的調試信息。

--debug-building

Prints what targets are being built and with what properties.
打印正在構建的目標和所帶的屬性。

--debug-generators

Produces debug output from generator search process. Useful for debugging custom generators.
從生成器查找過程產生調試輸出。用於調試客戶化的生成器。

--ignore-config

Do not load site-config.jam and user-config.jam configuration files.
不要裝入 site-config.jamuser-config.jam 配置文件。

--debug

Enables internal checks.
打開內部檢查。

For complete specification of command line syntax, see the section called 「Command line arguments」
命令行語法的完整說明,請見 「命令行參數」一節

Declaring Targets 聲明目標

A Main target is a user-defined named entity that can be built, for example an executable file. Declaring a main target is usually done using one of the main target rules described in the section called 「Builtin rules」. The user can also declare custom main target rules as shown in the section called 「Main target rules」.
主目標 是指用戶定義的一個可構建的命名實體,例如一個可執行文件。主目標通常是通過使用在 「內建規則」一節 中描述的主目標規則之一來聲明的。用戶也可以像在 「主目標規則」一節 中所說的那樣聲明定制的主目標規則。

Most main target rules in Boost.Build have the same common signature:
Boost.Build 中多數主目標規則都具有相同的公用簽名:

rule rule-name (
main-target-name :
sources + :
requirements * :
default-build * :
usage-requirements * )
  • main-target-name is the name used to request the target on command line and to use it from other main targets. A main target name may contain alphanumeric characters, dashes (『-』), and underscores (『_』).
    main-target-name 是用於在命令行請求該目標以及從其它主目標使用的名字。主目標名可以包含字母、連字符 (『-』) 和下劃線 (『_』)。
  • sources is the list of source files and other main targets that must be combined.
    sources 是源文件列表以及其它必須組合的主目標。
  • requirements is the list of properties that must always be present when this main target is built.
    requirements 是在構建主目標時必須一直使用的屬性的列表。
  • default-build is the list of properties that will be used unless some other value of the same feature is already specified, e.g. on the command line or by propagation from a dependent target.
    default-build 也是將被使用的屬性的列表,除非這些特性的值被通過命令行指定或從依賴目標傳播得到。
  • usage-requirements is the list of properties that will be propagated to all main targets that use this one, i.e. to all its dependents.
    usage-requirements 是一些屬性的列表,這些屬性將被傳播至所有依賴於該目標的主目標。

Some main target rules have a different list of parameters as explicitly stated in their documentation.
有些主目標規則具有不同的參數列表,將在它們的文檔中明確說明。

The actual requirements for a target are obtained by refining requirements of the project where a target is declared with the explicitly specified requirements. The same is true for usage-requirements. More details can be found in the section called 「Property refinement」
一個目標的實際要求是通過對聲明該目標的工程的要求和顯式指定的要求一起精化而得到的。對於 usage-requirements 也一樣。更多細節可以在 「屬性精化」一節 中找到。

Name 名稱

The name of main target has two purposes. First, it's used to refer to this target from other targets and from command line. Second, it's used to compute the names of the generated files. Typically, filenames are obtained from main target name by appending system-dependent suffixes and prefixes.
主目標的名稱有兩個目的。首先,它用於在其它目標或命令行中指稱該目標。其次,它用於計算生成文件的名字。通常,文件名由主目標名字加上系統相關的前綴和後綴而成。

The name of a main target can contain alphanumeric characters, dashes, undescores and dots. The entire name is significant when resolving references from other targets. For determining filenames, only the part before the first dot is taken. For example:
主目標名稱可以包含字母、連字符、下劃線和點符。在從其它目標進行引用解釋時使用完整的名稱。而在生成文件名時,則只使用第一個點符之前的部分。例如:

obj test.release : test.cpp : <variant>release ;
obj test.debug : test.cpp : <variant>debug ;

will generate two files named test.obj (in two different directories), not two files named test.release.obj and test.debug.obj.
將生成兩個名為 test.obj 的文件(在不同的目錄下),而不是兩個分別名為 test.release.objtest.debug.obj 的文件。

Sources 源

The list of sources specifies what should be processed to get the resulting targets. Most of the time, it's just a list of files. Sometimes, you'll want to automatically construct the list of source files rather than having to spell it out manually, in which case you can use the glob rule. Here are two examples:
源列表指明了要得到結果目標應處理些什麼。多數時候,它只是一個文件列表。有時,你可能想自動構造源文件的列表,而不是手工將它拼寫出來,這時你可以使用 glob 規則。以下是兩個例子:

exe a : a.cpp ;           # a.cpp is the only source file  a.cpp 是唯一的源文件
exe b : [ glob *.cpp ] ; # all .cpp files in this directory are sources 目錄中所有 .cpp 文件都是源

Unless you specify a file with an absolute path, the name is considered relative to the source directory — which is typically the directory where the Jamfile is located, but can be changed as described in the section called 「Projects」.
除非你以絕對路徑來指明文件,否則文件名被認為是相對於源目錄的 — 通常是 Jamfile 所在的目錄,但是也可以被修改,見 「工程」一節

The list of sources can also refer to other main targets. Targets in the same project can be referred to by name, while targets in other projects must be qualified with a directory or a symbolic project name. The directory/project name is separated from the target name by a double forward slash. There's no special syntax to distinguish the directory name from the project name—the part before the double slash is first looked up as project name, and then as directory name. For example: 
源列表也可以引向其它主目標。在同一個工程中的目標可以用名字來引用,而在其它工程中的目標則必須用一個目錄或工程符號名來限定。目錄/工程名與目標名之間以一個雙重斜槓分隔。沒有特殊的語法來區分目錄名和工程名—雙斜槓前的部分先按工程名查找,再按目錄名查找。例如:

lib helper : helper.cpp ;
exe a : a.cpp helper ;
# Since all project ids start with slash, ".." is directory name.
exe b : b.cpp ..//utils ;
exe c : c.cpp /boost/program_options//program_options ;

The first exe uses the library defined in the same project. The second one uses some target (most likely library) defined by Jamfile one level higher. Finally, the third target uses some C++ Boost library, referring to it by absolute symbolic name. More information about target references can be found in the section called 「Dependent Targets」 and the section called 「Target identifiers and references」.
第一個 exe 使用在本工程中定義的庫。第二個則使用在上一級 Jamfile 定義的某個目標(很可能是庫)。最後,第三個目標使用了某個 C++ Boost 庫,以絕對符號名稱來引用。有關目標引用的更多信息,可以在 「依賴目標」一節「目標標識符和引用」一節 中找到。

Requirements 要求

Requirements are the properties that should always be present when building a target. Typically, they are includes and defines:
要求是指在構建一個目標時要一直使用的屬性。典型地,它們是一些包含和定義:

exe hello : hello.cpp : <include>/opt/boost <define>MY_DEBUG ;

There is a number of other features, listed in the section called 「Builtin features」. For example if a library can only be built statically, or a file can't be compiled with optimization due to a compiler bug, one can use
還有多個其它的特性,列在 「內建特性」一節 中。例如,如果一個庫只能靜態構建,或者一個文件由於編譯器缺陷而不能以優化方式編譯,你可以使用:

lib util : util.cpp : <link>static ;
obj main : main.cpp : <optimization>off ;

Sometimes, particular relationships need to be maintained among a target's build properties. This can be achieved with conditional requirements. For example, you might want to set specific #defines when a library is built as shared, or when a target's release variant is built in release mode.
有時,有些特定的關係也需要在目標的構建屬性中維護。這時可以使用 條件要求。例如,你可能想在某個庫以動態方式構建時設置特定的 #defines,或者在某個目標的 release 版本按發佈模式構建時。

lib network : network.cpp
: <link>shared:<define>NEWORK_LIB_SHARED <variant>release:<define>EXTRA_FAST ;

In the example above, whenever network is built with <link>shared, <define>NEWORK_LIB_SHARED will be in its properties, too.
在上例中,當 network<link>shared 構建時,<define>NEWORK_LIB_SHARED 將成為它的屬性之一。

You can use several properties in the condition, for example:
你可以在條件中使用多個屬性,例如:

lib network : network.cpp
: <toolset>gcc,<optimization>speed:<define>USE_INLINE_ASSEMBLER
;

A more powerful variant of conditional requirements is indirect conditional requirements. You can provide a rule that will be called with the current build properties and can compute additional properties to be added. For example:
條件要求的一個更為強大的變體是 間接條件要求。你可以提供一個規則,以當前的構建屬性來調用它,計算得到要增加的其它屬性。例如:

lib network : network.cpp
: <conditional>@my-rule
;
rule my-rule ( properties * )
{
local result ;
if <toolset>gcc <optimization>speed in $(properties)
{
result += <define>USE_INLINE_ASSEMBLER ;
}
return $(result) ;
}

This example is equivalent to the previous one, but for complex cases, indirect conditional requirements can be easier to write and understand.
這個例子和上一個效果一樣,但是對於複雜的情形,間接條件要求更易於編寫,也更易懂。

Requirements explicitly specified for a target are usually combined with the requirements specified for the containing project. You can cause a target to completely ignore specific project's requirement using the syntax by adding a minus sign before a property, for example:
為一個目標顯式指定的要求通常要與其所在工程所指定的要求相合併。你可以在某個屬性之前加上一個減號,讓目標完全忽略工程所指定的要求,例如:

exe main : main.cpp : -<define>UNNECESSARY_DEFINE ;

This syntax is the only way to ignore free properties from a parent, such as defines. It can be also useful for ordinary properties. Consider this example:
這種語法是忽略來自於父工程的自由屬性(如定義)的唯一方法。它也可以用於普通屬性。考慮以下例子:

project test : requirements <threading>multi ;
exe test1 : test1.cpp ;
exe test2 : test2.cpp : <threading>single ;
exe test3 : test3.cpp : -<threading>multi ;

Here, test1 inherits project requirements and will always be built in multi-threaded mode. The test2 target overrides project's requirements and will always be built in single-threaded mode. In contrast, the test3 target removes a property from project requirements and will be built either in single-threaded or multi-threaded mode depending on which variant is requested by the user.
這裡,test1 繼承了工程要求,將總是按多線程模式構建。而目標 test2覆寫 了工程的要求,將總是按單線程模式構建。相比之下,目標 test3 去除 了工程要求的一個屬性,它根據用戶的請求來按單線程或多線程模式構建。

Note that the removal of requirements is completely textual: you need to specify exactly the same property to remove it.
注意,要求的去除需要完整的文字:你必須正確地給出要去除的相同屬性。

Default Build 缺省構建

The default-build parameter is a set of properties to be used if the build request does not otherwise specify a value for features in the set. For example:
參數 default-build 是一組這樣的屬性,如果構建請求中沒有指定該組中某個特性的值,就使用這個屬性。例如:

exe hello : hello.cpp : : <threading>multi ;

would build a multi-threaded target unless the user explicitly requests a single-threaded version. The difference between requirements and default-build is that requirements cannot be overridden in any way.
將構建一個多線程的目標,除非用戶明確指定要一個單線程版本。要求和缺省構建之間的區別在於,要求是不能被覆寫的。

Additional Information 額外信息

The ways a target is built can be so different that describing them using conditional requirements would be hard. For example, imagine that a library actually uses different source files depending on the toolset used to build it. We can express this situation using target alternatives:
構建目標的方式可以很不一樣,用條件要求來描述可能會有困難。例如,想像一個庫,它根據構建時所用的工具集來實際選用不同的源文件。我們可以用 目標選擇 來表示這種情形:

lib demangler : dummy_demangler.cpp ;                      # alternative 1
lib demangler : demangler_gcc.cpp : <toolset>gcc ; # alternative 2
lib demangler : demangler_msvc.cpp : <toolset>msvc ; # alternative 3

In the example above, when built with gcc or msvc, demangler will use a source file specific to the toolset. Otherwise, it will use a generic source file, dummy_demangler.cpp.
在上例中,如果用 gccmsvc 來構建,則 demangler 將使用指定給相應工具集的源文件。否則,它使用通用的源文件 dummy_demangler.cpp.

It is possible to declare a target inline, i.e. the "sources" parameter may include calls to other main rules. For example:
可以內聯地聲明一個目標,即參數 "sources" 可以包含對其它主規則的調用。例如:

exe hello : hello.cpp
[ obj helpers : helpers.cpp : <optimization>off ] ;

Will cause "helpers.cpp" to be always compiled without optimization. When referring to an inline main target, its declared name must be prefixed by its parent target's name and two dots. In the example above, to build only helpers, one should run bjam hello..helpers.
將使得 "helpers.cpp" 總是非優化地編譯。在引用一個內聯的主目標時,它的聲明名稱必須用它的父目標名稱和兩個點符作為前綴。在上例中,如果要只構建 helpers,你應該運行 bjam hello..helpers.

When no target is requested on the command line, all targets in the current project will be built. If a target should be built only by explicit request, this can be expressed by the explicit rule:
如果在命令行中沒有指定目標,則當前工程中的所有目標都將被構建。如果某個目標只能通過顯式請求構建,則可以用 explicit 規則實現:

explicit install_programs ;

Projects 工程

As mentioned before, targets are grouped into projects, and each Jamfile is a separate project. Projects are useful because they allow us to group related targets together, define properties common to all those targets, and assign a symbolic name to the project that can be used in referring to its targets.
如前所述,目標是被組織到工程中的,每一個 Jamfile 是一個獨立的工程。工程是非常有用的,因為它允許我們將相關聯的目標組織在一起,定義對所有目標通用的屬性,並賦予目標一個符號名稱,以便用於對其目標的引用。

Projects are named using the project rule, which has the following syntax:
工程是用 project 規則來命名的,具有以下語法:

project id : attributes ;

Here, attributes is a sequence of rule arguments, each of which begins with an attribute-name and is followed by any number of build properties. The list of attribute names along with its handling is also shown in the table below. For example, it is possible to write:
這裡的 attributes 是一個規則參數列表,其中每一個都是以屬性名開頭,後跟任意數量的構建屬性。屬性名列表及其處理在後文的表中列出。例如,你可以寫:

project tennis
: requirements <threading>multi
: default-build release
;

The possible attributes are listed below.
可用的屬性列出如下:

Project id is a short way to denote a project, as opposed to the Jamfile's pathname. It is a hierarchical path, unrelated to filesystem, such as "boost/thread". Target references make use of project ids to specify a target.
Project id 是表示工程的一個縮寫,與 Jamfile 的路徑名相反。它是一個分級路徑,與文件系統無關,例如 "boost/thread"。目標引用 使用 project id 來指定一個目標。

Source location specifies the directory where sources for the project are located.
Source location 指定該工程的源文件所在的目錄。

Project requirements are requirements that apply to all the targets in the projects as well as all subprojects.
Project requirements 是應用於該工程及所有子工程的所有目標的要求。

Default build is the build request that should be used when no build request is specified explicitly.
Default build 是在未明確指定構建請求時使用的構建請求。

The default values for those attributes are given in the table below.
這些屬性的缺省值在下表中給出。

Table 28.1. 
表 28.1.

Attribute
屬性
Name
名字
Default value
缺省值
Handling by the project rule
project 規則的處理
Project id none
none
Assigned from the first parameter of the 'project' rule. It is assumed to denote absolute project id.
從 'project' 規則的第一個參數賦值。它被假定為表示絕對的 project id。
Source location source-location The location of jamfile for the project
本工程的 jamfile 的位置
Sets to the passed value
設置為傳入的值。
Requirements requirements The parent's requirements
父工程的要求
The parent's requirements are refined with the passed requirement and the result is used as the project requirements.
將父工程的要求和傳入的要求精化,結果作為工程要求。
Default build default-build none
Sets to the passed value
設置為傳入的值。
Build directory build-dir Empty if the parent has no build directory set. Otherwise, the parent's build directory with the relative path from parent to the current project appended to it.
如果父工程沒有 build directory 設置則為空。否則,為父工程的構建目錄加上從父工程到本工程的相對路徑。
Sets to the passed value, interpreted as relative to the project's location.
設置為傳入的值,按相對於工程位置進行解釋。


Besides defining projects and main targets, Jamfiles often invoke various utility rules. For the full list of rules that can be directly used in Jamfile see the section called 「Builtin rules」.
除了定義工程和主目標之外,Jamfiles 通常還調用一些工具規則。有關可以在 Jamfile 中直接使用的規則的完整列表,請見 「內建規則」一節

Each subproject inherits attributes, constants and rules from its parent project, which is defined by the nearest Jamfile in an ancestor directory above the subproject. The top-level project is declared in a file called Jamroot rather than Jamfile. When loading a project, Boost.Build looks for either Jamroot or Jamfile. They are handled identically, except that if the file is called Jamroot, the search for a parent project is not performed.
各子工程會繼承來自於父工程的屬性、常量和規則,它們是由子工程的一個最近的父目錄的 Jamfile 所定義的。頂層的工程由一個名為 Jamroot 的文件聲明,而不是 Jamfile。在裝入一個工程時,Boost.Build 查找 JamrootJamfile。它們的處理方式是一樣的,除了一點,如果文件名為 Jamroot,則不再查找父工程。

Even when building in a subproject directory, parent project files are always loaded before those of their subprojects, so that every definition made in a parent project is always available to its children. The loading order of any other projects is unspecified. Even if one project refers to another via the use-project or a target reference, no specific order should be assumed.
即使是在一個子工程目錄中進行構建,父工程的文件也會在裝入子工程文件之前被裝入,這樣在父工程中的每個定義對於子工程來說都是可用的。而其它工程的裝入順序則是未指定的。即便一個工程通過 use-project 或目標引用來引用了另一個工程,也不能假定某個特定順序。

[Note] Note 說明

Giving the root project the special name 「Jamroot」 ensures that Boost.Build won't misinterpret a directory above it as the project root just because the directory contains a Jamfile.

為根工程給定一個特殊的名稱 「Jamroot」,可以確保 Boost.Build 不會由於更上一層的目錄中含有 Jamfile 而誤以為上層的目錄才是工程的根。

The Build Process 構建過程

When you've described your targets, you want Boost.Build to run the right tools and create the needed targets. This section will describe two things: how you specify what to build, and how the main targets are actually constructed.
當你完成了對目標的描述,你就會希望 Boost.Build 可以運行正確的工具來創建所需的目標。這一節將講述兩件事:你如何指定要構建什麼,以及主目標實際上是如何被構造的。

The most important thing to note is that in Boost.Build, unlike other build tools, the targets you declare do not correspond to specific files. What you declare in a Jamfile is more like a 「metatarget.」 Depending on the properties you specify on the command line, each metatarget will produce a set of real targets corresponding to the requested properties. It is quite possible that the same metatarget is built several times with different properties, producing different files.
要 留意的最重要的事情是,在 Boost.Build 中,和其它構建工具不同,你所聲明的目標並不對應於特定的文件。你在  Jamfile 中所聲明的東西類似於一個「元目標」。根據你在命令行中指定的屬性,各元目標會生成一組與請求屬性相對應的真實目標。同一個元目標很有可能被按不同的屬性 多次構建,生成不同的文件。

[Tip] Tip 提示

This means that for Boost.Build, you cannot directly obtain a build variant from a Jamfile. There could be several variants requested by the user, and each target can be built with different properties.
這意味著,對於 Boost.Build,你不能從一個 Jamfile 直接得到一個構建體。用戶可以請示多個構建體,各個目標可以按不同屬性構建。

Build Request 構建請求

The command line specifies which targets to build and with which properties. For example:
命令行指定了構建哪一個目標和按哪些屬性構建。例如:

bjam app1 lib1//lib1 toolset=gcc variant=debug optimization=full

would build two targets, "app1" and "lib1//lib1" with the specified properties. You can refer to any targets, using target id and specify arbitrary properties. Some of the properties are very common, and for them the name of the property can be omitted. For example, the above can be written as:
將按指定屬性構建兩個目標,"app1" 和 "lib1//lib1"。你可以用 target id 指定任何目標,並指定不同的屬性。有些屬性很常用,這些屬性的名字可以省略。例如,上一個例子可以寫為:

bjam app1 lib1//lib1 gcc debug optimization=full

The complete syntax, which has some additional shortcuts, is described in the section called 「Command line」.
完整的語法以及一些其它縮寫,在 「命令行」一節 中講述。

Building a main target 構建一個主目標

When you request, directly or indirectly, a build of a main target with specific requirements, the following steps are done. Some brief explanation is provided, and more details are given in the section called 「Build process」.
當你直接或間接地請求按指定要求構建一個主目標時,將執行以下步驟。這裡給出一些簡要的解釋,更多細節請見 「構建過程」一節

  1. Applying default build. If the default-build property of a target specifies a value of a feature that is not present in the build request, that value is added.
    應用缺省構建。如果一個目標的 default-build 屬性中所指定的某個特性值沒有在構建請求中出現,則加上該值。

  2. Selecting the main target alternative to use. For each alternative we look how many properties are present both in alternative's requirements, and in build request. The alternative with large number of matching properties is selected.
    進行主目標選擇。對於每一種選擇,我們查看有多少屬性在選擇要求和構建請求中都出現。具有最多匹配屬性的選擇將被選中。

  3. Determining "common" properties. The build request is refined with target's requirements. The conditional properties in requirements are handled as well. Finally, default values of features are added.
    確定"通用"屬性。構建請求要按目標要求 精化。在要求中的條件屬性也同樣被處理。最後,加上特性的缺省值。

  4. Building targets referred by the sources list and dependency properties. The list of sources and the properties can refer to other target using target references. For each reference, we take all propagated properties, refine them by explicit properties specified in the target reference, and pass the resulting properties as build request to the other target.
    構建由源列表和依賴關係屬性所涉及的目標。源列表和屬性可以通過 目標引用 引向其它目標。對於每一個引用,我們接受所有 傳播進來的 屬性,將它們與在目標引用中指定的顯式屬性進行精化,並將所得到的結果屬性作為構建請求傳遞給另一個目標。

  5. Adding the usage requirements produced when building dependencies to the "common" properties. When dependencies are built in the previous step, they return both the set of created "real" targets, and usage requirements. The usage requirements are added to the common properties and the resulting property set will be used for building the current target.
    將在構建依賴關係過程中生成的使用要求加入到"通用"屬性中。當上一步的依賴關係構建完成後,將返回要創建的"真實"目標集,以及使用要求。使用要求被加入到通用屬性中,得到的結果屬性集將被用於構建當前目標。

  6. Building the target using generators. To convert the sources to the desired type, Boost.Build uses "generators" --- objects that correspond to tools like compilers and linkers. Each generator declares what type of targets it can produce and what type of sources it requires. Using this information, Boost.Build determines which generators must be run to produce a specific target from specific sources. When generators are run, they return the "real" targets.
    用 生成器構建目標。為了將源文件轉換為所期望的類型,Boost.Build 使用了"生成器" --- 與工具相對應的對象,如編譯器和鏈接器。每個生成器聲明了它可以生成的目標類型以及它所要求的源類型。通過使用這些信息,Boost.Build 決定要運行哪些生成器來從指定源生成指定目標。當生成器運行完成,它將返回"真實"的目標。

  7. Computing the usage requirements to be returned. The conditional properties in usage requirements are expanded and the result is returned.
    計算被返回的使用要求。在使用要求中的條件屬性被展開並返回結果。

Building a Project 構建一個工程

Often, a user builds a complete project, not just one main target. In fact, invoking bjam without arguments builds the project defined in the current directory.
通常,用戶會構建一個完整的工程,而不僅僅是某個主目標。實際上,不帶參數調用 bjam 將構建在當前目標中所定義的工程。

When a project is built, the build request is passed without modification to all main targets in that project. It's is possible to prevent implicit building of a target in a project with the explicit rule:
在構建一個工程時,構建請求將不作修改地傳遞給工程中的所有目標。你可以用 explicit 規則阻止工程中的的某個目標被隱式構建:

explicit hello_test ;

would cause the hello_test target to be built only if explicitly requested by the user or by some other target.
這將使得目標 hello_test 只有在用戶或其它目標明確要求時才被構建。

The Jamfile for a project can include a number of build-project rule calls that specify additional projects to be built.
一個工程的 Jamfile 可以包含多個 build-project 規則來調用其它特定工程的構建。


PrevUpHomeNext