CMake学习记录

devtools/2024/12/22 23:48:20/

CMake 是一个非常强大的工具,用于构建和管理复杂的软件项目。下面是对 CMake 使用的更详细的总结,包括更多高级特性以及一些最佳实践。

基础概念

  • CMakeLists.txt: 这是 CMake 的配置文件,用于描述项目的构建逻辑。
  • CMake 最小版本: cmake_minimum_required 指令用于设置项目所需的 CMake 最低版本。
  • 项目: project 指令定义项目名称和其他属性,如版本号和语言。
  • 源文件: 包含 .cpp.h 等源代码文件。
  • 可执行文件: 由 add_executable 创建的目标文件。
  • 库文件: 由 add_library 创建的静态库或共享库。
  • 目标: 构建系统中的可执行文件或库。
  • 编译指令: target_compile_features, target_compile_options, target_include_directories 等用于控制编译行为。
  • 链接指令: target_link_libraries 用于链接库到目标。
  • 安装指令: install 用于安装构建好的文件到系统中。
  • 查找外部库: find_packagefind_library 用于查找外部库和其位置。

常用命令详解

项目定义
cmake_minimum_required(VERSION 3.10)
project(MyProject VERSION 1.0 LANGUAGES CXX)
  • cmake_minimum_required: 指定项目所需的 CMake 最低版本。
  • project: 定义项目的基本信息。
添加源文件
add_executable(myapp main.cpp util.cpp)
add_library(mylib STATIC src1.cpp src2.cpp)
  • add_executable: 创建可执行文件。
  • add_library: 创建静态库或共享库。
链接库
target_link_libraries(myapp PRIVATE mylib)
  • target_link_libraries: 将库链接到目标。
查找外部库
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(myapp ${OpenCV_LIBS})
  • find_package: 查找并配置外部库。
  • include_directories: 添加头文件搜索路径。
  • target_link_libraries: 链接外部库。
安装目标
install(TARGETS myapp DESTINATION bin)
install(DIRECTORY include/ DESTINATION include)
  • install: 安装编译后的文件到指定目录。
配置文件生成
configure_file(config.h.in config.h @ONLY)
  • configure_file: 用于生成配置文件。
自定义规则
add_custom_command(OUTPUT out.txtCOMMAND cat file1.txt file2.txt > out.txtDEPENDS file1.txt file2.txt
)
add_custom_target(custom OUT SOURCES out.txt)
  • add_custom_command: 定义自定义命令。
  • add_custom_target: 定义自定义目标。
条件判断
if(APPLE)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
endif()
  • if: 条件判断。
循环
foreach(dir ${CMAKE_SOURCE_DIR}/src)add_subdirectory(${dir})
endforeach()
  • foreach: 循环。
变量和缓存
set(SOURCE_FILES main.cpp util.cpp)
option(BUILD_TESTS "Build tests" OFF)
  • set: 定义变量。
  • option: 定义命令行选项。

高级特性

多配置构建
if(NOT CMAKE_BUILD_TYPE)set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
endif()
  • CMAKE_BUILD_TYPE: 控制构建类型。
版本控制
  • 将 CMakeLists.txt 文件加入版本控制系统,如 Git。
文档
  • 为重要的 CMakeLists.txt 文件添加注释,说明其用途和配置。
测试
enable_testing()
add_executable(tests tests.cpp)
target_link_libraries(tests PRIVATE mylib)
add_test(NAME basic_test COMMAND tests)
  • enable_testing: 启用测试。
  • add_test: 添加测试目标。
包装项目
install(TARGETS myapp EXPORT MyAppTargets)
install(EXPORT MyAppTargets DESTINATION lib/cmake/MyApp)
  • install(EXPORT): 生成包配置文件。

示例

这里给出一个稍微复杂一些的例子,其中包含了项目定义、可执行文件、静态库、查找外部库、安装、测试和自定义规则:

