CMake tutorial
refer link: https://cmake.org/cmake-tutorial/
源码地址:https://github.com/pluslin/cmake_tutorial/
注:每一个version对应一个源码的git分支
Building an installer : 作用就是对特定平台建立特定平台的installer
Getting start
version 1(simplest)
# 最简单cmake项目包括下面三行:cmake最低版本、cmake项目名、添加可执行文件
cmake_minimum_required (VERSION 2.6)
project (Tutorial)
add_executable (Tutorial tutorial.cxx) # 项目名 源文件
文件目录:
/Tutorial
CMakeLists.txt
tutorial.cxx
version 1.2(add version & configure header)
# CMakeLists.txt(add the new code)
# The version number.
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)
# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
"${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
"${PROJECT_BINARY_DIR}/TutorialConfig.h"
)
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
include_directories("${PROJECT_BINARY_DIR}")
上述创建了项目版本号1.0,并配置了头文件(由源头文件.h.in生成相应的头文件),再将头文件.h路径加入include_directories中,其中头文件的作用是将CMakeLists.txt设置传入源代码中
# TutorialConfig.h.in(定义了版本号,将CMake的版本号设置传入.cxx)
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
# tutorial.cxx(使用版本号)
#include "TutorialConfig.h"
fprintf(stdout,"%s Version %d.%d\n",
argv[0],
Tutorial_VERSION_MAJOR,
Tutorial_VERSION_MINOR);
文件目录:
/Tutorial
CMakeLists.txt
TutorialConfig.h.in
tutorial.cxx
version 2(Add a Library)
Using the user’s library function in the subdirectory
# MathFunctions/CMakeLists.txt (mysqrt.cxx implement new user's mysqrt function)
add_library(MathFunctions mysqrt.cxx)
在MathFunctions子目录下CMakeLists.txt中将mysqrt.cxx文件添加到库文件中
# CMakeLists.txt
include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
add_subdirectory (MathFunctions)
# add the executable
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial MathFunctions)
为了使用新的库文件,我们需要在顶级目录的CMakeLists.txt中,添加子目录、添加include路径、链接新的目标库路径
文件目录:
/Tutorial
CMakeLists.txt
TutorialConfig.h.in
tutorial.cxx
/Tutorial/MathFunctions
mysqrt.cxx
CMakeLists.txt
MathFunctions.h
- 注:以下版本文件目录皆相同
version 2.2(Make Math Functions library optional)
命名一个USE_MYMATH选项,当其被定义时,我们将程序连接到用户定义的库文件中;否则,使用原生的标准库sqrt方法
# CMakeLists.txt
# should we use our own math functions?
option (USE_MYMATH
"Use tutorial provided math implementation" ON)
# add the MathFunctions library?
#
if (USE_MYMATH)
include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
add_subdirectory (MathFunctions)
set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)
# add the executable
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial ${EXTRA_LIBS})
由于USE_MYMATH设置会存储在cache中,所以不需要每次都run CMake命令
# tutorial.cxx
#ifdef USE_MYMATH
double outputValue = mysqrt(inputValue);
#else
double outputValue = sqrt(inputValue);
#endif
tutorial.cxx通过宏来确定是否用mysqrt还是sqrt方法
# TutorialConfig.h.in
cmakedefine USE_MYMATH
在配置文件中用cmakedefine来定义USE_MYMATH,如果有这句,那么使用mysqrt function;否则,使用standard库的sqrt function。
Version 3(Add install rules)
在每层的CMakeLists.txt中添加install规则
make install : 作用是将头文件与二进制文件整理到install_prefix中的/include和/bin文件夹中(包括库文件)
# CMakeLists.txt
# add the install targets
install (TARGETS Tutorial DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
DESTINATION include)
# MathFunctions/CMakeLists.txt
install (TARGETS MathFunctions DESTINATION bin)
install (FILES MathFunctions.h DESTINATION include)
注:建立install规则之后就可以使用make install命令进行project的安装了–将项目所生成的头文件及可执行文件进行打包放置到install_prefix路径下
# Run the command
$ cmake .. -DCKAME_INSTALL_PREFIX=install_path
$ make && make install
- 注:到这基本的CMake的使用就结束了,是不是很简单呢?后面是一些测试及其他补充!
Version 3.2 – Add test example
在顶级CMakeLists.txt中添加测试样例(正数、负数、小数等)来测试程序是否正确运行,编译好之后运行ctest命令即可看出test结果
# CMakeLists.txt
include(CTest)
# does the application run
add_test (TutorialRuns Tutorial 25)
# does it sqrt of 25
add_test (TutorialComp25 Tutorial 25)
set_tests_properties (TutorialComp25 PROPERTIES PASS_REGULAR_EXPRESSION "25 is 5")
# does it handle negative numbers
add_test (TutorialNegative Tutorial -25)
set_tests_properties (TutorialNegative PROPERTIES PASS_REGULAR_EXPRESSION "-25 is 0")
# does it handle small numbers
add_test (TutorialSmall Tutorial 0.0001)
set_tests_properties (TutorialSmall PROPERTIES PASS_REGULAR_EXPRESSION "0.0001 is 0.01")
# does the usage message work?
add_test (TutorialUsage Tutorial)
set_tests_properties (TutorialUsage PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number")
Version 4 – platform difference
提供系统自检,判断该平台是否有某个函数支持或者功能支持
该功能主要是支持平台差异性
# CMakeLists.txt
# does this system provide the log and exp functions?
include (CheckFunctionExists)
check_function_exists (log HAVE_LOG)
check_function_exists (exp HAVE_EXP)
cmake检测平台是否存在log和exp函数
# TutorialConfig.h.in
// does the platform provide exp and log functions?
#cmakedefine HAVE_LOG
#cmakedefine HAVE_EXP
如果CMakeLists.txt中检测出这两个函数,就定义这两个宏
# MathFunctions/mysqrt.cxx
// if we have both log and exp then use them
#if defined (HAVE_LOG) && defined (HAVE_EXP)
result = exp(log(x)*0.5);
#else // otherwise use an iterative approach
. . .
若平台支持,在mysqrt.cxx使用这两个函数