使用 CMake 构建 LLVM

  • 1. 介绍
  • 2. 快速开始
  • 3. 基本的 CMake 用法
  • 4. 选项和变量
    • 4.1 经常使用的 CMake 变量
    • 4.2 特定于LLVM的变量
  • 5. CMake Caches
  • 6. 执行测试
  • 7. 交叉编译
  • 8. 在项目中嵌入 LLVM
    • 8.1 从源代码开发 LLVM passes
  • 9. 特定于编译器/平台的话题
    • 9.1 微软Visual c++

本文为译文,点击 此处查看原文。

1. 介绍

CMake是一个跨平台的构建生成器工具。CMake不构建项目,它生成用于构建 LLVM 的构建工具(GNU make、Visual Studio等)所需的文件。

如果您是一个新的贡献者,请从开始使用LLVM系统页面开始。这个页面适合从遗留 configure/make 系统迁移过来的现有贡献者。

如果您真的很想获得一个功能性的LLVM构建,请转到第2章 快速开始。如果您是 CMake 新手,可以从第3章 基本的 CMake 用法开始,然后在知道要做什么之后再回到第2章快速开始。第4章 选项和变量是自定义您的构建的参考。如果您已经有使用 CMake 的经验,这是推荐的起点。

此页面面向 LLVM CMake 构建的用户。如果您正在寻找有关修改 LLVM CMake 构建系统的信息,您可能想要查看CMake 入门页面。它对CMake语言有一个基本的概述。

2. 快速开始

我们在这里使用命令行,非交互式的CMake接口。

  1. 下载并安装 CMake。版本3.4.3是最低要求。
  2. 打开一个 shell。您的开发工具必须能够通过PATH环境变量从这个 shell 中访问。
  3. 创建一个 build 目录。不支持在 source 目录中构建 LLVM。进入到 build 目录:
    $ mkdir mybuilddir
    $ cd mybuilddir
    
  4. 在 shell 中执行这个命令,并且用您的 LLVM 源文件树的根路径替换 path/to/llvm/source/root
    $ cmake path/to/llvm/source/root
    

    CMake 将检测您的开发环境,执行一系列测试,并生成构建 LLVM 所需的文件。CMake 将为所有构建参数使用默认值。有关您可以修改的构建参数列表,请参阅第4章 选项和变量
    如果 CMake 无法检测到您的工具集,或者它认为环境不够健全,则此操作可能会失败。在本例中,请确保您打算使用的工具集是唯一可以从 shell 访问的工具集,并且 shell 本身是适合您的开发环境的工具集。例如,如果您有一个可以通过PATH环境变量访问的 POSIX shell,CMake将拒绝构建 MinGW makefile。您可以强制 CMake 使用一个给定的构建工具;有关说明,请参见第3章 基本的 CMake 用法

  5. CMake 运行完成后,继续使用 IDE 项目文件,或者从 build 目录开始构建:
    $ cmake --build .
    

    --build 选项告诉 cmake 调用底层构建工具(make、ninja、xcodebuild、msbuild等)。
    当然,底层构建工具可以直接调用,但是 --build 选项是可移植的。

  6. LLVM完成构建后,从build目录中安装:
    $ cmake --build . --target install
    

    除了 --build 选项外,--target 选项还带有 install 参数,它告诉cmake构建 install 目标。
    可以通过调用生成在 build 目录中的 cmake_install.cmake 脚本,以便在 install 时设置不同的 install 前缀:

    $ cmake -DCMAKE_INSTALL_PREFIX=/tmp/llvm -P cmake_install.cmake
    

3. 基本的 CMake 用法

本节解释 CMake 的基本方面,您可能在日常使用中需要这些方面。

CMake 附带了大量的文档,以 html 文件的形式提供,并通过 cmake 可执行文件本身提供在线帮助。执行 cmake --help 以获得更多的帮助选项。

CMake 允许您指定一个构建工具(例如,GNU make、Visual Studio 或 Xcode)。如果没有在命令行中指定,CMake 将根据您的环境尝试猜测要使用哪个构建工具。一旦确定了构建工具,CMake 就使用相应的 Generator 为构建工具创建文件(例如,Makefiles 或 Visual Studio 或 Xcode 项目文件)。您可以使用命令行选项 -G "Name of the generator" 显式指定 generator。要查看系统上可用generators的列表,请执行:

$ cmake --help

这将在帮助文本的末尾列出generators名称。

Generators 的名称区分大小写,并且可能包含空格。出于这个原因,您应该按照 cmake --help 输出中在引号中所列的,准确的输入它们。例如,要为 Visual Studio 12 生成特定的项目文件,您可以执行:

$ cmake -G "Visual Studio 12" path/to/llvm/source/root

