为构建系统定义二进制文件¶
构建系统的一部分工作是编译 C/C++ 并链接生成的对象以生成可执行文件和/或库。本文档描述了定义要构建的内容以及如何构建的基本知识。以下所有内容都描述了在 moz.build 文件中使用的构造。
源文件¶
要在给定目录中使用的源文件在 SOURCES 和 UNIFIED_SOURCES 变量中注册。 UNIFIED_SOURCES 具有特殊的行为,即它们以 16 个为一批进行聚合,例如,要求这些源文件中没有冲突的变量。
SOURCES 和 UNIFIED_SOURCES 是必须追加到的列表,并且每次追加都需要给定列表按字母顺序排序。
UNIFIED_SOURCES += [
'FirstSource.cpp',
'SecondSource.cpp',
'ThirdSource.cpp',
]
SOURCES += [
'OtherSource.cpp',
]
SOURCES 和 UNIFIED_SOURCES 可以包含各种不同文件类型的混合,例如 C、C++ 和 Objective C。
静态库¶
要构建静态库,除了定义源文件(见上文)之外,只需要使用 Library 模板定义库名称。
Library('foo')
库文件名在 UNIX 系统上将为 libfoo.a,在 Windows 上将为 foo.lib。
如果静态库需要聚合其他静态库,则可以将 Library 名称列表添加到 USE_LIBS 变量中。与 SOURCES 一样,它要求追加的列表按字母顺序排序。
USE_LIBS += ['bar', 'baz']
如果有多个目录包含相同的 Library 名称,可以通过添加所需库的路径(相对或绝对)来区分。
USE_LIBS += [
'/path/from/topsrcdir/to/bar',
'../relative/baz',
]
请注意,这些路径中的叶名称是 Library 名称,而不是实际的文件名。
请注意,当前,构建系统可能不会为静态库创建实际的库。这是一个实现细节,无需担心。
作为特殊规则,USE_LIBS 允许包含对共享库的引用。在这种情况下,链接此静态库的程序和共享库将继承这些共享库依赖项。
中间(静态)库¶
在树中的许多情况下,静态库的构建目的仅仅是为了链接到另一个更大的库(如 libxul)。与其将所有必需的库添加到较大库的 USE_LIBS 中,不如告诉构建系统当前目录中构建的库旨在使用 FINAL_LIBRARY 变量链接到该较大库。
FINAL_LIBRARY = 'xul'
FINAL_LIBRARY 值必须与树中某个地方的唯一 Library 名称匹配。
作为特殊规则,这些中间库不需要自己的 Library 名称。
可执行文件¶
可执行文件,也称为程序,在最简单的形式中,使用 Program 模板定义。
Program('foobar')
在 UNIX 系统上,可执行文件名将为 foobar,而在 Windows 上,将为 foobar.exe。
与静态库和共享库一样,可以使用 USE_LIBS 指示构建系统将库链接到可执行文件,其中列出了各种 Library 名称。
在某些情况下,我们希望为当前目录中的每个源文件创建一个可执行文件,在这种情况下,我们可以使用 SimplePrograms 模板
SimplePrograms([
'FirstProgram',
'SecondProgram',
])
与需要相应 SOURCES 的 Program 不同,使用 SimplePrograms 时,相应的 SOURCES 是隐含的。如果相应的 sources 的扩展名不同于 .cpp,则可以指定正确的扩展名
SimplePrograms([
'ThirdProgram',
'FourthProgram',
], ext='.c')
请注意,此构造是为了与 mozilla 树中已有的内容兼容而添加的;建议不要使用扩展名不同于 .cpp 的源文件添加新的简单程序。
类似于 SimplePrograms,还有 CppUnitTests 模板,它使用相同的规则定义 C++ 单元测试程序。与 SimplePrograms 一样,它接受一个 ext 参数来指定相应 SOURCES 的扩展名,如果它不同于 .cpp。
链接系统库¶
程序和库通常需要链接系统库,例如窗口小部件工具包等。可以使用 OS_LIBS 变量提供这些必需的依赖项。
OS_LIBS += [
'foo',
'bar',
]
使用 MSVC 构建时,它扩展为 foo.lib bar.lib,否则扩展为 -lfoo -lbar。
为了方便使用 pkg-config,OS_LIBS 还可以接受链接器标志,例如 -L/some/path 和 -llib,以便可以直接分配来自 CONFIG 的 LIBS 变量,例如
OS_LIBS += CONFIG['MOZ_PANGO_LIBS']
(假设 CONFIG['MOZ_PANGO_LIBS'] 是一个列表,而不是一个字符串)
与 USE_LIBS 一样,此变量适用于静态库和共享库以及程序。
来自第三方构建系统的库¶
树中的一些库不是由 moz.build 控制的构建系统构建的,并且没有与它们对应的 Library。
但是,USE_LIBS 允许通过提供完整路径来引用此类库(例如,在区分相同的 Library 名称时)。与 USE_LIBS 的其他用法相同,因此仅应提供不带前缀和后缀的库名称。
USE_LIBS += [
'/path/from/topsrcdir/to/third-party/bar',
'../relative/third-party/baz',
]
请注意,/path/from/topsrcdir/to/third-party 和 ../relative/third-party/baz 必须位于子配置目录(在 configure.in 中具有 AC_OUTPUT_SUBDIRS 的目录)或 security/nss 下。
其他¶
变量 SONAME 为库声明了一个“共享对象名称”。它默认为 Library 名称或如果已设置则为 SHARED_LIBRARY_NAME。当链接到具有 SONAME 的库时,生成的库或程序将依赖于名称对应于 SONAME 而不是 Library 名称的库。这仅影响 ELF 系统。
a/moz.build:
Library('mylib')
b/moz.build:
Library('otherlib')
SONAME = 'foo'
c/moz.build:
Program('myprog')
USE_LIBS += [
'mylib',
'otherlib',
]
例如在 Linux 上,上述 myprog 将具有针对 libmylib.so 和 libfoo.so 的 DT_NEEDED 标记,而不是 libmylib.so 和 libotherlib.so(如果没有 SONAME)。这意味着 myprog 的运行时需求是 libfoo.so 而不是 libotherlib.so。