石景山做网站的公司,wordpress源码教程,网络宣传平台,wordpress grace8下载目录
1. 注释
1.1 注释行
1.2 注释块
2. CMakeLists.txt的编写
2.1 同意目录下的源文件
2.2 SET指令
2.3 file和aux_source_directory
2.4 包含头文件
2.5 生成动态库和静态库
2.6 链接库文件
2.7 message指令
2.8 移除操作
2.9 find_library和find_package
3. 常…目录
1. 注释
1.1 注释行
1.2 注释块
2. CMakeLists.txt的编写
2.1 同意目录下的源文件
2.2 SET指令
2.3 file和aux_source_directory
2.4 包含头文件
2.5 生成动态库和静态库
2.6 链接库文件
2.7 message指令
2.8 移除操作
2.9 find_library和find_package
3. 常用的宏
4. 示例 参考
CMake 保姆级教程上subingwen.cn/cmake/CMake-primer/#2-6-3-%E6%80%BB%E7%BB%93编辑https://link.zhihu.com/?targethttps%3A//subingwen.cn/cmake/CMake-primer/%232-6-3-%25E6%2580%25BB%25E7%25BB%2593
cmake使用详细教程日常使用这一篇就足够了_cmake教程-CSDN博客blog.csdn.net/iuu77/article/details/129229361?ops_request_misc%257B%2522request%255Fid%2522%253A%25223BDC4C1F-AC50-4EB2-99A3-1FD7204C3A17%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257Drequest_id3BDC4C1F-AC50-4EB2-99A3-1FD7204C3A17biz_id0utm_mediumdistribute.pc_search_result.none-task-blog-2~all~top_positive~default-2-129229361-null-null.142%5Ev100%5Epc_search_result_base8utm_termcmakespm1018.2226.3001.4187编辑https://link.zhihu.com/?targethttps%3A//blog.csdn.net/iuu77/article/details/129229361%3Fops_request_misc%3D%25257B%252522request%25255Fid%252522%25253A%2525223BDC4C1F-AC50-4EB2-99A3-1FD7204C3A17%252522%25252C%252522scm%252522%25253A%25252220140713.130102334..%252522%25257D%26request_id%3D3BDC4C1F-AC50-4EB2-99A3-1FD7204C3A17%26biz_id%3D0%26utm_medium%3Ddistribute.pc_search_result.none-task-blog-2~all~top_positive~default-2-129229361-null-null.142%255Ev100%255Epc_search_result_base8%26utm_term%3Dcmake%26spm%3D1018.2226.3001.4187 需要注意的是CMakeLists.txt文件中的指令不区分大小写 1. 注释
1.1 注释行
CMake通过‘#’进行单行注释比如
# Cmake版本至少为3.1
cmake_minimum_required(VERSION 3.1)
1.2 注释块
CMake通过‘if(FALSE)’进行块注释比如
if(FALSE)# CMake版本至少为3.1# CMake版本至少为3.1# CMake版本至少为3.1
endif()
cmake_minimum_required(VERSION 3.1)
2. CMakeLists.txt的编写
2.1 同意目录下的源文件
如果只有一个源文件hello.cpp内容如下
#include iostream
using namespace std;int main()
{cout Hello World! endl;return 0;
}那么CMakeLists.txt可以这样写
cmake_minimum_required(VERSION 3.1)
project (LearnCMake LANGUAGES CXX)
add_executable(hello hello.cpp)
cmake_minimum_required指定使用的 cmake 的最低版本project定义工程名称并可指定工程的版本、工程描述、web主页地址、支持的语言默认情况支持所有语言如果不需要这些都是可以忽略的只需要指定出工程名字即可 这里项目名称为 LearnCMake 项目使用的语言是 CCXX表示C
# PROJECT 指令的语法是
project(PROJECT-NAME [language-name...])
project(PROJECT-NAME[VERSION major[.minor[.patch[.tweak]]]][DESCRIPTION project-description-string][HOMEPAGE_URL url-string][LANGUAGES language-name...])# 示例
project(GrpcServer VERSION 1.0.0 DESCRIPTION A gRPC server implementation in C HOMEPAGE_URL https://example.com/grpcserver LANGUAGES CXX)
add_executable定义工程会生成一个可执行程序可执行程序名为hello源文件名称为hello.cpp
# 单个源文件
add_executable(可执行程序名 源文件名称)
# 多个源文件名空格隔开
add_executable(hello add.c div.c main.c mult.c sub.c)
# 多个源文件名封号隔开
add_executable(hello add.c;div.c;main.c;mult.c;sub.c)
我们一般需要单独创建一个build文件夹用于存放
可执行文件已经编译过的可执行文件如Windows上的.exe文件Linux和Mac上的二进制文件。中间文件编译过程中生成的中间文件如目标文件.o或.obj、汇编文件.s等。构建脚本用于帮助构建项目的脚本文件如Makefile、CMakeLists.txt的生成版本或Ninja文件等。库文件如果项目包含库代码的编译那么还会生成静态库.a或动态库.so、.dll。
我们这里创建一个build文件夹进入之后执行cmake并编译
mkdir build
cd ./build/
cmake ..
build文件夹内会生成以下文件 执行make命令使用makefile进行编译
make 生成可执行程序hello并运行
./hello 2.2 SET指令
SET指令是 CMake 中用于定义和设置变量的命令它允许你创建一个新的变量或者修改一个已存在的变量的值。
2.2.1 使用SET将多个源文件存储至指定变量
如果我们有五个源文件需要添加
add_executable(hello add.c;div.c;main.c;mult.c;sub.c)
如果有多个源文件我们可以定义一个变量将文件名对应的字符串存储起来在cmake里定义变量需要使用set
# SET 指令的语法是
# [] 中的参数为可选项, 如不需要可以不写
SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
我们使用SET指令将这五个文件名和自定义的变量联系起来通过添加这个变量名即可同时调用这五个文件
set(SRC_LIST add.c;div.c;main.c;mult.c;sub.c)
add_executable(hello ${SRC_LIST})
如果源文件特别多一个个添加会特别慢此时可以使用cmake中的函数存储这些源文件。
aux_source_directory(dir var)
他的作用是把dir目录中的所有源文件都储存在var变量中然后需要用到源文件的地方用变量var来取代。
上述代码可以使用该函数改写为(我们一般把.cpp文件放在src文件夹下.h放在include文件夹下)
aux_source_directory(. SRC_LIST)
add_executable(hello ${SRC_LIST})
2.2.2 指定C标准
C标准对应有一宏叫做DCMAKE_CXX_STANDAR我们可以通过SET指令指定我们使用的C标准
#增加-stdc11
set(CMAKE_CXX_STANDARD 11)
#增加-stdc14
set(CMAKE_CXX_STANDARD 14)
#增加-stdc17
set(CMAKE_CXX_STANDARD 17)
该宏一般与宏CMAKE_CXX_STANDARD_REQUIRED进行配合使用该宏为ON时 如果编译器不支持你指定的 C 标准比如C17CMake 配置过程将会失败
set(CMAKE_CXX_STANDARD_REQUIRED ON)
2.2.3 指定输出的路径
在CMake中指定可执行程序输出的路径也对应一个宏叫做EXECUTABLE_OUTPUT_PATH可通过SET指令进行设置
set(HOME /home/robin/Linux/Sort)
set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin)
如果子目录bin不存在会自动生成
2.3 file和aux_source_directory
这两个指令都可以用于搜索指定目录下的文件后者用于查找指定目录下的所有源文件我们在2.1中使用过这里不再做介绍。
2.3.1 file
file(GLOB/GLOB_RECURSE 变量名 要搜索的文件路径和文件类型)
在 CMake 中file(GLOB ...) 和 file(GLOB_RECURSE ...) 命令用于从指定的目录中搜索匹配特定模式的文件并将这些文件的列表存储在一个变量中。
GLOB: 将指定目录下搜索到的满足条件的所有文件名生成一个列表并将其存储到变量中。GLOB_RECURSE递归搜索指定目录将搜索到的满足条件的文件名生成一个列表并将其存储到变量中。
如果我们有一个目录如下
project/
├── CMakeLists.txt
├── src/
│ ├── main.cpp
│ └── utils/
│ └── helper.cpp
如果我们像包含src/目录下的所有.cpp文件只需
# 使用 GLOB 只搜索 src 目录下的文件不递归并存储至变量SRC_FILES
file(GLOB SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) # 或者使用 GLOB_RECURSE 递归搜索 src 目录及其子目录中的文件
file(GLOB_RECURSE SRC_FILES_RECURSIVE ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) # 然后你可以使用这些变量来添加可执行文件或库
add_executable(MyExecutable ${SRC_FILES_RECURSIVE})
宏 CMAKE_CURRENT_SOURCE_DIR 是 CMake 提供的一个内置变量用于表示当前正在处理的CMakeLists.txt文件所在的源代码目录的路径 如果不同文件夹下有不同的CMakeLists.txt文件那么CMAKE_CURRENT_SOURCE_DIR 随着CMakeLists.txt文件所处的路径变化而变化。
2.4 包含头文件
2.4.1 头文件均在一个目录下
在CMake中通过命令 include_directories 设置要包含的目录。
# 在指定 dir目录下寻找头文件
include_directories ( dir )
如果我们有一个目录如下
$ tree
.
├── build
├── CMakeLists.txt
├── include
│ └── head.h
└── src├── add.cpp├── div.cpp├── main.cpp├── mult.cpp└── sub.cpp
我们可以使用如下指令包含头文件head.h
include_directories(${PROJECT_SOURCE_DIR}/include)
宏 PROJECT_SOURCE_DIR 是 CMake 在处理project()命令时自动设置的变量它指向包含最近一次调用project()命令定义的项目的源目录
该目录下的CMakeLists.txt文件这样写
cmake_minimum_required(VERSION 3.1)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project (LearnCMake LANGUAGES CXX)include_directories(${PROJECT_SOURCE_DIR}/include)
file(GLOB SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
add_executable(hello ${SRC_LIST})
2.4.2 头文件源文件分离并包含多个文件夹
假设我们有如下目录结构
LEARN_CMAKE
├── CMakeLists.txt
│ ├── inc_dir1
│ │ └── myfunc1.h
│ ├── inc_dir2
│ │ └── myfunc2.h
│ ├── main_dir
│ │ └── hello.cpp
│ ├── src_dir1
│ │ └── myfunc1.cpp
│ └── src_dir2
│ └── myfunc2.cpp
该目录下的CMakeLists.txt文件这样写
cmake_minimum_required(VERSION 3.1)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)# 项目名称
project (LearnCMake LANGUAGES CXX)# 头文件
include_directories(${PROJECT_SOURCE_DIR}/inc_dir1 ${PROJECT_SOURCE_DIR}/inc_dir2)# 获取源文件
file(GLOB SRC_LIST1 ${CMAKE_CURRENT_SOURCE_DIR}/src_dir1/*.cpp)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src_dir2 SRC_LIST2)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/main_dir MAIN_DIR)# 生成可执行文件
add_executable(hello ${SRC_LIST1} ${SRC_LIST2} ${MAIN_DIR})
2.5 生成动态库和静态库
动态库在编译时并不会将库的代码直接复制到最终的可执行文件中而是在程序运行时动态地加载库。这种机制有助于节省磁盘空间和内存因为多个程序可以共享同一个动态库的副本。当我们提到动态库的“后者”时如果是指与动态库相对的概念那么通常指的是静态库。静态库在编译时会被完整地复制到最终的可执行文件中因此每个使用静态库的程序都会有一个库的副本。
有些时候我们编写的源代码并不需要将他们编译生成可执行程序而是生成一些静态库或动态库提供给第三方使用下面来讲解在cmake中生成这两类库文件的方法。
2.5.1 静态库
静态库的生成需使用如下指令
add_library(库名称 STATIC 源文件1 [源文件2] ...)
库名称创建的静态库的名字。在构建成功后这个名字会出现在输出目录中。STATIC这个关键字指示你想要创建一个静态库。源文件1 [源文件2] ...这些是构成静态库的源文件列表。你可以列出多个源文件CMake 会将它们编译并打包进静态库中。
我们一般只需要指定出库的名字和STATIC关键字就可以另外两部分在生成该文件的时候会自动填充。
假设我们有如下目录结构
$ tree
.
├── build
├── CMakeLists.txt
├── include # include目录下存放头文件
│ └── head.h
├── lib # lib目录下存放生成的库
└── src # src目录下存放源文件├── add.cpp├── div.cpp├── main.cpp├── mult.cpp└── sub.cpp
如果我们要将其生成为静态库该目录下的CMakeLists.txt文件这样写
cmake_minimum_required(VERSION 3.1)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project (LearnCMake LANGUAGES CXX)include_directories(${PROJECT_SOURCE_DIR}/include)file(GLOB SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
add_library(hello STATIC ${SRC_LIST})
这样最终就会生成对应的静态库文件 hello.a或者hello.lib
2.5.2 动态库
动态库的指令和静态库类似只不过关键字STATIC需改为SHARED
add_library(库名称 SHARED 源文件1 [源文件2] ...)
编写对应的CMakeLists.txt文件最后生成对应的动态库文件hello.so或者hello.dll
2.5.3 指定库输出路径
我们使用宏 LIBRARY_OUTPUT_PATH 来指定静态/动态库的输出路径。而对于动态库因为动态库有可执行权限所以不仅可以像可执行程序一样使用宏 EXECUTABLE_OUTPUT_PATH 指定输出路径而且可以使用宏 LIBRARY_OUTPUT_PATH但静态库默认不具有可执行权限所以静态库只可以用宏 LIBRARY_OUTPUT_PATH 来指定输出路径。
假设我们有如下目录结构
$ tree
.
├── build
├── CMakeLists.txt
├── include # include目录下存放头文件
│ └── head.h
├── lib # lib目录下存放生成的库
└── src # src目录下存放源文件├── add.cpp├── div.cpp├── main.cpp├── mult.cpp└── sub.cpp
如果我们要将其生成为库并指定输出路径该目录下的CMakeLists.txt文件这样写
cmake_minimum_required(VERSION 3.1)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project (LearnCMake LANGUAGES CXX)
# 包含头文件
include_directories(${PROJECT_SOURCE_DIR}/include)
# 查找源文件
file(GLOB SRC_LIST ${PROJECT_SOURCE_DIR}/src/*.cpp)
# 设置动态库/静态库生成路径
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
# 生成动态库
add_library(hello SHARED ${SRC_LIST})
# 生成静态库
add_library(hello STATIC ${SRC_LIST})
2.6 链接库文件
如果lib目录下已经存在库文件我们应该如何用lib下的静态/动态库。
假设我们有如下目录结构
$ tree
.
├── build
├── CMakeLists.txt
├── bin $ bin目录下存放项目生成的可执行文件
├── include # include目录下存放头文件
│ └── head.h
├── lib # lib目录下存放生成的库├── libhello.a└── libhello.so
└── src # src目录下存放源文件├── add.cpp├── div.cpp├── main.cpp├── mult.cpp└── sub.cpp
2.6.1 链接静态库
在cmake中链接静态库的命令如下
link_libraries(static lib [static lib...])
静态库名称可以是全名 libxxx.a也可以是掐头lib去尾.a之后的名字 xxx
如果该静态库不是系统提供的自己制作或者使用第三方提供的静态库可能出现静态库找不到的情况此时可以将静态库的路径也指定出来
link_directories(lib path)
该目录下的CMakeLists.txt文件这样写
cmake_minimum_required(VERSION 3.1)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project (LearnCMake LANGUAGES CXX)
# 包含头文件
include_directories(${PROJECT_SOURCE_DIR}/include)
# 查找源文件
file(GLOB SRC_LIST ${PROJECT_SOURCE_DIR}/src/*.cpp)
# 包含静态库路径
link_directories(${PROJECT_SOURCE_DIR}/lib)
# 查找库文件
# 第一个参数变量用于存储查找到的库文件 第二个参数要查找的库文件 第三个参考指定目录下查找
find_library(HELLO_LIB libhello.a ${PROJECT_SOURCE_DIR}/lib)
# 链接静态库
link_libraries(${HELLO_LIB})
# 生成可执行程序
add_executable(hello ${SRC_LIST})
find_library函数用于查找指定目录下的库文件并将其存储至指定变量中。
2.6.2 链接动态库
在cmake中链接动态库的命令如下:
target_link_libraries(target PRIVATE|PUBLIC|INTERFACE item... [PRIVATE|PUBLIC|INTERFACE item...]...)
target指定要加载的库的文件的名字 该文件可能是一个源文件该文件可能是一个动态库/静态库文件该文件可能是一个可执行文件PRIVATE/PUBLIC/INTERFACE动态库的访问权限默认为PUBLIC 如果各个动态库之间没有依赖关系无需做任何设置三者没有没有区别一般无需指定使用默认的 PUBLIC 即可。动态库的链接具有传递性如果动态库 A 链接了动态库B、C动态库D链接了动态库A此时动态库D相当于也链接了动态库B、C并可以使用动态库B、C中定义的方法。 PUBLIC在public后面的库会被Link到前面的target中并且里面的符号也会被导出提供给第三方使用。PRIVATE在private后面的库仅被link到前面的target中并且终结掉第三方不能感知你调了啥库INTERFACE在interface后面引入的库不会被链接到前面的target中只会导出符号。 动态库的链接和静态库是完全不同的 1. 静态库会在生成可执行程序的链接阶段被打包到可执行程序中所以可执行程序启动静态库就被加载到内存中了。 2. 动态库在生成可执行程序的链接阶段不会被打包到可执行程序中当可执行程序被启动并且调用了动态库中的函数的时候动态库才会被加载到内存。因此在cmake中指定要链接的动态库的时候应该将 命令写到生成了可执行文件之后。 该目录下的CMakeLists.txt文件这样写
cmake_minimum_required(VERSION 3.1)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project (LearnCMake LANGUAGES CXX)
# 包含头文件
include_directories(${PROJECT_SOURCE_DIR}/include)
# 查找源文件
file(GLOB SRC_LIST ${PROJECT_SOURCE_DIR}/src/*.cpp)
# 包含动态库路径
link_directories(${PROJECT_SOURCE_DIR}/lib)
# 查找库文件
# 第一个参数变量用于存储查找到的库文件 第二个参数要查找的库文件 第三个参考指定目录下查找
find_library(HELLO_LIB libhello.so ${PROJECT_SOURCE_DIR}/lib)
# 生成可执行程序
add_executable(hello ${SRC_LIST})
# 链接的动态库
target_link_libraries(hello pthread ${HELLO_LIB})
其中pthread 和 libhello都是可执行程序hello需要链接的动态库名称。
2.6.3 target_link_libraries 和 link_libraries 的区别
target_link_libraries 是更现代和推荐的用法适合精细控制和管理项目的库依赖。link_libraries 适合简单的项目或早期的 CMake 版本但在复杂的项目中会带来管理上的困难
现在一般推荐使用target_link_libraries
a. target_link_libraries
仅对指定的目标如可执行文件或库在编译时需要链接哪些库生效。
target_link_libraries(target LIBRARIES)
比如
target_link_libraries(MyExecutable PRIVATE mylib)
优点
可以指定链接库的作用范围PRIVATE、PUBLIC、INTERFACE从而控制库的可见性和传递性。可以单独为每个目标配置链接库不会影响其他目标。支持接口库interface libraries和导出库exported libraries。
b. link_libraries
对整个目录内的所有目标生效.
缺点
由于是全局的无法控制库的作用范围PRIVATE、PUBLIC 等所有目标都会使用这些库。缺乏模块化不适合复杂的项目结构或多目标项目。
2.7 message指令
message命令用于在配置和生成过程中向用户输出信息。基本语法如下
message([SEND_ERROR | FATAL_ERROR | WARNING | AUTH_WARNING | STATUS | DEPRECATION_WARNING] message-text)
SEND_ERROR将消息作为错误输出并继续执行但通常会停止在产生错误的命令。FATAL_ERROR将消息作为错误输出并立即停止处理 CMakeLists.txt 文件。WARNING将消息作为警告输出。AUTH_WARNING输出一个授权警告通常用于策略警告。STATUS输出普通状态信息这是默认行为如果不指定类型。DEPRECATION_WARNING输出一个弃用警告。
举例
if(UNIX) message(STATUS Building for UNIX-like system.)
elseif(WIN32) message(STATUS Building for Windows.)
else() message(WARNING Unknown platform. Proceeding with caution.)
endif()
2.8 移除操作
若我们通过file或者aux_source_directory对某一个目录进行搜索但搜索结果中并不是全部的源文件都是我们需要的这时候我们需要通过将我们不需要的源文件移除。可以使用list命令
list(REMOVE_ITEM list value1 [value2 ...])
list 是要操作的列表的名称。value1, value2, ... 是希望从列表中移除的元素
举例
# 假设我有一个列表包含以下元素
set(my_list a b c d e)
# 删除b和d
list(REMOVE_ITEM my_list b d)
假设我们有如下目录结构
$ tree
.
├── build
├── CMakeLists.txt
├── include # include目录下存放头文件
│ └── head.h
├── lib # lib目录下存放生成的库
└── src # src目录下存放源文件├── add.cpp├── div.cpp├── main.cpp├── mult.cpp└── sub.cpp
若源文件不包含sub.cpp该目录的CMakeLists.txt文件这样写
cmake_minimum_required(VERSION 3.1)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project (LearnCMake LANGUAGES CXX)
# 包含头文件
include_directories(${PROJECT_SOURCE_DIR}/include)
# 查找源文件
file(GLOB SRC_LIST ${PROJECT_SOURCE_DIR}/src/*.cpp)
# 移除前日志
message(STATUS message: ${SRC_LIST })
# 移除 main.cpp
list(REMOVE_ITEM SRC_LIST ${PROJECT_SOURCE_DIR}/sub.cpp)
# 移除后日志
message(STATUS message: ${SRC_LIST })
# 生成可执行文件
add_executable(hello ${SRC_LIST})
2.9 find_library和find_package
find_library用于查找指定目录下的指定文件并将其存储至变量中。
# 第一个参数变量用于存储查找到的库文件 第二个参数要查找的库文件 第三个参考指定目录下查找
find_library(HELLO_LIB libhello.so ${PROJECT_SOURCE_DIR}/lib)
find_package根据系统环境找到指定的软件包或库并将其相关信息如库的路径、头文件的路径等提供给项目使用。
find_package(PackageName [version] [REQUIRED] [COMPONENTS components...])
PackageName: 需要查找的软件包的名称例如 Boost、OpenCV 等。[version]: 可选指定软件包的版本号。如果需要特定版本可以指定版本号例如 1.70.0。[REQUIRED]: 可选表示该包是必需的。如果 CMake 找不到该包它会停止并报错。[COMPONENTS components...]: 可选指定要查找的组件或模块。例如某些库可能有多个子模块如 Boost 中的 system、filesystem 模块你可以通过此选项指定只查找需要的部分。
举例
find_package(Boost 1.70 REQUIRED COMPONENTS system filesystem)
查找 Boost 库的版本 1.70并确保 system 和 filesystem 两个组件被找到。如果找不到这些组件CMake 将报错并停止构建。
3. 常用的宏
宏功能PROJECT_NAME用函数project(demo)指定的项目名称PROJECT_SOURCE_DIR一般为工程的根目录指向包含最近一次调用project()命令定义的项目的源目录PROJECT_BINARY_DIR执行cmake命令的目录一般为buildCMAKE_CURRENT_SOURCE_DIR当前处理的CMakeLists.txt文件所在目录CMAKE_CURRENT_BINARY_DIR当前处理的二进制输出目录也就是 CMake 将生成构建文件例如 Makefile 或其他生成器文件的目录CMAKE_CURRENT_LIST_DIRCMakeLists.txt的完整路径CMAKE_CURRENT_LIST_LINE当前所在行EXECUTABLE_OUTPUT_PATH重新定义目标二进制可执行文件的存放位置LIBRARY_OUTPUT_PATH重新定义目标链接库文件的存放位置CMAKE_CXX_STANDARD指定C标准CMAKE_CXX_STANDARD_REQUIRED如果编译不符合指定C标准编译
4. 示例
这是我们之前在linux上编译grpc通信代码用到的CMakeLists.txt文件现在可以分析每条指令的作用是什么
# 指定cmake版本最低为3.1
cmake_minimum_required(VERSION 3.1)
# 项目名称为GrpcServer编程语言C
project(GrpcServer LANGUAGES CXX)
# 将 CMAKE_CURRENT_SOURCE_DIR 和 CMAKE_CURRENT_BINARY_DIR 自动添加到包含路径中这些目录下的头文件被自动包含
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# C版本17
set(CMAKE_CXX_STANDARD 17)
# 如果不满足C17强制编译失败
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 查找Threads 库如果找不到该包编译停止并报错
find_package(Threads REQUIRED)
# 使用模块查找的规则优先使用 CMake 自带的 FindProtobuf.cmake 文件而不是使用配置模式即通过 protobuf-config.cmake 文件进行查找
set(protobuf_MODULE_COMPATIBLE TRUE)
# 查找protobuf库并要求找到的是基于CONFIG模式的配置文件(protobuf-config.cmake)且找不到会报错
find_package(Protobuf CONFIG REQUIRED)
# 输出protobuf版本号
message(STATUS Using protobuf ${Protobuf_VERSION})
# 将protobuf的核心库libprotobuf赋值给变量_PROTOBUF_LIBPROTOBUF
set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf)
# 将grpc的反射库赋值给_REFLECTION
set(_REFLECTION gRPC::grpc_reflection)
# Find gRPC installation
# Looks for gRPCConfig.cmake file installed by gRPCs cmake installation.
find_package(gRPC CONFIG REQUIRED)
message(STATUS Using gRPC ${gRPC_VERSION})set(_GRPC_GRPCPP gRPC::grpc)
# 添加可执行文件和源文件
file(GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
file(GLOB PBSOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
# 生成可执行程序GrpcServer
add_executable(GrpcServer ${SOURCES}${PBSOURCES})
# 链接库动态库文件
target_link_libraries(GrpcServer${_REFLECTION}${_GRPC_GRPCPP}${_PROTOBUF_LIBPROTOBUF}) 文章转载自: http://www.morning.jqlx.cn.gov.cn.jqlx.cn http://www.morning.slfmp.cn.gov.cn.slfmp.cn http://www.morning.hbdqf.cn.gov.cn.hbdqf.cn http://www.morning.djpps.cn.gov.cn.djpps.cn http://www.morning.hqbk.cn.gov.cn.hqbk.cn http://www.morning.cwknc.cn.gov.cn.cwknc.cn http://www.morning.zqcgt.cn.gov.cn.zqcgt.cn http://www.morning.fkmrj.cn.gov.cn.fkmrj.cn http://www.morning.xnltz.cn.gov.cn.xnltz.cn http://www.morning.nccqs.cn.gov.cn.nccqs.cn http://www.morning.yuminfo.com.gov.cn.yuminfo.com http://www.morning.kklwz.cn.gov.cn.kklwz.cn http://www.morning.ntlxg.cn.gov.cn.ntlxg.cn http://www.morning.dmcxh.cn.gov.cn.dmcxh.cn http://www.morning.gkxyy.cn.gov.cn.gkxyy.cn http://www.morning.ztqyj.cn.gov.cn.ztqyj.cn http://www.morning.csxlm.cn.gov.cn.csxlm.cn http://www.morning.ybshj.cn.gov.cn.ybshj.cn http://www.morning.bmts.cn.gov.cn.bmts.cn http://www.morning.ndxmn.cn.gov.cn.ndxmn.cn http://www.morning.rhfh.cn.gov.cn.rhfh.cn http://www.morning.czxrg.cn.gov.cn.czxrg.cn http://www.morning.rwqk.cn.gov.cn.rwqk.cn http://www.morning.lsfbb.cn.gov.cn.lsfbb.cn http://www.morning.hkysq.cn.gov.cn.hkysq.cn http://www.morning.zdhxm.com.gov.cn.zdhxm.com http://www.morning.kzpy.cn.gov.cn.kzpy.cn http://www.morning.jbpdk.cn.gov.cn.jbpdk.cn http://www.morning.lgnbr.cn.gov.cn.lgnbr.cn http://www.morning.sgqw.cn.gov.cn.sgqw.cn http://www.morning.zqdhr.cn.gov.cn.zqdhr.cn http://www.morning.wbysj.cn.gov.cn.wbysj.cn http://www.morning.xlbyx.cn.gov.cn.xlbyx.cn http://www.morning.cwskn.cn.gov.cn.cwskn.cn http://www.morning.jhtrb.cn.gov.cn.jhtrb.cn http://www.morning.mwkwg.cn.gov.cn.mwkwg.cn http://www.morning.qdxtj.cn.gov.cn.qdxtj.cn http://www.morning.wbqt.cn.gov.cn.wbqt.cn http://www.morning.pmdlk.cn.gov.cn.pmdlk.cn http://www.morning.xykst.cn.gov.cn.xykst.cn http://www.morning.wwsgl.com.gov.cn.wwsgl.com http://www.morning.yhtnr.cn.gov.cn.yhtnr.cn http://www.morning.pfkrw.cn.gov.cn.pfkrw.cn http://www.morning.jwtjf.cn.gov.cn.jwtjf.cn http://www.morning.ltpzr.cn.gov.cn.ltpzr.cn http://www.morning.jqkjr.cn.gov.cn.jqkjr.cn http://www.morning.sbjbs.cn.gov.cn.sbjbs.cn http://www.morning.lzqdl.cn.gov.cn.lzqdl.cn http://www.morning.mnrqq.cn.gov.cn.mnrqq.cn http://www.morning.rymb.cn.gov.cn.rymb.cn http://www.morning.jfwrf.cn.gov.cn.jfwrf.cn http://www.morning.mzcsp.cn.gov.cn.mzcsp.cn http://www.morning.rjhts.cn.gov.cn.rjhts.cn http://www.morning.hengqilan.cn.gov.cn.hengqilan.cn http://www.morning.rsnd.cn.gov.cn.rsnd.cn http://www.morning.yhljc.cn.gov.cn.yhljc.cn http://www.morning.ryxdr.cn.gov.cn.ryxdr.cn http://www.morning.fpzpb.cn.gov.cn.fpzpb.cn http://www.morning.gbfuy28.cn.gov.cn.gbfuy28.cn http://www.morning.wrlxy.cn.gov.cn.wrlxy.cn http://www.morning.rkdw.cn.gov.cn.rkdw.cn http://www.morning.xkyqq.cn.gov.cn.xkyqq.cn http://www.morning.kaweilu.com.gov.cn.kaweilu.com http://www.morning.npxht.cn.gov.cn.npxht.cn http://www.morning.skwwj.cn.gov.cn.skwwj.cn http://www.morning.bkslb.cn.gov.cn.bkslb.cn http://www.morning.jyjqh.cn.gov.cn.jyjqh.cn http://www.morning.dfkmz.cn.gov.cn.dfkmz.cn http://www.morning.tytly.cn.gov.cn.tytly.cn http://www.morning.nxnrt.cn.gov.cn.nxnrt.cn http://www.morning.hhrpy.cn.gov.cn.hhrpy.cn http://www.morning.fhghy.cn.gov.cn.fhghy.cn http://www.morning.fbmjl.cn.gov.cn.fbmjl.cn http://www.morning.hdrrk.cn.gov.cn.hdrrk.cn http://www.morning.kjxgc.cn.gov.cn.kjxgc.cn http://www.morning.nzqqd.cn.gov.cn.nzqqd.cn http://www.morning.hydkd.cn.gov.cn.hydkd.cn http://www.morning.dblgm.cn.gov.cn.dblgm.cn http://www.morning.jpgfx.cn.gov.cn.jpgfx.cn http://www.morning.tqsmc.cn.gov.cn.tqsmc.cn