对于给定的开发平台,可能有多个足够的生成器。如果您使用 Visual Studio,“NMake makefile”是一个您可以使用的生成器,它使用 NMake 进行构建。默认情况下,CMake 选择您的开发环境支持的最特定的生成器。如果你想要一个替代的生成器,你必须使用 -G 选项告诉CMake。

4. 选项和变量

变量(Variable)可以自定义生成构建的方式。选项(Option)是布尔变量,可能的 valueON/OFF。选项和变量在 CMake 命令行上定义如下:

$ cmake -DVARIABLE=value path/to/llvm/source

您可以在初始 CMake 调用之后设置一个变量来更改它的值。你也可以取消定义一个变量:

$ cmake -UVARIABLE path/to/llvm/source

变量存储在 CMake 缓存中。这是一个名为 CMakeCache.txt 的文件,存储在由cmake生成的build目录的根目录中。不建议您自己编辑它。

稍后在本文档中列出 CMake 缓存中的变量,变量名和类型由冒号分隔。您还可以在 CMake 命令行上指定变量和类型:

$ cmake -DVARIABLE:TYPE=value path/to/llvm/source
4.1 经常使用的 CMake 变量

下面是一些经常使用的 CMake 变量,以及简单的解释和特定于 LLVM 的注释。要获得完整的文档,请参考 CMake 手册,或者执行 cmake --help-variable VARIABLE_NAME

  • CMAKE_BUILD_TYPE:STRING
    为基于 make 的生成器设置构建类型。可能的值是 Release、Debug、RelWithDebInfo 和 MinSizeRel。如果您正在使用诸如 Visual Studio 之类的 IDE,您应该使用 IDE setting 来设置构建类型。注意 Release 和 RelWithDebInfo 在大多数平台上使用不同的优化级别。
  • CMAKE_INSTALL_PREFIX:PATH
    调用 “make install” 或构建 “install” 目标时,LLVM 将安装到的路径。
  • LLVM_LIBDIR_SUFFIX:STRING
    附加到要安装库的目录的额外后缀。在64位体系结构上,可以使用 -DLLVM_LIBDIR_SUFFIX=64 将库安装到 /usr/lib64
  • CMAKE_C_FLAGS:STRING
    当编译 C 源文件时要使用的额外标志。
  • CMAKE_CXX_FLAGS:STRING
    当编译 C++ 源文件时要使用的额外标志。
