1. CMake 说明 #

  • CMake 的定义:高级编译配置工具
  • 用途:处理多语言、不同编译器的项目生成可执行文件或共享库
  • 操作:通过编译 CMakeLists.txt 完成
  • 官方网站:www.cmake.org
  • 学习目标:为处理大型 C/C++/Java 项目做准备

2. CMake 安装 #

  • 大多数 Linux 系统已预装 CMake
  • Windows 或某些未预装 Linux 系统需访问官网下载

3. CMake 一个 Hello World 示例 #

3.1 写一个 Hello World 程序 #

// main.cpp
#include <iostream>

int main() {
    std::cout << "hello world" << std::endl;
}

3.2 创建 CMakeLists.txt 文件 #

// CMakeLists.txt
PROJECT(HELLO)
SET(SRC_LIST main.cpp)
MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR})
MESSAGE(STATUS "This is SOURCE dir " ${HELLO_SOURCE_DIR})
ADD_EXECUTABLE(hello ${SRC_LIST})

3.3 使用 CMake 生成 Makefile #

cmake .

3.4 使用 make 命令编译 #

make

3.5 生成可执行程序 #

4. CMake Hello World 语法介绍 #

4.1 PROJECT 关键字 #

  • 用于指定项目名称及支持语言(如 CXX 为 C++)

4.2 SET 关键字 #

  • 用于显式指定变量

4.3 MESSAGE 关键字 #

  • 向终端输出用户自定义信息

4.4 ADD_EXECUTABLE 关键字 #

  • 生成可执行文件

5. 语法基本原则 #

  • 变量使用 ${} 取值,在 IF 控制语句中直接使用变量名
  • 指令和参数用括号括起,参数间用空格或分号分开
  • 指令大小写不敏感,推荐使用大写指令

5.1 语法注意事项 #

  • SET(SRC_LIST main.cpp) 可以写成 SET(SRC_LIST “main.cpp”)
  • ADD_EXECUTABLE(hello main) 后缀可省略,CMake 会自动查找 .c.cpp

6. 内部与外部构建 #

  • 内部构建:生成临时文件,清理不便
  • 外部构建:生成的临时文件放在 build 目录,推荐使用外部构建

6.1 外部构建方式示例 #

  1. 创建 build 目录
  2. build 目录执行 cmake ..
  3. build 目录执行 make

7. 改进 Hello World 示例 #

7.1 目标结构设计 #

  • 添加 srcdoc 子目录
  • 使用 runhello.sh 脚本调用二进制文件

7.2 ADD_SUBDIRECTORY 指令 #

  • 向工程中添加子目录并指定编译输出路径

7.3 更改二进制保存路径 #

  • 使用 SET(EXECUTABLE_OUTPUT_PATH ...) 修改目标文件存放路径

8. 安装目标与文件 #

  • 使用 INSTALL 指令安装目标文件(如二进制、动态库、静态库等)

8.1 安装示例 #

INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/)

8.2 安装脚本与文档 #

  • 使用 INSTALL(PROGRAMS runhello.sh DESTINATION bin) 安装脚本
  • 安装文档:INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake)

9. 静态库与动态库的构建 #

9.1 静态库与动态库的区别 #

  • 静态库(.a/.lib):编译时合并进目标程序
  • 动态库(.so/.dll):编译时不合并,目标程序不能独立运行

9.2 构建实例 #

// CMakeLists.txt
PROJECT(HELLO)
ADD_SUBDIRECTORY(lib bin)

10. 同时构建静态与动态库 #

10.1 使用 ADD_LIBRARY 指令 #

  • 构建动态库:ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
  • 构建静态库:ADD_LIBRARY(hello STATIC ${LIBHELLO_SRC})

10.2 设置输出名称 #

SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")

10.3 动态库版本号 #

  • 设置版本号:SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)

10.4 安装共享库和头文件 #

INSTALL(FILES hello.h DESTINATION include/hello)
INSTALL(TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)

11. 使用外部共享库与头文件 #

11.1 设置头文件搜索路径 #

INCLUDE_DIRECTORIES(/usr/include/hello)

11.2 设置库链接路径 #

LINK_DIRECTORIES(/home/myproject/libs)
TARGET_LINK_LIBRARIES(main libhello.a)