cmake_minimum_required(VERSION 3.10)
project(MyApp VERSION 1.0 LANGUAGES CXX)# 添加可执行文件
add_executable(myapp main.cpp)# 添加静态库
add_library(mylib STATIC src1.cpp src2.cpp)# 链接库
target_link_libraries(myapp PRIVATE mylib)# 查找外部库
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(myapp ${OpenCV_LIBS})# 安装目标
install(TARGETS myapp DESTINATION bin)
install(DIRECTORY include/ DESTINATION include)# 自定义规则
add_custom_command(OUTPUT out.txtCOMMAND cat file1.txt file2.txt > out.txtDEPENDS file1.txt file2.txt
)
add_custom_target(custom OUT SOURCES out.txt)# 条件编译
if(APPLE)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
endif()# 循环添加子目录
foreach(dir ${CMAKE_SOURCE_DIR}/src)add_subdirectory(${dir})
endforeach()# 测试
enable_testing()
add_executable(tests tests.cpp)
target_link_libraries(tests PRIVATE mylib)
add_test(NAME basic_test COMMAND tests)# 包装项目
install(TARGETS myapp EXPORT MyAppTargets)
install(EXPORT MyAppTargets DESTINATION lib/cmake/MyApp)

以上内容提供了 CMake 的基本使用方法以及一些高级特性。


http://www.ppmy.cn/devtools/92459.html

相关文章

Golang | Leetcode Golang题解之第326题3的幂

题目: 题解: func isPowerOfThree(n int) bool {return n > 0 && 1162261467%n 0 }

统一响应结果封装,Result类的实现【后端 06】

统一响应结果封装,Result类的实现 在开发Web应用或API接口时,如何优雅地处理并返回响应结果是每个开发者都需要考虑的问题。统一响应结果封装(Unified Response Encapsulation)作为一种广泛采用的实践,不仅提高了API的…

【区块链+社会公益】长安大学城梦想小镇居民公益积分项目 | FISCO BCOS应用案例

如何在一个小镇生态内,利用区块链技术助力文明行为,在数据层面完成“链上个人文明积分激励 公共基础设 施共享 商品消费”的社会自治试验?西电链融主导开发、天朗科技共同打造,基于 FISCO BCOS 研发的西安市 长安大学城梦想小镇…

计算机网络中接收窗口与门限值的区别

计算机网络中接收缓存和门限值的关系主要体现在TCP的流量控制和拥塞控制机制中。‌ TCP(‌传输控制协议)‌是一种面向连接的、‌可靠的、‌基于字节流的传输层通信协议。‌在TCP中,‌接收缓存的大小由接收端根据其可用资源(‌如内…

【HarmonyOS NEXT星河版开发学习】小型测试案例06-小红书卡片

个人主页→VON 收录专栏→鸿蒙开发小型案例总结​​​​​ 基础语法部分会发布于github 和 gitee上面(暂未发布) 前言 在鸿蒙(HarmonyOS)开发中,自适应伸缩是指应用程序能够根据不同设备的屏幕尺寸、分辨率和形态&…

pytorch分布式训练卡住,显卡占用100

1、问题 使用pytorch进行分布式训练,一机多卡,采用 DistributedDataParallel 方式,多次执行卡在了同一个地方。但是单卡和 DataParallel 方式都没有卡住的现象。 执行nvidia-smi,此时全部GPU利用率均为100%: 2、debug…

缓冲字符流、文件字符流

BufferedInputStream 字节缓冲输入流: 1.是一个高级流,内部维护一个缓冲区,默认8KB 2.读取文件数据时一次性尽可能读取到缓冲区大小的字节 3.read方法从缓冲区获取数据:当缓冲区全部读完,会再次从磁盘上读取数据存…

前端实现文件下载常用几种方式

项目中前端下载一般分为两种情况: 后端直接提供一个文件地址,通过浏览器打开就可以下载。需要发送请求,后端返回二进制流数据,前端解析流数据,生成URL实现下载。 前端对应的实质是a标签和Blob文件下载,这…