4.2 特定于LLVM的变量
  • LLVM_TARGETS_TO_BUILD:STRING
    以分号分隔的要构建的目标列表,或用于构建所有目标的all。大小写敏感的。默认为全部。例如:-DLLVM_TARGETS_TO_BUILD = " X86; PowerPC”。
  • LLVM_BUILD_TOOLS: BOOL
    构建LLVM工具。默认为上。在任何情况下,都会生成构建每个工具的目标。您可以通过调用工具的目标来单独构建工具。例如,您可以通过在构建目录的根目录下执行make llvm-as来使用基于makefile的系统构建llvm-as。
  • LLVM_INCLUDE_TOOLS: BOOL
    为LLVM工具生成生成目标。默认为上。您可以使用此选项来禁用为LLVM工具生成构建目标。
  • LLVM_INSTALL_BINUTILS_SYMLINKS: BOOL
    安装从binutils工具名称到相应LLVM工具的符号链接。例如,ar将符号链接到llvm-ar。
  • LLVM_BUILD_EXAMPLES: BOOL
    构建LLVM的例子。缺省值为OFF。在任何情况下都会生成构建每个示例的目标。有关更多细节,请参见上面的LLVM_BUILD_TOOLS文档。
  • LLVM_INCLUDE_EXAMPLES: BOOL
    为LLVM示例生成构建目标。默认为上。您可以使用此选项来禁用生成LLVM示例的构建目标。
  • LLVM_BUILD_TESTS: BOOL
    构建LLVM单元测试。在任何情况下,都会生成构建每个单元测试的目标。您可以使用在单元测试下定义的目标来构建一个特定的单元测试,例如ADTTests、IRTests、SupportTests等等(在单元测试的子目录中搜索add_llvm_unittest,以获得完整的单元测试列表)。可以使用目标单元测试构建所有单元测试。
  • LLVM_INCLUDE_TESTS: BOOL
    为LLVM单元测试生成生成目标。默认为上。您可以使用此选项来禁用为LLVM单元测试生成构建目标。
  • LLVM_BUILD_BENCHMARKS: BOOL
    将基准添加到默认目标列表中。默认为关闭。
  • LLVM_INCLUDE_BENCHMARKS: BOOL
    为LLVM基准生成构建目标。默认为上。
  • LLVM_APPEND_VC_REV: BOOL
    嵌入版本控制修订信息(svn修订号或Git修订id)。版本信息由llvm/include/llvm/Support/ vcsupdate .h中的LLVM_REVISION宏提供。不需要修订信息的git开发人员可以禁用此选项,以避免在分支切换之后重新链接大多数二进制文件。默认为上。
  • LLVM_ENABLE_THREADS: BOOL
    如果可以的话,使用线程支持构建。默认为上。
  • LLVM_ENABLE_UNWIND_TABLES: BOOL
    启用二进制文件中的展开表。禁用unwind表可以减小库的大小。默认为上。
  • LLVM_CXX_STD:字符串
    使用指定的c++标准构建。默认为“c + + 11”。
  • LLVM_ENABLE_ASSERTIONS: BOOL
    使代码的断言。当且仅当CMAKE_BUILD_TYPE为Debug时,默认值为ON。
  • LLVM_ENABLE_EH: BOOL
    使用异常处理支持构建LLVM。如果希望链接到LLVM库,并在自己的代码中使用c++异常(需要通过LLVM代码传播),那么这是必要的。默认为关闭。
  • LLVM_ENABLE_EXPENSIVE_CHECKS: BOOL
    启用额外的时间/内存昂贵的检查。默认为关闭。
  • LLVM_ENABLE_IDE: BOOL
    告诉构建系统正在使用IDE。这反过来又禁止创建某些方便的构建系统目标,比如各种install-*和check-*目标,因为ide并不总是能很好地处理大量目标。这通常是自动检测的,但是可以手动配置它来显式地控制这些目标的生成。当使用Visual Studio 2017的CMake集成时,可能需要手动覆盖,否则不会被检测为IDE。
  • LLVM_ENABLE_PIC: BOOL
    如果编译器支持此标志,则将-fPIC标志添加到编译器命令行。有些系统,比如Windows,不需要这个标志。默认为上。
  • LLVM_ENABLE_RTTI: BOOL
    使用运行时类型信息构建LLVM。默认为关闭。
  • LLVM_ENABLE_WARNINGS: BOOL
    启用所有编译器警告。默认为上。
  • LLVM_ENABLE_PEDANTIC: BOOL
    启用迂腐的模式。如果可能,这将禁用特定于编译器的扩展。默认为上。
  • LLVM_ENABLE_WERROR: BOOL
    如果触发编译器警告,则停止并失败构建。默认为关闭。
  • LLVM_ABI_BREAKING_CHECKS:字符串
    用于决定是否应该用ABI中断检查来构建LLVM。允许的值是with_assert(默认值)、FORCE_ON和FORCE_OFF。with_assert打开ABI,在启用断言的构建中中断检查。无论是否启用了普通(基于ndebug)断言,FORCE_ON (FORCE_OFF)都会打开(关闭)它们。使用ABI中断检查构建的LLVM版本与不使用ABI的版本不兼容。
  • LLVM_BUILD_32_BITS: BOOL
    在64位系统上构建32位可执行程序和库。此选项仅在某些64位Unix系统上可用。默认为关闭。
  • LLVM_TARGET_ARCH:字符串
    用于本地代码生成的LLVM目标。这是JIT生成所必需的。它默认为“host”,这意味着它将选择正在构建LLVM的机器的架构。如果要交叉编译,请将其设置为目标体系结构名称。
  • LLVM_TABLEGEN:字符串
    本地TableGen可执行文件的完整路径(通常称为llvm-tblgen)。这是用于交叉编译的:如果用户设置了这个变量,则不会创建本机TableGen。
  • LLVM_LIT_ARGS:字符串
    参数给文学使检查和使学生clang-test都受到影响。默认情况下,’-sv -no-progress-bar’在Visual c++和Xcode上,’-sv’在其他代码上。
  • LLVM_LIT_TOOLS_DIR:路径
    用于测试的GnuWin32工具的路径。在Windows主机上有效。默认为空字符串,在这种情况下,lit将在%PATH%中查找测试所需的工具(例如grep、sort等)。如果GnuWin32不在您的%PATH%中,那么您可以将该变量设置为GnuWin32目录,以便lit可以在该目录中找到测试所需的工具。
  • LLVM_ENABLE_FFI: BOOL
    指示是否将LLVM解释器链接到外部函数接口库(libffi)以启用调用外部函数。如果库或库头安装在自定义位置,还可以将变量FFI_INCLUDE_DIR和FFI_LIBRARY_DIR设置为ffi.h和libffi所在的目录。所以可以分别找到。默认为关闭。
  • LLVM_EXTERNAL_{CLANG,LLD,POLLY}_SOURCE_DIR:PATH
    这些变量分别指定相对于顶级源目录的外部LLVM项目Clang、lld和Polly的源目录路径。如果外部项目的in-tree子目录存在(例如,llvm/tools/clang for clang),则不会使用相应的变量。如果外部项目的变量不指向有效路径,则不会构建该项目。
  • LLVM_ENABLE_PROJECTS:字符串
    以分号分隔的要构建的项目列表,或用于构建所有(clang、libcxx、libcxxabi、lldb、compiler-rt、lld、polly)项目的all。这个标志假设项目是并排签出的,而不是嵌套的,即clang需要与llvm并行,而不是嵌套在llvm/tools中。该特性允许仅为LLVM构建一个版本,并使用相同的源代码检出为clang+ LLVM构建另一个版本。
  • LLVM_EXTERNAL_PROJECTS:字符串
    要作为llvm的一部分构建的其他外部项目的分号分隔列表。对于每个项目LLVM_EXTERNAL_<name>_SOURCE_DIR必须用项目源代码的路径指定。>例如:-DLLVM_EXTERNAL_PROJECTS=“Foo;Bar” -DLLVM_EXTERNAL_FOO_SOURCE_DIR=/src/ Foo -DLLVM_EXTERNAL_BAR_SOURCE_DIR=/src/ Bar。
  • LLVM_USE_OPROFILE: BOOL
    启用构建OProfile JIT支持。默认为关闭。
  • LLVM_PROFDATA_FILE:路径
    要传递到clang的-fprofile-研习班-use标志的profdata文件的路径。这只能在使用clang构建时指定。
  • LLVM_USE_INTEL_JITEVENTS: BOOL
    启用对Intel JIT事件API的构建支持。默认为关闭。
  • LLVM_ENABLE_LIBPFM: BOOL
    启用libpfm构建来支持LLVM工具中的硬件计数器测量。默认为上。

