CMake学习

1. CMake基本介绍

CMake 是一个跨平台的开源构建系统生成器。它的核心功能不是直接编译代码,而是根据一个名为 CMakeLists.txt 的配置文件,为你现有的编译环境(如 Make、Ninja、Visual Studio、Xcode 等)生成标准的构建文件。

为什么需要 CMake?

  1. 跨平台性:这是最主要的原因。你的项目需要在 Windows(Visual Studio)、Linux(GCC/Make)、macOS(Xcode/Clang)上编译。没有 CMake,你需要为每个平台维护一套独立的构建文件(如 Makefile、.vcxproj),极其繁琐且容易出错。CMake 让你只写一套配置,通吃所有平台。

  2. 管理复杂项目:现代软件项目通常包含多个子目录、库、可执行文件,依赖关系复杂。CMake 提供了清晰的结构化方式来管理这些依赖。

  3. 依赖管理:CMake 内置了查找系统库和外部包的功能(find_package),并能很好地与包管理器(如 Conan、vcpkg)配合,简化第三方库的集成。

  4. 生态成熟:CMake 已成为 C/C++ 社区的事实标准,绝大多数开源 C/C++ 项目(如 Qt、VTK、OpenCV、LLVM)都使用 CMake。这意味着你可以轻松地将这些项目作为依赖集成到自己的项目中。

  5. 支持现代开发实践:支持测试(CTest)、打包(CPack)、持续集成等。

CMake 的主要工作流程
一个典型的 CMake 项目构建分为三个步骤:

  1. 配置阶段
    执行 cmake -B build -S . 命令。
    CMake 读取项目根目录的 CMakeLists.txt 文件。分析项目结构、依赖、编译器,并在指定的 build 目录中生成对应的构建系统文件(如 Makefile 或 .sln)。

  2. 生成阶段
    在上一步中自动完成,生成了本地构建系统所需的文件。

  3. 构建阶段
    使用本地构建工具来实际编译链接。
    Linux/macOS:通常在 build 目录执行 make(这实际上是调用 CMake 生成的 Makefile)。
    Windows:打开生成的 .sln 文件用 Visual Studio 构建,或在命令行使用 msbuild。
    更通用的跨平台命令是:cmake --build build

“源代码外构建” 是 CMake 的推荐做法(即在独立的 build 目录中构建),这能保持源码目录的清洁,并允许你为不同配置(Debug/Release)创建多个构建目录。

2. CMakeLists.txt 基本示例

cmake_minimum_required(VERSION 3.16)

#指定CMake最低版本要求。
project(QtUdpCommLibProj VERSION 1.0.0 DESCRIPTION "Qt UDP Communication Library" LANGUAGES CXX)

#指定项目名称为QtUdpCommLibProj,是项目的标识符,在整个CMake配置中作为根命名空间。
#会自动定义以下变量:
#PROJECT_NAME = QtUdpCommLibProj
#PROJECT_SOURCE_DIR = 项目根目录路径
#PROJECT_BINARY_DIR = 构建目录路径

#VERSION定义项目版本号为1.0.0,定义项目版本,CMake 会自动将其拆分为多个变量,这些变量可以在代码中使用(通过配置头文件传递)。
#PROJECT_VERSION = 1.0.0
#PROJECT_VERSION_MAJOR = 1
#PROJECT_VERSION_MINOR = 0
#PROJECT_VERSION_PATCH = 0

#DESCRIPTION定义项目的简短描述内容,存储在PROJECT_DESCRIPTION变量中。

#LANGUAGES指定项目使用C++语言,CMake 会根据这个设置查找相应的编译器。
#当指定LANGUAGES CXX时,CMake会自动查找C++编译器,并设置一些与C++相关的变量,如下所示:
# CMAKE_CXX_COMPILER      # C++ 编译器路径
# CMAKE_CXX_FLAGS         # C++ 编译标志
# CMAKE_CXX_STANDARD      # C++ 标准(需额外设置)
set(CMAKE_CXX_STANDARD 17)				#指定项目要求使用 C++17 标准
set(CMAKE_CXX_STANDARD_REQUIRED ON) 	#强制要求必须支持指定的 C++ 标准
set(CMAKE_CXX_EXTENSIONS OFF)			#禁用编译器特定的扩展,使用标准的 ISO C++

# 设置编译器使用 UTF-8
# 针对 Windows MSVC 编译器的特殊配置,主要解决字符编码和安全性警告问题
if(MSVC)
    add_compile_options(/utf-8)  					# 源代码文件、执行字符集均使用UTF-8编码
    add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
endif()
set(QT_PATH  "E:/CollectDoc/lib_files/qt/5.15.12/msvc2019_64")
set(CMAKE_PREFIX_PATH "${QT_PATH}/lib/cmake/Qt5" ${CMAKE_PREFIX_PATH})

