cmake基础知识

Cmake

Cmake变量

Cmake的基本类型只有两种,分别是字符串字符串列表,使用set命令来设置变量

set(var abc) # abc是字符串,var是值为“abc”的字符串变量
set(var a b c) # var是包含a b c三个元素的字符串列表
set(var a;b;c) # 同上
set(var “a b c”) # var是值为“a b c”的字符串变量

Cmake命令不区分大小写,变量区分大小写

变量取值方法如下:

set(var abc)  # abc是字符串,var是变量
message(${var}) # 使用${变量}的形式来取值,并打印

条件语句

(1)if条件语句

if(condition1)
	expression1
elseif(condition2)
	expression2
endif()

(2)循环语句

foreach(item IN LISTS list_var)
	message(${item})
endforeach()

常用命令

(1)版本号要求

指定Cmake最低版本号

cmake_minimum_required(VERSION xx.xx)

(2)指定项目信息

project(PRO_NAME)

(3)设置构建目标Target

  • 创建可执行文件
add_executable()  # 用于创建一个可执行的Target
  • 创建静态库/动态库
add_library(target STATIC/SHARED a.cpp b.cpp)

源文件过多的情况下,可以通过调用aux_source_directory([目录] [变量名])来批量添加

aux_source_directory(./src Clist)
add_library(target STATIC ${Clist})
  • 子目录联编

父级CMakeList.txt通过调用add_subdirectory()来实现包含、调用存在CMakeList.txt的子目录或者子工程

add_subdirectory([目录])
  • 指定链接选项
  1. 仅用于可执行文件或者动态库目标(必须先创建target):
add_executable(mymathApp mymathApp.cc)
target_link_options(mymathApp <INTERFACE|PUBLIC|PRIVATE> -wl,-shared,-z,noexecstack)

PUBLIC、PRIVATE和INTERFACE是目标属性的修饰符

  1. 指定目标的属性
set_target_properties
  1. 设置链接属性变量LINK_FLAGS
set(LINK_FLAGS "-rdynamic -W1,-z,noexecstack -W1,-z,relro -W1,-z,now")
  • 添加源编译选项

1)向源文件编译添加选项,相关选项将添加到COMPILE_OPTIONS目录属性。从当前目录和下一级目录编译target时,将使用这些选项。

add_compile_options(<option> ...)
e.g.
add_compile_options(-DSAMPLE_ADD_VALUE=10)
add_compile_options(-Wall -Wextra -pedantic -Werror)

2)向target添加编译选项

add_executable(main samples/sample_add.cpp)
target_compile_options(main
PRIVATE $<$<CXX_COMPILER_ID:AppleClang,IBMClang,Clang,GNU,LCC>:-DMY_PRIVATE_DEFINE>
PUBLIC $<$<COMPILE_LANG_AND_ID:CXX,GNU,LCC>:-DMY_PUBLIC_DEFINE>
PUBLIC $<$<COMPILE_LANG_AND_ID:CXX,GNU,LCC,Clang,AppleClang,IBMClang>:-
DMY_MUTLI_COMP_PUBLIC_DEFINE>
INTERFACE $<$<CXX_COMPILER_ID:GNU,LCC>:-DMY_INTERFACE_DEFINE>
INTERFACE $<$<CXX_COMPILER_ID:GNU,LCC,Clang,AppleClang,IBMClang>:-
DMY_MULTI_COMP_INTERFACE_DEFINE>
)
  • 给顶级目标添加依赖项

使顶级<目标>依赖于其他顶级目标,以确保子一级的目标在<目标>之前构建 ,顶级目标是由add_executable()、 add_library()或add_custom_target()命令创建的

ADD_EXECUTABLE(main main.cpp)
ADD_DEPENDENCIES(main a.so b.so) ## main有一些符号的定义在a.so或者b.so中,提示编译器先生产依赖库,再去生成main
TARGET_LINK_LIBRARIES(main a.so b.so c.so d.so)
  • 查找某级目录下的所有源文件,并保存文件列表到变量
aux_source_directory([目录] [变量名])
e.g.
aux_source_directory(../ DIR_SRC)
  • 添加子目录进行构建
add_subdirectory(../src)
  • 添加头文件搜索目录,如果是相对路径,则是基于当前源文件的路径
include_directories
  • 添加链接器寻找库文件的目录
link_directories

注意:该命令只适用于在它被调用后创建target的场景, 如果必须提供库搜索路径,则最好尽可能使用 target_link_directories命令

  • 将库文件链接目录添加到target里,指定连接器在链接给定target的时候应该在设置的目录下搜索库文件
target_link_directories(<target> [INTERFACE/PUBLIC/PRIVATE] DIR)

注意:命名中的target必须先由add_excecutable或者add_library等命令创建

  • 将库链接到稍后添加的所有目标里
link_libraries("/opt/libeng.so" "/opt/bin/libmx.so")

注意:该命令只适用于在它被调用后创建target的场景

  • 指定将要链接到给定target的库
target_link_libraries(<target> [INTERFACE/PUBLIC/INTERFACE] item1 ...)
target_link_libraries(myProject libcomm.so) # 这些库名写法都可以
target_link_libraries(myProject comm)
target_link_libraries(myProject -lcomm)

PUBLIC 在public后面的库会被Link到你的target中,并且里面的符号也会被导出,提供给第三方使用。

PRIVATE在private后面的库仅被link到你的target中,并且终结掉,第三方不能感知你调了啥库 INTERFACE 在 interface后面引入的库不会被链接到你的target中,只会导出符号。

作用域

没有指定作用域的情况

父目录的CMakeList.txt变量作用域会扩展至子目录,但是子目录不能扩展到父亲目录。例如, sub_module_a1/CMakeLists.txt可以访问到module_a和root下的CMakeLists.txt中定义的变量,反之 module_a/CMakeLists.txt访问不到sub_module_a1/CMakeLists.txt中定义的变量。

root
    |--CMakeLists.txt
    |--module_a
    | 	|--CMakeLists.txt
    | 	|--sub_module_a1
    | 		|--CMakeLists.txt
    |
    |--module_b
    	|--CMakeLists.txt

如果子目录变量需要被上一级父目录访问

set(var xxx PARENT_SCOPE)

如果子目录变量作用域需要扩大到全局CMakeList.txt

set(var xxx CACHE INTERNAL "")

常见的内部变量

变量名 描述
CMAKE_C_COMPILER/CMAKE_CXX_COMPILER C/C++编译器
CMAKE_C_FLAGS/CMAKE_CXX_FLAGS C/C++编译选项
CMAKE_BINARY_DIR/PROJECT_BINARY_DIR 执行cmake命令的dir,即cmake生成件所在dir
CMAKE_SOURCE_DIR/PROJECT_SOURCE_DIR 工程顶层目录
CMAKE_CURRENT_SOURCE_DIR 当前CMakeLists.txt所在dir
CMAKE_INSTALL_PREFIX 执行make install的发布件安装dir
CMAKE_TOOLCHAIN_FILE 指定交叉编译环境的配置文件,在cmake命令中指定
CMAKE_CXX_STANDARD 指定C++的版本号: 11、17等
posted @ 2024-09-14 16:18  ihuahua1415  阅读(48)  评论(0编辑  收藏  举报
*/