启用对Perf (linux分析工具)JIT支持的构建支持。默认为关闭。

  • LLVM_ENABLE_ZLIB: BOOL
    启用zlib构建以支持LLVM工具中的压缩/解压。默认为上。
  • LLVM_ENABLE_DIA_SDK: BOOL
    支持使用MSVC DIA SDK构建PDB调试支持。只能与MSVC。默认为上。
  • LLVM_USE_SANITIZER:字符串
    定义用于构建LLVM二进制文件和测试的杀毒软件。可能的值是Address、Memory、memorywithorigin、Undefined、Thread和Address;Undefined。默认为空字符串。
  • LLVM_ENABLE_LTO:字符串
    在编译和链接命令行中添加-flto或-flto=标志,启用链接时间优化。可能的值是Off、On、Thin和Full。默认为关闭。
  • LLVM_USE_LINKER:字符串
    将-fuse-ld={name}添加到链接调用中。可能的值取决于编译器,因为clang的值可以是自定义链接器的绝对路径,否则clang将在名称前面加上ld.并应用其通常的搜索。例如,要链接LLVM和Gold链接器,可以使用-DLLVM_USE_LINKER= Gold调用cmake。
  • LLVM_ENABLE_LLD: BOOL
    这个选项等价于-DLLVM_USE_LINKER=lld,除非在2阶段构建期间,从第一阶段添加依赖项到第二阶段,以确保在第二阶段开始之前构建lld。
  • LLVM_PARALLEL_COMPILE_JOBS:字符串
    定义并发编译作业的最大数量。
  • LLVM_PARALLEL_LINK_JOBS:字符串
    定义并发链接作业的最大数量。
  • LLVM_BUILD_DOCS: BOOL
    将所有启用的文档目标(例如Doxgyen和Sphinx目标)添加为默认构建目标的依赖项。这导致所有(启用的)文档目标都是正常构建的一部分。如果运行了安装目标,那么还可以安装所有构建的文档目标。要启用特定的文档目标,请参见LLVM_ENABLE_SPHINX和LLVM_ENABLE_DOXYGEN。
  • LLVM_ENABLE_DOXYGEN: BOOL
    支持使用doxygen生成可浏览的HTML文档。默认为关闭。
  • LLVM_ENABLE_DOXYGEN_QT_HELP: BOOL
    支持生成Qt压缩的帮助文件。默认为OFF。这将影响make目标doxygen-llvm。启用后,除了doxygen生成的正常HTML输出之外,还将生成一个名为org.llvm.qch的QCH文件。然后可以将该文件加载到Qt Creator中。此选项仅与-DLLVM_ENABLE_DOXYGEN=ON组合使用;否则就没有效果。
  • LLVM_DOXYGEN_QCH_FILENAME:字符串
    给出-DLLVM_ENABLE_DOXYGEN=ON和-DLLVM_ENABLE_DOXYGEN_QT_HELP=ON时生成的Qt压缩帮助文件的文件名。默认为org.llvm.qch。此选项仅与-DLLVM_ENABLE_DOXYGEN_QT_HELP=ON组合使用;否则就没有效果。
  • LLVM_DOXYGEN_QHP_NAMESPACE:字符串
    中间Qt帮助项目文件所在的名称空间。有关更多信息,请参见Qt帮助项目。默认为“org.llvm”。此选项仅与-DLLVM_ENABLE_DOXYGEN_QT_HELP=ON组合使用;否则就没有效果。
  • LLVM_DOXYGEN_QHP_CUST_FILTER_NAME:字符串
    有关更多信息,请参见Qt帮助项目。默认为CMake变量${PACKAGE_STRING},它是包名称和版本字符串的组合。然后,Qt Creator中可以使用这个过滤器,在浏览可能已加载的所有帮助文件时,只从LLVM中选择文档。此选项仅与-DLLVM_ENABLE_DOXYGEN_QT_HELP=ON组合使用;否则就没有效果。
  • LLVM_DOXYGEN_QHELPGENERATOR_PATH:字符串
    qhelpgenerator可执行文件的路径。默认为CMake的find_program()可以找到的任何内容。此选项仅与-DLLVM_ENABLE_DOXYGEN_QT_HELP=ON组合使用;否则就没有效果。
  • LLVM_DOXYGEN_SVG: BOOL
    对Doxygen输出中的图形使用.svg文件而不是.png文件。默认为关闭。
  • LLVM_INSTALL_DOXYGEN_HTML_DIR:字符串
    安装doxygen生成的HTML文档的路径。这个路径可以是绝对的,也可以是相对于CMAKE_INSTALL_PREFIX的。默认为/ doc / llvm / doxygen-html分享。
  • LLVM_ENABLE_SPHINX: BOOL
    如果指定,CMake将搜索sphinx-build可执行文件,并使SPHINX_OUTPUT_HTML和SPHINX_OUTPUT_MAN CMake选项可用。默认为关闭。
  • SPHINX_EXECUTABLE:字符串
    CMake检测到的sphinx-build可执行文件的路径。有关安装说明,请参见http://www.sphinx-doc.org/en/latest/install.html
  • SPHINX_OUTPUT_HTML: BOOL
    如果启用了(启用了LLVM_ENABLE_SPHINX),则添加将文档构建为html的目标(但默认情况下不会构建,除非启用了LLVM_BUILD_DOCS)。源树中每个使用sphinx的项目都有一个目标(例如,docs-llvm-html、docs-clang-html和docs-lld-html)。默认为上。
  • SPHINX_OUTPUT_MAN: BOOL
    如果启用了(启用了LLVM_ENABLE_SPHINX),则添加构建手册页的目标(但默认情况下不会构建,除非启用了LLVM_BUILD_DOCS)。目前唯一添加的目标是doc -llvm-man。默认为上。
  • SPHINX_WARNINGS_AS_ERRORS: BOOL
    如果启用,那么sphinx文档警告将被视为错误。默认为上。
  • LLVM_INSTALL_SPHINX_HTML_DIR:字符串
    安装sphinx生成的HTML文档的路径。这个路径可以是绝对的,也可以是相对于CMAKE_INSTALL_PREFIX的。默认共享/ doc / llvm / html。
  • LLVM_INSTALL_OCAMLDOC_HTML_DIR:字符串
    安装ocamldoc生成的HTML文档到的路径。这个路径可以是绝对的,也可以是相对于CMAKE_INSTALL_PREFIX的。默认为/ doc / llvm / ocaml-html分享。
  • LLVM_CREATE_XCODE_TOOLCHAIN: BOOL
    macOS Only:如果启用CMake,将生成一个名为“install-xcode-toolchain”的目标。这个目标将在$CMAKE_INSTALL_PREFIX/Toolchains上创建一个目录,其中包含一个xctoolchain目录,可用来覆盖默认的系统工具。
  • LLVM_BUILD_LLVM_DYLIB: BOOL
    如果启用,则添加构建libLLVM共享库的目标。这个库包含一个共享库中的所有LLVM组件。默认值为OFF。这不能与BUILD_SHARED_LIBS一起使用。只有当LLVM_LINK_LLVM_DYLIB也打开时,工具才会链接到libLLVM共享库。通过将LLVM_DYLIB_COMPONENTS设置为所需组件列表,可以定制库中的组件。
  • LLVM_LINK_LLVM_DYLIB: BOOL
    如果启用,工具将与libLLVM共享库链接。将LLVM_LINK_LLVM_DYLIB设置为ON也将LLVM_BUILD_LLVM_DYLIB设置为ON。
  • BUILD_SHARED_LIBS: BOOL
    标志,指示是否将每个LLVM组件(例如Support)构建为共享库(ON)或静态库(OFF)。它的默认值是关闭的。在Windows上,当使用MinGW(包括MinGW -w64)构建时可以使用共享库,但当使用Microsoft工具链构建时则不能。

