《Modern CMake》读书笔记

简介: 《Modern CMake》读书笔记



1. Running cmake


1.1. cmake选项



--build  指定输出目录


-j 指定并行度


--target 指定编译目标



1.2. 选择编译器


EXPORT CC=clang CXX=clang++ cmake ..


1.3. 选择生成器


默认为make  通过cmake -G Ninja指定ninja



1.4. 指定编译选项


cmake -DXXX=YYY

cmake会将各种编译选项缓存到一个文件中,即CMakeCache.txt



1.5. 调试


调试makefile: VERBOSE=1 make

调试cmake:


  • cmake --trace,  打印出cmake运行的每一行脚本


  • cmake --trace-source=打印出中运行的每一行脚本




1.6. 指定编译类型


-DCMAKE_BUILD_TYPE:Debug或Release或RelWithDebInfo

-DCMAKE_INSTALL_PREFIX: 指定安装路径,默认为/usr/local

-DBUILD_SHARED_LIBS: 是否编译共享库,ON or OFF

-DBUILD_TESTING:  是否编译tests



2. Do's and Don'ts


2.1. 不要做


  • 不要使用全局函数:  link_directories, include_libraries等


  • 非必要不使用PULIBC限制


  • 不要用glob匹配文件:当新增文件时,除非重新跑一遍cmake, make或其他编译工具将不会感知到新文件


  • lib不要直接link到最终的target


  • link lib时不要忽略PUBLIC/PRIVATE关键字



2.2. 要做


  • 把cmake当做正经代码维护


  • 站在target的角度思考


  • 善用alias


  • 将通用功能抽象成函数或宏


  • 函数名统一小写



  • 善用cmake_policy


2.3. 选择cmake版本


2.3.1. os支持


  • 3.4: The bare minimum. Never set less.


  • 3.7: Debian old-stable.


  • 3.10: Ubuntu 18.04.


  • 3.11: CentOS 8 (use EPEL or AppSteams, though)


  • 3.13: Debian stable.


  • 3.16: Ubuntu 20.04.


  • 3.19: First to support Apple Silicon.


  • latest: pip/conda-forge/homebew/chocolaty, ect.


笔者目前用的是3.16




2.3.2. 特性

  • 3.8: C++ meta features, CUDA, lots more


  • 3.11: IMPORTED INTERFACE setting, faster, FetchContent, COMPILE_LANGUAGE in IDEs


  • 3.12: C++20, cmake --build build -j N, SHELL:, FindPython


  • 3.14/3.15: CLI, FindPython updates


  • 3.16: Unity builds / precompiled headers, CUDA meta features


  • 3.17/3.18: Lots more CUDA, metaprogramming



3. What's new in in CMake


  • cmake 3.0: interface libraries, 允许将一组头文件抽象成一个lib


  • cmake 3.1: 支持c++11和compile features


  • cmake 3.2: 支持UTF-8


  • cmake 3.4:  支持swift语言,支持ccache


  • cmake 3.5: 支持ARM平台


  • cmake 3.6: 支持clang-tidy


  • 其他:略


4. 基础知识


指定最小版本


cmake_minimum_required(VERSION 3.1)


创建工程

project(MyProject VERSION 1.0
                  DESCRIPTION "Very nice project"
                  LANGUAGES CXX)


新增executable

add_executable(one two.cpp three.h)



新增library

add_library(one STATIC two.cpp three.h)



用户可指定STATIC、SHARED、MODULE 。缺省使用BUILD_SHARED_LIBS选项。

INTERFAC用于创建头文件库

ALIAS用于指定库的别名.


绑定头文件路径


target_include_directories(one PUBLIC include)


PUBLIC表示所有依赖lib的target都自动绑定了该头文件路径


PRIVATE表示该头文件路径仅对本target有效


INTERFACE表示该头文件路径仅对依赖该lib的target生效


PUBLIC = PRIVATE + INTERFACE




5. 变量和cache


定义变量

set(MY_VARIABLE "value")



访问变量时使用${MY_VARIABLE}

变量仅在当前作用域内有效。



定义变量(多个值)

set(MY_LIST "one" "two")



等效于

set(MY_LIST "one;two")



属性

