option
# 提供了一个在ON和OFF中做出选择的选项,默认为OFF
option(<option_variable> "描述性文字" [initial value])
option(protolib_BUILD_PROTOBUF "build protobuf" ON)
if (protolib_BUILD_PROTOBUF)
...
endif()
foreach
foreach (i IN LISTS num_list)
message(STATUS ${i})
endforeach ()
list
# test1添加到变量O_LIST中,以列表的形式存储
list(APPEND O_LIST test1)
# test2添加到变量O_LIST中,以列表的形式存储
list(APPEND O_LIST test2)
# test3添加到变量O_LIST中,以列表的形式存储
list(APPEND O_LIST test3)
# 将O_LIST的length值设置到LEN中
list(LENGTH O_LIST LEN)
project
# 定义project名称
project(CMakeModule)
# 这样${PROJECT_NAME}的值就是CMakeModule了,默认值为Project
${PROJECT_NAME}
install
# 安装普通文件到指定目录,将hello.h拷贝到/usr/local/include下
install(FILES hello.h DESTINATION /usr/local/include)
# 安装目录到指定目录,将SharedLib目录及其子文件拷贝到/usr/local/dir下
install(DIRECTORY SharedLib DESTINATION /usr/local/dir)
# 只将SharedLib下的文件拷贝到/usr/local/dir下
install(DIRECTORY SharedLib/ DESTINATION /usr/local/dir)
# 安装目标文件到指定目录,这里是将libsharedHello.so安装到/usr/local/lib下
# 目标文件主要为静态库文件,共享库文件,可执行二进制文件等
install(TARGETS sharedHello DESTINATION /usr/local/lib)
function
# 定义函数,在内部使用arg1,需要以${arg1}这样的形式
function(<name> [arg1 [arg2 [arg3 ...]]])
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
...
endfunction()
function(add_cc_executable EXECUTABLE_NAME EXECUTABLE_SOURCES)
add_executable(${EXECUTABLE_NAME} ${EXECUTABLE_SOURCES})
target_link_libraries(${EXECUTABLE_NAME} handy_s)
target_include_directories(${EXECUTABLE_NAME} PUBLIC ${PROJECT_SOURCE_DIR})
install(TARGETS ${EXECUTABLE_NAME} DESTINATION ${CMAKE_INSTALL_NAME_DIR})
endfunction()
add_definitions
add_definitions(-DLINUX)
在代码中
#ifdef LINUX
...
#endif
就处于可执行状态
aux_source_directory
# 将dir目录下(不包括子目录)所有的源文件(不包括头文件)添加到变量variable中
aux_source_directory(<dir> <variable>)
# 将当前目录的所有源文件添加到SRCS变量中
aux_source_directory(. SRCS)
link_directories
LD_LIBRARY_PATH 用于指定除了默认的共享库路径外的其它路径
比如寻找libxxx.so,如果该文件不在省缺目录/usr/lib和/usr/local/lib下,就需要将libxxx.so的目录添加到LD_LIBRARY_PATH下
link_directories(directory1 directory2 ...)
就是将directory1 directory2添加到LD_LIBRARY_PATH下的cmake命令
find_file find_path find_library
# 查找xxx.yy文件的完整路径,并将(路径/xxx.yy)赋值给VAR
find_file(<VAR> xxx.yy [path1 path2 ...])
find_file(FLAME_CFG flame.cfg /steven/file)
FLAME_CFG的值为/steven/file/flame.cfg
# 查找xxx.h头文件的路径,并将(路径)赋值给VAR,优先去CMAKE_INCLUDE_PATH下搜索,再去默认路径下搜索,最后去path1 path2...下搜寻
# 如果不希望搜索CMAKE_INCLUDE_PATH,可以指定NO_CMAKE_PATH
# 如果不希望搜索默认路径,可以指定NO_DEFAULT_PATH
find_path(<VAR> xxx.h [path1 path2 ...])
find_path(CPIO cpio.h /steven/include NO_DEFAULT_PATH)
CPIO的值为/steven/include/cpio.h
# 查找libxxx.so库的路径,并将(路径/libxxx.so)赋值给VAR,优先去CMAKE_LIBRARY_PATH下搜索,再去默认路径下搜索,最后去path1 path2...下搜寻
# 如果不希望搜索CMAKE_LIBRARY_PATH,可以指定NO_CMAKE_PATH
# 如果不希望搜索默认路径,可以指定NO_DEFAULT_PATH
find_library(<VAR> libxxx.so [path1 path2 ...])
find_library(HGFS_LIB libhgfs.so /steven/lib)
HGFS_LIB的值为/steven/lib/libhgfs.so
add_custom_command vs add_custom_target
# 自定义目标,该目标实质上并不生成可执行文件(可以理解为生成了不可见的可执行文件),而只是为了执行`构建时候设置的命令`,如果目标有依赖,则优先执行依赖的那些目标
add_custom_target(Name [ALL] [COMMAND command2 [args2...] ...] [DEPENDS depend depend depend ... ])
# 自定义命令,一般只是创建了命令,而不会自动执行
add_custom_command(OUTPUT output1 COMMAND command1[ARGS] [args1...] [COMMAND command2 [ARGS] [args2...] ...] [DEPENDS[depends...]]
# 只通过add_custom_target执行命令
add_custom_target(mkJP ALL /bin/mkdir Japan)
默认不会执行目标文件,需要使用命令 cmake --target <Name>执行。但是如果指定了ALL参数,那么在生成上述目标文件时也会执行目标文件
# 只通过add_custom_command执行命令
add_custom_command(TARGET sharedHello COMMAND /bin/mkdir China)
# add_custom_command配合add_custom_target执行文件
add_custom_command(OUTPUT mkItaly COMMAND /bin/mkdir Italy)
add_custom_target(mkEU ALL COMMAND /bin/mkdir Germany DEPENDS mkItaly)
include_directories vs target_include_directories
# 具体参考了https://stackoverflow.com/a/51968659
# 相同点:
比如log.h的完整路径是/usr/local/include/Log/log.h
在CMakeList.txt中添加
include_directories(/usr/local/include)
或者
target_include_directories(xxx /usr/local/include)
这样在代码中可以直接这样调用
#include "Log/log.h"
# 不同点:
include_directories(../include ${SOME_OTHER_PATH}/include)
add_library(math SHARED ${MATH_SOURCES})
target_include_directories(math math_include)
add_executable(calculator ${MYCALCULATOR_SOURCES})
target_include_directories(calculator calc_include)
1. 在这里math是一个共享库文件,calculator是一个可执行文件,通过include_directories添加的
"../include"和"${SOME_OTHER_PATH}/include"目录对math和calculator都是可见的
2. 通过target_include_directories添加的"math_include"只对math可见
3. 通过target_include_directories添加的"calc_include"只对calculator可见
SHARED lib
# 扩展名为libxxx.so或xxx.dll
|-SharedLib
|-CMakeList.txt
|-hello.h
|-hello.cpp
cmake_minimum_required(VERSION 3.5)
project (SharedLib)
set(SRC hello.cpp)
# 生成链接文件,这里是设置库的类型为SHARED和名称为sharedHello
add_library(sharedHello SHARED ${SRC})
# 头文件安装在/home/vaad/CPros/CMakeModule/include
INSTALL(FILES hello.h DESTINATION /home/vaad/CPros/CMakeModule/include)
# 库文件安装在/home/vaad/CPros/CMakeModule/lib下
INSTALL(TARGETS sharedHello LIBRARY DESTINATION /home/vaad/CPros/CMakeModule/lib)
STATIC lib
# 扩展名为libxxx.a或xxx.lib
|-CMakeModule
|-StaticLib
|-CMakeList.txt
|-hello.h
|-hello.cpp
|-CMakeList.txt
|-main.cpp
# StaticLib-CMakeList.txt
cmake_minimum_required(VERSION 3.5)
project (StaticLib)
set(SRCS hello.cpp)
# 生成链接文件,这里是设置库的类型为STATIC和名称为staticHello
add_library(staticHello STATIC ${SRCS})
# CMakeModule-CMakeList.txt
cmake_minimum_required(VERSION 3.5)
project(CMakeModule)
set(CMAKE_CXX_STANDARD 14)
add_executable(CMakeModule main.cpp)
# 执行StaticLib下的CMakeList.txt(StaticLib下必须有CMakeList.txt文件)
# 在这里StaticLib/CMakeList.txt会生成静态库文件,并将该库文件libstaticHello.a放在了build/StaticLibOut目录下
add_subdirectory(StaticLib StaticLibOut)
# 然后将静态库链接至CMakeModule
target_link_libraries(CMakeModule staticHello)
INTERFACE|PUBLIC|PRIVATE
# sub CMakeList.txt
target_include_directories(target1 INTERFACE|PUBLIC|PRIVATE item1)
PRIVATE 表示item1可以被target1使用,不可以被其它依赖target1的模块使用
INTERFACE 表示item1不可以被target1使用,可以被其它依赖target1的模块使用
PUBLIC 表示item1可以被target1使用,也可以被其它依赖target1的模块使用
# CMakeList.txt
target_link_libraries(target2 INTERFACE|PUBLIC|PRIVATE target1)
如果这里target2想使用target1#item1属性,
那么item1的修饰符只能是INTERFACE或PUBLIC,
并且target1的修饰符只能是PRIVATE或PUBLIC