请注意

BUILD_SHARED_LIBS只建议LLVM开发人员使用。如果希望将LLVM构建为共享库,应该使用LLVM_BUILD_LLVM_DYLIB选项。

  • LLVM_OPTIMIZED_TABLEGEN: BOOL
    如果启用并构建调试或断言构建,CMake构建系统将生成一个发布构建树,以构建一个完全优化的tablegen,以便在构建期间使用。启用此选项可以显著加快构建时间,特别是在调试配置中构建LLVM时。
  • LLVM_REVERSE_ITERATION: BOOL
    如果启用,所有受支持的无序llvm容器将按相反的顺序迭代。这对于揭示无序容器迭代所导致的非决定论非常有用。
  • LLVM_BUILD_INSTRUMENTED_COVERAGE: BOOL
    如果启用,则在构建llvm时启用基于源代码的代码覆盖插装。
  • LLVM_CCACHE_BUILD: BOOL
    如果启用了ccache程序,并且ccache程序可用,那么将使用ccache构建LLVM,以加速LLVM及其组件的重构。默认值为OFF。ccache维护的缓存的大小和位置可以通过分别传递给CCACHE_MAXSIZE和CCACHE_DIR环境变量的LLVM_CCACHE_MAXSIZE和LLVM_CCACHE_DIR选项进行调整。
  • LLVM_FORCE_USE_OLD_TOOLCHAIN: BOOL
    如果启用,编译器和标准库版本将不会被选中。LLVM可能根本无法编译,或者在运行时由于这些工具链中的已知错误而失败。
  • LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN: BOOL
    如果启用,编译器版本检查只会在使用要废弃的工具链时发出警告,而不是发出错误。
  • LLVM_USE_NEWPM: BOOL
    如果启用,请使用实验性的new pass管理器。

