cmake使用教程

cmake 教程

cmake 与make

make是一个工具,它控制可执行程序和程序源文件中非源码文件的生成。“make” 工具需要清楚地知道如何构建程序。通过"makefile"文件知晓如何构建你的程序。这个文件列出了所有非源码文件以及如何由别的文件来计算它。当你编写一个程序时,你应该为它写一个makefile文件,这样才有可能通过make来构建你的程序。简而言之,就是自动化项目编链过程,及控制生成最终的目标文件。
CMake支持跨平台Make。cmake辨别使用哪种编译器去编译给出的源码种类,为每一种类型的目标平台按照正确的顺序调用命令。
cmake与make对比具有以下优点:

  • 自动发现跨平台系统库。
  • 自动发现和管理的工具集。
  • 更容易将文件编译进共享库,以一种平台无关的方式或者比make更容易使用的生成方式。
    CMake 比 make更复杂。从长远来看,最好能够学会使用它。

CMake 简介

基本操作流程

cmake ..   # 根据CMakeLists.txt生成Makefile文件。保证在CMakeLists.txt所在目录。  
make       # make 命令

CMake的执行就是这么简单,其难点在于如何编写CMakeLists.txt文件。

CMakeLists.txt

CMake 的所有的语句都写在一个叫 CMakeLists.txt 的文件中。当 CMakeLists.txt 文件确定后,可以用 ccmake 命令对相关 的变量值进行配置。这个命令必须指向 CMakeLists.txt 所在的目录。配置完成之后,应用 cmake 命令生成相应的 makefile(在Unix like系统下) 或者 project文件(指定用window下的相应编程工具编译时)。

cmake 要求工程 主目录 和所有存放 源代码子目录 下都要编写 CMakeLists.txt 文件,注意大小写.

CMakeLists.txt(命令说明)

## 指定允许执行的最低 CMake 版本要求;不写会出警告 
cmake_minimum_required( VERSION 2.8 ) ## 指定项目的名称,通常对应于项目文件夹名 
project( SAMPLE_SINGLE_DIR ) ## 指定引用目录 
include_directories( include ) ## 自动构建源文件目录 
aux_source_directory( src DIR_SRCS ) ## 指定编译目标文件 
add_executable( demo ${DIR_SRCS} ) ## 添加链接库,相同于指定-l参数(此处没有用到) 
#TARGET_LINK_LIBRARIES(${PROJECT_NAME} m) #比如我们用到了libm.so(命名规则:lib+name+.so

CMakeLists.txt(命令)

介绍
  • 每个需要进行cmake操作的目录下面都必须存在文件CMakeLists.txt.
  • camke指令不区分大小写。
  • 变量使用**${}**方式取值,但是在IF控制语句中是直接使用变量名的。
  • 指令(参数1 参数2 …),参数使用括弧,参数之间使用空格或分号分开。
CMake中常用预定义变量
Cmake的预定义变量
  • PROJECT_SOURCE_DIR:工程根目录
  • PROJECT_BINARY_DIR:运行cmake命令的目录
  • CMAKE_INCLUDE_PATH:环境变量,非cmake变量
  • CMAKE_LIBRARY_PATH: 环境变量
  • CMAKE_CURRENT_SOURCE_DIR:当前处理的CMakeLists.txt文件所在路径
  • CMAKE_CURRENT_BINARY_DIR:target编译路径
CMake常用语法
  • CMAKE_MINIMUM_REQUIRED
    用于说明CMake最低版本要求。
cmake_minimum_required(VERSION 2.6)
  • PROJECT
    格式:
	PROJECT(name)
  • SET
    格式:
SET(VAR [VALUE] [CACHE TYPEDOCSTRING [FORCE]]])
例:
SET(CMAKE_INSTALL_PREFIX /usr/local)
  • ADD_SUBDIRECTORY
ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

用于向当前工程添加存放源文件的子目录。

  • INCLUDE_DERECTORIES(dir1 dir2)
    向工程添加多个特定的头文件搜索路径,路径之间用空格分隔。
INCLUDE_DIRECTORIES(/usr/include/thrift)
  • ADD_EXECUTABLE
ADD_EXECUTABLE(exename srcname)
- exename: 可执行文件名
- srcname: 生成可执行文件的源文件
- ADD_EXECUTABEL(hello ${LIST})
- SET(LIST main.c
           rpc/CRNode.cpp
           rpc/task.cpp)
  • ADD_LIBRARY
ADD_LIBRARY(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2)
- libname: 库文件名称;
- [SHARED|STATIC|MODULE]: 生成库文件类型(共享库/静态库)
- source1, ... , sourceN: 生成库所依赖的源文件

ADD_LIBRARY(hello SHARED &{LIST})
  • LINK_DIRECTORIES
