创建 LLVM 项目¶
概述¶
LLVM 构建系统旨在方便构建使用 LLVM 头文件、库和工具的第三方项目。为了使用这些功能,项目中的 Makefile 必须执行以下操作
设置
make变量。 有几个变量Makefile需要设置才能使用 LLVM 构建系统PROJECT_NAME- 您的项目的名称。LLVM_SRC_ROOT- LLVM 源代码树的根目录。LLVM_OBJ_ROOT- LLVM 对象树的根目录。PROJ_SRC_ROOT- 项目源代码树的根目录。PROJ_OBJ_ROOT- 项目对象树的根目录。PROJ_INSTALL_ROOT- 根安装目录。LEVEL- 从当前目录到项目根目录($PROJ_OBJ_ROOT)的相对路径。
包含来自
$(LLVM_OBJ_ROOT)的Makefile.config。包含来自
$(LLVM_SRC_ROOT)的Makefile.rules。
您可以通过两种方式设置所有这些变量
您可以编写自己的
Makefile,在其中硬编码这些值。您可以使用预制的 LLVM 示例项目。此示例项目包括
Makefile、一个可用于配置 LLVM 位置的 configure 脚本,以及支持来自单个源代码目录的多个对象目录的能力。
如果您想设计自己的构建系统,研究其他项目和 LLVM Makefile 可能会提供足够的信息来了解如何编写自己的 Makefile。
源代码树布局¶
为了使用 LLVM 构建系统,您需要组织您的源代码,使其能够受益于构建系统的功能。主要是,您希望您的源代码树布局看起来类似于 LLVM 源代码树布局。
在您的顶层目录下,您应该有以下目录
lib
此子目录应包含您的所有库源代码。对于您构建的每个库,您将在 lib 中有一个目录,其中将包含该库的源代码。
库可以是目标文件、归档文件或动态库。 lib 目录只是库的一个方便位置,因为它将它们都放在一个目录中,以便稍后可以链接它们。
include
此子目录应包含任何对您的项目全局的头文件。全局是指它们被项目的多个库或可执行文件使用。
通过将您的头文件放在 include 中,LLVM 构建系统将自动找到它们。例如,如果您有一个文件 include/jazz/note.h,那么您的源文件可以简单地使用 #include “jazz/note.h” 包含它。
tools
此子目录应包含您的所有可执行文件源代码。对于您构建的每个程序,您将在 tools 中有一个目录,其中将包含该程序的源代码。
test
此子目录应包含验证您的代码是否正常工作的测试。自动化测试尤其有用。
目前,LLVM 构建系统为测试提供基本支持。LLVM 系统提供以下内容
LLVM 在
llvm/test中包含回归测试。 这些测试由 Lit 测试工具运行。 此测试过程使用实际测试用例中的RUN行来确定如何运行测试。 有关更多详细信息,请参阅 LLVM 测试基础设施指南。LLVM 包含一个名为
llvm-test的可选包,它提供已知可以使用 Clang 前端编译的基准测试和程序。 您可以使用这些程序来测试您的代码、收集统计信息,并将其与当前的 LLVM 性能统计信息进行比较。目前,没有办法将您的测试直接挂钩到
llvm/test测试工具中。 您只需找到一种方法来使用该目录中提供的源代码。
通常,您会希望首先构建 lib 目录,然后再构建 tools 目录。
编写 LLVM 风格的 Makefile¶
LLVM 构建系统提供了一种方便的方式来构建库和可执行文件。您项目的大多数 Makefile 只需要定义几个变量。以下是可以设置的变量列表以及它们可以执行的操作
必需变量¶
LEVEL
此变量是从此
Makefile到项目源代码顶层目录的相对路径。例如,如果您的源代码位于/tmp/src中,则/tmp/src/jump/high中的Makefile会将LEVEL设置为"../.."。
用于构建子目录的变量¶
DIRS
这是应该构建的子目录的空格分隔列表。 它们将按指定的顺序一次构建一个。
PARALLEL_DIRS
这是可以并行构建的目录列表。 这些目录将在 DIRS 中的目录构建完成后构建。
OPTIONAL_DIRS
这是如果存在可以构建的目录列表,但如果它们不存在也不会导致错误。 它们按列出的顺序串行构建。
用于构建库的变量¶
LIBRARYNAME
此变量包含将要构建的库的基本名称。 例如,要构建名为
libsample.a的库,应将LIBRARYNAME设置为sample。
BUILD_ARCHIVE
默认情况下,库是一个直接链接到程序中的
.o文件。 要构建归档文件(也称为静态库),请设置BUILD_ARCHIVE变量。
SHARED_LIBRARY
如果在您的 Makefile 中定义了
SHARED_LIBRARY,则将构建共享(或动态)库。
用于构建程序的变量¶
TOOLNAME
此变量包含将要构建的程序的名称。 例如,要构建名为
sample的可执行文件,应将TOOLNAME设置为sample。
USEDLIBS
此变量保存一个空格分隔的库列表,这些库应链接到程序中。 这些库必须是来自您的 lib 目录的库。 必须在不带
lib前缀的情况下指定库。 例如,要链接libsample.a,您应将USEDLIBS设置为sample.a。请注意,这仅适用于静态链接库。
LLVMLIBS
此变量保存一个空格分隔的库列表,这些库应链接到程序中。 这些库必须是 LLVM 库。 必须在不带
lib前缀的情况下指定库。 例如,要链接执行 IR 转换的驱动程序,您可以将LLVMLIBS设置为这个最少的库集LLVMSupport.a LLVMCore.a LLVMBitReader.a LLVMAsmParser.a LLVMAnalysis.a LLVMTransformUtils.a LLVMScalarOpts.a LLVMTarget.a。请注意,这仅适用于静态链接库。 LLVM 分解为大量静态库,您需要的库列表可能比上面的列表长得多。 要查看完整的库列表,请使用:
llvm-config --libs all。 使用如下所述的LINK_COMPONENTS可以消除设置LLVMLIBS的需要。
LINK_COMPONENTS
此变量保存一个空格分隔的组件列表,LLVM
Makefile将这些组件传递给llvm-config工具,以生成程序的链接行。 例如,要链接所有 LLVM 库,请使用LINK_COMPONENTS = all。
LIBS
要链接动态库,请将
-l<库基本名称>添加到LIBS变量。 LLVM 构建系统将在与静态库相同的位置查找动态库。例如,要链接
libsample.so,您的Makefile中将包含以下行LIBS += -lsample
请注意,LIBS 必须在 Makefile 中 Makefile.common 包含之后出现。
杂项变量¶
CFLAGS & CPPFLAGS
此变量可用于向 C 和 C++ 编译器分别添加选项。 它通常用于添加选项,告诉编译器搜索头文件的其他目录的位置。
强烈建议您附加到
CFLAGS和CPPFLAGS,而不是覆盖它们。 LLVMMakefile可能已经包含您可能不想覆盖的有用选项。
目标代码的放置¶
构建的库和可执行文件的最终位置将取决于您执行的是 Debug、Release 还是 Profile 构建。
库
所有库(静态和动态)都将存储在
PROJ_OBJ_ROOT/<type>/lib中,其中 type 对于调试、优化或性能分析构建分别是Debug、Release或Profile。
可执行文件
所有可执行文件都将存储在
PROJ_OBJ_ROOT/<type>/bin中,其中 type 对于调试、优化或性能分析构建分别是Debug、Release或Profile。
更多帮助¶
如果您有任何问题或需要创建 LLVM 项目的任何帮助,LLVM 团队将非常乐意为您提供帮助。 您可以随时将您的问题发布到 Discourse 论坛。