5. CMake Caches

最近,LLVM 和 Clang 添加了一些更复杂的构建系统特性。利用这些新特性通常需要在命令行上传递一系列复杂的 CMake 变量。Clang 提供了一组 CMake cache 脚本,使这些特性更易于访问。
使用 CMake 的 -C 标志来处理 CMake cache 文件:

$ cmake -C <path to cache file> <path to sources>

CMake cache 脚本是在一个独立的范围内处理的,只有缓存的变量在主配置运行时保持设置。CMake缓存变量不会重置已设置的变量,除非指定了 FORCE 选项。

关于 CMake Caches 的几点注意事项:

  • 命令行参数的顺序很重要

    • -C 之前指定的 -D 参数将在处理缓存前设置,并可以在缓存文件中读取
    • -C 之后指定的 -D 参数将在处理缓存后设置,并在缓存文件中取消设置
  • 所有的 -D 参数将覆盖缓存文件设置
  • CMAKE_TOOLCHAIN_FILE 在缓存文件和命令行参数之后计算
  • 建议在 -C 之前指定所有 -D 选项

有关通过缓存文件支持的一些高级构建配置的更多信息,请参见高级构建配置。

6. 执行测试

在构建 check-all 目标时执行测试。例如,如果您正在使用 Makefiles,请在 build 目录下执行以下命令:

$ make check-all

在 Visual Studio 上,您可以通过构建项目 “check-all” 来运行测试。有关测试的更多信息,请参阅 LLVM 测试基础设施指南。

7. 交叉编译

有关如何使用 CMake 进行交叉编译的通用说明,请参阅此 wiki 页面。它进行了详细的解释,可能看起来令人生畏,但事实并非如此。在这个 wiki 页面上有几个例子,包括工具链文件。请直接到本节中获取一个快速解决方案。
还请参阅第4.2节 特定于LLVM的变量,了解交叉编译时使用的变量。

8. 在项目中嵌入 LLVM

从 LLVM 3.5 开始,CMakeautoconf/Makefile 构建系统都将 LLVM 库导出为可导入的 CMake targets。这意味着 LLVM 的客户端现在可以可靠地使用 CMake 针对已安装的 LLVM 版本开发自己的基于 LLVM 的项目,而不管它是如何构建的。

下面是一个 CMakeLists.txt 文件的简单示例,该文件导入 LLVM 库并使用它们构建一个简单的应用程序simple-tool

cmake_minimum_required(VERSION 3.4.3)
project(SimpleProject)find_package(LLVM REQUIRED CONFIG)message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")# Set your project compile flags.
# E.g. if using the C++ header files
# you will need to enable C++11 support for your compiler.include_directories(${LLVM_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})# Now build our tools
add_executable(simple-tool tool.cpp)# 找到与我们希望使用的LLVM组件相对应的库
llvm_map_components_to_libnames(llvm_libs support core irreader)# Link against LLVM libraries
target_link_libraries(simple-tool ${llvm_libs})

