CMake构建集成编译环境

268 阅读3分钟

一. CMake简介

使用方便,可以跨平台,构建项目编译环境,尤其比直接写Makefile简单(在构建大型工程编译时,需要写大量的文件依赖关系),可以通过简单的CMake生成负责的Makefile文件。

二. CMake安装

ubuntu上直接执行sudo apt install cmake安装完成,可以通过cmake -version查看其版本

image.png

三. CMake使用介绍

vscode上使用cmake时,在远程Linux安装如下插件

image.png

在vscode的cmake的配置文件中添加cmake的路径 image.png

1. 示例

cmake命令会执行目录下的CMakeLists.txt的配置文件内容如下:

#要求cmake最低的版本号
cmake_minimum_required(VERSION 3.0)
#定义当前工程名字
project(main)

#配置编译选项
set(CMAKE_BUILD_TYPE "Debug")#设置debug模式,如果没有这一行将不能调试设断点
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -g)

#配置头文件搜索路径
#include_directories()
#配置库文件搜索路径
#link_directories()

#如果需要编译的有多个源文件,可以都添加到add_executable(main main.cpp test.cpp)列表当中,
#但是如果源文件太多,一个个添加到add_executable的源文件列表中,就太麻烦了,
#此时可以用aux_source_directory(dir var)来定义源文件列表,
#把.指定路径下的所有源文件名字放入变量名SRC_LIST里面
#aux_source_directory(. SRC_LIST)

#aux_source_directory()也存在弊端,它会把指定目录下的所有源文件都加进来,
#可能会加入一些我不需要的文件,此时我们可以使用set命令去新建变量来存放需要的源文件
set(SRC_LIST ./muduo_server.cpp)

#表示生成可执行文件server,由SRC_LIST所定义的源文件编译而来
add_executable(server ${SRC_LIST})

#表示server这个目标程序,需要连接muduo_net muduo_base pthread这三个库文件
target_link_libraries(server muduo_net muduo_base pthread)

image.png

2. 静态库和动态库的编译控制

把sum和minor源文件直接生成静态库或者动态库,让外部程序进行链接使用,代码结构如下:

image.png 最外层的CMakeLists.txt是总控制编译,内容如下

cmake_minimum_required (VERSION 2.8)
project (math)
add_subdirectory (test)
add_subdirectory (src)

src里面的源代码要生成静态库或动态库,CMakeLists.txt内容如下:

set (LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
# 生成库,动态库是SHARED,静态库是STATIC
add_library (sum SHARED sum.cpp)
add_library (minor SHARED minor.cpp)
# 修改库的名字
#set_target_properties (sum PROPERTIES OUTPUT_NAME "libsum")
#set_target_properties (minor PROPERTIES OUTPUT_NAME "libminor")

test里面的CMakeLists.txt内容如下:

set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
include_directories (../include) # 头文件搜索路径
link_directories (${PROJECT_SOURCE_DIR}/lib) # 库文件搜索路径
add_executable (main main.cpp) # 指定生成的可执行文件
target_link_libraries (main sum minor) # 执行可执行文件需要依赖的库

在build目录下执行cmake ..命令,然后执行make,如下:

shen@ubuntu-vm:~/code/test/build$ make
[ 16%] Building CXX object src/CMakeFiles/minor.dir/minor.cpp.o
[ 33%] Linking CXX shared library ../../lib/libminor.so
[ 33%] Built target minor
[ 50%] Building CXX object src/CMakeFiles/sum.dir/sum.cpp.o
[ 66%] Linking CXX shared library ../../lib/libsum.so
[ 66%] Built target sum
Scanning dependencies of target main
[ 83%] Building CXX object test/CMakeFiles/main.dir/main.cpp.o
[100%] Linking CXX executable ../../bin/main
[100%] Built target main

查看生成的可执行文件,检验其链接的库有哪些

PROJECT_NAME : 通过 project() 指定项目名称

PROJECT_SOURCE_DIR : 工程的根目录

PROJECT_BINARY_DIR : 执行 cmake 命令的目录

CMAKE_CURRENT_SOURCE_DIR : 当前 CMakeList.txt 文件所在的目录

CMAKE_CURRENT_BINARY_DIR : 编译目录,可使用 add subdirectory 来修改

EXECUTABLE_OUTPUT_PATH : 二进制可执行文件输出位置

LIBRARY_OUTPUT_PATH : 库文件输出位置

BUILD_SHARED_LIBS : 默认的库编译方式 ( shared 或 static ) ,默认为 static

CMAKE_C_FLAGS : 设置 C 编译选项

CMAKE_CXX_FLAGS : 设置 C++ 编译选项

CMAKE_CXX_FLAGS_DEBUG : 设置编译类型 Debug 时的编译选项

CMAKE_CXX_FLAGS_RELEASE : 设置编译类型 Release 时的编译选项

CMAKE_GENERATOR : 编译器名称

CMAKE_COMMAND : CMake 可执行文件本身的全路径

CMAKE_BUILD_TYPE : 工程编译生成的版本, Debug / Release

3. 自行编写CMakeLists测试一

使用CMakeLists.txt生成了很多的中间文件,会和工程源文件混在一起,这不合适

我们在项目中应该这么做: 一个正式的工程源码应该有这几个目录:

  • bin:生成的可执行文件
  • lib:生成的中间库文件
  • include:生成的头文件
  • src:源文件
  • build:编译过程中产生临时的中间文件
  • test/example:测试文件或示例
  • thridparty:依赖的第三方库文件
  • CMakeList.txt
  • autobuild.sh:一键编译脚本

一般我们使用gcc/g++编译,需要涉及到以下6部分:生成的文件、调试参数、编译的源文件、头文件搜索路径、库文件搜索路径、需要链接的库

image.png

image.png 生成的文件全部放在了build里面。

4. 自行编写CMakeLists测试二

生成的可执行文件应该在bin里面,需要设置可执行文件最终存储路径set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

image.png

此时目录结构就和我们预期一样了。