Boost.Build简明教程(译)
Written by Boris Schäling.html
历史:linux
2018-12-20 姚彧 初版
目录c++
一个与编译器和平台都无关的编译系统 Compiler- and platform-independent build systemgit
Boost.Build是一个高级编译系统, 它能尽量容易地管理C++项目(集)。 其思想是, 在配置文件中指定生成程序所需的内容。例如,不须要告诉Boost.Build如何使用某个编译器, Boost.Build支持多个编译器,并知道如何使用它们。若是你建立一个配置文件,你只须要告诉Boost.Build源文件在哪里,调用哪些可执行文件,使用哪一个编译器。而后,Boost.Build会查找编译器并自动生成程序。github
Boost.Build支持许多不包含任何特定编译器选项的编译器配置文件。配置文件彻底是与编译器无关的。能够设置是否优化代码之类的选项, 不过,这些选项都是用Boost.Build语言写的。一旦选择编译器进行编译, Boost.Build会将配置文件中的选项翻译成相应的编译器命令行选项。这样就有可能写一次配置文件,在不一样的平台上用不一样的编译器生成程序。编程
听起来不错,但Boost.Build只支持C++和C项目. Boost.Build不知道如何使用其余编译器,好比Java编译器。虽然Boost.Build是可扩展的,可是对于用其余编程语言实现的程序,使用不一样的构建系统更有意义。bootstrap
建立Boost.Build,是为了在不一样平台上使用不一样的编译器轻松编译和安装Boost C++库。虽然Boost.Build是Boost C++库的一部分,而且附带了它,但它能够单独用于任何C++或C项目。若是您不想使用Boost C++库,甚至能够只下载Boost.Build。windows
本文是一个介绍,帮助在C++或C项目中使用Boost.Build。它让咱们对Boost.Build如何工做以及怎么使用它有基本的了解。在阅读了本文以后,您不只应该可以在本身的项目中使用Boost.Build,并且还能更容易理解Boost.Build文档,由于您将了解整个过程。安全
Jamfiles和b2解析器 Jamfiles and an interpreter called b2markdown
用于生成由Boost.Build管理项目的程序称为b2. 若是你下载和编译了Boost C++库, 你就已经用过了b2。b2查找配置文件,读取配置文件, 并编译相应的项目。它还接受各类命令行选项,例如显示在b2编译项目过程当中全部的命令。
项目能够很大,能够由许多组件组成,其源代码分布在多个目录中。不须要为整个项目建立一个大的配置文件,组件有本身的配置文件。这对于Boost.Build没有什么不一样:在一个大的项目中, 有不少的配置文件,b2会发现和解释它们。
对Boost.Build来讲, 有配置文件的目录就是一个项目: 若是目录里有配置文件,就能够编译。对Boost.Build来讲, 子目录里的一个组件与包含不少组件的软件没有区别.
当b2启动时,它不会在整个文件系统上运行搜索配置文件。它仅在当前工做目录中搜索配置文件。若是没有找到配置文件,它就什么也不作。若是当前工做目录中没有配置文件,b2不会在任何其余目录中搜索配置文件。
b2配置文件叫Jamfile.jam
. 有jam
后缀的文件叫Jamfiles
. 若是b2发现当前目录下有Jamfile
, 它会逐层查找父目录中的Jamfiles
。b2逐层查找上级目录,直到找到Jamroot.jam
文件. Jamroot.jam
与Jamfile.jam
没有区别, 它只是告诉b2不须要再查找下去.
为何b2在父目录中查找Jamfiles,是由于这样能够进行批量设置。若是一些组件有一些相同的设置, 他们能够存储在父目录的Jamfile中,这些设置会自动应用到子目录组件中。
注意:
b2必需要找到Jamroot.jam
文件, 没有Jamroot.jam
文件就会报错. 若是当前目录下有Jamroot.jam
文件, 就不须要其它Jamfile.jam
文件. 若是Jamroot.jam
在父目录, 当前目录必须有Jamfile.jam
文件, 不然, b2不会作任何事情.
若是将b2复制到不包含Jamfiles
文件的目录,并运行程序,则会收到错误消息。可是b2不会报“不能找到Jamfile”的错误,它会报”找不到构建系统”的错误。
Unable to load Boost.Build: could not find "boost-build.jam" --------------------------------------------------------------- Attempted search from C:\Users\Boris\Desktop up to the root Please consult the documentation at 'http://www.boost.org'.
b2所作的第一件事不是查找Jamfile,而是加载编译系统。可是Boost.Build的编译系统到底是什么呢?
b2是一个解释器。它不知道如何编译任何东西。b2的任务就是解释jamfile。Boost.Build其实是在jamfile中实现的。它们包含了全部使Boost.Build成为强大工具的逻辑。由于b2只作它在Jamfiles中读取的任务,因此它须要知道在哪里能够找到构成Boost.Build的Jamfiles。
当b2启动时,它会在当前工做目录中寻找boost-build.jam
。若是没有找到文件,它会搜索全部的父目录。这个文件只须要包含一行就能够告诉b2在哪里找到编译系统。
boost-build C:/boost_1_57_0/tools/build/src ;
boost-build
以后的路径必须引用一个目录,该目录包含一个名为bootstrap.jam
的文件。这是b2加载编译系统所需的文件。随着Boost C++库,附带了Boost.Build。您能够引用Boost C++库根目录的子目录tools/build
。并且,您能够始终使用斜杠做为路径分隔符,即便是Windows。
请注意,路径和行尾的分号之间必须有空格。没有空格是语法错误。在本文后面,您将了解更多Jamfiles中使用的语法。
若是b2找到了boost-build.jam
。它使用文件中的路径来加载编译系统。编译系统加载后,它还会准备要使用的编译器、连接器,和编译项目所需的其余工具。Boost.Build将这些程序称为工具集。若是运行b2时没有使用命令行选项,则编译系统将尝试找到它能够自动使用的工具集(toolset)。例如,它在Windows上搜索Visual C++。若是它检测到Visual C++已经安装,它就会使用工具集(toolset)msvc。
warning: No toolsets are configured. warning: Configuring default toolset "msvc". warning: If the default is wrong, your build may not work correctly. warning: Use the "toolset=xxxxx" option to override our guess. warning: For more configuration options, please consult warning: http://boost.org/boost-build2/doc/html/bbv2/advanced/configuration.html
若是在启动b2时, 没有指定使用哪一个工具集,则会看到警告。b2告诉您它检测到并决定使用哪一个工具集。若是您想要隐藏警告,您必须本身指定工具集。例如,要使用Visual C++, 输入b2 toolset=msvc
。若是但愿使用GCC,则输入b2 toolset= GCC
。
到目前为止,支持的工具集超过10个。Boost.Build颇有可能与您使用的编译器能够一块儿工做。
一旦找到了编译系统, 加载并知道使用哪个工具集(要么指定, 要么是编译系统自动检测的) b2在当前目录找到Jamfile.jam
文件。若是没有找到Jamfile, 就会输出错误消息。
error: error: no Jamfile in current directory found, and no target references specified.
若是您建立一个空Jamfile.jam
文件, 启动b2会输出另外的错误消息。
error: Could not find parent for project at '.' error: Did not find Jamfile.jam or Jamroot.jam in any parent directory.
b2要找到一个名为Jamroot.jam
的Jamfile。若是它不存在于当前的工做目录中,b2但愿在父目录中找到它。
若是您建立一个空的Jamroot.jam
文件, 运行b2, 错误消息会消失。显然, 如今Boost.Build什么都没有作。可是如今您知道了b2是如何编译程序的,以及最小Boost.Build配置是什么样子的。
注意: 若是是一个小项目,而且只须要一个配置文件,那么能够只要Jamroot.jam
, 而不要Jamfile.jam
。
规则和特性 Rules and features
若是查看Jamfiles
,语法可能会让您想起其余编译系统使用的配置文件。简单的Jamfile
可能看起来像普通的旧配置文件,也是键值对。可是须要理解的关键点是,Jamfile
其实是脚本文件。是在用编程语言编写Jamfile
。b2不是Boost.Build
的核心组件, 它知道如何编译程序。Boost.Build的逻辑在Jamfile中, 它在告诉b2如何编译程序。
即便Boost.Build是基于编程语言,在建立Jamfile时也不须要考虑编程。Boost.Build编程语言的语法, 能让咱们更多地建立普通的旧配置文件。这样作的目的是实现两个方面的最佳结合:(深刻浅出)一种功能强大且灵活的编程语言,但又是在其它编译系统中熟悉的简单语法。
本文不是向您介绍Boost.Build的编程语言。这种编程语言是专有的,使用起来并不有趣。它不是Javascript或Python等流行脚本语言的竞争对手。Boost.Build的开发人员认识到这一点,并使用另外一个基于Python的Boost.Build版本。然而,对于计划使用Boost.Build管理项目的开发人员来讲,全部这些都没有什么关系。一旦认识到Boost.Build中有一种编程语言,它将有助于更好地理解jamfile的语法。可是不须要学习编程语言的细节。
让咱们看一个简单的Jamfile,它能够用于从源文件hello.cpp
编译hello执行程序。
exe hello : hello.cpp ;
Boost.Build提供了许多内置规则,exe
就是其中之一。虽然Boost.Build的文档将exe
做为规则引用,可是您已经知道,上面的Jamfile其实是使用编程语言构建的。事实上, 规则只是函数。上面的Jamfile包含一个函数调用。
对于编译程序一般须要作的大多数任务,Boost.Build提供了预约义规则(函数)。它和其余编程语言中的函数同样,能够传递参数。在上面的Jamfile中,在调用函数exe
时, 使用了两个参数hello
和hello.cpp
。
Boost.Build编程语言只基于一种数据类型: 全部内容都是字符串列表。列表能够是空的,也能够包含一个或多个字符串。在上面的Jamfile中,在调用函数exe
时, 使用了两个参数, 每一个参数包含一个字符串的列表。
exe "hello" : "hello.cpp" ;
可使用引号, 但并没必要须, 由于列表中的每一个值都是字符串数据类型。只有参数包含空格时才使用引号。
规则和第一个参数之间没有特殊的分隔符,可是必须其余参数间必须使用冒号分隔。它还须要以分号结束一行,就像您从C++中习惯的那样。
请注意,Boost.Build的编程语言要求在全部标志周围都有一个空格。例如,冒号的左边和右边必须有一个空格, 分号的左边必须有一个空格。若是标志周围没有空格,b2将没法正确解析jamfile。
若是在包含上面Jamfile和hello.cpp
文件的目录中运行b2, 且在Windows上使用msvc工具集,将建立一个子目录bin\msvc-9.0\debug
, 用来编译可执行的hello.exe。
PS > b2 warning: No toolsets are configured. warning: Configuring default toolset "msvc". warning: If the default is wrong, your build may not work correctly. warning: Use the "toolset=xxxxx" option to override our guess. warning: For more configuration options, please consult warning: http://boost.org/boost-build2/doc/html/bbv2/advanced/configuration.html ...found 16 targets... ...updating 10 targets... msvc.write-setup-script bin\standalone\msvc\msvc-14.1\msvc-setup.bat compile-c-C++ bin\msvc-14.1\debug\hello.obj hello.cpp msvc.link bin\msvc-14.1\debug\hello.exe msvc.manifest bin\msvc-14.1\debug\hello.exe ...updated 11 targets...
正如您所看到的,从源文件编译可执行文件只须要Jamfile中的一行。若是程序是在Windows上编译的,甚至还有正确的文件扩展名exe
。
Boost.Build的主要优势是,定义所需的内容, 以告诉编译系统如何生成程序. Boost.Build能够自动完成的任何事情都是自动完成的。您不须要检测构建在某个程序上的平台,以决定是否应该添加exe之类的文件扩展名。您不须要指定如何调用Visual C++
之类的编译器来编译源代码。
Boost.Build支持许多现成的工具集。因为可使用不一样的工具集编译程序,Boost.Build使用与工具集相关的目录。经过这种方式,能够用不一样的工具集构建程序,而不须要一个工具集不断覆盖另外一个工具集生成的文件。
不只有工具集相关的目录, 还有版本相关的目录。版本是指调试或发行。对于每一个版本, 都有一个目录用于编译程序 —— 这样也不会覆盖另外一个版本生成的文件。默认状况下, 生成调试版本。这就是为何会建立子目录bin\msvc-9.0\debug
的缘由。若是您想要建立一个发行版本, 您能够在命令行中指定版本b2 variant=release
, 或, 甚至更简单b2 release
。
b2 release warning: No toolsets are configured. warning: Configuring default toolset "msvc". warning: If the default is wrong, your build may not work correctly. warning: Use the "toolset=xxxxx" option to override our guess. warning: For more configuration options, please consult warning: http://boost.org/boost-build2/doc/html/bbv2/advanced/configuration.html ...found 15 targets... ...updating 3 targets... compile-c-C++ bin\msvc-14.1\release\hello.obj hello.cpp msvc.link bin\msvc-14.1\release\hello.exe msvc.manifest bin\msvc-14.1\release\hello.exe ...updated 3 targets...
根据variant
参数release
, 将hello.exe
编译到目录bin\msvc-9.0\release
.
选择版本是一件常常要作的事情,b2 release
就能够。Boost.Build指出发行版是为了选择版本(variant)。
若是您不但愿在命令行上指定版本,但但愿在默认状况下构建hello.exe
的发行版,Jamfile修改以下:
exe hello : hello.cpp : <variant>release ;
exe
规则(函数)接受几个可选参数。第三个参数是需求列表。您能够想象命令行选项,这些选项老是设置并传递给运行命令以编译可执行文件。
为了强制编译发行版,variant
属性必须设置为release
,就像之前在命令行上所作的那样。可是在Jamfile中设置变量的语法与其它编译工具是不一样的。
Boost.Build定义了类XML标记的特性(features)。Boost.Build支持的特性之一是<variant>
。若是一个特性要设置为一个值,那么值必须放在<variant>
标记的旁边(中间没有空格)。一些特性是自由的,这意味着它们能够被设置为您想要的任何值。<variant>
是一个非自由特性,由于它只能被设置为debug
或release
, 不容许有其余值。若是设置了其它值,b2会输出错误。
若是您运行b2 variant=debug
, 并试图编译hello.exe的调试版, 它不能成功,由于Jamfile包含hello.exe
要做为一个发布版编译的要求(requirement)。若是您但愿可以在命令行上覆盖该特性,则必须将该特性做为第四个参数而不是第三个参数传递。
exe hello : hello.cpp : : <variant>release ;
第四个参数包含默认使用但能够覆盖的特性。
若是您要在默认状况下, 生成hello.exe的debug和release版, 那么, 须要两次设置<variant>
特性为debug
和release
。
exe hello : hello.cpp : : <variant>debug <variant>release ;
这很是重要,<variant>
在第四个参数(默认值)中设置了两次。若是是指定需求的第三个参数,b2将输出错误。能够在需求中屡次设置特性,可是只有在值不是互斥的状况下才能够。程序不能在第三个参数中同时设置为debug,release版. 只有在默认值部分设置<variant>
, 这样, Boost.Build才理解如何编译hello的两个exe
版本。
exe hello : hello.cpp : <define>WIN32 <define>_WIN32 : <variant>debug <variant>release ;
上面的Jamfile是一个在需求中屡次设置特性的例子。特性<define>
用于定义预处理器指令。定义几个预处理器指令是没有问题的。所以,hello.exe
的两个版本都使用了的两个指令WIN32
和_WIN32
来生成它们。
exe hello : hello.cpp : : <variant>debug <variant>release <define>WIN32 <define>_WIN32 ;
若是将定义移动到第四个参数,并运行b2,则hello.exe
的两个版本, 都一样使用两个指令WIN32和_WIN32进行编译. 因为<define>
不指望互斥值,所以没有生成其余可执行文件集。这个Jamfile与上一个Jamfile的唯一区别是,在第四个参数中传递的指令是默认值,能够删除这些值,而做为第三个参数传递的任何指令都是不可变的要求。
下面是另外一个值互斥的特性示例。
exe hello : hello.cpp : : <variant>debug <variant>release <optimization>speed <optimization>off ;
b2建立hello.exe
的四个版本。针对速度优化的调试版、没有优化的调试版、针对速度优化的发行版和没有优化的发行版。全部这些版本都编译在自动建立的独立目录中。
到目前为止,惟一使用的规则是exe
。可是Boost.Build提供了更多的内置规则。另外一个重要的规则是lib
,它用于编译一个库。
lib world : world.cpp ;
上面的Jamfile从源文件world.cpp
编译了一个共享库。在Windows上, 会建立一个world.dll
的文件。一般, 文件扩展名是由Boost.Build自动追加。
默认状况下,将生成一个共享库。若是但愿生成静态库,能够将<link>
特性设置为static
。
lib world : world.cpp : <link>static ;
另外一个有用的规则是install
。在生成了可执行文件和库以后,可使用此规则来安装它们。
exe hello : hello.cpp ; install "C:/Program Files/hello" : hello ;
上面的Jamfile, 会把可执行文件hello.exe
安装到C:\Program Files\hello
. 第二个参数hello
是对第一行中定义的目标hello
的引用。请注意,路径必须加引号,由于它包含一个空格。
在这里,从其它编译系统的概念颇有价值: 与其考虑函数调用,不如每行定义一个目标。依赖关系是经过引用其余目标建立的。这就是Boost.Build如何知道应该以什么顺序生成目标。
可是,install
规则的编写一般是不一样的。使用<location>
特性在第三个参数中设置安装目录,而不是将安装目录做为第一个参数传递。
exe hello : hello.cpp ; install install-bin : hello : <location>"C:/Program Files/hello" ;
使用<location>
更好的主要缘由是, 第一个参数老是定义一个目标。其余规则可能引用目标。这就是为何, 使用之后没必要更改的目标名称是一个好主意。设想一个程序应该安装到另外一个目录。若是<location>
特性已被用做不须要更新可能引用到install-bin的其余规则,则更改安装目录将更容易。It's easier to change the installation directory if the <location>
feature has been used as no other rules which might refer to install-bin have to be updated.
使用特性还有另外一个缘由。Boost.Build支持条件属性,这些属性能够根据编译程序的平台使用不一样的安装目录。
exe hello : hello.cpp ; install install-bin : hello : <target-os>windows:<location>"C:/Program Files/hello" <target-os>linux:<location>/usr/local/bin ;
特性<target-os>
是另外一个具备互斥值的特性。例如,它能够设置为windows或linux,但不能同时设置为windows和linux。
特性<location>
在<target-os>
以后, 仅用冒号分隔。这样的构造称为条件属性: Boost.Build根据操做系统选择安装目录。
固然,条件属性也能够与其余规则一块儿使用。例如,在编译程序或库时,能够根据不一样的版本定义不一样的预处理器指令。
Boost.Build提供了更多的内置规则。另外一个有用的规则是glob
,它让使用通配符成为可能。在一个包含许多源文件的大型项目中,不须要逐一列出它们,而是使用glob
引用它们。
exe hello : [ glob *.cpp ] ;
上面的Jamfile包含一个嵌套的函数调用: 规则glob
的结果做为第二个参数传递给exe。因为编程语言的要求,Boost.Build是基于方括号的,必须用于嵌套函数调用。
多Jamfiles
在有不少jamfile的大型项目中,须要以某种方式链接jamfile。在项目的根目录, 一般有一个Jamroot.jam
文件, 在各个子目录, 有Jamfile.jam文件。若是在根目录中运行b2,开发人员可能但愿生成整个项目,包括子目录中的全部组件。当b2在父目录而不是子目录中查找jamfile时,jamfile须要显式地引用子目录中的jamfile。
build-project hello ;
若是一个Jamfile看起来像上面的示例,它将引用hello
子目录中的Jamfile。build-project
是一个规则,它指望路径做为它的惟一参数, 而后在该路径中查找Jamfile。
build-project hello ; build-project world ;
若是您但愿构建多个项目,则必须屡次使用build-project。
除了在子目录中引用jamfile以外,在项目中生成组件时, 对应该使用的选项进行分组也是有意义的。
project : default-build release ; build-project hello ; build-project world ;
project
规则接受各类参数,以便为当前工做目录和子目录中的Jamfile设置选项。
project
规则使用命名参数, 而其余规则,如exe
和lib
,参数顺序传递。在上面的示例中,参数的名称是default-build。这就是为何能够在一个很是不一样的参数中传递值release
。(That's why it is possible to pass the value release in a very different parameter.)
project : : : : : : : : : default-build release ; build-project hello ; build-project world ;
将release
做为第10个参数传递是没有意义的。但它的工做原理是, project
不关心顺序。它可使用第10个参数default-build
。
project
只支持几个命名参数。另外一个参数是requirements
,它能够用来设置不能修改的选项。
project : requirements <variant>release ; build-project hello ; build-project world ;
上面的Jamfile只生成release版。不可能再生成debug版本,由于不能修改需求。这与上一个示例中使用的名为default-build的命名参数不一样: 它能够修改。
当使用build-project
时,Boost.Build假定该参数是对一个子目录的引用。咱们之前见过另外一种类型的引用。
exe hello : hello.cpp ; install install-bin : hello : <location>"C:/Program Files/hello" ;
在上面的Jamfile中,install
规则引用第一行中定义的目标hello
。
在大型项目中,可能须要引用在其余目录里jamfile中定义的目标。可使用双斜杠将路径与Jamfile中的目标相连。It is possible to concatenate a path to a Jamfile and a target with a double slash.)
install install-bin : subdir//hello : <location>"C:/Program Files/hello" ;
如今,install
规则引用子目录subdir
中的Jamfile中的目标hello
。
让咱们假设可执行hello依赖于另外一个目录中的world
库。这个库也是用Boost.Build使用lib
规则生成的。
lib world : world.cpp ;
在生成可执行文件的Jamfile中,须要引用库的Jamfile。没有必要直接引用world
目标,由于默认状况下,Jamfile中的全部目标都是构建的。
exe hello : hello.cpp world : : <variant>debug <variant>release ;
上面的Jamfile假设库及其Jamfile位于子目录world
中。
在生成可执行文件时,会生成两个版本 — 调试版和发行版。虽然库的Jamfile没有设置<variant>
特性, 可是Boost.Build假定它也会构建这个库的两个版本。特性<variant>
在这里就进行了传播。
传播特性(Propagating features)简化了项目管理,由于您不须要在各类jamfile中设置相同的特性。固然,这也使得理解组件是如何构建的变得更加复杂,由于它彻底依赖于传播的特性。您能够假定Boos.tBuild知道它应该作什么。固然,这并不意味着你很容易理解它作了什么。
让咱们看另外一个使用特性<define>
的例子。
exe hello : hello.cpp world : <define>WIN32 : <variant>debug <variant>release ;
上面的Jamfile为程序hello
定义了一个预处理器指令WIN32
。可是WIN32
也会为这个库定义吗?
它不会,由于<define>
不是一个传播特性。若是您想知道应该如何知道: 查找传播特性的唯一方法是查找文档。
若是您安装了Boost C++库,您可能但愿连接到其中一些库。您必须以某种方式向项目的Jamfile中相应的Boost C++库添加一个依赖项。若是没有删除已解压缩Boost C++库源文件的目录,则能够引用根目录中Jamfile中的目标。
exe hello : hello.cpp world C:/boost_1_39_0//filesystem/ ;
如今, hello还依赖于Boost.Filesystem库。因为目标文件系统是在Boost C++库根目录下的Jamfile中定义的,所以exe
规则能够引用它。不只会连接适当的Boost C++库 —— 还会将include目录传递给编译器以查找头文件。若是hello.cpp
包含boost/filesystem.hpp
,就会找到这个头文件。
在上面的Jamfile中,Boost C++库的根目录的路径是硬编码的。b2须要知道在哪里能够找到Boost C++库。可是,若是只硬编码一次路径,以防止项目中的几个组件须要连接到某个Boost C++库,那就更好了。
project : requirements <variant>release ; use-project /boost : C:/boost_1_39_0 ; build-project hello ; build-project world ;
use-project
规则用于定义另外一个目录中Jamfile的别名。子目录中的Jamfiles使用别名引用Boost C++库。
exe hello : hello.cpp world /boost//filesystem ;
b2会分析出hello.cpp
是源文件,world
是子目录,/boost//filesystem
是对C:\boost_1_39_0
目录里, Jamfile文件中的目标filesystem的引用。
请注意, 若是引用的是项目,引用必须以斜杠开头。
因为库能够用不一样的方式连接,所以能够设置与连接器相关的特性。
exe hello : hello.cpp world /boost//filesystem/<link>static ;
默认状况下,库是动态连接的。若是库应该静态连接,则必须将特性<link>
设置为static
。
特性能够用斜杠附加。若是须要设置多个特性,则在前一个特性后面附加另外一个斜杠。
exe hello : hello.cpp world /boost//filesystem/<link>static/<threading>multi ;
<threading>
是另外一个能够设置为single(单线程)
或multi(多线程)
的特性。若是hello应该连接到线程安全( thread-safe)版本的Boost.Filesystem,则能够相应地设置该特性。
经过引用Jamfile连接Boost C++库可能并不老是有效。若是Boost C++库的安装方式不一样,由于它们不是从源代码生成的,那么就不会有任何能够引用的Jamfile。
lib filesystem : : <name>libboost_filesystem <search>C:/libs ; exe hello : hello.cpp world filesystem : <include>C:/include ;
lib
规则不只能够用于从源代码生成库。它还用于引用现有预生成的库。
若是lib
不须要从源代码生成库,则第二个参数必须为空。在第三个参数中,特性<name>
和<search>
用于指定库的名称和用于Boost.Build查找库的位置。
以独立于平台的方式指定库名很是重要。例如,对于上面的Jamfile, Boost.Build将尝试在Windows上找到libboost_filesystem.lib文件。一般的文件扩展名会自动附加。
若是您想经过指定文件的确切名称来引用文件,可使用<file>
特性。
若是应该引用一个系统库,您能够指望Boost.Build知道在哪里能够找到它,那么能够删除<search>
特性。
也可使用project
规则来确保项目中的全部目标都自动连接到库。
lib filesystem : : <name>libboost_filesystem <search>C:/libs ; explicit filesystem ; project : requirements <include>C:/include <library>filesystem ; lib world : world.cpp ;
必须使用名为<library>
的特性向project
规则添加库依赖项。<library>
必须引用一个使用已知特性<name>
和<search>
的lib
规则。
如今,明确lib
规则很是重要。这是经过使用explicit
规则来实现的。这很重要,由于默认状况下,Jamfile中的全部目标都是生成的。当project
规则为Jamfile中的全部目标定义需求时,它们也是lib
规则的需求。所以,lib
规则指的是它本身。若是lib
规则是explicit(显式)
的,它就不会生成的,也不会发生递归引用。
请注意,只有当规则引用目标时,Jamfile中的规则顺序才重要: 在引用目标以前,必须定义了目标。
其余人如何使用Boost.Build How Boost.Build is used by others
因为Boost.Build是一个高级编译系统,若是您保持Jamfiles平台和编译器独立,那么您将得到最大的好处。毕竟,您的想法是在任何平台上使用任何编译器编译C++或C项目,而不须要修改或维护多个jamfile。
您将遇到的一个典型问题是,但愿使用的第三方库将安装在不一样的目录中。若是但愿在Windows和Unix平台上生成项目,路径看起来也很是不一样。此外,您可能须要连接某个平台上的一些系统库,而在另外一个平台上不须要。
与其尝试将不一样平台的路径放在项目的jamfile中,不如依赖每一个系统上的配置文件进行特定于系统的设置。实际上,b2在启动时确实会寻找另外两个配置文件。
应该使用site-config.jam
文件为整个系统设置选项, 它是机器特有的, b2是但愿在下列目录中找到它, Windows平台上的C:\Windows
目录, Unix系统的/etc
目录。由于site-config.jam
是依赖于机器的,因此到本地库的路径是没有问题的。
可是, 用户可能没法建立或更改site-config.jam
。它们要么须要等待系统管理员更新文件,要么再次被迫向本身的jamfile添加特定于系统的路径。因为这两种方法都不是一个好的解决方案,b2还会在用户的主目录中寻找user-config.jam
。在Windows上它是C:\Users
的子目录,在Unix上它是/home
的子目录。因为用户能够维护user-config.jam
文件,因此它可能比site-config.jam
更经常使用。
您能够像使用其余任何Jamfile同样使用site-config.jam
和user-config.jam
。因为这些配置文件不属于项目,而是属于机器或机器上的用户,所以容许它们包含特定于机器的选项。例如,它们能够包含一个using
规则。
using msvc ;
上面的using
规则告诉b2使用msvc工具集。若是您知道系统上只安装了Visual C++,那么将这行代码放入配置文件是有意义的。这样b2就不须要再猜想要使用哪一个工具集,也不会遗漏一个警告。
若是您在site-config.jam
或user-config.jam
中定义目标,而且但愿在Jamfiles中引用这些目标,则必须使用project
规则来设置名称。
using msvc ; project user-config ; lib xml : : <name>libxml <search>C:/lib : : <include>C:/include ;
这里, lib
规则用于引用一个预生成的库,它的名称是libxml
,能够在C:\lib
中找到它。使用这个XML库的程序可能须要包含这个库中的头文件。这就是为何在使用需求中的第五个参数 —— 特性<include>
设置为C:\include
: 使用这个规则将继承<include>
特性。
因为project
规则设置了名称为user-config
,因此Jamfile能够经过 /user-config//xml
引用XML库。
exe xmlparser : xmlparser.cpp : <library>/user-config//xml ;
为了生成xmlparser
,必须将程序连接到XML库。尽管库及其头文件的位置可能有所不一样,可是Jamfile并不包含任何特定于系统的路径。Jamfile但愿在项目user-config
中找到目标xml
。若是这是一个配置文件,那么在将全部配置文件绑定到机器或机器上的用户以后,使用特定于系统的路径是没有问题的。
因为已经建立了Boost.Build来生成和安装Boost C++库,所以在系统配置文件中内置,能够更轻松地使用预生成的Boost C++库。
using msvc ; project user-config ; using boost : 1.39 : <include>C:/include/boost-1_39 <library>C:/lib ;
using
规则必须用于引用名为boost的工具集。这个工具集不一样于msvc这样的工具集(到目前为止您已经读过的): 它不包含任何将在稍后运行的程序。做为对预生成的Boost C++库的支持,已经在一个工具集中实现了,可是须要使用using
规则。
与其余库同样,Boost C++库的位置可能有所不一样。所以,将using
规则放入两个配置文件之一是有意义的。
能够将参数传递给using
规则: 第一个是版本号,第二个是选项列表。在上面的Jamfile中使用了Boost C++库1.39,能够在做为选项传递的目录中找到它。
一旦使用了boost工具集,就可使用Boost C++库而无需本身定义目标。
import boost ; boost.use-project 1.39 ; exe hello : hello.cpp : <library>/boost//thread ;
若是一个程序使用Boost C++库,它能够引用名为boost
的项目中的目标。为了识别项目的boost,必须导入boost模块和使用boost.use-project
规则: 导入boost模块让boost.use-project
规则可用。此规则指望版本号做为其惟一参数。因为可使用using
规则来引用Boost C++库的不一样版本,因此项目能够指定要使用哪一个版本。在上面的Jamfile中,程序hello
使用1.39版的Boost.Thread
。
Building blocks for Jamfiles
若是您使用Boost.Build管理项目并建立jamfile,那么您将一直使用规则。所以,您应该知道存在哪些规则以及如何使用它们。下表概述了最重要的规则。
在一些参数后面有一个星号、加号或问号。星号意味着能够有任意多个值,加号必须至少有一个值,问号必须是零或刚好有一个值。
Name | Parameters | Description |
---|---|---|
alias | name : sources * : requirements * : default-build * : usage-requirements * | Refer to sources or |
build-project | dir | Refer to a Jamfile in another directory to build a project. |
conditional | condition + : requirements * | Create conditional requirements without using conditional |
exe | name : sources * : requirements * : default-build * : usage-requirements * | Build an executable. |
explicit | target-names * | Make targets explicit. |
glob | wildcards + : excludes * | Reference files in a directory via wildcards. |
glob-tree | wildcards + : excludes * | Reference files in a directory and all subdirectories via wildcards. |
install | name-and-dir : sources * : requirements * : default-build * | Install files to a directory. |
lib | names + : sources * : requirements * : default-build * : usage-requirements * | Build a library. |
project | id ? : options * : * | Set project options. |
unit-test | target : source : properties * | Build and run an executable. |
use-project | id : where | Reference a Jamfile in another directory to use the project id as a target. |
using | toolset-module : * | Select a toolset. |
您的Boost.Build版本可能支持比上面列出的更多的规则。若是您想知道支持哪些规则,您应该查看Boost.Build安装的子目录build
中的文件。
生成过程的配置选项 Configuration options for the build process
Name | Values | Description |
---|---|---|
<address-model> |
16, 32, 64, 32_64 | Generate 16-, 32- or 64-bit code. |
<architecture> |
x86, ia64, sparc, power, mips1, mips2, mips3, mips4, mips32, mips32r2, mips64, parisc, arm, combined, combined-x86-power | Set processor family to generate code for. |
<c++-template-depth> |
1, 2, 3, ... | Set maximum template depth. |
<cflags> |
... | Pass flags to C compiler. |
<cxxflags> |
... | Pass flags to C++ compiler |
<debug-symbols> |
on, off | Create debug symbols. |
<def-file> |
... | Set path to def file (specific to Windows DLLs). |
<define> |
... | Define preprocessor directives. |
<embed-manifest> |
on, off | Embed manifest (specific to msvc toolset). |
<host-os> |
aix, bsd, cygwin, darwin, freebsd, hpux, iphone, linux, netbsd, openbsd, osf, qnx, qnxnto, sgi, solaris, unix, unixware, windows | Use in conditional properties if features depend on host operating systems. |
<include> |
... | Set include directories. |
<inlining> |
off, on, full | Inline functions. |
<library> |
... | Link to a library (use in project rule). |
<link> |
shared, static | Link to shared or static version of a library. |
<linkflags> |
... | Pass flags to linker. |
<location> |
... | Set directory (use in install rule). |
<name> |
... | Set basename of a library (use in lib rule). |
<optimization> |
off, speed, space | Generate optimized code. |
<profiling> |
off, on | Generate profiled code. |
<runtime-link> |
shared, static | Link to single-threaded or thread-safe runtime library. |
<search> |
... | Set directory to search for libraries (use in lib rule together with `). |
<source> |
... | Set source in requirements parameter of project rule or in conditional properties. |
<target-os> |
aix, appletv, bsd, cygwin, darwin, freebsd, hpux, iphone, linux, netbsd, openbsd, osf, qnx, qnxnto, sgi, solaris, unix, unixware, windows | Use in conditional properties if features depend on target operating systems. |
<threading> |
single, multi | Build singlethreaded or thread-safe version. |
<toolset> |
gcc, msvc, intel-linux, intel-win, acc, borland, como-linux, cw, dmc, hp_cxx, sun | Use in conditional properties if features depend on toolsets. |
<undef> |
... | Undefine preprocessor directives. |
<use> |
... | Take over only usage requirements of a referenced target but don't do anything else. |
<variant> |
debug, release, profile | Build debug, release or profile version. |
<warnings> |
on, all, off | Switch off warnings. |
<warnings-as-errors> |
off, on | Treat warnings as errors. |
有关Boost.Build特性的完整和最新引用,请在Boost.Build安装的子目录tool
中查找文件builtin.jam
。搜索以feature.feature
开始的行 —— 这是用来定义特性的内部规则。