CMake快速入门

本文详细介绍了CMake的基本语法、重要指令和常用变量,演示了如何通过CMakeLists.txt统一管理项目配置,包括添加源文件、设置编译选项、链接库等。特别强调了CMake在解决多工具环境一致性问题上的优势。
摘要由CSDN通过智能技术生成

前言:

  • CMake是一个跨平台的安装编译工具,可以用简单的语句来描述所有平台的安装(编译过程)。
  • CMake可以说已经成为大部分C++开源项目标配

CMake官方文档

Cross-platform development

在这里插入图片描述
What you will do if you want to add new bar.cpp source file? You have to add it to every tool you use:

在这里插入图片描述
To keep the environment consistent you have to do the similar update several times. And the most important thing is that you have to do it manually (arrow marked with a red color on the diagram in this case). Of course such approach is error prone and not flexible.

CMake solve this design flaw by adding extra step to development process. You can describe your project in CMakeLists.txt file and use CMake to generate tools you currently interested in using cross-platform CMake code:

在这里插入图片描述
Same action - adding new bar.cpp file, will be done in one step now:

在这里插入图片描述
Note that the bottom part of the diagram was not changed. I.e. you still can keep using your favorite tools like Visual Studio/msbuild, Xcode/xcodebuild and Makefile/make!


语法特性介绍

基本语法格式:指令(参数 1 参数 2…)

  • 参数使用括弧括起
  • 参数之间使用空格或分号分开

指令是大小写无关的,参数和变量是大小写相关的

set(HELLO hello.cpp)
add_executable(hello main.cpp hello.cpp)
ADD_EXECUTABLE(hello main.cpp ${HELLO})

变量使用${}方式取值,但是在 IF 控制语句中是直接使用变量名

# 1.cmake verson,指定cmake版本 
cmake_minimum_required(VERSION 3.4.1)

# 2.project name,指定项目的名称,一般和项目的文件夹名称对应
PROJECT(test_math_lib)

# 3.head file path,头文件目录
INCLUDE_DIRECTORIES(include)

# 4.source directory,源文件目录
AUX_SOURCE_DIRECTORY(src DIR_SRCS)

# 5.set environment variable,设置环境变量,编译用到的源文件全部都要放到这里,否则编译能够通过,但是执行的时候会出现各种问题,比如"symbol lookup error xxxxx , undefined symbol"
SET(TEST_MATH ${DIR_SRCS})

# 6.add executable file,添加要编译的可执行文件
ADD_EXECUTABLE(${PROJECT_NAME} ${TEST_MATH})

# 7.add link library,添加可执行文件所需要的库,比如我们用到了libm.so(命名规则:lib+name+.so),就添加该库的名称
TARGET_LINK_LIBRARIES(${PROJECT_NAME} m)

重要指令和CMake常用变量

重要指令

cmake_minimum_required - 指定CMake的最小版本要求
# CMake最小版本要求为2.8.3
cmake_minimum_required(VERSION 2.8.3)

语法:cmake_minimum_required(VERSION versionNumber [FATAL_ERROR])

project - 定义工程名称,并可指定工程支持的语言
# 指定工程名为HELLOWORLD
project(HELLOWORLD)

语法:project(projectname [CXX] [C] [Java])

set - 显式的定义变量
# 定义SRC变量,其值为main.cpp hello.cpp
set(SRC sayhello.cpp hello.cpp)

语法:set(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])

include_directories - 向工程添加多个特定的头文件搜索路径 —>相当于指定g++编译器的-I参数
# 将/usr/include/myincludefolder 和 ./include 添加到头文件搜索路径
include_directories(/usr/include/myincludefolder ./include)

语法:include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 …)

link_directories - 向工程添加多个特定的库文件搜索路径 —>相当于指定g++编译器的-L参数
# 将/usr/lib/mylibfolder 和 ./lib 添加到库文件搜索路径
link_directories(/usr/lib/mylibfolder ./lib)