# 定义一个变量 QT_PATH ,存储 Qt 的安装路径。并将 Qt 的 CMake 配置路径添加到 CMAKE_PREFIX_PATH 中

# CMAKE_PREFIX_PATH 是 CMake 的查找路径变量,CMake 在查找包时会搜索这些路径。
# 类似系统 PATH,但用于 CMake 的 find_package() 命令。优先级顺序:从左到右,先添加的路径优先级高。
# 特别要注意,这里需要设置Qt的lib/cmake目录,而不是根目录。
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# CMake 中的一个便捷设置,CMake 会自动为当前 CMakeLists.txt 文件中创建的所有目标添加两个包含路径
# 当前源代码目录 (${CMAKE_CURRENT_SOURCE_DIR})
# 当前构建目录 (${CMAKE_CURRENT_BINARY_DIR})

# 当不使用 CMAKE_INCLUDE_CURRENT_DIR 时,需要在target_include_directories中手动添加这两个路径:如下所示:
add_executable(my_app src/main.cpp src/utils.cpp)
set(CMAKE_INCLUDE_CURRENT_DIR OFF)
target_include_directories(my_app 
	PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}      # 当前目录(根目录)
        ${CMAKE_CURRENT_BINARY_DIR}      # 构建目录
        src                              # 源代码目录
)

# 使用 CMAKE_INCLUDE_CURRENT_DIR 时,如下所示:
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(my_app src/main.cpp src/utils.cpp)
target_include_directories(my_app PRIVATE src)
set(CMAKE_AUTOMOC ON)
# CMake中自动处理Qt的元对象编译器(MOC)的设置,当CMAKE_AUTOMOC设置为ON时:
# 1. 自动检测需要MOC的文件,CMake会自动扫描源代码,找出包含Q_OBJECT宏的文件。
# 2. 自动运行MOC编译器,为需要MOC的文件生成moc_*.cpp文件。
# 3. 自动添加到构建系统,生成的MOC文件会自动添加到目标的源文件列表中。
# 4. 自动处理包含路径,确保MOC文件能被正确包含。

set(CMAKE_AUTOUIC ON)
# CMake中用于自动处理Qt的用户界面编译器(UIC)的设置。它用于自动编译Qt Designer创建的.ui文件(用户界面文件)
# 1. 自动检测.ui文件,CMake会自动扫描项目中的.ui文件。
# 2. 为每个.ui文件生成ui_*.h头文件。
# 3. 自动处理依赖关系,确保 UI 文件的更改会触发重新编译。
# 4. 自动设置包含路径,确保生成的 UI 头文件能被正确包含。

set(CMAKE_AUTORCC ON)
# CMake中用于自动处理Qt的资源编译器(RCC)的设置。它用于自动编译Qt资源文件(.qrc 文件),将资源嵌入到应用程序中。
# 1. CMake会自动扫描项目中的.qrc资源文件。
# 2. 自动运行RCC编译器,为每个 .qrc 文件生成 qrc_*.cpp 源文件。
# 3. 资源嵌入到可执行文件,资源被编译进程序,不需要外部文件。
# 4. 自动处理依赖关系,确保资源文件的更改会触发重新编译。
# 让CMake自动查找Qt
find_package(Qt5 REQUIRED COMPONENTS Core Widgets Network)

# Qt5 指定包名为Qt5
# CMake 会按照以下顺序查找:1. CMAKE_PREFIX_PATH;2. 系统路径,即标准安装位置;3. 环境变量。
# 找到后会设置如下变量:
# Qt5_FOUND           # TRUE 表示找到
# Qt5_VERSION         # 找到的 Qt 版本,如 "5.15.2"
# Qt5_DIR             # Qt5Config.cmake 所在目录

# REQUIRED 指定如果找不到 Qt5 或指定的组件,CMake 配置阶段直接失败。

# COMPONENTS 指定需要的模块,找到后需要通过target_link_libraries命令为每个模块创建导入目标。
# CMAKE_ARCHIVE_OUTPUT_DIRECTORY用于控制静态库(.a、.lib 文件)的输出目录
# 影响所有通过 add_library() 创建的静态库,默认输出到构建目录的根目录。
# 变量${CMAKE_BINARY_DIR}表示项目的构建目录(通常是 build/ 目录),设置静态库输出到build/lib/子目录。
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)

