CMake 基础学习

CMake 常用变量

使用 ${}进行变量的引用。例如:message(${Hello_VERSION}),
Hello为工程名。CMake提供了很多有用的变量。以下仅列举常用的变量:

CMAKE_BINARY_DIR:
构建树的顶层路径

CMAKE_COMMAND:
指向CMake可执行文件的完整路径

CMAKE_CURRENT_BINARY_DIR:
当前正在被处理的二进制目录的路径。

CMAKE_CURRENT_SOURCE_DIR:
指向正在被处理的源码目录的路径。

CMAKE_HOME_DIRECTORY:
指向源码树顶层的路径。

CMAKE_PROJECT_NAME:
当前工程的工程名。

CMAKE_ROOT:
CMake的安装路径。

CMAKE_SOURCE_DIR:
源码树的顶层路径。

CMAKE_VERSION:
cmake的完整版本号。

PROJECT_BINARY_DIR:
指向当前编译工程构建的全路径。

<PROJECT-NAME>_BINARY_DIR:
指向当前编译工程构建的全路径。

<PROJECT-NAME>_SOURCE_DIR:
指向构建工程的全路径。

PROJECT_SOURCE_DIR:
指向构建工程的全路径。

PROJECT_NAME:
project命令传递的工程名参数。

<PROJECT-NAME>_VERSION:
项目的完整版本号。

CMake常用命令

cmake_minimum_required 和 project

设置项目要求的CMake最低版本号 和 设置项目名称

# 设置cmake 版本信息
cmake_minimum_required(VERSION 3.16)

# 设置 项目名称
project(demo)

add_library

添加一个库文件

add_library(<name> [STATIC | SHARED | MODULE]
            [EXCLUDE_FROM_ALL]
            [source1] [source2 ...])

<name> : 表示库文件的名字
[STATIC | SHARED | MODULE] : 生成的库文件类型
STATIC 静态库,在链接其他目标时使用
SHARED 动态链接库,运行时加载
MODULE 不会被链接到其它目标中,但是可能会在运行时使用dlopen-系列的函数动态链接

例:
# create lib , 在当前cmake 中 创建一个lib,名称为model_login,SHARED 动态库 ,后面为源文件列表
add_library(model_login SHARED
        lib_login_model/LoginService.cpp
        utils/common_utils.cpp)

add_library(lib_model_a model_utils.cpp)
// 设置别名
add_library(sub::modelA ALIAS lib_model_a) 

add_subdirectory

向构建中添加子目录(子目录中可以包含另一个cMakeLists.txt)。命令格式为

add_subdirectory(source_dir [binary_dir]
                 [EXCLUDE_FROM_ALL])


source_dir 需要包含的子目录。
binary_dir 指定中间二进制和目标二进制存放的位置
EXCLUDE_FROM_ALL 编译过程中排除的文件

aux_source_directory

查找目录中的所有源文件

aux_source_directory(<dir> <variable>)
查找指定目录dir中所有源文件的名称,并将列表存储在提供的variable中
例:
aux_source_directory(. DIR_SRCS)
add_executable(${APP_NAME} ${DIR_SRCS})

target_link_directories

target_link_directories(<target> [BEFORE]
  <INTERFACE|PUBLIC|PRIVATE> [items1...]
  [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])

指定链接器在链接给定目标时应在其中搜索库的路径

<target>: add_library 创建的target名称 或者 add_executable 创建的target名称

target_link_libraries([TARGET_NAME] [链接库名字])  # 按名字添加
target_link_directories([链接库目录])  # 按目录添加

target_include_directories

target_include_directories(<target> [SYSTEM] [BEFORE]
  <INTERFACE|PUBLIC|PRIVATE> [items1...]
  [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])

指定在编译给定目标时要使用的包含目录
# 添加头文件的路径,以便查找到头文件
<target>: add_library 创建的target名称 或者 add_executable 创建的target名称
例:
target_include_directories(lib_model_a PUBLIC ${PROJECT_SOURCE_DIR})

find_library

查找一个库文件.
该命令用来查找一个库文件。一个名为<VAR>的cache条目会被创建来存储该命令的结果。如果找到了该库文件,那么结果会存储在该变量里,并且搜索过程将不再重复,除非该变量被清空。如果没有找到,结果变量将会是<VAR>-NOTFOUND,并且在下次使用相同变量调用find_library命令时,搜索过程会再次尝试。

find_library(<VAR> name1 [path1 path2 ...])