LINK_DIRECTORIES(directory1 directory2)
添加外部库的搜索路径
  • TARGET_LINK_LIBRARIES
TARGET_LINK_LIBRARIES(target library1 library2 ..)
target: 目标文件
library1, ..., library2:链接外部库文件
  • MESSAGE
MESSAGE()
向终端输出用户定义的信息或变量值

-SET_TARGET_PROPERTIES

设置目标的某些属性,改变它们构建的方式。
格式:

SET_TARGET_PROPERTIES(target1 target2 ...
            PROPERTIES prop1 value1 prop2 value2 ...)

    1
    2

该指令为一个目标设置属性,语法是列出所有用户想要变更的文件,然后提供想要设置的值。用户可以使用任何想用的属性与对应的值,并在随后的代码中调用GET_TARGET_PROPERTY命令取出属性的值。
影响目标输出文件的属性PROPERTIES详述如下:
(1) PREFIX, SUFFIX
PREFIX覆盖了默认的目标名前缀(如lib);
SUFFIX覆盖了默认的目标名后缀(如.so)。
(2) IMPORT_PREFIX, IMPORT_PREFIX
与PREFIX, SUFFIX是等价的属性,但针对的是DLL导入库(即共享库目标)。
(3) OUTPUT_NAME
构建目标时,OUTPUT_NAME用来设置目标的真实名称。
(4) LINK_FLAGS
为一个目标的链接阶段添加额外标志。
LINK_FLAGS_< CONFIG >将为配置< CONFIG >添加链接标志,如DEBUG, RELEASE, MINSIZEREL, RELWITHDEBINFO。
(5) COMPILE_FLAGS
设置附加的编译器标志,在构建目标内的源文件时被用到。
(6) LINKER_LANGUAGE
改变链接可执行文件或共享库的工具。默认值是设置与库中文件相匹配的语言。
CXX与C是该属性的公共值。
(7) VERSION, SOVERSION
VERSION指定构建的版本号,SOVERSION指定构建的API版本号。
构建或安装时,如果平台支持符号链接,且链接器支持so名称,那么恰当的符号链接将会被创建。如果只指定两者中的一个,缺失的另一个假定为具有相同版本号。
例1:
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
例2:
SET_TARGET_PROPERTIES(hello PROPERTEIES VERSION 1.2 SOVERSION 1)
该指令用于控制版本,VERSION指代动态库版本,SOVERSION指代API版本。

参考文档

https://www.jianshu.com/p/c417e4ab8b30
https://blog.csdn.net/ajianyingxiaoqinghan/article/details/70229799
https://blog.csdn.net/ajianyingxiaoqinghan/article/details/70230902
https://blog.csdn.net/liukang325/article/details/52222023
https://blog.csdn.net/ajianyingxiaoqinghan/article/details/70338459

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面为您介绍 CMake 中的 macro 和 function。 ## 1. macro macro 是一种 CMake 的宏定义机制,可以将一组 CMake 命令封装起来,用一个名字来调用,从而简化 CMakeLists.txt 中的代码量。 macro 的定义格式如下: ``` macro(macro_name [arg1 [arg2 [arg3 ...]]) # command1 # command2 # ... endmacro() ``` 其中,macro_name 是宏的名称,arg1、arg2、arg3...是宏的参数列表,可以有 0 至多个参数。 下面是一个简单的例子,定义了一个名为 print_info 的宏,该宏接受两个参数,分别是 name 和 age,然后输出一条信息: ``` macro(print_info name age) message("Name: ${name}, Age: ${age}") endmacro() print_info("Alice" 18) ``` 执行上述代码后,输出结果为: ``` Name: Alice, Age: 18 ``` ## 2. function function 与 macro 的作用类似,也是将一组 CMake 命令封装起来,用一个名字来调用,但 function 有明确的返回值。function 的定义格式如下: ``` function(func_name [arg1 [arg2 [arg3 ...]]) # command1 # command2 # ... return(value) endfunction() ``` 其中,func_name 是函数的名称,arg1、arg2、arg3...是函数的参数列表,可以有 0 至多个参数。value 是函数的返回值。 下面是一个简单的例子,定义了一个名为 add 的函数,该函数接受两个参数,分别是 a 和 b,然后返回它们的和: ``` function(add a b) set(result ${a}+${b}) return(${result}) endfunction() set(sum 0) math(EXPR sum "${sum} + $(add(1 2))") message("Sum: ${sum}") ``` 执行上述代码后,输出结果为: ``` Sum: 3 ``` 在 function 中,我们使用 set 命令定义了一个变量 result,然后用 return 返回了这个变量的值。在调用 add 函数时,我们使用了 $() 将函数调用结果作为表达式的一部分,然后再用 math 命令计算出 sum 的值。 以上就是 CMake 中 macro 和 function 的介绍,希望对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值