# cmake_study **Repository Path**: chenchang/cmake_study ## Basic Information - **Project Name**: cmake_study - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2016-04-02 - **Last Updated**: 2024-11-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # CMake Study ## CASE 01: 使用Log4Cpp记录日志(动态链接) 使用Log4Cpp的动态库,并根据生成配置将相应的dll文件复制到目标目录。 并将Log4Cpp配置文件,复制到工程目录。 使用前,需要设置LOG4CPP的安装目录。 ## CASE 02: 使用Log4Cpp记录日志(静态链接) 使用Log4Cpp的静态库。并将Log4Cpp配置文件,复制到工程目录。 使用前,需要设置LOG4CPP的安装目录。 ## CASE 03: 使用Google Test测试框架(动态链接) 使用Google Test的动态库,并根据生成配置将相应的dll文件复制到目标目录。 ## CASE 04: 使用Google Test测试框架(静态链接) 使用Google Test的静态库。 项目需要使用/MT(d)编译选项,以与Google Test静态库的编译选项相同。 ## CASE 05: 使用工具生成CPP源文件 使用Python生成CPP源文件,并在CPP工程中使用。 ## CASE 06: 对源文件进行分组 使用`source_group`对源文件进行分组,在CPP工程中方便文件组织。 ## CASE 07: 使用 cotire 进行预编译头文件设置 `cotire` 可以帮助设置预编译头文件。 一个工程中的多个项目,只有一个项目的 `COTIRE_ENABLE_PRECOMPILED_HEADER` 可以设为 `TRUE` 。如果有多个项目的 `COTIRE_ENABLE_PRECOMPILED_HEADER` 设为 `TRUE` , CMAKE 生成构建配置文件时,将会出错。 一个工程中的多个项目,至少有一个项目的 `COTIRE_ENABLE_PRECOMPILED_HEADER` 设为 `TRUE` ,工程中的项目才会使用预编译头文件。如果整个工程中,没有一个项目的 `COTIRE_ENABLE_PRECOMPILED_HEADER` 设为 `TRUE` ,那么工程中的项目不会使用预编译头文件。 项目的 `COTIRE_ADD_UNITY_BUILD` 如果设为 `TRUE` ,该项目的多个源文件会合并成一个进行编译,以加速编译过程。该属性默认值为 `TRUE` 。如果不需要 `Unity` 编译,可将该属性设为 `FALSE` 。 ## CASE 08: 编译时,排除部分源文件 CMAKE 中,没有与 Visual Studio 2015 中的源文件属性的 `Excluded From Build` 对应的设置。 因此,通过将源文件的属性 `HEADER_FILE_ONLY` 设为 `TRUE` ,让 Visual Studio 将该源文件当做头文件,从而不编译该源文件。 https://cmake.org/cmake/help/latest/prop_sf/VS_SETTINGS.html 新增的 `VS_SETTINGS` 可以通过指定 `PROPERTY VS_SETTINGS "ExcludedFromBuild=true"` 设置 `Excluded From Build` 选项。 ## CASE 09: Use static link libraries An executable links with two separated static libraries. ## CASE 10: Use static or dynamic link libraries by macros An executable links with two separated static/dynamic libraries. Use `BUILD_SHARED_LIBS` CMAKE option to control whether to build/link static or dynamic libraries. When libraries are build as shared, CMAKE adds compile definition `_Exports` to preprocessed macros of the libraries. User can use `_Exports` macros to generate `__declspec(dllexport)` or `__declspec(dllimport)` keywords for dynamic libraries or executables. ## CASE 11: Use static or dynamic link libraries by `CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS` global variable An executable links with two separated static/dynamic libraries. Use `BUILD_SHARED_LIBS` CMAKE option to control whether to build/link static or dynamic libraries. `CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS` global variable is available in CMAKE version 3.4 and after. `CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS` enables dynamic library to be linked with a definition file which contains all symbols collected from object files linked to the library. When library is changed between static type and dynamic type, the header and source files of the library are not required to be modified. It is very convenient for transplanting shared libraries of Linux platform to Windows platform. ## CASE 12: 通过 CMake 的命令行参数,设置源文件中的宏 源文件中的宏,通过 CMake 的命令行参数,进行设置。在不修改源文件的情况下,通过 CMake 命令行参数,修改源文件的内容。 ## CASE 13: 设置链接选项 例如:Windows 下设置链接 Windows 子系统的选项: /SUBSYSTEM:WINDOWS 。 ## CASE 14: 用户自定义命令构建后复制文件、目录及创建目录 将必须的附加文件、目录复制到构建目录下,及创建用于输出文件用的目录。并演示了用 Generator Expression 获得 target 的输出文件路径、文件名等。 ## CASE 15: 用户自定义的静态库 通过 `add_custom_command` 创建静态库,并且主应用链接该静态库。注意: `add_custom_command` 的 `OUTPUT` 参数不能使用 `generator expression` ,但是可以使用 `CMAKE_CFG_INTDIR` 变量。 ## CASE 16: 自动更新主程序所需的文本文件,无论主程序是否更新 通过 `add_custom_command` 复制主程序所需要的文本文件。并通过 `add_custom_target` 创建一个自定义目标,该目标依赖于 `add_custom_command` 所复制的文本文件。主程序依赖于该自定义目标。 自定义目标始终需要构建,因此始终通过 `add_custom_command` 检查所需的文本文件是否最新。 也可以不设置主程序与自定义目标的依赖关系,而将设置自定义目标的 `ALL` 属性。这样的好处是:可以在自定义目标中添加与主程序相关的 `generator expression` 而不引发循环引用的错误。缺点是重新构建主程序时,需要手动构建自定义目标。 ## case 17: 自动生成项目文件列表 项目文件列表通过脚本生成,而不是硬编码在项目配置文件中。演示 `execute_process` 命令及 `string(REGEX MATCHALL )` 命令的用法。 ## case 18: 将项目放在解决方案的目录中 使用 `USE_FOLDERS` 全局属性,启用项目目录功能。设置项目的 `FOLDER` 属性,指定项目的目录。 使用 `CMAKE_SUPPRESS_REGENERATION` 变量,控制是否生成 `ZERO_CHECK` 目标。默认为 `OFF` ,即生成 `ZERO_CHECK` 目标。 ## case 19: 链接资源文件 添加 .rc 文件,编译成 .res 文件并链接进可执行文件。 ## case 20: 可执行程序要求使用管理员权限执行 可执行程序要求使用管理员权限执行,并弹出 User Access Control 提示用户。 ## case 21: 列出项目中所有的 target 使用 `BUILDSYSTEM_TARGETS` 目录属性,列出项目中所有的 target ,包括子目录中的 target 。 ## case 22: 演示 ExternalProject 的用法 以 `glfw` 为例,演示 `ExternalProject` 模块的用法。 ## case 23: 演示 FetchContent 的用法 以 `googletest` 为例,演示 `FetchContent` 的用法。 ## case 24: 演示 Catch2 单独头文件下载用法 将 `catch.hpp` 文件下载到本地,创建 interface 库,并且项目依赖该库。 ## case 25: 演示静态库传递依赖关系 main 依赖于静态库 func3 ,而静态库 func3 私有链接 ( `target_link_library(func3 PRIVATE func2)` ) 到静态库 func2 。 main 仍然可以链接到静态库 func2 。 [Linking Object Libraries via $](https://cmake.org/cmake/help/latest/command/target_link_libraries.html#linking-object-libraries-via-target-objects) Since a static library does not link, it does not consume the object files from object libraries referenced this way. Instead, the object files become transitive link dependencies of the static library. ## case 26: 显示 PLATFORM_ID 和 C(XX)_COMPILER_ID 通过 CMake generator expression 显示环境信息。 ## case 27: 使用 Code Analyze 静态错误检查工具 通过添加 `/analyze` 编译选项,在构建时,选择 `Run Code Analysis on ` 可以对代码进行静态分析,并给出警告信息。 ## case 28: 根据配置,复制不同的文件到同一个目标文件 `add_custom_command` 根据配置不同,生成不同的文件。 因为 `add_custom_command` 与 `add_custom_target` 的依赖关系是在 `configure` 阶段建立的,所以无法在 `generate` 阶段依据 `$` 进行更改。 `add_custom_command` 的 `OUTPUT` 必须有一个值,不能为空。因此,在 `add_custom_command` 的 `OUTPUT` 不需要时,需要建立一个 `dummy` 输出文件,作为占位用。 ## case 29: 添加自定义的配置 添加自定义配置 `MyDebug` 和 `MyRelease` ,并指定 STATIC 、 SHARED 、 MODULE 和 EXECUTABLE 的编译和链接选项。 ## case 30: 添加自动复制附加文件的功能 添加了 `copy_attached_files` 自定义函数,可以复制多个文件到构建输出目录。 另外,添加了如下文件供参考: * PreTarget.cmake * PostTarget.cmake * Utils.cmake