库目标使用 lib
规则创建,它遵循 通用语法 。例如
lib helpers : helpers.cpp ;
这将定义一个名为 helpers
的库目标,它由 helpers.cpp
源文件构建。它可以是静态库或共享库,具体取决于 <link> 特性的值。
库目标可以表示
应该从源代码构建的库,如上例所示。
已存在于系统中的预构建库。这些库可以由使用它们的工具搜索(通常使用链接器的 -l
选项),或者它们路径可以由构建系统预先知道。
预构建库的语法如下所示
lib z : : <name>z <search>/home/ghost ; lib compress : : <file>/opt/libs/compress.a ;
name
属性指定库的名称,不包括标准前缀和后缀。例如,根据系统,z
可以指代名为 z.so、libz.a 或 z.lib 的文件等。 search
特性指定在默认编译器路径之外搜索库的路径。 search
可以多次指定,也可以省略,在这种情况下,只搜索默认编译器路径。 file
属性指定文件位置。
使用 file
特性与使用 name
和 search
特性组合的区别在于 file
更精确。
search
特性的值只是添加到链接器搜索路径中。当链接到多个库时,由 search
指定的路径将合并在一起,而不考虑每个路径来自哪个 lib
目标。因此,鉴于
lib a : : <name>a <search>/pool/release ; lib b : : <name>b <search>/pool/debug ;
如果 /pool/release/a.so、/pool/release/b.so、/pool/debug/a.so 和 /pool/release/b.so 都存在,链接器可能会从同一个目录中获取 a
和 b
,而不是在 /pool/release 中找到 a
,在 /pool/debug 中找到 b
。如果你需要区分多个同名库,使用 file
更安全。
为了方便起见,允许使用以下语法
lib z ; lib gui db aux ;
其效果与以下完全相同
lib z : : <name>z ; lib gui : : <name>gui ; lib db : : <name>db ; lib aux : : <name>aux ;
当库引用另一个库时,你应该将另一个库放在它的源列表中。这将确保在所有情况下都能正确处理。为了便携性,你应该即使对于搜索的和预构建的库也指定库依赖关系,否则,Unix 上的静态链接将无法工作。例如
lib z ; lib png : z : <name>png ;
当库具有共享库作为源,或者静态库具有另一个静态库作为源时,任何链接到第一个库的目标也会自动链接到它的源库。
另一方面,当共享库具有静态库作为源时,第一个库将被构建以完全包含第二个库。
如果你不希望共享库包含其源代码中指定的所有库(特别是静态链接的库),你需要使用以下方法
lib b : a.cpp ; lib a : a.cpp : <use>b : : <library>b ;
这指定了库 a
使用库 b
,并导致所有链接到 a
的可执行文件也链接到 b
。在这种情况下,即使是共享链接,a
库也不会引用 b
。
使用要求 通常对于定义库目标非常有用。例如,假设你想构建一个 helpers
库,它的接口在与 helpers.cpp
源文件位于同一目录的 helpers.hpp
头文件中描述。然后,你可以在位于同一目录中的 Jamfile 中添加以下内容
lib helpers : helpers.cpp : : : <include>. ;
这将自动将目标定义所在的目录(以及库头文件所在的位置)添加到所有使用 helpers
库的目标的编译器包含路径中。此功能极大地简化了 Jamfiles。