# CMAKE_LIBRARY_OUTPUT_DIRECTORY用于控制动态库(.so、.dll)的输出目录
# 影响通过 add_library() 创建的共享库(SHARED 库)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
# 控制库的构建类型(静态库或动态库)
# BUILD_SHARED_LIBS:ON/OFF选项会全局影响项目中所有add_library()命令的行为
# ON时会构建为动态库;OFF时会构建为静态库
option(BUILD_SHARED_LIBS "Build shared library" ON)
# 创建库(不要包含头文件在源文件列表中)
# add_library 为 CMake 中创建库目标的核心命令。
# 需要通过指定 BUILD_SHARED_LIBS 确定库文件的类型。
# 也可以在 add_library 中通过 SHARED 与 STATIC 指定编译为动态库或静态库。
add_library(QtUdpCommLib
    UdpBroadcaster.cpp
    UdpReceiver.cpp
    UdpCommMng.cpp
)


# 创建可执行文件
add_executable(QtUdpComm
	main.cpp				# 注意一定要有main函数
	UdpBroadcaster.cpp
    UdpReceiver.cpp
    UdpCommMng.cpp
)
# 链接Qt库
# 指定目标(库或可执行文件)需要链接的库
# 传递依赖关系:自动处理包含目录、编译定义等
# 解决符号引用:让编译器/链接器找到外部函数和类的定义
# 可以在 target_link_libraries 中通过 PRIVATE、PUBLIC、INTERFACE 决定链接的库的暴露程度。
# PRIVATE 指定库内部使用,不暴露给用户
# PUBLIC 指定库内部使用,并暴露给用户
# INTERFACE 库本身并未使用,仅暴露给用户
target_link_libraries(QtUdpCommLib
    Qt5::Core
    Qt5::Network
    Qt5::Widgets
)
<think>嗯,用户想要查找关于CMake学习资料,包括教程和资源。我需要先整理现有的引用内容,看看有哪些可用的信息。根据用户提供的引用[1],里面有提到一个详细的CMake教程、构建应用程序的经验、使用CPack打包软件,以及一个视频教程《Getting Started with CMake》。这些都是很好的资源。引用[2]提到在CentOS 7上更新CMake的方法,可能对用户的环境配置有帮助。 首先,用户可能需要基础教程,所以应该推荐官方文档和那个超详细的教程。然后,视频教程可能更适合视觉学习者,所以需要提到。接着,实战经验和小技巧也很重要,比如如何组织项目结构,处理依赖等,引用里的“cmake的一些小经验”应该包含这些。CPack打包可能属于进阶内容,但用户可能有兴趣,所以也要列出来。 用户可能在使用旧版系统,比如CentOS 7,所以需要提醒他们升级CMake的方法,如通过EPEL或源码编译,这点在引用[2]里提到了。此外,可能需要补充其他资源,比如书籍或在线课程,虽然引用里没有,但可以建议《CMake Cookbook》和Udemy的课程作为补充。 然后,生成相关问题的时候,要考虑用户可能遇到的后续问题,比如基础学习资料、项目构建方法、处理依赖、跨平台配置、调试技巧,以及推荐的书籍或课程。这样能帮助他们进一步深入学习。 最后,确保回答结构清晰,分点列出,每个部分有对应的引用,并在末尾添加相关问题。检查是否符合之前的格式要求,比如数学表达式是否正确,但这个问题可能不涉及数学内容,所以主要关注资源推荐和步骤。</think>以下是关于CMake学习教程和资源的整理,结合系统级要求和实际应用场景: ### 一、基础学习资源 1. **官方文档与教程** - CMake官方文档是最权威的参考资料,涵盖语法、命令和模块说明[^1]。 - 推荐教程:[Linux下CMake使用教程](https://example-link.com),详细讲解项目构建流程,适合入门[^1]。 2. **视频教程** - 《Getting Started with CMake》:适合零基础学习,涵盖构建、测试和安装流程[^1]。 3. **实战经验** - 参考《CMake的一些小经验》,学习项目结构优化和依赖管理技巧[^1]。 ### 二、进阶内容 1. **跨平台构建** - 使用`CMAKE_TOOLCHAIN_FILE`配置交叉编译,例如嵌入式开发或Windows/macOS兼容性设置。 2. **依赖管理** - 通过`find_package`或`FetchContent`管理第三方库,例如集成OpenCV或Boost。 3. **打包与分发** - 使用CPack生成DEB/RPM包或Windows安装程序,简化部署流程。 ### 三、环境配置注意事项 - **CentOS 7用户**:系统自带的CMake版本较旧,建议通过EPEL仓库或源码编译升级[^2]。 示例升级命令: ```bash # 通过EPEL安装 sudo yum install epel-release sudo yum install cmake3 # 或源码编译 wget https://cmake.org/files/v3.25/cmake-3.25.1.tar.gz tar xzf cmake-3.25.1.tar.gz cd cmake-3.25.1 ./bootstrap && make && sudo make install ``` ### 四、推荐工具与扩展 - **IDE支持**:CLion、VS Code + CMake插件 - **调试技巧**:使用`message()`命令输出变量值,或`--debug-output`参数运行CMake
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值