ToB企服应用市场:ToB评测及商务社交产业平台

标题: Linux C++ 开发5 - 一文了解CMake构建 [打印本页]

作者: 熊熊出没    时间: 2024-8-26 16:25
标题: Linux C++ 开发5 - 一文了解CMake构建
上一篇《Linux C++ 开发4 - 入门makefile一篇文章就够了》我们讲解了通过Makefile来编译 包含多个.cpp和多个.h文件 的复杂C++项目。这种方式用来构建中小型的Linux(或类Unix系统)C++项目,是没有问题的。但假如是跨平台项目或者大型项目,Makefile就显得力有未逮了;因为Makefile不具备良好的跨平台性,大型项目的编译规则和依靠项也是比力复杂的,Makefile的编写和维护资本都比力高。这时,CMake就可以派上用场了。
1. 什么是CMake?

1.1. CMake的定义

CMake是一个跨平台的开源构建系统天生器。它能够天生各种构建系统文件,如Makefile、Visual Studio 项目文件等。CMake通过读取一个或多个CMakeLists.txt文件来设置项目的构建过程。
1.2. CMake有哪些优势?

相较于Makefile,CMake有以下优势。
1.3. CMake 的特点

1.4. Cmake 、CMakeLists.txt 、Make 、Makefile 之间的关系

他们之间的关系可以用下面这张图来表示。

2. 应用案例

Linux C++ 开发4 - 入门makefile一篇文章就够了》一文中,我们用Makefile编译了Iterator项目。如今我们任然以这个项目为例,将其改成通过CMake来构建。
2.1. 项目概述

一个公司有多个部门,每个部门有多个人组成,这些人中有开发人员,有测试人员,和与项目相关的别的人员,其结构如下图片。

如今要遍历这个公司的所有开发人员,遍历这个公司的所有测试人员。
在项目的源代码中,我们用迭代器模式实现了这个需求,类的结构图是这样的:

详细代码参见: https://gitee.com/spencer_luo/iterator/tree/cmake/
如今我们就以这个项目为例,看看这个项目的CMakeLists.txt需要怎么写?
2.2. CMakeLists.txt

2.2.1. 基本用法

设置 cmake的最低版本号:
  1. cmake_minimum_required(VERSION 3.28.3)
复制代码
注意:这一项要放在CMakeLists.txt的第一行,否则可能会报错。
设置 项目名称、版本、语言:
  1. project(Iterator VERSION 1.0.0 LANGUAGES CXX)
复制代码
这里CXX表示C++语言。
设置 C/C++ 的标准:
  1. set(CMAKE_C_STANDARD 11)
  2. set(CMAKE_CXX_STANDARD 11)
复制代码
可以根据自己的需求设置编译时利用的C++版本,如:98/11/14/17/20。(注意:你的编译也要能支持你设置的C++版本)
查找要编译的.cpp文件:
  1. file(GLOB SRC_FILES
  2.     ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
  3. )
  4. message(DEBUG "COMMON_UTIL_SRC:" ${SRC_FILES})
复制代码
构建可实行文件:
  1. add_executable(${PROJECT_NAME} ${SRC_FILES})
复制代码
根据不同的编译模式添加不同的编译选项:
  1. # 设置构建类型: Debug/Release
  2. set(CMAKE_BUILD_TYPE Debug)
  3. # 设置编译选项
  4. if(CMAKE_BUILD_TYPE STREQUAL "Debug")
  5.     # Debug模式,编译是需要保留调试符号表
  6.     set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -pg")
  7. elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
  8.     # Release模式,编译时优化代码,优化选项:-O2
  9.     set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2")
  10. endif()
复制代码
这里通过 if(CMAKE_BUILD_TYPE STREQUAL "Debug") 来判断是Debug模式照旧Release模式,然后设置不同的编译选项,Debug模式下编译时保留调试符号表,Release模式下编译时会优化代码。
2.2.2. 完整内容
  1. # 要求的cmake的最低版本号cmake_minimum_required(VERSION 3.28.3)# 项目名称、版本、语言project(Iterator VERSION 1.0.0 LANGUAGES CXX)# C/C++ 的标准: C11/C++11set(CMAKE_C_STANDARD 11)
  2. set(CMAKE_CXX_STANDARD 11)# 查找要编译的.cpp文件file(GLOB SRC_FILES
  3.     ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
  4. )
  5. message(DEBUG "COMMON_UTIL_SRC:" ${SRC_FILES})# 构建可实行文件add_executable(${PROJECT_NAME} ${SRC_FILES})