例如:
link_directories(....) // 动态链接库或静态链接库的搜索路径
find_library(Foundation Foundation)

add_definitions

// 为源文件的编译添加由-D引入的宏定义。命令格式为:
add_definitions(-DFOO -DBAR ...)

add_dependencies

使顶级目标依赖于其他顶级目标,以确保它们在该目标之前构建。这里的顶级目标是由add_executable,add_library或add_custom_target命令之一创建的目标

add_library(model_login SHARED
        lib_login_model/LoginService.cpp
        utils/common_utils.cpp)
add_executable(demo main.cpp config.h.in Simple.cpp)
add_dependencies(demo model_login)

add_executable

添加一个可执行文件

# create exe
add_executable(demo main.cpp config.h.in Simple.cpp)

target_link_libraries

将给定的库链接到一个目标上

target_link_libraries(<target> ... <item>... ...)

例:
target_link_libraries(demo
        model_login)

include_directories

将给定的目录添加到编译器用于搜索包含文件的目录。相对路径则相对于当前源目录。命令格式为:

include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])

例:
// 指定头文件的搜索路径
include_directories(
  ${CMAKE_CURRENT_SOURCE_DIR}
  ${CMAKE_CURRENT_SOURCE_DIR}/cocos
  ${CMAKE_CURRENT_SOURCE_DIR}/cocos/platform
  ${CMAKE_CURRENT_SOURCE_DIR}/extensions
  ${CMAKE_CURRENT_SOURCE_DIR}/external
)

message

向用户显示消息。命令格式为:

message([<mode>] "message to display" ...)
参数说明:
mode:
可选的值为none,STATUS,WARNING,AUTHOR_WARNING,SEND_ERROR,FATAL_ERROR,DEPRECATION。
例:
message(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR})

set

将一个CMAKE变量设置为给定值。命令格式为:

set(<variable> <value>... [PARENT_SCOPE])

例:
set(COCOS2D_ROOT ${CMAKE_SOURCE_DIR}/cocos2d)

set(CMAKE_CXX_FLAGS)

传递FLAGS给C++编译器:设置CMAKE_CXX_FLAGS变量

set(CMAKE_CXX_COMPILER      "clang++" )         # 显示指定使用的C++编译器
set(CMAKE_CXX_FLAGS   "-std=c++11")             # c++11
set(CMAKE_CXX_FLAGS   "-g")                     # 调试信息
set(CMAKE_CXX_FLAGS   "-Wall")                  # 开启所有警告
set(CMAKE_CXX_FLAGS_DEBUG   "-O0" )             # 调试包不优化
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG " )   # release包优化


CMAKE_CXX_FLAGS 是CMake传给C++编译器的编译选项,通过设置这个值就好比 g++ -std=c++11 -g -Wall
CMAKE_CXX_FLAGS_DEBUG 是除了CMAKE_CXX_FLAGS外,在Debug配置下,额外的参数
CMAKE_CXX_FLAGS_RELEASE 同理,是除了CMAKE_CXX_FLAGS外,在Release配置下,额外的参数


configure_file

将文件复制到其他位置并修改其内容。命令格式为

configure_file(<input> <output>
               [COPYONLY] [ESCAPE_QUOTES] [@ONLY]
               [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])


例:
# 添加config 配置文件 版本信息 
set(demo_VERSION_MAJOR 1)
set(demo_VERSION_MINOR 0)
set(demo_VERSION_PATCH 10)
set(demo_VERSION_BUILD 100)

set(CONFIG_VERSION "${demo_VERSION_MAJOR}.${demo_VERSION_MINOR}.${demo_VERSION_PATCH}.${demo_VERSION_BUILD}")


configure_file(${PROJECT_SOURCE_DIR}/config.h.in ${PROJECT_BINARY_DIR}/config.h)

config.h.in 文件如下:


#cmakedefine USE_MYMATH


#ifndef DEMO_CONFIG_H
#define DEMO_CONFIG_H




const char* version = "${CONFIG_VERSION}";



#endif //DEMO_CONFIG_H

file

文件操作相关的命令。命令格式为:

file(WRITE <filename> <content>...)
file(APPEND <filename> <content>...)
file(READ <filename> <variable>
     [OFFSET <offset>] [LIMIT <max-in>] [HEX])
file(STRINGS <filename> <variable> [<options>...])
file(<MD5|SHA1|SHA224|SHA256|SHA384|SHA512> <filename> <variable>)
file(GLOB <variable>
     [LIST_DIRECTORIES true|false] [RELATIVE <path>]
     [<globbing-expressions>...])
