【cmake 教程】

前言 介绍

cmake是一个开源的,跨平台的工具,可以用来构建,测试和打包软件。cmake使用简单的独立于平台和编译器的配置文件,来控制软件编译过程,并且可以生成你选择的编译环境中可以可以使用的makefile文件和工程目录。cmake是kitware公司开发,以满足更强大和跨平台的构建环境的需求,比如ITK和VTK.
(来自 官网www.cmake.org)

cmake教程

cmake教程提供了分步的指导,可以覆盖常见的问题。从这个教程里,可以看到各个不同的模块怎么协同工作的。
这个教程和代码示例可以在cmake的开源代码help/guide/tutorial中找到。每一个步骤都有一个子文件夹。教程提供的示例是渐进式的,所以每一步都包括了上一步的完整的解决方案。

简单的开头

最基础的工程是构建一个可执行文件。一个三行的CMakefileList.txt包括了所有需要的内容。

cmake_minimum_required (VERSION 2.8)
project (HELLO)
SET(SRC_LIST main.cpp)
MESSAGE(STATUS "This is SOURCE dir "${HELLO_SOURCE_DIR})
add_executable(test ${SRC_LIST})

note:该例子中的command都用了小写。CMake不区分大小写。

构建并运行

现在我们就可以构建了。cmake建议外编译(建立build目录专门用来编译)
step1目录中包含了如上 CMakeLists.txt 和 main.cpp

  • 首先建立一个step1_build目录
    整个目录下:
    在这里插入图片描述
    执行步骤如下:
    在这里插入图片描述
  1. 进入step1_build目录,执行step1中的cmakelist
    cmake …/step1
  2. 查看生产了Makefile
  3. 执行make 生成可执行程序

指令

基本语法规则
1,变量使用${}方式取值,但是在 IF 控制语句中是直接使用变量名
2,指令(参数 1 参数 2…)

PROJECT指令

PROJECT(projectname [CXX] [C] [Java])

定义工程名称,并可指定工程支持的语言,支持的语言列表是可以忽略的, 默认情况表示支持所有语言。这个指令隐式的定义了两个 cmake 变量:
_BINARY_DIR 以及_SOURCE_DIR,这里就是
HELLO_BINARY_DIR 和 HELLO_SOURCE_DIR,同时 cmake 系统也帮助我们预定义了 PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR
变量,他们的值分别跟 HELLO_BINARY_DIR 与 HELLO_SOURCE_DIR 一致

SET 指令的语法是:

SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])

SET 指令可以用来显式的定义变量,如果有多个源文件,也可以定义成:
SET(SRC_LIST main.c t1.c t2.c)

MESSAGE 指令的语法是:

MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display"
...)

这个指令用于向终端输出用户定义的信息,包含了三种类型:
SEND_ERROR,产生错误,生成过程被跳过。
SATUS,输出前缀为—的信息。
FATAL_ERROR,立即终止所有 cmake 过程

ADD_EXECUTABLE指令

ADD_EXECUTABLE(hello ${SRC_LIST})

定义了这个工程会生成一个文件名为 hello 的可执行文件,相关的源文件是 SRC_LIST 中 定义的源文件列表

ADD_SUBDIRECTORY指令
这个指令用于向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存 放的位置
比如ADD_SUBDIRECTORY(src bin) 将src加入工程,并且指定编译输出包括中间结果存放到bin目录,如果不指定会输出到build/src下(全部默认为外部编译,在build下编译)
EXECUTABLE_OUTPUT_PATH 和 LIBRARY_OUTPUT_PATH 变量 可以指定最终的目标二进制的位置,从而使上述指令的行为改变。一个简单的原则,在哪里用了 ADD_EXECUTABLE 或 ADD_LIBRARY, 如果需要改变目标存放路径,就在哪里加入上述的定义

ADD_LIBRARY指令
这个指令是用来生成库文件

ADD_LIBRARY(libname [SHARED|STATIC|MODULE]
 [EXCLUDE_FROM_ALL]
 source1 source2 ... sourceN)

SHARED,动态库
STATIC,静态库
MODULE,在使用 dyld 的系统有效,如果不支持 dyld,则被当作 SHARED 对待。
EXCLUDE_FROM_ALL 参数的意思是这个库不会被默认构建,除非有其他的组件依赖或者手 工构建

SET_TARGET_PROPERTIES指令
设置target的属性

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

比如SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME “hello”)
此时输出为hello_static输出为hello

INCLUDE_DIRECTORIES指令

INCLUDE_DIRECTORIES(dir)

这条指令可以用来向工程添加多个特定的头文件搜索路径,路径之间用空格分割,如果路径 中包含了空格,可以使用双引号将它括起来,默认的行为是追加到当前的头文件搜索路径的 后面,通过 AFTER 或者 BEFORE 参数,也可以控制是追加还是置前

注意此处的目录是相对于CMakelist.txt的相对目录

LINK_DIRECTORIES指令
添加非标准的共享库搜索路径

LINK_DIRECTORIES(directory1 directory2 ...)

实际上,这个command不被推荐,更好的选择是使用环境变量 CMAKE_INCLUDE_PATH和CMAKE_LIBRARY_PATH并且用FIND_PATH配合来添加第三方库的头文件和库

TARGET_LINK_LIBRARIES指令

TARGET_LINK_LIBRARIES(target library1
 <debug | optimized> library2
 ...)

target添加共享库

AUX_SOURCE_DIRECTORY 指令

aux_source_directory(<dir> <variable>)

AUX_SOURCE_DIRECTORY(src/ FILES)查找src下所有的文件,并添加到FILES变量中

FIND_PACKAGE指令

FIND_PACKAGE(<name> [major.minor] [QUIET] [NO_MODULE]
 [[REQUIRED|COMPONENTS] [componets...]])

扩展cmake
其中name对应配置文件文件名中的name findname.cmake ,比如FIND_PACKAGE(hello…)
Findhello.cmake,并且要把该配置文件的目录加入到CMAKE_MODULE_PATH, 比如SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)

新手遇到的问题

  • 不生成makefile
    执行下cmake . -G “Unix Makefiles”

  • link时找不到库
    LINK_DIRECTORIES(/tmp/usr/lib/)
    ADD_EXECUTABLE(main main.c)
    TARGET_LINK_LIBRARIES(main hello)
    注意顺序 LINK_DIRECTORIES要放在ADD_EXECUTABLE前面,否则还是会提示找不到库
    TARGET_LINK_LIBRARIES要在ADD_EXECUTABLE 后面,否则会提示找不到main

  • cmake文件定义后,FIND PACKAGE依然找不到
    SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) 这个配置必须放在ADD_SUBDIRECTORY的后面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值