当在 CONFIG模式下使用 find_package(…) 指令时(如上例所示),它将查找位于不同位置的 LLVMConfig.cmake 文件(详细信息请参阅 cmake 手册)。它创建一个 LLVM_DIR 缓存条目来保存 LLVMConfig.cmake 被找到的目录或允许用户指定目录(例如,通过将 -DLLVM_DIR=/usr/lib/cmake/llvm 传递给 cmake 命令,或者直接在 ccmakecmake-gui 中设置)。

该文件在两个不同的位置可用。

  • <INSTALL_PREFIX>/lib/cmake/llvm/LLVMConfig.cmake,其中<INSTALL_PREFIX>是 LLVM 已安装版本的 install 前缀。在 Linux 上,通常是 /usr/lib/cmake/llvm/LLVMConfig.cmake
  • <LLVM_BUILD_ROOT>/lib/cmake/llvm/LLVMConfig.cmake,其中 <LLVM_BUILD_ROOT> 是 LLVM 构建树的根。注意:这只在使用 CMake 构建 LLVM 时可用

如果 LLVM 安装在操作系统的正常安装前缀中(例如,在 Linux 上通常是 /usr/), find_package(LLVM …) 将自动找到 LLVM(如果安装正确)。如果没有安装 LLVM,或者希望直接针对 LLVM 构建树构建,可以使用前面提到的 LLVM_DIR

LLVMConfig.cmake 文件设置各种有用的变量。显著的变量包括

  • LLVM_CMAKE_DIR
    到 LLVM CMake 目录(即包含 LLVMConfig.cmake 的目录)的路径。
  • LLVM_DEFINITIONS
    在针对 LLVM 构建时应该使用的预处理器定义(preprocessor defines)列表。
  • LLVM_ENABLE_ASSERTIONS
    如果 LLVM 构建时使用了断言,则将其设置为ON,否则设置为OFF。
  • LLVM_ENABLE_EH
    如果 LLVM 构建时启用了异常处理(exception handling,EH),则设置为ON,否则设置为OFF。
  • LLVM_ENABLE_RTTI
    如果 LLVM 构建时使用了运行时类型信息(run time type information,RTTI),则设置为ON,否则设置为OFF。
  • LLVM_INCLUDE_DIRS
    包含指向包含 LLVM 头文件的目录的路径列表。
  • LLVM_PACKAGE_VERSION
    LLVM 的版本。这个字符串可以与 CMake 条件一起使用,例如,if (${LLVM_PACKAGE_VERSION} VERSION_LESS "3.5")
  • LLVM_TOOLS_BINARY_DIR
    指向包含 LLVM 工具(例如 llvm-as)的目录的路径。

注意,在上面的示例中,我们将 simple-tool 链接到几个 LLVM 库。库的列表是通过使用 llvm_map_components_to_libnames() CMake 函数确定的。要查看可用组件列表,请查看运行 llvm-config --components 的输出。

注意,对于 LLVM < 3.5,使用的是 llvm_map_components_to_libraries(),而不是 llvm_map_components_to_libnames()。现在不赞成这样做,并将在 LLVM 的未来版本中删除。

8.1 从源代码开发 LLVM passes

可以从LLVM的源代码树(即针对已安装或已构建的 LLVM)开发 LLVM passes。下面提供了一个项目布局的示例。

<project dir>/|CMakeLists.txt<pass name>/|CMakeLists.txtPass.cpp...

<project dir>/CMakeLists.txt 的内容:

find_package(LLVM REQUIRED CONFIG)add_definitions(${LLVM_DEFINITIONS})
include_directories(${LLVM_INCLUDE_DIRS})add_subdirectory(<pass name>)

<project dir>/<pass name>/CMakeLists.txt 的内容:

add_library(LLVMPassname MODULE Pass.cpp)

注意,如果您打算在将来的某个时候将此 Pass 合并到 LLVM 源代码树中,那么使用 LLVM 的内部 add_llvm_library 函数并使用MODULE参数来代替…

将以下内容添加到 <project dir>/CMakeLists.txt(在find_package(LLVM ...)之后):

list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
include(AddLLVM)

然后将<project dir>/<pass name>/CMakeLists.txt修改为:

add_llvm_library(LLVMPassname MODULEPass.cpp)

当您完成了对 Pass 的开发之后,您可能希望将它集成到 LLVM 源代码树中。你可以通过两个简单的步骤来实现:

  1. <pass name> 文件夹复制到 <LLVM root>/lib/Transform 目录。
  2. add_subdirectory(<pass name>) 行添加到 <LLVM root>/lib/Transform/CMakeLists.txt

9. 特定于编译器/平台的话题

特定编译器和平台的说明。

9.1 微软Visual c++
  • LLVM_COMPILER_JOBS:STRING
    指定使用 msbuild 或 Visual Studio 构建每个项目时要使用的并行编译器作业的最大数量。只支持 Visual Studio 2010 CMake 生成器。0表示使用所有处理器。默认值为0。

