|
|
hai 1 ano | |
|---|---|---|
| .. | ||
| Image | hai 1 ano | |
| src | hai 1 ano | |
| .gitignore | hai 1 ano | |
| README.md | hai 1 ano | |
以 src/demo1 为例
$ tree
.
├── add.c
├── div.c
├── head.h
├── main.c
├── mult.c
└── sub.c
在 build 文件夹中使用 cmake .. 生成项目
# CMakeList.txt
cmake_minimum_required(VERSION 3.0)
project(CALC)
add_executable(app add.c div.c main.c mult.c sub.c)
# 等价于 add_executable(app add.c;div.c;main.c;mult.c;sub.c)
因为
cmake生成的临时文件可能很多,所以在 build 文件夹中生成,这样不会污染根目录
使用 cmake 之后,会生成中间文件和 Makefile,再使用 make 来执行,最后生成 app.exe (Windows 平台)
| 命令 | 作用 |
|---|---|
| cmake_minimum_required | 指定使用的 cmake 的最低版本 |
| project | 定义工程名称,并可指定工程的版本、工程描述、web主页地址、支持的语言(默认情况支持所有语言),如果不需要这些都是可以忽略的,只需要指定出工程名字即可 |
| add_executable(可执行程序名 源文件名称) | 定义工程会生成一个可执行程序 |
如果想要使用 cmake 创建指定类型的项目,可以在命令中指定
使用 cmake -G 可以查看可以生成的项目
*标记的是默认生成项目类型
如果想要生成 Unix Makefiles 或者其他版本的 Visual Studio 项目 的话,可以使用
cmake .. -G "Unix Makefiles"
cmake .. -G "Visual Studio 16 2019"
为了方便使用
make命令,所以后面一些测试使用Unix Makefiles
这个
visual studio项目的名称就是project中设置的CALC
对应的命令就是 add_executable(app add.c div.c main.c mult.c sub.c)
app 就是最后生成可执行程序的名称如果一直使用 add.c div.c main.c mult.c sub.c 来表示所添加的问题,也是挺麻烦的
可以定义变量来表示整个 add.c div.c main.c mult.c sub.c 文件
# SET 指令的语法是:
# [] 中的参数为可选项, 如不需要可以不写
# SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
set(SRC_LIST add.c;div.c;main.c;mult.c;sub.c)
add_executable(app ${SRC_LIST})
SRC_LIST: 变量名${SRC_LIST}: 获取值编译 C++ 项目的时候需要指定 C++ 版本:C++11、C++14、C++17、C++20 等,有些项目会用到对应版本的特性
以 g++ 编译的命令为例
g++ *.cpp -std=c++11 -o app
-std=c++11对应 C++ 标准有一个宏叫做DCMAKE_CXX_STANDARD
在 cmake 可以通过 SET 设置 DCMAKE_CXX_STANDARD 的值
# -std=c++11
set(CMAKE_CXX_STANDARD 11)
# -std=c++14
set(CMAKE_CXX_STANDARD 14)
# -std=c++17
set(CMAKE_CXX_STANDARD 17)
也可以使用在 cmake 命令中控制
cmake CMakeLists.txt文件路径 -DCMAKE_CXX_STANDARD=11
cmake CMakeLists.txt文件路径 -DCMAKE_CXX_STANDARD=14
cmake CMakeLists.txt文件路径 -DCMAKE_CXX_STANDARD=17
在CMake中指定可执行程序输出的路径,也对应一个宏,叫做EXECUTABLE_OUTPUT_PATH,它的值还是通过 set 命令进行设置
set(HOME ./build)
set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin)
生成 Unix Makefiles 项目,然后使用 make 执行
最后 app.exe 就生成在 build/bin 目录中
如果路径不存在,会自动创建,无需手动生成
如果项目中的源文件非常多,在编写 CMakeLists.txt 文件的时候不可能将项目目录的各个文件一一罗列出来,所以 CMake 提供了搜索文件的命令
可以使用 aux_source_directory 命令或者 file 命令
aux_source_directory(<dir> <variable>)
dir: 要搜索的目录variable: 将从 dir 目录下搜索的源文件列表存储到该变量中file(GLOB/GLOB_RECURSE 变量名 要搜索的文件路径和文件类型)
GLOB: 将指定目录下搜索到的满足条件的所有文件名生成一个列表,并将其存储到变量中GLOB_RECURSE: 递归搜索指定目录,将搜索到的满足条件的文件名生成一个列表,并将其存储到变量中file(GLOB MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.c)
file(GLOB MAIN_HEAD ${CMAKE_CURRENT_SOURCE_DIR}/*.h)
# message(${MAIN_SRC})
# message(${MAIN_HEAD})
message(${PROJECT_SOURCE_DIR})
message(${CMAKE_CURRENT_SOURCE_DIR})
FOREACH(item ${MAIN_SRC})
message(${item})
ENDFOREACH()
| 函数的变量 | 作用 |
|---|---|
| CMAKE_CURRENT_SOURCE_DIR | 当前访问的 CMakeLists.txt 文件所在的路径 |
| FOREACH | CMake 中遍历的写法,这里是遍历的头 |
| ENDFOREACH | CMake 中遍历的写法,这里是遍历的尾 |
| message | 输出指定内容 |
编译项目源文件的时候,很多时候需要将源文件的头文件路径指定出来,这样才能保证在编译过程中编译器能找到这些文件,可以使用 include_directories 来包含这些头文件
include_directories(headpath)
以
demo2为例
cmake_minimum_required(VERSION 3.0)
project(CALC)
set(CMAKE_CXX_STANDARD 11)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/build/bin/)
include_directories(${PROJECT_SOURCE_DIR}/include)
file(GLOB SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/src/*.c)
add_executable(app ${SRC_LIST})
有些时候我们编写的源代码并不需要将他们编译生成可执行程序,而是生成一些静态库或动态库提供给第三方使用
以 demo3 为例
直接使用 add_library 制作静态库
add_library(库名称 STATIC 源文件1 [源文件2] ...)
STATIC
在 linux 中静态库名字分为三个部分:lib + 库名称 + .a ,但是这里只用指定出库的名字就可以了,另外两部分在生成该文件的时候会自动填充
Windows 与 Linux 的库名虽然不同,但是也只用指定名字即可
Linux 平台下,可以直接通过 make 编译链接项目生成静态库Windows 平台下,通过 CMake 生成 Visual Studio 项目,通过 Ctrl + B 生成静态库
Windows平台就不要生成之前的说的Unix Makefiles的项目了
以 demo4 为例
制作动态库也是 add_library
add_library(库名称 SHARED 源文件1 [源文件2] ...)
SHARED
Linux 平台下动态库的名字也是三部分:lib + 库名字 + .soWindows 平台下动态库的名字以 dll 结尾前面使用 EXECUTABLE_OUTPUT_PATH 指定了可执行程序的输出路径
由于在 Linux 下生成的动态库默认是有执行权限的,所以可以按照生成可执行程序的方式 EXECUTABLE_OUTPUT_PATH 去指定它生成的目录
但是 Linux 下静态库默认不具备可执行权限,所以 EXECUTABLE_OUTPUT_PATH 并不通用
基于上面的原因,建议统一使用 LIBRARY_OUTPUT_PATH 来设置输出路径,该宏动态库和静态库都可以使用
set(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib)
Demo5 为例
message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR] "message to display" ...)
| category | 作用 |
|---|---|
| (无) | 重要消息 |
| STATUS | 非重要消息 |
| WARNING | CMake 警告, 会继续执行 |
| AUTHOR_WARNING | CMake 警告 (dev), 会继续执行 |
| SEND_ERROR | CMake 错误, 继续执行,但是会跳过生成的步骤 |
| FATAL_ERROR | CMake 错误, 终止所有处理过程 |
Demo5 为例
使用 set 进行字符串拼接
set(变量名1 ${变量名1}${变量名2}...)