复制代码
2.2.3. 构建实行

构建项目:
  1. # 开始构建项目,生成Makefile构建系统文件
  2. cmake -B ./build -S ./
  3. -- The CXX compiler identification is GNU 13.2.0
  4. -- Detecting CXX compiler ABI info
  5. -- Detecting CXX compiler ABI info - done
  6. -- Check for working CXX compiler: /usr/bin/c++ - skipped
  7. -- Detecting CXX compile features
  8. -- Detecting CXX compile features - done
  9. -- Configuring done (1.5s)
  10. -- Generating done (0.1s)
  11. -- Build files have been written to: /mnt/d/workspace/iterator/build
  12. ➜  iterator git:(cmake) ✗
复制代码
cmake -B ./build -S ./阐明:
开始编译链接:
  1. # 进入 build 目录
  2. cd build
  3. # 查看 build 目录有哪些文件
  4. ls
  5. CMakeCache.txt  CMakeFiles  Makefile  cmake_install.cmake
  6. # 执行make,开始编译链接
  7. make
  8. [ 25%] Building CXX object CMakeFiles/Iterator.dir/Company.cpp.o
  9. [ 50%] Building CXX object CMakeFiles/Iterator.dir/Iterator.cpp.o
  10. [ 75%] Building CXX object CMakeFiles/Iterator.dir/Person.cpp.o
  11. [100%] Linking CXX executable Iterator
  12. [100%] Built target Iterator
复制代码
实行编译结果:
  1. # 进入 build 目录。此时会发现多了一个可执行文件 Iterator
  2. ls
  3. CMakeCache.txt  CMakeFiles  Iterator  Makefile  cmake_install.cmake
  4. # 执行 Iterator 可执行文件,查看输出结果
  5. ./Iterator
  6. 遍历所有开发者:
  7. 员工:1-Developer11 开发工程师,擅长语言:C++,负责项目:智慧城市
  8. 员工:2-Developer12 开发工程师,擅长语言:Java,负责项目:智慧城市
  9. 员工:3-Developer13 开发工程师,擅长语言:JavaScript,负责项目:智慧城市
  10. 员工:6-Developer21 开发工程师,擅长语言:IOS,负责项目:智能语音
  11. 员工:7-Developer22 开发工程师,擅长语言:Android,负责项目:智能语音
  12. 员工:9-Developer31 开发工程师,擅长语言:C++,负责项目:电子书内核
  13. 遍历所有测试人员:
  14. 员工:4-Tester15 测试工程师,测试类型:LoadRunner
  15. 员工:5-Tester16 测试工程师,测试类型:黑盒测试
  16. 员工:8-Tester24 测试工程师,测试类型:TestIn
  17. 员工:10-Tester35 测试工程师,测试类型:LoadRunner
  18. 遍历公司所有员工:
  19. 员工:1-Developer11 开发工程师,擅长语言:C++,负责项目:智慧城市
  20. 员工:2-Developer12 开发工程师,擅长语言:Java,负责项目:智慧城市
  21. 员工:3-Developer13 开发工程师,擅长语言:JavaScript,负责项目:智慧城市
  22. 员工:4-Tester15 测试工程师,测试类型:LoadRunner
  23. 员工:5-Tester16 测试工程师,测试类型:黑盒测试
  24. 员工:6-Developer21 开发工程师,擅长语言:IOS,负责项目:智能语音
  25. 员工:7-Developer22 开发工程师,擅长语言:Android,负责项目:智能语音
  26. 员工:8-Tester24 测试工程师,测试类型:TestIn
  27. 员工:9-Developer31 开发工程师,擅长语言:C++,负责项目:电子书内核
  28. 员工:10-Tester35 测试工程师,测试类型:LoadRunner
复制代码
大家好,我是陌尘。
IT从业10年+, 北漂过也深漂过,目前暂定居于杭州,未来不知还会飘向何方。
搞了8年C++,也干过2年前端;用Python写过书,也玩过一点PHP,未来还会折腾更多东西,不死不休。
感谢大家的关注,期待与你一起成长。
【SunLogging】
扫码二维码,关注微信公众号,阅读更多出色内容
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4