使用 CMake 构建 LLVM相关推荐

  1. cmake 构建路径_基于CMake构建系统的MLIR Example扩展

    上一篇文章讲了把pybind11的示例程序嵌入到了MLIR的Example中,但是在构建的过程中有一定运气成分,并不知道具体是怎么通过CMake构建系统编译出的共享库文件.在分析了MLIR各层级的CM ...

  2. 用CMake构建工程时 cmake -G“Unix Makefiles“ 的使用

    在Windows上使用CMake构建项目出现了很多错误,搜索了很多资料尝试改了很多地方始终没能找到与我类似的情况,一度让我以为是系统问题.今天发现就一句,是没用cmake -G"Unix M ...

  3. CMake 构建项目Android NDK项目基础知识

    本篇文章将介绍如何使用 CMake 构建实现你的第一个 NDK 项目. ##前言 你好!欢迎来到我的的学习笔记分享系列,第一次给大家分享的是 Android NDK 开发的学习笔记,让我们先开始了解 ...

  4. cmake could not find openssl_使用CMake构建C++项目

    背景 现代CMake如今开始转向使用targets和properties,比如下面文章介绍的这样: https://pabloariasal.github.io/2018/02/19/its-time ...

  5. cmake构建NNIE工程

    cmake构建NNIE工程 <cmake构建NNIE工程>   利用海思芯片在摄像头端做模型推理是大势所趋,本文介绍了笔者在做 NNIE 开发的过程中使用 cmake 构建 NNIE 工程 ...

  6. 【笔记】CMake构建C++工程

    一句话结论:本文归纳CMake构建c++工程的基本用法,实现多依赖.多工程.多文件格式的工程编译构建. 1.简介 CMake(cross-platform make)是一个跨平台编译工具,它不能直接生 ...

  7. windows平台下使用cmake构建静态lib库以及使用静态lib库gtest项目

    有些时候我们需要将部分代码编译成单独的一个库,然后在另一个项目中去使用这个库 大部分是linux环境下的指令,但是也差不是很多 记录一下构建的经过 目录 1.使用cmake构建及使用lib库 构建li ...

  8. QtCreator使用CMake构建项目时jom Error 2问题

    QtCreator使用MSVC编译环境构建项目时,会因为配置不正确出现jom: C:/-/- [cmTC_fe41e\fast] Error 2错误,这里记录一下我的解决办法和对此问题的理解,希望能帮 ...

  9. CLion 2022,CMake构建进度

    CLion 2022,CMake构建进度 CLion 是一个完全集成的 C/C++ 开发环境.它将通过智能编辑器.代码质量保证.自动重构以及与 CMake 构建系统的深度集成来提高您的生产力. CLi ...

最新文章

  1. hibernate配置之property name=hbm2ddl.autocreate/property导致每次创建SessionFactory都清空数据库中的数据...
  2. python matplotlib显示图片_Python OpenCV ——Matplotlib显示图片
  3. CentOS 7 为firewalld添加开放端口及相关资料
  4. Matlab之DNN:基于Matlab利用神经网络模型(epochs=10000000)预测勒布朗詹姆斯的2018年总决赛(骑士VS勇士)第一场得分、篮板、助攻
  5. 索引使用的好处与坏处(Oracle测试)
  6. armadillo 使用注意 越界不报错
  7. 解决:SyntaxError: Non-UTF-8 code starting with '\xe6' in file
  8. 吴恩达:机器学习应以数据为中心
  9. visio中给文字添加上下标
  10. Python中的正则表达式找到请求体为form-data格式的请求参数
  11. 10种电脑无法启动故障
  12. pandas数据处理实践三(DataFrame.apply、merge、rename,数据预处理、DataFrame.drop_duplicates去重)
  13. 博客访问量,有没有可能是系统所为?
  14. python全自动化渗透工具_Python自动化渗透(一)
  15. OpenMP中的常用函数
  16. 临时邮箱获取验证信息
  17. 广东最美的历史古村落,再不去就没了
  18. ASP.NET Core 自定义中间件
  19. python查看list的shape_列表list、数组np.array等的len,size,shape操作
  20. 跑腿小程序系统,同城闪送、帮买帮送

热门文章

  1. Android:设计一个在屏幕上移动的小球程序
  2. 线径看板帮助电线电缆厂提高生产效率的工作原理
  3. Android-UI 慕淘旅游
  4. centos及MySQL远程登陆问题
  5. 实际波动率预测:kaggle比赛
  6. iOS通知和KVO的区别和用法
  7. java统计一段英文中单词及个数
  8. 一步步搭建Retrofit+RxJava+MVP网络请求框架(一)
  9. 技术分享 | 在GreatDB分布式部署模式中使用Chaos Mesh做混沌测试
  10. 股票中的做T的是什么意思?