cMake官方文档学习

cmake 3.23.1官方文档学习

Step1: A Basic Starting Point

我们在CMake01的文件下建立一个hello.cpp用于输出hello world

1
2
3
4
5
#include <iostream>

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

并建立CMakeLists.txt

写入

1
2
3
4
5
6
7
cmake_minimum_required(VERSION 3.10)

# set the project name
project(Hello)

# add the executeable
add_executable(hello hello.cpp)

CMake支持大写和小写

cmake_minimum_required(VERSION 3.10):指明我们的最低cmake版本号

project(Hello):指定了工程的名字,并且支持所有语言

也可以写成project(Hello cpp),这指定了工程名字和支持的语言c++

add_executable(hello hello.cpp)

生成可执行文件的名称为hello,读取的源文件为hello.cpp

编译和运行

现在我们可以开始进行编译运行,不过编译可能会产生需要我们不需要的文件,这让我们的项目不好管理,我们建立一个文件夹Step1_build用来存放编译信息。

1
2
mkdir Step1_build
cd Step1_build

执行

1
cmake ..

当然..表示上一级目录,你也可以写CMakeLists.txt所在的绝对路径,这里我用的是相对路径,生产的文件都在Step1_build目录下了

现在我们开始链接

1
cmake --build .

可以看到以下信息,代表我们链接成功

[ 50%] Building CXX object CMakeFiles/hello.dir/hello.cpp.o

[100%] Linking CXX executable hello

[100%] Built target hello

输入

1
ll

看到我们的可执行文件hello已经生成

-rw-r--r-- 1 SJCHEN staff 14K 5 17 01:51 CMakeCache.txt

drwxr-xr-x 13 SJCHEN staff 416B 5 17 01:54 CMakeFiles

-rw-r--r-- 1 SJCHEN staff 5.2K 5 17 01:51 Makefile

-rw-r--r-- 1 SJCHEN staff 1.5K 5 17 01:51 cmake_install.cmake

-rwxr-xr-x 1 SJCHEN staff 55K 5 17 01:54 hello

执行

1
./hello

输出

hello world

至此我们已经编译运行成功。

CMake 编译工程

我们新建CMake02,并根据目录树结构创建对应的文件

1
2
3
4
5
6
7
8
.
├── CMakeLists.txt
├── build
├── main.cpp
├── include
│   └── hello.h
└── src
└── hello.cpp

hello.h

1
2
3
4
5
6
7
8
// hello.h
#ifndef HELLO_H
#define HELLO_H

#include <iostream>
void SayHello();

#endif

hello.cpp

1
2
3
4
5
#include "hello.h"

void SayHello(){
std::cout << "hello world" << std::endl;
}

main.cpp

1
2
3
4
5
6
#include "hello.h"

int main(){
SayHello();
return 0;
}

CMakeLists.txt

1
2
3
4
5
6
7
cmake_minimum_required(VERSION 3.0)

project(HELLO)

include_directories(include)

add_executable(hello main.cpp src/hello.cpp)

include_directories(include)向工程添加多个特定的库文件搜索路径,相当于指定g++编译器的-L参数

add_executable:生成可执行文件

  • 语法:add_executable(exe文件名 source1 source2 .. sourceN)

外部构建编译执行

1
2
3
cd build
cmake ..
cmake --build .

重要指令&常用变量

1. 重要指令

  • cmake_minimum_required

    :指定CMake的最小版本要求

    • 语法:cmake_minimum_required(VERSION 版本号 [FATAL_ERROR])
1
2
// CMake最小版本要求为2.8.3
cmake_minimum_required(VERSION 2.8.3)
  • project

    :定义工程名称,并可指定工程支持的语言

    • 语法:project(工程名称 [CXX] [C] [java])
1
2
// 指定工程名为HELLOWORLD
project(HELLOWORLD)
  • set

    :显式的定义变量

    • 语法:set(变量名 [变量值] [CACHE TYPE DOCSTRING [FORCE]])
1
2
// 定义SRC变量,其值为main.cpp hello.cpp
set(SRC sayhello.cpp hello.cpp)
  • include_directories

    :向工程添加多个特定的头文件搜索路径,相当于指定g++编译器的

    -I

    参数

    • 语法:include_directories([AFTER|BEFORE][SYSTEM] dir1 dir2 ...)
1
2
// 将/usr/include/myincludefolder 和 ./include 添加到头文件搜索路径
include_directories(/usr/include/myincludefolder ./include)
  • link_directories

    :向工程添加多个特定的库文件搜索路径,相当于指定g++编译器的

    -L

    参数

    • 语法:link_directories(dir1 dir2 ...)
1
2
// 将/usr/lib/mylibfolder 和 ./lib 添加到库文件搜索路径
link_directories(/usr/lib/mylibfolder ./lib)
  • add_library

    :生成库文件

    • 语法:add_library(库名 [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 .. sourceN)
1
2
3
// 通过变量 SRC 生成 libhello.so 共享库
// SHARED代表动态库,STATIC代表静态库
add_library(hello SHARED ${SRC})
  • add_compile_options

    :添加编译参数

    • 语法:add_compile_options(编译参数)
1
2
// 添加编译参数 -wall -std=c++11
add_compile_options(-wall -std=c++11 -o2)
  • add_executable

    :生成可执行文件

    • 语法:add_executable(exe文件名 source1 source2 .. sourceN)
1
2
// 编译main.cpp生成可执行文件main
add_executable(main main.cpp)
  • target_link_libraries

    :为target添加需要链接的共享库,相当于指定g++编译器-l参数

    • 语法:target_link_libraries(target library1<debug|optimized> library2...)
1
2
// 将hello动态库文件链接到可执行文件main
target_link_libraries(main hello)
  • add_subdirectory

    :向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置

    • 语法:add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
1
2
// 添加src子目录,src中需要有一个CMakeLists.txt
add_subdirectory(src)
  • aux_source_directory

    :发现一个目录下所有的源代码文件并将列表存储在一个变量中,这个指令临时被用来自动构建源文件列表

    • 语法:aux_source_directory(文件夹路径 变量名)
1
2
3
4
// 定义SRC变量,其值为当前目录下所有的源代码文件
aux_source_directory(. SRC)
// 编译SRC变量所代表的源代码文件,生成main可执行文件
add_executable(main ${SRC})

2. 常用变量

  • CMAKE_C_FLAGS:gcc编译选项
  • CMAKE_CXX_FLAGS:g++编译选项
1
2
// 在CMAKE_CXX_FLAGS编译选项后追加-std=c++11
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
  • CMAKE_BUILD_TYPE:编译类型(Debug, Release)

    1
    2
    3
    4
    // 设定编译类型为debug,因为在调试时需要选择debug
    set(CMAKE_BUILD_TYPE Debug)
    // 设定编译类型为release,因为在发布时需要选择release
    set(CMAKE_BUILD_TYPE release)
  • EXECUTABLE_OUTPUT_PATH:可执行文件输出的存放路径

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