file(GLOB_RECURSE <variable> [FOLLOW_SYMLINKS]
     [LIST_DIRECTORIES true|false] [RELATIVE <path>]
     [<globbing-expressions>...])
file(RENAME <oldname> <newname>)
file(REMOVE [<files>...])
file(REMOVE_RECURSE [<files>...])
file(MAKE_DIRECTORY [<directories>...])
file(RELATIVE_PATH <variable> <directory> <file>)
file(TO_CMAKE_PATH "<path>" <variable>)
file(TO_NATIVE_PATH "<path>" <variable>)
file(DOWNLOAD <url> <file> [<options>...])
file(UPLOAD   <file> <url> [<options>...])
file(TIMESTAMP <filename> <variable> [<format>] [UTC])
file(GENERATE OUTPUT output-file
     <INPUT input-file|CONTENT content>
     [CONDITION expression])
file(<COPY|INSTALL> <files>... DESTINATION <dir>
     [FILE_PERMISSIONS <permissions>...]
     [DIRECTORY_PERMISSIONS <permissions>...]
     [NO_SOURCE_PERMISSIONS] [USE_SOURCE_PERMISSIONS]
     [FILES_MATCHING]
     [[PATTERN <pattern> | REGEX <regex>]
      [EXCLUDE] [PERMISSIONS <permissions>...]] [...])
file(LOCK <path> [DIRECTORY] [RELEASE]
     [GUARD <FUNCTION|FILE|PROCESS>]
     [RESULT_VARIABLE <variable>]
     [TIMEOUT <seconds>])

例:
# 查找src目录下所有以hello开头的文件并保存到SRC_FILES变量里
file(GLOB SRC_FILES "src/hello*")
# 递归查找
file(GLOB_RECURSE SRC_FILES "src/hello*")

完整CmakeList.txt 文件

工程结构如下:

├── 
├── lib_login_model/
│   ├── LoginService.cpp
│   ├── LoginService.h
├── lib_modelA/
│   ├── CMakeLists.txt
│   ├── model_utils.cpp
│   ├── model_utils.h
├── uils/
│   ├── common_utils.cpp
│   ├── common_utils.h
├── CMakeLists.txt
├── ServiceResult.h

CmakeList配置文件如下:

cmake_minimum_required(VERSION 3.16)

# set the project name
project(demo)

# 设置 C++ 14
set(CMAKE_CXX_STANDARD 14)


# create lib , 在当前cmake 中 创建一个lib
add_library(model_login SHARED
        lib_login_model/LoginService.cpp
        utils/common_utils.cpp)


# 添加头文件的路径,以便查找到头文件
target_include_directories(model_login PRIVATE ${PROJECT_SOURCE_DIR}/lib_login_model ${PROJECT_SOURCE_DIR}/utils)


# 添加config 配置文件
set(demo_VERSION_MAJOR 1)
set(demo_VERSION_MINOR 0)
set(demo_VERSION_PATCH 10)
set(demo_VERSION_BUILD 100)

set(CONFIG_VERSION "${demo_VERSION_MAJOR}.${demo_VERSION_MINOR}.${demo_VERSION_PATCH}.${demo_VERSION_BUILD}")


configure_file(${PROJECT_SOURCE_DIR}/config.h.in ${PROJECT_BINARY_DIR}/config.h)


# 添加子目录, 子目录中有另外一个cMakeLists.txt文件 lib_modelA
#include_directories ("${PROJECT_SOURCE_DIR}/lib_modelA")
add_subdirectory(lib_modelA)


option (USE_MYMATH
        "Use tutorial provided math implementation" OFF)


# ADD_DEFINITIONS 添加 编译宏

ADD_DEFINITIONS(-DENABLE_REALEASE)



# create exe
add_executable(demo main.cpp config.h.in Simple.cpp)

target_include_directories(demo PUBLIC ${PROJECT_BINARY_DIR})
target_include_directories(demo PUBLIC ${PROJECT_SOURCE_DIR})

target_link_libraries(demo
        model_login)

target_link_libraries(demo
        sub::modelA)
  

lib 库的配置文件

cmake_minimum_required(VERSION 3.16)

# project 貌似设置或者不设置都可以
project(model_a)

add_library(lib_model_a model_utils.cpp)
add_library(sub::modelA ALIAS lib_model_a)


target_include_directories(lib_model_a PUBLIC ${PROJECT_SOURCE_DIR})

参考资料:
CMake 官网

CMake学习

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容