CMake日常配置使用
概述
最近在搞一个C/C++的库,以前编译都会通过makefile来组织库和代码之前的依赖关系,对于简单点的依赖,写起来还好,但项目编译的变得复杂的时候,写起来就比较累了,所以就换成Cmake的编译方式去实现这个功能,你会发现事情变得简单了。 CMake是一种跨平台编译工具,比make更为高级,使用起来要方便得多。CMake主要是编写CMakeLists.txt文件,然后用cmake命令将CMakeLists.txt文件转化为make所需要的makefile文件,简单点说就是cmake命令会根据CMakeLists.txt的配置来生成make命令所需要makefile文件。
接下来我会把CMakeLists.txt日常使用的配置记录下来,命令不区分大小写,变量区分大小写,对于以下内容如理解有不对的地方请指出。
设置CMake命令运行的最低版本
cmake_minimum_required(VERSION 2.8)
当前最新版本为3.14
设置项目名称
project(CMake_Demo)
set命令给对应的变量赋值
//赋值
set(VAR "abc")
//访问变量
VAR = ${VAR}
使用语法 ${Name} 来访问名字为 Name 的变量的值。在字符串中也可以使用 ${Name} 来访问变量的值
unset移除变量
unset(VAR)
用于在执行CMake命令时,打印执行信息
message 打印信息
message ("VAR = ${VAR}")
用于在执行CMake命令时,打印执行信息
条件控制和循环结构
set(RELEASE TRUE)
if(RELEASE)
message("RELEASE = ${VAR}")
else()
message("DEBUG = ${VAR}")
endif()
对于 if(string) 来说:
如果 string 为(不区分大小写)1、ON、YES、TRUE、Y、非 0 的数则表示真
如果 string 为(不区分大小写)0、OFF、NO、FALSE、N、IGNORE、空字符串、以 -NOTFOUND 结尾的字符串则表示假
如果 string 不符合上面两种情况,则 string 被认为是一个变量的名字。变量的值为第二条所述的各值则表示假,否则表示真。
此策略(Policy)在 CMake2.8.0 才被引入
find_package命令
find_package(Threads REQUIRED)
find_package可以根据cmake内置的.cmake的脚本去找相应的库的模块,这样子就可以使用linux内置的多进程库了
include命令
include(file1 [OPTIONAL])
include(module [OPTIONAL])
//编译引入的第三方库,具体请看ExternalProject_Add命令
include(ExternalProject)
可以指定载入一个文件,如果定义的是一个模块,那么将在CMAKE_MODULE_PATH中搜索这个模块并载入。
include_directories
//"include_directories"用来指定build时需要的头文件路径
//"PROJECT_BINARY_DIR"是内置变量,表示工程编译的目录,也就是--prefix指定的目录
include_directories("${PROJECT_BINARY_DIR}" "${include_dir}")
aux_source_directory命令
aux_source_directory(. DIR_SRCS)
用于将 dir 目录下的所有源文件的名字保存在变量 DIR_SRCS中
add_executable命令
add_executable(demo ${COMMON_SRCS} ${SRCS})
用于指定从一组源文件 COMMON_SRCS SRCS … sourceN 编译出一个可执行文件且命名为 demo
add_library命令
add_library(demo ${COMMON_SRCS} ${SRCS})
用于指定从一组源文件 COMMON_SRCS SRCS … sourceN 编译出一个库文件且命名为 demo
add_dependencies命令
add_dependencies(demo depend-target1 depend-target2)
用于指定某个目标(可执行文件或者库文件)依赖于其他的目标。这里的目标必须是 add_executable、add_library、add_custom_target 命令创建的目标
target_link_libraries命令
target_link_libraries(demo SHARED item1 item2...)
用于指定 demo需要链接item1 item2…。这里 demo必须已经被创建,链接的 item 可以是已经存在的 target(依赖关系会自动添加) demo
C 编译标志相关变量
CMAKE_C_FLAGS
CMAKE_C_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO]
C++ 编译标志相关变量
CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO]
CMAKE_C_FLAGS 或CMAKE_CXX_FLAGS 可以指定编译标志
CMAKE_C_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO]或 CMAKE_CXX_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO] 则指定特定构建类型的编译标志,这些编译标志将被加入到 CMAKE_C_FLAGS 或 CMAKE_CXX_FLAGS 中去,例如,如果构建类型为 DEBUG,那么 CMAKE_CXX_FLAGS_DEBUG 将被加入到 CMAKE_CXX_FLAGS中去
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DLOG_DEBUG -g")
ExternalProject_Add引用第三方库
set(createSqliteManifestScript "${CMAKE_CURRENT_SOURCE_DIR}/prepare_sqlite.sh")
ExternalProject_Add(libsqlite
PREFIX "${CMAKE_BINARY_DIR}/deps"
GIT_REPOSITORY "https://github.com/mackyle/sqlite"
#GIT_REPOSITORY "$ENV{HOME}/dev/github/sqlite"
GIT_TAG "version-3.26.0"
CONFIGURE_COMMAND ${createSqliteManifestScript} && ./configure
BUILD_IN_SOURCE 1
BUILD_COMMAND make
INSTALL_COMMAND ""
TEST_COMMAND ""
UPDATE_COMMAND ""
GIT_SHALLOW 1
GIT_PROGRESS 1
)
ExternalProject_Get_Property(libsqlite SOURCE_DIR)
set(SQLITE3_INCLUDE_DIR ${SOURCE_DIR})
set(SQLITE3_LIBRARY_DIR ${SOURCE_DIR}/.libs)
add_library(sqlite IMPORTED STATIC GLOBAL)
add_dependencies(sqlite libsqlite)
set_target_properties(sqlite PROPERTIES IMPORTED_LOCATION "${SQLITE3_LIBRARY_DIR}/libsqlite3.a")
最后链接的时候执行以下命令,就可以把sqlite加入到demo库中
target_link_libraries(demo sqlite)
总结
有更多的命令就没有时间去罗列出来了,如果平时自己需要用到哪个命令,大家最好上去官网查看更多用法