用了一段CMake,总结一下
首先说一下什么是CMake
1、cmake是一种跨平台构建系统,它首先允许开发者编写一种平台无关的 CMakeList.txt 文件来定制整个编译流程,然后再根据目标用户的平台进一步生成所需的本地化 Makefile 和工程文件,我理解就是这玩意可以帮你根据不同平台自动生成Makefile文件,再通过Makefile编译你的代码
2、cmake是一种脚本语言,不要把cmake想象的多么复杂,这玩意还没有我们用的python或者shell复杂
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(Tutorial)
add_executable(Tutorial tutorial.cxx)
mkdir build && cd build && cmake … && make install
一个最简单的cmake写好了
①版本要求
②project,这个可以写,可以不写,但是cmake推荐写,用的时候照抄就行
③add_executable()生成一个可执行的target
④这里解释一下什么是target,add_executable和add_library都可以生成target
add_library(MathFunctions mysqrt.cxx)
add_executable(Tutorial tutorial.cxx)
target_link_libraries(Tutorial MathFunctions)
这儿会将两个target链接在一起
set(<variable> <value>... [PARENT_SCOPE])
set(algorithm_lib_src “awesome.cpp” PARENT_SCOPE)
set(<variable> <value>... CACHE <type> <docstring> [FORCE])
set(OpenCV_DIR "/usr/local" CACHE PATH "OpenCV root directory")
⑤变量,设置变量(变量有两种,一种是普通变量,一种是缓存变量),变量是有属性的,例如PARENT_SCOPE是一种特殊变量,这样在子模块中改变也会影响其父模块中的value,通俗点理解就是如果不用该参数传递给子模块的是copy,用了传递的是引用
message([<mode>] "message text" …)
message(STATUS ${algorithm_lib_src})
mode: FATAL_ERROR, WARNING, STATUS
⑥message用来交互,模式可以有FATAL_ERROR, WARNING, STATUS这几种
if (UNIX)
if (NOT APPLE AND NOT ANDROID)
find_package(Threads QUIET)
if (CMAKE_THREAD_LIBS_INIT)
list(APPEND Algorithm_LINKER_LIBS ${CMAKE_THREAD_LIBS_INIT})
else ()
message(FATAL_ERROR "Could not find threads")
endif ()
endif ()
endif ()
⑦使用if endif()
UNIX关键字,不需要使用$
NOT APPLE AND NOT ANDROID,不是苹果也不是安卓,这两个系统都是类Unix
通过上述命令导入多线程
function(<name> [<arg1> ...])
<commands>
endfunction()
⑧定义函数,在此处要特别注意,cmake是一种脚本语言,name为函数名, 可以传递一些列args
例子:
function (dmsg)
message(STATUS ${ARGN})
endfunction ()
dmsg(“hello”)
⑨宏,和C中宏一样
macro(<name> [<arg1> ...])
<commands>
endmacro()
macro (clear_vars)
foreach (_var ${ARGN})
unset(${_var})
endforeach ()
endmacro ()
此处需要和函数对比一下,始终记住cmake是传递的都是copy,所以在函数里面不会改变parent的变量,需要用户set设置变量属性
10.安装,install
install(TARGETS <target>... […])
install(TARGETS algorithm DESTINATION ${Algorithm_INSTALL_LIB_PREFIX})
install({FILES | PROGRAMS} <file>... […])
install(FILES python/__init__.py DESTINATION ${CMAKE_INSTALL_PREFIX})
install 有两种,可以是library可以是file,可以理解成将库以及头文件拷贝到指定的目录下
最后cmake综合
一个典型的cmake系统具有以下几个部分
src下面存放源码
cmake/module存在 findXXXX模块
cmake/extern用来下载外部依赖库