语法:link_directories(dir1 dir2 …)

add_library - 生成库文件
# 通过变量 SRC 生成 libhello.so 共享库
add_library(hello SHARED ${SRC})

语法:add_library(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 … sourceN)

add_compile_options - 添加编译参数
# 添加编译参数 -Wall -std=c++11
add_compile_options(-Wall -std=c++11 -O2)

语法:add_compile_options(

add_executable - 生成可执行文件
# 编译main.cpp生成可执行文件main
add_executable(main main.cpp)

语法:add_library(exename source1 source2 … sourceN)

target_link_libraries - 为 target 添加需要链接的共享库 —>相同于指定g++编译器-l参数
# 将hello动态库文件链接到可执行文件main
target_link_libraries(main hello)

语法:target_link_libraries(target library1library2…)

add_subdirectory - 向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置
# 添加src子目录,src中需有一个CMakeLists.txt
add_subdirectory(src)

语法:add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

aux_source_directory - 发现一个目录下所有的源代码文件并将列表存储在一个变量中,这个指令临时被用来自动构建源文件列表
# 定义SRC变量,其值为当前目录下所有的源代码文件
aux_source_directory(. SRC)
# 编译SRC变量所代表的源代码文件,生成main可执行文件
add_executable(main ${SRC})

语法:aux_source_directory(dir VARIABLE)


6.3.2 CMake常用变量

  • CMAKE_C_FLAGS gcc编译选项
  • CMAKE_CXX_FLAGS g++编译选项
# 在CMAKE_CXX_FLAGS编译选项后追加-std=c++11
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
  • CMAKE_BUILD_TYPE 编译类型(Debug, Release)
# 设定编译类型为debug,调试时需要选择debug
set(CMAKE_BUILD_TYPE Debug) 
# 设定编译类型为release,发布时需要选择release
set(CMAKE_BUILD_TYPE Release) 
  • CMAKE_BINARY_DIR

  • PROJECT_BINARY_DIR

  • __BINARY_DIR

    • 这三个变量指代的内容是一致的。
    • 如果是 in source build,指的就是工程顶层目录。
    • 如果是 out-of-source 编译,指的是工程编译发生的目录。
  • PROJECT_BINARY_DIR 跟其他指令稍有区别,不过现在,你可以理解为他们是一致的。

  • CMAKE_SOURCE_DIR

  • PROJECT_SOURCE_DIR

  • __SOURCE_DIR

    • 这三个变量指代的内容是一致的,不论采用何种编译方式,都是工程顶层目录。
    • 也就是在 in source build时,他跟 CMAKE_BINARY_DIR 等变量一致。
    • PROJECT_SOURCE_DIR 跟其他指令稍有区别,现在,你可以理解为他们是一致的。
  • CMAKE_C_COMPILER:指定C编译器

  • CMAKE_CXX_COMPILER:指定C++编译器

  • EXECUTABLE_OUTPUT_PATH:可执行文件输出的存放路径

  • LIBRARY_OUTPUT_PATH:库文件输出的存放路径


6.4 CMake编译工程

CMake目录结构:项目主目录存在一个CMakeLists.txt文件

两种方式设置编译规则:

包含源文件的子文件夹包含CMakeLists.txt文件,主目录的CMakeLists.txt通过add_subdirectory添加子目录即可;

包含源文件的子文件夹未包含CMakeLists.txt文件,子目录编译规则体现在主目录的CMakeLists.txt中;

6.4.1 编译流程

在 linux 平台下使用 CMake 构建C/C++工程的流程如下:

手动编写 CmakeLists.txt。

执行命令 cmake PATH生成 Makefile ( PATH 是顶层CMakeLists.txt 所在的目录 )。

执行命令make 进行编译。

# important tips
.          # 表示当前目录
./         # 表示当前目录

..      # 表示上级目录
../     # 表示上级目录

6.4.2 两种构建方式

内部构建(in-source build):不推荐使用

内部构建会在同级目录下产生一大堆中间文件,这些中间文件并不是我们最终所需要的,和工程源文件放在一起会显得杂乱无章。

## 内部构建

# 在当前目录下,编译本目录的CMakeLists.txt,生成Makefile和其他文件
cmake .
# 执行make命令,生成target
make
外部构建(out-of-source build):推荐使用

将编译输出文件与源文件放到不同目录中

## 外部构建
# 1. 在当前目录下,创建build文件夹
mkdir build 
# 2. 进入到build文件夹
cd build
# 3. 编译上级目录的CMakeLists.txt,生成Makefile和其他文件
cmake ..
# 4. 执行make命令,生成target
make

6.5 【实战】CMake代码实践

6.5.1 最小CMake工程

# Set the minimum version of CMake that can be used
cmake_minimum_required(VERSION 3.0)

# Set the project name
project (HELLO)

# Add an executable
add_executable(hello_cmake main.cpp)

6.5.2 多目录工程 - 直接编译

# Set the minimum version of CMake that can be used
cmake_minimum_required(VERSION 3.0)

#project name
project(SWAP)

#head file pat
include_directories( include )

#source directory files to var
add_subdirectory( src DIR_SRCS )

#add executable file  
add_executable(swap_02 ${TEST_MATH})

#add link library  
target_link_libraries(${FS_BUILD_BINARY_PREFIX}sqrt ${LIBRARIES}) 

6.5.3 多目录工程 - 生成库编译

# Set the minimum version of CMake that can be used
cmake_minimum_required(VERSION 3.0)

#project name  
project(SWAP_LIBRARY)

#add compile options
add_compile_options("-Wall -std=c++11")

#set CMAKE_BUILD_TYPE
set( CMAKE_BUILD_TYPE Debug ) 

# set output binary path  
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

############################################################
# Create a library
############################################################

#Generate the static library from the library sources
add_library( swap_library STATIC src/Swap.cpp )

target_include_directories( swap_lib PUBLIC ${PROJECT_SOURCE_DIR}/include )

############################################################
# Create an executable
############################################################

# Add an executable with the above sources
add_executable( swap_01 main.cpp )

# link the new swap_01 target with the swap_lib target
target_link_libraries( swap_01 swap_liby )
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CMake是一个跨平台的开源构建工具,它能够自动生成各种不同平台的构建脚本,简化了项目的构建过程。下面是一个300字快速入门CMake的实战教程。 首先,安装CMake并确保它被正确添加到系统的环境变量中。 接下来,在你的项目根目录下创建一个CMakeLists.txt文件,这个文件是CMake的配置文件,用来指导CMake生成项目的构建脚本。在CMakeLists.txt文件中,首先指定项目的名称和最低版本要求,例如: ``` cmake_minimum_required(VERSION 3.10) project(MyProject) ``` 然后,添加你的项目的源文件和头文件,使用add_executable或add_library命令指定它们的路径,例如: ``` add_executable(MyApp main.cpp foo.cpp bar.cpp) ``` 接下来,你可以添加依赖库,使用target_link_libraries命令指定它们的路径,例如: ``` target_link_libraries(MyApp ${CMAKE_DL_LIBS}) ``` 此外,你还可以指定编译选项,例如: ``` set(CMAKE_CXX_FLAGS "-std=c++11 -Wall") ``` 最后,你可以通过命令行执行cmake命令来生成构建脚本,并执行构建过程,例如: ``` mkdir build cd build cmake .. make ``` 在build目录中,你会找到生成的构建脚本及其生成的可执行文件(或库文件)。 通过这个简单的实战教程,你可以快速入门CMake,并且开始使用它来管理你的项目的构建过程。当然,在实际应用中,你还可以进行更多高级配置,例如添加条件编译、安装目标等。希望这个简短的回答能够给你一个基本的CMake入门指导。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值