[C++] CMake简介

1. CMake简介

  • CMake 是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的编译过程;他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。
  • CMake是一种跨平台编译工具,比make更为高级,使用起来方便得多。CMake主要是编写CMakeLists.txt文件,然后使用cmake命令将CMakeLists.txt文件转化为make所需要的makefile文件,然后用make命令编译源码生成可执行程序或共享库。

2. CMakeList.txt常用命令简介

  • cmake_minimum_required(VERSION3.5.1) 指定cmake版本;
cmake_minimum_required(VERSION 2.6)
  • project(marianCXXC) 指定项目的名称,一般和项目的文件夹名称对应;
project(module_da_where_what)
  • include_directories(marian_SOURCE_DIR/src) 引入头文件;
list(APPEND include_list ${work_home}/include)
list(APPEND include_list ${sug_da_lib_include})
  • aux_source_directory(<dir> <variable>) 用于将dir目录下的所有源文件的名字保存在变量variable中;
aux_source_directory(./src ${hello_src})
  • set(<variable> <value> [[CACHE <type><docstring> [FORCE]] | PARENT_SCOPE]) 用于设置变量variable的值为value。如果指定了CACHE变量将被放入Cache中;
set(CMAKE_CXX_COMPILER "/usr/local/gcc/bin/c++")
  • option 选项,让你可以根据选项值进行条件编译;
option(TARGET_DEBUG_MODE "xxxxx" OFF)
  • unset 用于移除变量variable。如果指定CACHE变量将被从Cache中移除;

  • add_executable(<name> [WIN32] [MACOSX_BUNDLE][EXCLUDE_FROM_ALL] source1 source2 … sourceN) 添加要编译的可执行文件,用于从一组源文件source1 source2 ... source N编译出一个可执行文件且命名为name;

include_directories(${CMAKE_CURRENT_LIST_DIR}/include)
link_directories(${CMAKE_CURRENT_LIST_DIR}/lib)
aux_source_directory(${CMAKE_CURRENT_LIST_DIR}/src ${hello_src})
add_executable(${PROJECT_NAME} ${hello_src})
target_link_libraries(${PROJECT_NAME} util)
  • target_link_libraries() 添加可执行文件所需要的库;链接所有动态、静态库
target_link_libraries(${target} xxx ${library_list})
  • add_subdirectory() 用于添加一个需要进行构建的子目录;
  • message(STATUS"Projectname:${PROJECT_NAME}") 打印消息;
message("MODUEL WW INCLUDE")
forearch(dir ${include_list})
    message(STATUS ${dir})
endforeach()
  • add_dependencies(target-name depend-target1 depend-target2 …) 用于指定某个目标(可执行文件或者库文件)依赖于其他的目标。这里的目标必须是add_executable, add_library, add_custom_target命令创建的目标;

  • find_path(<VAR> name1 [path1 path2 …]) 用于查找包含文件name1的路径,如果找到则将路径保存在VAR中,如果没有找到则结果为<VAR>-NOTFOUND。

find_library(my_ceres libceres.so /home/wenhaolun/ubuntu18.04_lib/ceres/)
  • find_library(<VAR> name1 [path1 path2 …]) 用于查找库文件name1的路径,如果找到则将路径保存在VAR中;

  • find_package() 查找动态库文件;

  • add_library(common STATIC util.cpp) 生成静态库;add_library(common SHARED util.cpp) 生成动态库或共享库;

add_library(test_a STATIC ${source_list})
  • add_definitions 向C/c++编译器添加-D定义;例如:add_definitions(-DENABLE_DEBUG -DABC),参数之间用空格分割;如果你的代码中定义了#ifdef ENABLE_DEBUG #endif 这个代码就会生效;如果要添加其他的编译器开关,可以通过CMAKE_C_FLAGS变量和CMAKE_CXX_FLAGS变量设置;

  • exec_program(executable [directory in which to run] ...) 在CMakeLists.txt处理过程中执行命令,并不会在生成的makefile中执行;

  • file 指令,文件操作命令;

file(WRITE filename "message to write"...)  WRITE将一则信息写入文件filename中,如果该文件存在,它会覆盖它;如果不存在,它会创建该文件;
file(APPEND filename "message to write"...) 如同WRITE,区别在于它将信息内容追加到文件末尾;
file(READ filename variable ...)  读取文件内容并存入变量中;
file(GLOB test_source_list "${work_home}/test/*.cpp")
  • include 指令,用来载入CMakeLists.txt文件,也用于载入预定义的cmake模块;

  • install 指令,用于安装模块;它可以用来安装很多内容,可以包括目标二进制、动态库、静态库以及文件、目录、脚本等;

  • 控制指令:
(1)if指令,if  ... else ... endif
(2)while指令,while(condition) ... endwhile(condition)
(3)forearch指令,forearch(loop_var arg1 arg2 ...) ... endforearch(loop_var)
  • list 指令,用于创建;分隔的列表,常用子命令:APPEND,INSERT,FIND
list(APPEND include_list ${work_home}/include)
  • get_filename_component 指令:获取文件路径的内容
get_filename_component(test ${origin_test} NAME)
  • string 指令:用于处理字符串
string(REGEX_REPLACE "(.*).cpp$" "\\1" target ${test})

3. 预定义变量

  • PROJECT_SOURCE_DIR 工程的根目录;
  • PROJECT_BINARY_DIR 运行cmake命令的目录,通常是${PROJECT_SOURCE_DIR}/build;
  • PROJECT_NAME 返回通过project命令定义的项目名称;
  • CMAKE_CURRENT_SOURCE_DIR 当前处理的CMakeLists.txt所在路径;
  • CMAKE_CURRENT_BINARY_DIR target编译目录;
  • CMAKE_CURRENT_LIST_DIR CMakeLists.txt的完整路径;
  • CMAKE_CURRENT_LIST_LINE 当前所在的行;
  • CMAKE_MODULE_PATH 定义自己的cmake模块所在的路径;
  • EXECUTABLE_OUTPUT_PATH 重新定义目标二进制可执行文件的存放位置;
  • LIBRARY_OUTPUT_PATH 重新定义目标链接库文件的存放位置;
  • CMAKE_C_FLAGS 设置C编译选项;
  • CMAKE_CXX_FLAGS 设置c++编译选项;

4. 简单例子

参考资料

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

推荐阅读更多精彩内容