CMake学习使用(基于vscode)

参考:
基于VSCode和CMake实现C/C++开发 | Linux篇

语法

基本语法格式:指令(arg1 arg2 …)

  • 参数使用括弧括起来
  • 参数之间使用空格或者分号分开
    指令是大小写无关的,参数和变量是大小写相关的
set(HELLO hello.cpp) # 将hello.cpp 作为一个名为 HELLO 的变量
add_executable(hello main.cpp hello.cpp)
ADD_EXECUTABLE(hello main.cpp ${HELLO})

变量使用 方 式 取 值 , 但 是 在 I F 控 制 语 句 里 面 直 接 使 用 变 量 名 , 例 如 : ‘ I F ( H E L L O ) ‘ 而 不 是 ‘ I F ( {}方式取值,但是在IF控制语句里面直接使用变量名,例如:`IF(HELLO)`而不是`IF( IF使IF(HELLO)IF({HELLO})`

一些重要指令

  • cmake_minimum_required : 用来指定CMake的最小版本要求
# CMake最小版本要求为2.8.3
cmake_minimum_required(VERSION 2.8.3)
  • project :用来定义工程名称,并可指定工程支持的语言
project(HELLOWORLD C)
  • set :显示的定义变量
# 定义SRC变量,其值为sayhello.cpp hello.cpp
set(SRC sayhello.cpp hello.cpp)
  • include_directories :向工程添加多个特定的头文件搜索路径->相当于指定g++编译器的-I参数
# 将usr/include/myincludefolder 和 ./include 添加到头文件搜索路径
include_directories(usr/include/myincludefolder ./include)
  • link_directories:向工程添加多个特定的库文件搜索路径->相当于指定g++编译器的-L参数
# 将usr/lib/mylibfolder 和 ./lib 添加到库文件搜索路径
link_directories(usr/lib/mylibfolder ./lib)
  • add_library :生成库文件
# 通过变量 SRC 生成 libhello.so 共享库
add_library(hello SHARED ${SRC})
  • add_compile_options :添加编译参数
# 添加编译参数 -Wall -std=c++11 -O2
add_compile_options(-Wall -std=c++11 -O2)
  • add_executable:生成可执行文件
# 编译main.cpp生成可执行文件main
add_executable(main main.cpp)
  • target_link_libraries:为target添加需要链接的共享库->相当于指定g++编译器的-l 参数
# 将hello动态库链接到可执行文件main上
target_link_libraries(main hello)
  • add_subdirectory:向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置
# 添加src子目录,src中需要有一个CMakeLists.txt
add_subdirectory(src)
  • aux_source_directory :发现一个目录下所有的源代码文件并将列表存储在一个变量中,这个指令被用来临时自动构建源文件列表
# 定义SRC变量,其值为当前目录下所有的源代码文件
aux_source_directory(. SRC)
# 编译SRC变量所代表的源代码文件,生成main可执行文件
add_executable(main ${SRC})

CMake常用变量

  • CMAKE_C_FLAGS :gcc编译选项
  • CMAKE_CXX_FLAGS:g++编译选项
# 在编译选项后追加-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_DIRPROJECT_BINARY_DIR_BINARY_DIR

这三个变量指代的内容是一致的
如果是 in source build,指的是工程顶层目录
如果是out-of-source编译,指的是工程编译发生的目录

  • CMAKE_SOURCE_DIRPROJECT_SOURCE_DIR_SOURCE_DIR

这三个变量指代内容一致,不管采用何种编译方式,都是工程顶层目录
in source build时,与CMAKE_BINARY_DIR等变量一致

  • CMAKE_C_COMPILER:指定C编译器
  • CMAKE_CXX_COMPILER:指定C++编译器
  • EXECUTABLE_OUTPUT_PATH:可执行文件输出的存放路径
  • LIBRARY_OUTPUT_PATH:库文件输出的存放路径

CMake编译工程

CMake目录结构:项目主目录存在一个CMakeLists.txt文件
一般有两种方式设置编译规则
1、包含源文件的子文件夹包含CMakeLists.txt文件,主目录的CMakeList.txt通过add_subdirectory添加子目录即可
2、包含源文件的子文件夹未包含CMakeLists.txt文件,子目录编译规则体现在主目录的CMakeLists.txt中

编译流程

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

  • 手写CMakeLists.txt文件
  • 执行命令cmake PATH生成Makefile(PATH是顶层CMakeLists.txt所在的目录)
  • 执行命令make进行编译

两种构建方式

1、内部构建(in-source build):这种方式不推荐使用
内部构建会在同级目录下产生一大堆中间文件,和工程源文件放在一起会显得杂乱无章

# 内部构建
# 在当前目录下,编译本目录的CMakeLists.txt,生成Makefile文件和其他文件
cmake .
# 执行make命令,生成target
make

2、外部构建(out-of-source build) :这种方式推荐使用
该方式将编译输出文件和源文件放在不同目录中

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

实例展示

实例一

dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/hello$   tree
.
├── hello
└── hello.cpp

hello.cpp内容为:

#include<iostream>
using namespace std;
int main()
{
    
    
        cout << "hello world!" << endl;
        return 0;
}      

我们进入目录,然后输入:
code . 这样就能打开vscode了
我们要给这个最简单的cpp程序写一个CMakeLists.txt
CMakeLists.txt一般处于项目的顶层目录,此处就在文件夹下了
一般来说,在vscode中写cmakelists的话会有只能提示的,如果你装了插件的话

# 指定最低版本要求
cmake_minimum_required(VERSION 3.0)
# 指定项目名称
project(HELLO)
# 指定生成的可执行文件的名字 源文件
add_executable(hello_cmake hello.cpp)
## 此时等价于 g++ hello.cpp -o hello_cmake

接下来我们在vscode的终端里面进行外部构建并编译
在这里插入图片描述我们在终端下使用tree命令看看文件结构:

dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/hello$ tree
.
├── build
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   │   ├── 3.16.3
│   │   │   ├── CMakeCCompiler.cmake
│   │   │   ├── CMakeCXXCompiler.cmake
│   │   │   ├── CMakeDetermineCompilerABI_C.bin
│   │   │   ├── CMakeDetermineCompilerABI_CXX.bin
│   │   │   ├── CMakeSystem.cmake
│   │   │   ├── CompilerIdC
│   │   │   │   ├── a.out
│   │   │   │   ├── CMakeCCompilerId.c
│   │   │   │   └── tmp
│   │   │   └── CompilerIdCXX
│   │   │       ├── a.out
│   │   │       ├── CMakeCXXCompilerId.cpp
│   │   │       └── tmp
│   │   ├── cmake.check_cache
│   │   ├── CMakeDirectoryInformation.cmake
│   │   ├── CMakeOutput.log
│   │   ├── CMakeTmp
│   │   ├── hello_cmake.dir
│   │   │   ├── build.make
│   │   │   ├── cmake_clean.cmake
│   │   │   ├── CXX.includecache
│   │   │   ├── DependInfo.cmake
│   │   │   ├── depend.internal
│   │   │   ├── depend.make
│   │   │   ├── flags.make
│   │   │   ├── hello.cpp.o
│   │   │   ├── link.txt
│   │   │   └── progress.make
│   │   ├── Makefile2
│   │   ├── Makefile.cmake
│   │   ├── progress.marks
│   │   └── TargetDirectories.txt
│   ├── cmake_install.cmake
│   ├── hello_cmake
│   └── Makefile
├── CMakeLists.txt
├── hello
└── hello.cpp

此时发现可执行文件是在build文件夹下的
实例二
此处用到的实例请参考:
gcc 编译器使用指南
此时工程结构如下:

.
├── include
│   └── swap.h
├── main.cpp
├── sharemain
├── src
│   ├── libswap.a
│   ├── libswap.so
│   ├── swap.cpp
│   └── swap.o
└── staticmain

然后写cmakelists.txt

cmake_minimum_required(VERSION 3.0)

project(SWAP)
# 与 -Iinclude 命令对应
include_directories(include)

# 此命令相当于 g++ main.cpp src/swap.cpp -Iinclude -o main_cmake
add_executable(main_cmake main.cpp src/swap.cpp)

然后执行cmake、make:

dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ mkdir build
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ cd build/
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST/build$ cmake ..
-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/dyy/Desktop/GCCTEST/build
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST/build$ make
Scanning dependencies of target main_cmake
[ 33%] Building CXX object CMakeFiles/main_cmake.dir/main.cpp.o
[ 66%] Building CXX object CMakeFiles/main_cmake.dir/src/swap.cpp.o
[100%] Linking CXX executable main_cmake
[100%] Built target main_cmake
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST/build$ ./main_cmake 
before
10 20
after
20 10

猜你喜欢

转载自blog.csdn.net/qq_42604176/article/details/120852602