[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中;
aux_source_directory(./src ${hello_src})
  • set( [[CACHE [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( [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( name1 [path1 path2 …]) 用于查找包含文件name1的路径,如果找到则将路径保存在VAR中,如果没有找到则结果为-NOTFOUND。

find_library(my_ceres libceres.so /home/wenhaolun/ubuntu18.04_lib/ceres/)
  • find_library( 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. 简单例子

  • hello-headers例子
    https://github.com/ttroy50/cmake-examples/tree/master/01-basic/B-hello-headers
  • 静态链接库例子
    https://github.com/ttroy50/cmake-examples/tree/master/01-basic/C-static-library
  • 动态链接库
    https://github.com/ttroy50/cmake-examples/blob/master/01-basic/D-shared-library/CMakeLists.txt
  • install安装命令
    https://github.com/ttroy50/cmake-examples/blob/master/01-basic/E-installing/CMakeLists.txt
  • 设置编译类型
    https://github.com/ttroy50/cmake-examples/blob/master/01-basic/F-build-type/CMakeLists.txt
  • 设置编译参数
    https://github.com/ttroy50/cmake-examples/blob/master/01-basic/G-compile-flags/CMakeLists.txt
  • 第三方库依赖
    https://github.com/ttroy50/cmake-examples/blob/master/01-basic/H-third-party-library/CMakeLists.txt
  • 设置c++编译标准
    https://github.com/ttroy50/cmake-examples/tree/master/01-basic/L-cpp-standard
  • 子项目
    https://github.com/ttroy50/cmake-examples/tree/master/02-sub-projects
  • protobuf代码生成
    https://github.com/ttroy50/cmake-examples/blob/master/03-code-generation/protobuf/CMakeLists.txt
  • 单元测试
    https://github.com/ttroy50/cmake-examples/blob/master/05-unit-testing/boost/CMakeLists.txt
  • c/c++库管理
    https://github.com/ttroy50/cmake-examples/tree/master/07-package-management

参考资料

  • CMakeLists.txt 语法介绍与实例演练
    https://blog.csdn.net/afei__/article/details/81201039
  • 【使用CMake组织C++工程】2:CMake 常用命令和变量
    https://elloop.github.io/tools/2016-04-10/learning-cmake-2-commands
  • CMakeFile命令之file
    https://blog.csdn.net/fuyajun01/article/details/8880121
  • CMakeList.txt相关例子git:https://github.com/ttroy50/cmake-examples

你可能感兴趣的:([C++] CMake简介)