set_property(TARGET TargetName
             PROPERTY CXX_STANDARD 11)
set_target_properties(TargetName PROPERTIES
                      CXX_STANDARD 11)
get_property(ResultVariable TARGET TargetName PROPERTY CXX_STANDARD)




6. cmake编程


6.1. 控制流

if(variable)
    # If variable is `ON`, `YES`, `TRUE`, `Y`, or non zero number
else()
    # If variable is `0`, `OFF`, `NO`, `FALSE`, `N`, `IGNORE`, `NOTFOUND`, `""`, or ends in `-NOTFOUND`
endif()
# If variable does not expand to one of the above, CMake will expand it then try again



There are a variety of keywords as well, such as:

  • Unary: NOT, TARGET, EXISTS (file), DEFINED, etc.
  • Binary: STREQUAL, AND, OR, MATCHES (regular expression), VERSION_LESS, VERSION_LESS_EQUAL (CMake 3.7+), etc.
  • Parentheses can be used to group



generator-expressions


target_compile_options(MyTarget PRIVATE "$<$<CONFIG:Debug>:--my-flag>")


当使用debug编译时,加上--my-flag编译选项

That last one is very common. You'll see something like this in almost every package that supports installing:

target_include_directories(
    MyTarget
  PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
)



相关文章
|
JavaScript 前端开发
Vue 3中如何处理懒加载?
Vue 3中如何处理懒加载?
|
计算机视觉 Python
OpenCV中图像的开、闭运算讲解与实战应用(附Python源码)
OpenCV中图像的开、闭运算讲解与实战应用(附Python源码)
509 0
|
算法
【计算机组成原理】(四)原码补码的加减乘除
各种码的作用: 模运算的性质:
617 0
|
NoSQL MongoDB 数据库
docker 部署MongoDB
docker 部署MongoDB
1393 0
|
10月前
|
分布式计算 资源调度 大数据
Spark 如何保证宕机迅速恢复?
Spark 通过多种机制确保节点宕机时迅速恢复,主要包括:1. RDD 的 Lineage 机制,记录数据生成路径以便重计算;2. 检查点机制,持久化中间结果减少重算开销;3. 任务调度和资源管理,自动重新调度失败任务;4. 数据本地性,优先调度到数据所在节点;5. 持久化机制,将 RDD 持久化到内存或磁盘。这些机制共同保证了大数据处理的高可用性和可靠性。
|
前端开发 Java 数据库
SpringBoot解析指定Yaml配置文件
最近在看某个开源项目代码并准备参与其中,代码过了一遍后发现多个自定义的配置文件用来装载业务配置代替数据库查询,直接响应给前端,这里简单记录一下实现过程。
750 0
|
机器学习/深度学习 人工智能 自然语言处理
人工智能在医疗诊断中的最新应用
人工智能在医疗诊断中的最新应用
|
运维 JavaScript jenkins
鸿蒙5.0版开发:分析CppCrash(进程崩溃)
在HarmonyOS 5.0中,CppCrash指C/C++运行时崩溃,常见原因包括空指针、数组越界等。系统提供基于posix信号机制的异常检测能力,生成详细日志辅助定位。本文详解CppCrash分析方法,涵盖异常检测、问题定位思路及案例分析。
456 4
|
存储 Kubernetes 调度
关于Pod的基础知识概览
【6月更文挑战第19天】Pod是Kubernetes的基本执行单元,是最小部署和管理的粒度,包含一个或多个共享网络和存储的容器,常比喻为豆荚中的豆子。Pod中的容器共享IP和端口,便于协作,支持Docker等容器运行时。
|
监控 安全 数据库
【Docker专栏】Docker容器化应用的最佳实践
【5月更文挑战第7天】本文介绍了 Docker 容器化应用的关键最佳实践,包括使用官方基础镜像、保持镜像精简、以非 root 用户运行容器、安全扫描、编写高效 Dockerfile、环境隔离、使用数据卷、选择合适网络模式、设置资源限制、使用版本标签、容器编排以及文档和自动化部署。遵循这些实践可提升效率和安全性,同时要注意随着技术发展不断更新知识。
387 10
【Docker专栏】Docker容器化应用的最佳实践

热门文章

最新文章