CMakeLists
参考
https://zhuanlan.zhihu.com/p/500002865
https://subingwen.cn/cmake/CMake-primer/#3-%E9%A2%84%E5%AE%9A%E4%B9%89%E5%AE%8F
http://geekdaxue.co/read/CMake-Cookbook/README.md
最小项目
cmake_minimum_required(VERSION 3.15) project(test) add_executable(app add.c div.c main.c mult.c sub.c)
set
使用set定义变量优化上文
cmake_minimum_required(VERSION 3.15) project(test) #定义变量SRC set(SRC add.c div.c main.c mult.c sub.c) #使用变量SRC add_executable(app ${SRC})
指定C++标准
cmake_minimum_required(VERSION 3.15) project(test) set(SRC add.c div.c main.c mult.c sub.c) #指定c++标准 set(CMAKE_CXX_STANDARD 14) add_executable(app ${SRC})
指定输出路径
定义输出路径指定输出路径:EXECUTABLE_OUTPUT_PATH
cmake_minimum_required(VERSION 3.15) project(test) set(SRC add.c div.c main.c mult.c sub.c) set(CMAKE_CXX_STANDARD 14) #定义输出路径 set(HOME /home/omm/temp/camek_test) #指定输出路径 set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin) add_executable(app ${SRC})
搜索文件
新建文件夹src,把.c文件移动到src目录下。通过搜索直接获取src目录下的.c文件;由于.c文件寻找头文件时,会在自己的同级目录下找会发现找不到,所以需要指定头文件路径新建文件夹include,把.h文件移动到include目录下。通过搜索直接获取include目录下的.h文件;
${PROJECT_SOURCE_DIR}的值是cmake后面的路径,其实也就是CMakeLists的路径(优先记忆)${CMAKE_CURRENT_SOURCE_DIR}的值是CMakeLists的路径
cmake_minimum_required(VERSION 3.15) project(test) #搜索源文件 aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src SRC) #搜索头文件 include_directories(${PROJECT_SOURCE_DIR}/include) set(CMAKE_CXX_STANDARD 14) set(HOME /home/omm/temp/camek_test) set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin) add_executable(app ${SRC})
如果一个项目里边的源文件很多,在编写 CMakeLists.txt 文件的时候不可能将项目目录的各个文件一一罗列出来,这样太麻烦了。所以,在 CMake 中为我们提供了搜索文件的命令,他就是 file(当然,除了搜索以外通过 file 还可以做其他事情)。
file(GLOB/GLOB_RECURSE 变量名 要搜索的文件路径和文件类型)
GLOB: 将指定目录下搜索到的满足条件的所有文件名生成一个列表,并将其存储到变量中。GLOB_RECURSE:递归搜索指定目录,将搜索到的满足条件的文件名生成一个列表,并将其存储到变量中。
搜索当前目录的 src 目录下所有的源文件,并存储到变量中
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) file(GLOB HEAD ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h) include_directories(${HEAD})
制作静态库或者动态库
add_library(库名称 STATIC 源文件1 [源文件2] ...)在 Linux 中,静态库名字分为三部分:lib+ 库名字 +.a,此处只需要指定出库的名字就可以了,另外两部分在生成该文件的时候会自动填充。把main.c文件移动到CMakeLists的同级目录下。**add_library(库名称 SHARED 源文件1 [源文件2] ...) **
指定库输出路径
如果不指定输出路径,那么默认输出在执行cmake命令的那个目录下面。不能同时生成静态库和动态库。set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin)不能指定动态库的生成路径。只能指定动态库:set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)指定静态库或动态库(优先使用):set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
链接静态库
链接静态库:link_libraries(<static lib> [<static lib>...])需指定第三方静态库路径link_directories(<lib path>)
步骤:
- 包含静态库头文件
- 指明静态库路径
- 链接静态库
cmake_minimum_required(VERSION 3.0) project(CALC) # 搜索指定目录下源文件 file(GLOB SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) # 包含头文件路径 include_directories(${PROJECT_SOURCE_DIR}/include) # 包含静态库路径 link_directories(${PROJECT_SOURCE_DIR}/lib) # 链接静态库 link_libraries(calc) add_executable(app ${SRC_LIST})
链接动态库
target_link_libraries( <target> <PRIVATE|PUBLIC|INTERFACE> <item>... [<PRIVATE|PUBLIC|INTERFACE> <item>...]...)
- 包含动态库头文件路径
- 指定动态库路径
- 链接动态库的语句总是应该放在最后面
cmake_minimum_required(VERSION 3.0) project(TEST) file(GLOB SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) # 指定源文件或者动态库对应的头文件路径 include_directories(${PROJECT_SOURCE_DIR}/include) # 指定要链接的动态库的路径 link_directories(${PROJECT_SOURCE_DIR}/lib) # 添加并生成一个可执行程序 add_executable(app ${SRC_LIST}) # 指定要链接的动态库 target_link_libraries(app pthread calc)
日志
在 CMake 中可以用用户显示一条消息,该命令的名字为 message:
message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR] "message to display" ...)
(无) :重要消息STATUS :非重要消息WARNING:CMake 警告,会继续执行AUTHOR_WARNING:CMake 警告 (dev), 会继续执行SEND_ERROR:CMake 错误,继续执行,但是会跳过生成的步骤FATAL_ERROR:CMake 错误,终止所有处理过程CMake 的命令行工具会在 stdout 上显示 STATUS 消息,在 stderr 上显示其他所有消息。CMake 的 GUI 会在它的 log 区域显示所有消息。
CMake 警告和错误消息的文本显示使用的是一种简单的标记语言。文本没有缩进,超过长度的行会回卷,段落之间以新行做为分隔符。
变量操作
set追加
set(变量名 ${变量名} ${变量名1}……)其实就是把新的变量赋值给原来的变量
list追加
可以把list看作是一个类,而追加是它的一个成员方法。list(append 变量名 ${变量名1}……)
list移除
list(REMOVE_ITEM 变量名 ${变量名1}……)
其它
不常用,略过
宏定义
CMake中有很多预定义宏
PROJECT_SOURCE_DIR | 使用 cmake 命令后紧跟的目录,一般是工程的根目录 |
PROJECT_BINARY_DIR | 执行 cmake 命令的目录 |
CMAKE_CURRENT_SOURCE_DIR | 当前处理的 CMakeLists.txt 所在的路径 |
CMAKE_CURRENT_BINARY_DIR | target 编译目录 |
EXECUTABLE_OUTPUT_PATH | 重新定义目标二进制可执行文件的存放位置 |
LIBRARY_OUTPUT_PATH | 重新定义目标链接库文件的存放位置 |
PROJECT_NAME | 返回通过 PROJECT 指令定义的项目名称 |
CMAKE_BINARY_DIR | 项目实际构建路径,假设在 build 目录进行的构建,那么得到的就是这个目录的路径 |
CMake嵌套
对于上级CMake,通过add_subdirectory添加自己的子CMake路径。上级CMake定义的变量可以在子CMake中使用。
条件判断
if(USE_LIBRARY) # add_library will create a static library # since BUILD_SHARED_LIBS is OFF add_library(message ${_sources}) add_executable(hello-world hello-world.cpp) target_link_libraries(hello-world message) else() add_executable(hello-world hello-world.cpp ${_sources}) endif()
编译选项
set(USE_LIBRARY OFF)这种方式被称为硬编码,USE_LIBRARY的值被设为了OFF,已经被写死。用一个选项替换上一个示例的set(USE_LIBRARY OFF)命令。该选项将修改USE_LIBRARY的值,并设置其默认值为OFF:option(USE_LIBRARY "Compile sources into a library" OFF)现在,可以通过CMake的-DCLI选项,将信息传递给CMake来切换库的行为cmake -D USE_LIBRARY=ON ..
option可接受三个参数:
option(<option_variable> "help string" [initial value])
<option_variable>表示该选项的变量的名称。"help string"记录选项的字符串,在CMake的终端或图形用户界面中可见。[initial value]选项的默认值,可以是ON或OFF。
需弄清楚下面两个示例cmake_dependent_option(MAKE_STATIC_LIBRARY "Compile sources into a static library" OFF"USE_LIBRARY" ON)
cmake_dependent_option(MAKE_SHARED_LIBRARY "Compile sources into a shared library" ON"USE_LIBRARY" ON)
设置编译选项(难点)
编写安装程序hello
目录结构如下:
├── build├── CMakeLists.txt├── COPYRIGHT├── doc│ └── hello.txt├── README├── runhello.sh└── src├── CMakeLists.txt└── hello.cpp
编写安装程序hello
顶层CMakeLists内容如下:
cmake_minimum_required(VERSION 3.15) project(HELLO) add_subdirectory(src bin) #cmake_install_prefix默认值为/usr/local #安装的路径若不存在则会自动创建 install(FILES COPYRIGHT README DESTINATION share/doc/cmake/) install(PROGRAMS runhello.sh DESTINATION bin) install(DIRECTORY doc/ DESTINATION share/doc/cmake) install(TARGETS hello DESTINATION bin)
src/CMakeLists内容如下:
add_executable(hello hello.cpp)
这里的疑惑是,顶层CMakeLists是怎么知道底层生成了hello?
习题与解答(最小项目与拓展)
怎样构建cmake最小项目
答:
- 构建最小项目需要指定cmake最低版本,cmake_minimum_required()
- 需要指定项目名称,project()
- 需要生成可执行文件,add_executable()
怎样指定可执行文件的输出路径
set(EXECUTABLE_OUTPUT_PATH ${PATH})
怎样搜索文件
已知源文件在某个文件夹下,但是要一个一个的将源文件列出来保存在SRC变量中实在是太麻烦了?有什么简单的办法来解决吗?答:可以使用自动搜索文件。
- 搜索源文件:aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src SRC)
- 或者使用file()
怎样指定头文件
有些源文件包含了头文件,当头文件与源文件不在同一目录下时就会报错,需要指出头文件目录?那么怎样指出头文件目录呢?答:include_directories()
库制作与使用
怎样制作静态库和动态库?
答:add_library(库名称 STATIC 源文件1 [源文件2] ...)在 Linux 中,静态库名字分为三部分:lib+ 库名字 +.a,此处只需要指定出库的名字就可以了,另外两部分在生成该文件的时候会自动填充。把main.c文件移动到CMakeLists的同级目录下。**add_library(库名称 SHARED 源文件1 [源文件2] ...) **
怎样指定库输出位置
如果不指定输出路径,那么默认输出在执行cmake命令的那个目录下面。不能同时生成静态库和动态库。指定静态库或动态库:set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin)用于指定可执行程序的输出路径
怎样链接静态库
答:分三步走
- 指定静态库头文件路径,include_directories()
- 指定静态库路径,link_directories()
- 指定要链接的静态库,link_libraries() 为何不需要指定用到的哪些头文件呢?这是因为要用到哪些头文件已经由源文件来确定了。也可以用target_link_libraries来链接静态库 示例如下:
cmake_minimum_required(VERSION 3.15) project(test) include_directories(${PROJECT_SOURCE_DIR}/include) link_directories(${PROJECT_SOURCE_DIR}/lib) add_executable(main main.c) target_link_libraries(main cacl)
怎样链接动态库
答:分为三步走
- 指定头文件路径,include_directories()
- 指定动态库路径,link_directories()
- 指定要链接的动态库,link_libraries() 为何不需要指定用到的哪些头文件呢?这是因为要用到哪些头文件已经由源文件来确定了。
link_libraries与target_link_libraries的区别
link_libraries(lib1 lib2 ...)其中,lib1
、lib2
等参数是要链接的库的名称。这个命令会将这些库链接到所有的目标中,包括可执行文件和库文件。
target_link_libraries(target lib1 lib2 ...)其中,target
是要链接库的目标名称,lib1
、lib2
等参数是要链接的库的名称。这个命令只会将这些库链接到指定的目标中,而不会影响其他目标。
因此,如果你想将某个库链接到所有的目标中,可以使用 link_libraries
命令;如果你只想将某个库链接到特定的目标中,可以使用 target_link_libraries
命令。
宏定义
列出所有涉及过的宏定义
控制编译选项
怎样让用户控制编译选项
使用option()
拓展
怎样把一个变量中的某项给移除出去
list(REMOVE_ITEM ${变量} 待移除项)
找出下面的错误
cmake_minimum_required(VERSION 3.15)
project(test)
include_directories(${PROJECT_SOURCE_DIR}/include)
link_directories(${PROJECT_SOURCE_DIR}/lib)
target_link_libraries(main.c cacl)
add_executable(main main.c)
答:上面有两处错误:
- target_link_libraries的第一个参数应该是目标文件(可执行文件,而不是.o文件),而不是.cpp文件。
- target_link_libraries应该放在最后,因为动态链接时,必须要先找到目标文件,所以上面由于目标文件还没有生成,所以会错误。
https://zhuanlan.zhihu.com/p/500002865
https://subingwen.cn/cmake/CMake-primer/#3-%E9%A2%84%E5%AE%9A%E4%B9%89%E5%AE%8F
http://geekdaxue.co/read/CMake-Cookbook/README.md
最小项目
cmake_minimum_required(VERSION 3.15) project(test) add_executable(app add.c div.c main.c mult.c sub.c)
set
使用set定义变量优化上文
cmake_minimum_required(VERSION 3.15) project(test) #定义变量SRC set(SRC add.c div.c main.c mult.c sub.c) #使用变量SRC add_executable(app ${SRC})
指定C++标准
cmake_minimum_required(VERSION 3.15) project(test) set(SRC add.c div.c main.c mult.c sub.c) #指定c++标准 set(CMAKE_CXX_STANDARD 14) add_executable(app ${SRC})
指定输出路径
定义输出路径指定输出路径:EXECUTABLE_OUTPUT_PATH
cmake_minimum_required(VERSION 3.15) project(test) set(SRC add.c div.c main.c mult.c sub.c) set(CMAKE_CXX_STANDARD 14) #定义输出路径 set(HOME /home/omm/temp/camek_test) #指定输出路径 set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin) add_executable(app ${SRC})
搜索文件
新建文件夹src,把.c文件移动到src目录下。通过搜索直接获取src目录下的.c文件;由于.c文件寻找头文件时,会在自己的同级目录下找会发现找不到,所以需要指定头文件路径新建文件夹include,把.h文件移动到include目录下。通过搜索直接获取include目录下的.h文件;
${PROJECT_SOURCE_DIR}的值是cmake后面的路径,其实也就是CMakeLists的路径(优先记忆)${CMAKE_CURRENT_SOURCE_DIR}的值是CMakeLists的路径
cmake_minimum_required(VERSION 3.15) project(test) #搜索源文件 aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src SRC) #搜索头文件 include_directories(${PROJECT_SOURCE_DIR}/include) set(CMAKE_CXX_STANDARD 14) set(HOME /home/omm/temp/camek_test) set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin) add_executable(app ${SRC})
如果一个项目里边的源文件很多,在编写 CMakeLists.txt 文件的时候不可能将项目目录的各个文件一一罗列出来,这样太麻烦了。所以,在 CMake 中为我们提供了搜索文件的命令,他就是 file(当然,除了搜索以外通过 file 还可以做其他事情)。
file(GLOB/GLOB_RECURSE 变量名 要搜索的文件路径和文件类型)
GLOB: 将指定目录下搜索到的满足条件的所有文件名生成一个列表,并将其存储到变量中。GLOB_RECURSE:递归搜索指定目录,将搜索到的满足条件的文件名生成一个列表,并将其存储到变量中。
搜索当前目录的 src 目录下所有的源文件,并存储到变量中
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) file(GLOB HEAD ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h) include_directories(${HEAD})
制作静态库或者动态库
add_library(库名称 STATIC 源文件1 [源文件2] ...)在 Linux 中,静态库名字分为三部分:lib+ 库名字 +.a,此处只需要指定出库的名字就可以了,另外两部分在生成该文件的时候会自动填充。把main.c文件移动到CMakeLists的同级目录下。**add_library(库名称 SHARED 源文件1 [源文件2] ...) **
指定库输出路径
如果不指定输出路径,那么默认输出在执行cmake命令的那个目录下面。不能同时生成静态库和动态库。set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin)不能指定动态库的生成路径。只能指定动态库:set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)指定静态库或动态库(优先使用):set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
链接静态库
链接静态库:link_libraries(<static lib> [<static lib>...])需指定第三方静态库路径link_directories(<lib path>)
步骤:
- 包含静态库头文件
- 指明静态库路径
- 链接静态库
cmake_minimum_required(VERSION 3.0) project(CALC) # 搜索指定目录下源文件 file(GLOB SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) # 包含头文件路径 include_directories(${PROJECT_SOURCE_DIR}/include) # 包含静态库路径 link_directories(${PROJECT_SOURCE_DIR}/lib) # 链接静态库 link_libraries(calc) add_executable(app ${SRC_LIST})
链接动态库
target_link_libraries( <target> <PRIVATE|PUBLIC|INTERFACE> <item>... [<PRIVATE|PUBLIC|INTERFACE> <item>...]...)
- 包含动态库头文件路径
- 指定动态库路径
- 链接动态库的语句总是应该放在最后面
cmake_minimum_required(VERSION 3.0) project(TEST) file(GLOB SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) # 指定源文件或者动态库对应的头文件路径 include_directories(${PROJECT_SOURCE_DIR}/include) # 指定要链接的动态库的路径 link_directories(${PROJECT_SOURCE_DIR}/lib) # 添加并生成一个可执行程序 add_executable(app ${SRC_LIST}) # 指定要链接的动态库 target_link_libraries(app pthread calc)
日志
在 CMake 中可以用用户显示一条消息,该命令的名字为 message:
message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR] "message to display" ...)
(无) :重要消息STATUS :非重要消息WARNING:CMake 警告,会继续执行AUTHOR_WARNING:CMake 警告 (dev), 会继续执行SEND_ERROR:CMake 错误,继续执行,但是会跳过生成的步骤FATAL_ERROR:CMake 错误,终止所有处理过程CMake 的命令行工具会在 stdout 上显示 STATUS 消息,在 stderr 上显示其他所有消息。CMake 的 GUI 会在它的 log 区域显示所有消息。
CMake 警告和错误消息的文本显示使用的是一种简单的标记语言。文本没有缩进,超过长度的行会回卷,段落之间以新行做为分隔符。
变量操作
set追加
set(变量名 ${变量名} ${变量名1}……)其实就是把新的变量赋值给原来的变量
list追加
可以把list看作是一个类,而追加是它的一个成员方法。list(append 变量名 ${变量名1}……)
list移除
list(REMOVE_ITEM 变量名 ${变量名1}……)
其它
不常用,略过
宏定义
CMake中有很多预定义宏
PROJECT_SOURCE_DIR | 使用 cmake 命令后紧跟的目录,一般是工程的根目录 |
PROJECT_BINARY_DIR | 执行 cmake 命令的目录 |
CMAKE_CURRENT_SOURCE_DIR | 当前处理的 CMakeLists.txt 所在的路径 |
CMAKE_CURRENT_BINARY_DIR | target 编译目录 |
EXECUTABLE_OUTPUT_PATH | 重新定义目标二进制可执行文件的存放位置 |
LIBRARY_OUTPUT_PATH | 重新定义目标链接库文件的存放位置 |
PROJECT_NAME | 返回通过 PROJECT 指令定义的项目名称 |
CMAKE_BINARY_DIR | 项目实际构建路径,假设在 build 目录进行的构建,那么得到的就是这个目录的路径 |
CMake嵌套
对于上级CMake,通过add_subdirectory添加自己的子CMake路径。上级CMake定义的变量可以在子CMake中使用。
条件判断
if(USE_LIBRARY) # add_library will create a static library # since BUILD_SHARED_LIBS is OFF add_library(message ${_sources}) add_executable(hello-world hello-world.cpp) target_link_libraries(hello-world message) else() add_executable(hello-world hello-world.cpp ${_sources}) endif()
编译选项
set(USE_LIBRARY OFF)这种方式被称为硬编码,USE_LIBRARY的值被设为了OFF,已经被写死。用一个选项替换上一个示例的set(USE_LIBRARY OFF)命令。该选项将修改USE_LIBRARY的值,并设置其默认值为OFF:option(USE_LIBRARY "Compile sources into a library" OFF)现在,可以通过CMake的-DCLI选项,将信息传递给CMake来切换库的行为cmake -D USE_LIBRARY=ON ..
option可接受三个参数:
option(<option_variable> "help string" [initial value])
<option_variable>表示该选项的变量的名称。"help string"记录选项的字符串,在CMake的终端或图形用户界面中可见。[initial value]选项的默认值,可以是ON或OFF。
需弄清楚下面两个示例cmake_dependent_option(MAKE_STATIC_LIBRARY "Compile sources into a static library" OFF"USE_LIBRARY" ON)
cmake_dependent_option(MAKE_SHARED_LIBRARY "Compile sources into a shared library" ON"USE_LIBRARY" ON)
设置编译选项(难点)
编写安装程序hello
目录结构如下:
├── build├── CMakeLists.txt├── COPYRIGHT├── doc│ └── hello.txt├── README├── runhello.sh└── src├── CMakeLists.txt└── hello.cpp
编写安装程序hello
顶层CMakeLists内容如下:
cmake_minimum_required(VERSION 3.15) project(HELLO) add_subdirectory(src bin) #cmake_install_prefix默认值为/usr/local #安装的路径若不存在则会自动创建 install(FILES COPYRIGHT README DESTINATION share/doc/cmake/) install(PROGRAMS runhello.sh DESTINATION bin) install(DIRECTORY doc/ DESTINATION share/doc/cmake) install(TARGETS hello DESTINATION bin)
src/CMakeLists内容如下:
add_executable(hello hello.cpp)
这里的疑惑是,顶层CMakeLists是怎么知道底层生成了hello?
习题与解答(最小项目与拓展)
怎样构建cmake最小项目
答:
- 构建最小项目需要指定cmake最低版本,cmake_minimum_required()
- 需要指定项目名称,project()
- 需要生成可执行文件,add_executable()
怎样指定可执行文件的输出路径
set(EXECUTABLE_OUTPUT_PATH ${PATH})
怎样搜索文件
已知源文件在某个文件夹下,但是要一个一个的将源文件列出来保存在SRC变量中实在是太麻烦了?有什么简单的办法来解决吗?答:可以使用自动搜索文件。
- 搜索源文件:aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src SRC)
- 或者使用file()
怎样指定头文件
有些源文件包含了头文件,当头文件与源文件不在同一目录下时就会报错,需要指出头文件目录?那么怎样指出头文件目录呢?答:include_directories()
库制作与使用
怎样制作静态库和动态库?
答:add_library(库名称 STATIC 源文件1 [源文件2] ...)在 Linux 中,静态库名字分为三部分:lib+ 库名字 +.a,此处只需要指定出库的名字就可以了,另外两部分在生成该文件的时候会自动填充。把main.c文件移动到CMakeLists的同级目录下。**add_library(库名称 SHARED 源文件1 [源文件2] ...) **
怎样指定库输出位置
如果不指定输出路径,那么默认输出在执行cmake命令的那个目录下面。不能同时生成静态库和动态库。指定静态库或动态库:set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin)用于指定可执行程序的输出路径
怎样链接静态库
答:分三步走
- 指定静态库头文件路径,include_directories()
- 指定静态库路径,link_directories()
- 指定要链接的静态库,link_libraries() 为何不需要指定用到的哪些头文件呢?这是因为要用到哪些头文件已经由源文件来确定了。也可以用target_link_libraries来链接静态库 示例如下:
cmake_minimum_required(VERSION 3.15) project(test) include_directories(${PROJECT_SOURCE_DIR}/include) link_directories(${PROJECT_SOURCE_DIR}/lib) add_executable(main main.c) target_link_libraries(main cacl)
怎样链接动态库
答:分为三步走
- 指定头文件路径,include_directories()
- 指定动态库路径,link_directories()
- 指定要链接的动态库,link_libraries() 为何不需要指定用到的哪些头文件呢?这是因为要用到哪些头文件已经由源文件来确定了。
link_libraries与target_link_libraries的区别
link_libraries(lib1 lib2 ...)其中,lib1
、lib2
等参数是要链接的库的名称。这个命令会将这些库链接到所有的目标中,包括可执行文件和库文件。
target_link_libraries(target lib1 lib2 ...)其中,target
是要链接库的目标名称,lib1
、lib2
等参数是要链接的库的名称。这个命令只会将这些库链接到指定的目标中,而不会影响其他目标。
因此,如果你想将某个库链接到所有的目标中,可以使用 link_libraries
命令;如果你只想将某个库链接到特定的目标中,可以使用 target_link_libraries
命令。
宏定义
列出所有涉及过的宏定义
控制编译选项
怎样让用户控制编译选项
使用option()
拓展
怎样把一个变量中的某项给移除出去
list(REMOVE_ITEM ${变量} 待移除项)
找出下面的错误
cmake_minimum_required(VERSION 3.15)
project(test)
include_directories(${PROJECT_SOURCE_DIR}/include)
link_directories(${PROJECT_SOURCE_DIR}/lib)
target_link_libraries(main.c cacl)
add_executable(main main.c)
答:上面有两处错误:
- target_link_libraries的第一个参数应该是目标文件(可执行文件,而不是.o文件),而不是.cpp文件。
- target_link_libraries应该放在最后,因为动态链接时,必须要先找到目标文件,所以上面由于目标文件还没有生成,所以会错误。