1. 介绍
基于CMake的构建系统通过一系列高级逻辑目标定义了项目的编译和链接规则。每个目标都对应一个具体的可执行文件或库,或者包含自定义命令的特殊目标。在buildsystem中,目标之间的依赖关系通过依赖列表明确,定义了生成顺序和基于变更检测的重新生成规则。
2. 二进制目标
在CMake中,可执行文件和库是通过
add_executable和add_library命令定义的。生成的二进制文件会根据目标平台的特定前缀、后缀和扩展名来命名。二进制目标之间的依赖关系通常用target_link_libraries命令来表示。例如,在定义静态库和可执行文件的示例中:
add_library(archive archive.cpp zip.cpp lzma.cpp)add_executable(zipapp zipapp.cpp)target_link_libraries(zipapp archive)
archive是一个静态库,由archive.cpp、zip.cpp和lzma.cpp编译而生成。而zipapp则是通过编译zipapp.cpp形成的可执行文件,并通过依赖archive静态库进行链接。2.1 二进制可执行文件
定义可执行目标的关键命令是
add_executable。add_executable(mytool mytool.cpp)CMake会确保在尝试运行命令之前生成该可执行文件。这可以让buildsystem规则在实际运行时有一个可靠的参考。
2.2 二进制库类型
2.2.1 普通库
默认情况下,
add_library命令会创建一个静态库,除非指定了具体的库类型。例如,可以通过在命令中添加参数来定义共享库或静态库:add_library(archive SHARED archive.cpp zip.cpp lzma.cpp)|add_library(archive STATIC archive.cpp zip.cpp lzma.cpp)通过设置
SHARED或STATIC属性,可以控制库的类型,默认情况下为静态库。使用SHARED属性可以生成共享库,但需要确保库中有可导出的符号(尤其是在Windows环境下)。2.2.2 Apple Frameworks
对于macOS或iOS框架,可以通过指定特定的目标属性来创建框架包。需要注意的是,共享库通常会用
FRAMEWORK属性进行标记,同时也需要设置目标属性。macOS上这一操作通常遵循使用A值的约定,而MACOSX_FRAMEWORK_IDENTIFIER是唯一标识包的键。add_library(MyFramework SHARED MyFramework.cpp)| 代码块>set_target_properties(MyFramework PROPERTIES FRAMEWORK TRUE FRAMEWORK_VERSION A # Version "A"符合macOS的约定 MACOSX_FRAMEWORK_IDENTIFIER org.cmake.MyFramework)3. 对象库
OBJECT库类型的作用是将一组对象文件(由编译源文件生成)汇总成一个非存档的集合。这些对象文件可以被用作其他目标的输入,例如通过使用$<TARGET_OBJECTS:name>语法将OBJECT库的内容传递给其他目标。例如,可以使用
add_library命令定义一个OBJECT库:add_library(objs OBJECT objs.cpp)。这种类型的库在复杂项目中非常有用,可以灵活地管理源文件和编译配置。通过这种方式,可以避免将大量源文件纳入所有目标,从而提高build效率。