cmake 编译 C 和 C++ 工程,只需要编写一个 CMakeLists.txt 文件即可,过程很简单,所有的工作只要编写 CMakeLists.txt 文件上。本例列举最简单的一个可执行文件的编译过程。

/*** @File Name: main.cc* @Description:*      最基础的往往是个可执行的 exe 工程,其 cmake 的编写参见 CMakeLists.txt 文件*/#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int argc, char* argv[]) {if (argc < 2) {fprintf(stdout, "Usage: %s number\n", argv[0]);return 1;}double inputValue = atof(argv[1]);double outputValue = sqrt(inputValue);fprintf(stdout, "%g 的平方根是 %g\n", inputValue, outputValue);return 0;
}

编写 CMakeLists.txt 如下:

cmake_minimum_required (VERSION 2.6)
project (tutorial)
add_executable(tutorial main.cc)

把这两个文件放在同一目录下,然后:

$ cmake .
-- The C compiler identification is GNU 4.8.4
-- The CXX compiler identification is GNU 4.8.4
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/joshua/Documents/cmake_tutorials
$ make
Scanning dependencies of target tutorial
[100%] Building CXX object CMakeFiles/tutorial.dir/main.cc.o
Linking CXX executable tutorial
[100%] Built target tutorial
$ ./tutorial 4.8
4.8 的平方根是 2.19089

好了,整个过程完成!接下来

Step 1:添加版本号和配置头文件

版本号添加在 CMakeFiles 中可以灵活修改,当然你也可以在代码中添加。

cmake_minimum_required(VERSION 2.6)
project(Tutorial)# 版本号
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)# 配置一个头文件来传递 CMake 设置
configure_file ("${PROJECT_SOURCE_DIR}/TutorialConfig.h.in""${PROJECT_BINARY_DIR}/TutorialConfig.h")# 添加二进制树到搜索路径以搜索代码文件
include_directories("${PROJECT_BINARY_DIR}")add_executable(tutorial main.cc)

配置文件将会写进二进制树中,所以我们得把那个目录添加到搜索路径上去。然后创建 TutorialConfig.h.in 文件并写入如下内容:

#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@

当 cmake 配置这个头文件时 @Tutorial_VERSION_MAJOR@ 和 @Tutorial_VERSION_MINOR@ 的值将会被 CMakeLists 中的值替代。接下来可以修改 main.cc 来验证:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "config.h"

int main(int argc, char* argv[]) {if (argc < 2) {fprintf(stdout, "%s 版本号 %d.%d\n",argv[0],Tutorial_VERSION_MAJOR,Tutorial_VERSION_MINOR);fprintf(stdout, "用法: %s 数字\n", argv[0]);return 1;}double inputValue = atof(argv[1]);double outputValue = sqrt(inputValue);fprintf(stdout, "%g 的平方根是 %g\n", inputValue, outputValue);return 0;
}

Step 2:添加 lib

假如要添加一个自定义的求平方根的 lib libmymath.a,其文件目录如下:

|-- mymath
|   |-- CMakeLists.txt
|   `-- mymath.h
|-- mysqrt.cc
|-- main.cc
|-- CMakeLists.txt

首先,需要编译出 lib 文件,在 CMakeLists.txt 中添加:

add_library(mymath mysqrt.cc)
add_subdirectory(mymath)

其次需要在 main.cc 中引用 mysqrt 需要把 mymath.h 引入编译搜索路径

include_directories("${PROJECT_SOURCE_DIR}/mymath")

最后,链接 lib 文件到 可执行文件

target_link_libraries(tutorial mymath)

OK, lib 添加完毕并能正常运行。但我想在编译时选择使用自定义的数学函数或者仍然使用库里的函数怎么办呢?可以使用 option 定义编译宏

# 宏 ON 表示开启
option (USE_MYMATH "使用自定义数学函数" ON)if (USE_MYMATH)include_directories("${PROJECT_SOURCE_DIR}/mymath")add_subdirectory(mymath)set (EXTRA_LIBS ${EXTRA_LIBS} mymath}
endif (USE_MYMATH)add_executable(tutorial main.cc)
target_link_libraries(tutorial, ${EXTRA_LIBS})

然后在 config.h.in 中定义这个宏

#cmakedefine USE_MYMATH

然后在 main.cc 中就可以使用这个宏了

#include <stdio.h>
#include <stdlib.h>
#include "config.h"
#ifdef USE_MYMATH
#include "mymath.h"
#else
#include <math.h>
#endif

int main(int argc, char* argv[]) {if (argc < 2) {fprintf(stdout, "%s 版本 %d.%d\n", argv[0],Tutorial_VERSION_MAJOR,Tutorial_VERSION_MINOR);fprintf(stdout, "用法:%s 数\n", argv[0]);return 1;}double inValue = atof(argv[1]);
#ifdef USE_MYMATH
    double outValue = mysqrt(inValue);
#else
    double outValue = sqrt(inValue);
#endif
    fprintf(stdout, "%g 的平方根是 %g\n", inValue, outValue);return 0;
}

Step 3: 安装和测试

接下来,将进行安装规则和测试支持的配置,安装规则很直接,对于自定义数学库的安装规则,可以在 CMakeLists.txt 这么写:

install (TARGETS mymath DESTINATION bin)
install (FILES mymath.h DESTINATION include)

对于本项目的可执行文件的安装,需要这么写:

install (TARGETS tutorial DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/config.h" DESTINATION include)

这就是安装所需要做的,编译后直接 make install 就安装了,普通用户默认安装在 /usr/local/bin 下,修改 CMAKE_INSTALL_PREFIX 可修改安装目录了,安装到此为止。

测试

CMake 内置了一个测试工具叫 CTest,可以在 Top level 的 CMakeLists 中引入它,并进行简单测试:

# 引入 CTest
include(CTest)# 能否正常执行
add_test(TutorialRuns tutorial 25)# 求 25 的平方根
add_test(TutorialComp25 tutorial 25)
set_tests_properties(TutorialComp25PROPERTIES PASS_REGULAR_EXPRESSION "25 的平方根是 5")# 求 -25 的平方根
add_test(TutorialNegative tutorial -25)
set_tests_properties(TutorialNegativePROPERTIES PASS_REGULAR_EXPRESSION "-25 的平方根是 0")# 求小数的平方根
add_test(TutorialSmall tutorial 0.0001)
set_tests_properties(TutorialSmallPROPERTIES PASS_REGULAR_EXPRESSION "0.0001 的平方根是 0.01")# 帮助是否正常
add_test(TutorialUsage tutorial)
set_tests_properties(TutorialUsagePROPERTIES PASS_REGULAR_EXPRESSION "用法:.*数")

编译后,直接运行 ctest 或者 make test 就可以进行测试了,add_test 添加测试用例,set_test 设置测试成功条件,如果有很多相同的测试用例,可以使用宏来定义测试函数:

# 定义测试宏
macro(do_test arg result)add_test(TutorialComp${arg} tutorial ${arg})set_tests_properties(TutorialComp${arg}PROPERTIES PASS_REGULAR_EXPRESSION ${result})
endmacro(do_test)do_test(25 "25 的平方根是 5")
do_test(-25 "-25 的平方根是 0")
do_test(100 "100 的平方根是 10")
do_test(0.0001 "0.0001 的平方根是 0.01")

Step 4:添加系统自检(System Introspection)

许多时候应用程序需要检查系统是否满足自己的运行条件,这时就需要用到系统自检。比如应用程序用到了 log 和 exp 函数,CMake 使用 CheckFunctionExists.cmake 宏来检查函数可见性:

# 引入函数检查
include(CheckFunctionExists)
check_function_exists(log HAVE_LOG)
check_function_exists(exp HAVE_EXP)

然后修改 config.h.in 来定义宏如果 CMake 在系统上找到的话:

#cmakedefine HAVE_LOG
#cmakedefine HAVE_EXP

很重要的一点是,检测函数必须得在 configure_file 命令之前完成,否则就不起作用了,然后就可以在代码中使用这两个宏了:

#if defined(HAVE_LOG) && defined(HAVE_EXP)
    result = exp(log(x) * 0.5);
#endif

Step 5:添加中间生成文件和生成器

本章将展示如何添加文件生成器代码并把生成的头文件配置在工程中,加入我们需要0~9的开方表,那么新建一个名为 maketable.cc 的文件:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int argc, char* argv[]) {// 确保有文件名传入
    if (argc < 2)return 1;// 创建文件
    FILE* fo = fopen(argv[1], "w");if (!fo)return 1;fprintf(fo, "double sqrtTable[] = \n");for (int i = 0; i < 10; ++i) {double result = sqrt(static_cast<double>(i));fprintf(fo, "%g,\n", result);}// 关闭文件
    fprintf(fo, "0};\n");fclose(fo);return 0;
}

可以看出,这个生成器产生了一段合法的 C++ 代码并根据输入参数保存成了一个文件,接下来将在 mymath 目录下的 CMakeLists.txt 中使用合适的命令来编译 maketable 并执行它来产生目标文件,命令如下:

# 定义添加可执行文件
add_executable(maketable maketable.cc)# 产生源代码的命令行
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/table.hCOMMAND maketable ${CMAKE_CURRENT_BINARY_DIR}/table.hDEPENDS maketable)# 添加至搜索路径
include_directories(${CMAKE_CURRENT_BINARY_DIR})# 添加至 main library
add_library(mymath mysqrt.cc ${CMAKE_CURRENT_BINARY_DIR}/table.h)# 安装
install(TARGETS mymath DESTINATION bin)
install(FILES mymath.h DESTINATION include)

首先添加 maketable 为可执行工程,然后添加了自定义命令来指定如何使用 maketable 生成 table.h,接下来让 CMake 知道 mysqrt.cc 依赖于生成的 table.h,把table.h 添加到 mymath 库的 source 下就可以了。同样,也需要把当前的二进制目录添加到 include 目录下去,这样 table.h 才能被 mysqrt.cc 看到并引用。

这样,当工程被编译时将先编译 maketable,然后产生 table.h,然后编译 mymath 库,然后编译 tutorial。

这时,root 下的 CMakeLists.txt 调整如下:

# 指定 cmake 最低版本
cmake_minimum_required(VERSION 2.6)# 指定工程名称
project(tutorial)# 引入 CTest
include(CTest)# 版本号
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)# 引入函数检查
include(${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
check_function_exists(log HAVE_LOG)
check_function_exists(exp HAVE_EXP)# 配置一个头文件来传递 CMake 的设置到源代码中
configure_file ("${PROJECT_SOURCE_DIR}/config.h.in""${PROJECT_BINARY_DIR}/config.h"
)# 把二进制目录树添加到引入路径的搜索路径上,
# 这样源代码中就可以找到上面配置的 config.h 了
include_directories("${PROJECT_BINARY_DIR}")# 定义宏
option (USE_MYMATH "使用自定义数学函数" ON)#
# 添加自定义 lib
if (USE_MYMATH)# 添加头文件(被源码引用)include_directories("${PROJECT_SOURCE_DIR}/mymath")# 添加子目录(好让 lib 被编译)add_subdirectory(mymath)set (EXTRA_LIBS ${EXTRA_LIBS} mymath)
endif (USE_MYMATH)# 指定工程输出为可执行文件 tutotial
add_executable(tutorial main.cc)
target_link_libraries(tutorial ${EXTRA_LIBS})#
# 安装配置
install (TARGETS tutorial DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/config.h" DESTINATION include)#
# 测试# 能否正常执行
add_test(TutorialRuns tutorial 25)# 定义测试宏
macro(do_test arg result)add_test(TutorialComp${arg} tutorial ${arg})set_tests_properties(TutorialComp${arg}PROPERTIES PASS_REGULAR_EXPRESSION ${result})
endmacro(do_test)do_test(25 "25 的平方根是 5")
do_test(-25 "-25 的平方根是 0")
do_test(100 "100 的平方根是 10")
do_test(0.0001 "0.0001 的平方根是 0.01")# 帮助是否正常
add_test(TutorialUsage tutorial)
set_tests_properties(TutorialUsagePROPERTIES PASS_REGULAR_EXPRESSION "用法:.*数")

Step 6: 创建安装包

使用 cmake 创建安装包是如此的简单, CMake 使用 CPack 制作安装包,支持二进制安装和安装包管理工具(cygwin,debian,RPMs等等)的安装,只需要在顶层目录下的 CMakeLists 中写入如下命令即可:

# 创建由 CPack 驱动的安装包
include(InstallRequiredSystemLibraries)
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/license.txt")
set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
include(CPack)

这就完事了,正常执行 cmake 命令,会发现多个几个文件:CPackConfig.cmake 和 CPackSourceConfig.cmake,然后使用 CPack 命令就可以做包了:

制作二进制包:

$ cpack --config CPackConfig.cmake

制作源发布包:

$ cpack --config CPackSourceConfig.cmake

恭喜!

cmake 编译 C 和 C++ 工程,只需要编写一个 CMakeLists.txt 文件即可,过程很简单,所有的工作只要编写 CMakeLists.txt 文件上。本例列举最简单的一个可执行文件的编译过程。

/*** @File Name: main.cc* @Description:*      最基础的往往是个可执行的 exe 工程,其 cmake 的编写参见 CMakeLists.txt 文件*/#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int argc, char* argv[]) {if (argc < 2) {fprintf(stdout, "Usage: %s number\n", argv[0]);return 1;}double inputValue = atof(argv[1]);double outputValue = sqrt(inputValue);fprintf(stdout, "%g 的平方根是 %g\n", inputValue, outputValue);return 0;
}

编写 CMakeLists.txt 如下:

cmake_minimum_required (VERSION 2.6)
project (tutorial)
add_executable(tutorial main.cc)

把这两个文件放在同一目录下,然后:

$ cmake .
-- The C compiler identification is GNU 4.8.4
-- The CXX compiler identification is GNU 4.8.4
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/joshua/Documents/cmake_tutorials
$ make
Scanning dependencies of target tutorial
[100%] Building CXX object CMakeFiles/tutorial.dir/main.cc.o
Linking CXX executable tutorial
[100%] Built target tutorial
$ ./tutorial 4.8
4.8 的平方根是 2.19089

好了,整个过程完成!接下来

Step 1:添加版本号和配置头文件

版本号添加在 CMakeFiles 中可以灵活修改,当然你也可以在代码中添加。

cmake_minimum_required(VERSION 2.6)
project(Tutorial)# 版本号
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)# 配置一个头文件来传递 CMake 设置
configure_file ("${PROJECT_SOURCE_DIR}/TutorialConfig.h.in""${PROJECT_BINARY_DIR}/TutorialConfig.h")# 添加二进制树到搜索路径以搜索代码文件
include_directories("${PROJECT_BINARY_DIR}")add_executable(tutorial main.cc)

配置文件将会写进二进制树中,所以我们得把那个目录添加到搜索路径上去。然后创建 TutorialConfig.h.in 文件并写入如下内容:

#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@

当 cmake 配置这个头文件时 @Tutorial_VERSION_MAJOR@ 和 @Tutorial_VERSION_MINOR@ 的值将会被 CMakeLists 中的值替代。接下来可以修改 main.cc 来验证:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "config.h"

int main(int argc, char* argv[]) {if (argc < 2) {fprintf(stdout, "%s 版本号 %d.%d\n",argv[0],Tutorial_VERSION_MAJOR,Tutorial_VERSION_MINOR);fprintf(stdout, "用法: %s 数字\n", argv[0]);return 1;}double inputValue = atof(argv[1]);double outputValue = sqrt(inputValue);fprintf(stdout, "%g 的平方根是 %g\n", inputValue, outputValue);return 0;
}

Step 2:添加 lib

假如要添加一个自定义的求平方根的 lib libmymath.a,其文件目录如下:

|-- mymath
|   |-- CMakeLists.txt
|   `-- mymath.h
|-- mysqrt.cc
|-- main.cc
|-- CMakeLists.txt

首先,需要编译出 lib 文件,在 CMakeLists.txt 中添加:

add_library(mymath mysqrt.cc)
add_subdirectory(mymath)

其次需要在 main.cc 中引用 mysqrt 需要把 mymath.h 引入编译搜索路径

include_directories("${PROJECT_SOURCE_DIR}/mymath")

最后,链接 lib 文件到 可执行文件

target_link_libraries(tutorial mymath)

OK, lib 添加完毕并能正常运行。但我想在编译时选择使用自定义的数学函数或者仍然使用库里的函数怎么办呢?可以使用 option 定义编译宏

# 宏 ON 表示开启
option (USE_MYMATH "使用自定义数学函数" ON)if (USE_MYMATH)include_directories("${PROJECT_SOURCE_DIR}/mymath")add_subdirectory(mymath)set (EXTRA_LIBS ${EXTRA_LIBS} mymath}
endif (USE_MYMATH)add_executable(tutorial main.cc)
target_link_libraries(tutorial, ${EXTRA_LIBS})

然后在 config.h.in 中定义这个宏

#cmakedefine USE_MYMATH

然后在 main.cc 中就可以使用这个宏了

#include <stdio.h>
#include <stdlib.h>
#include "config.h"
#ifdef USE_MYMATH
#include "mymath.h"
#else
#include <math.h>
#endif

int main(int argc, char* argv[]) {if (argc < 2) {fprintf(stdout, "%s 版本 %d.%d\n", argv[0],Tutorial_VERSION_MAJOR,Tutorial_VERSION_MINOR);fprintf(stdout, "用法:%s 数\n", argv[0]);return 1;}double inValue = atof(argv[1]);
#ifdef USE_MYMATH
    double outValue = mysqrt(inValue);
#else
    double outValue = sqrt(inValue);
#endif
    fprintf(stdout, "%g 的平方根是 %g\n", inValue, outValue);return 0;
}

Step 3: 安装和测试

接下来,将进行安装规则和测试支持的配置,安装规则很直接,对于自定义数学库的安装规则,可以在 CMakeLists.txt 这么写:

install (TARGETS mymath DESTINATION bin)
install (FILES mymath.h DESTINATION include)

对于本项目的可执行文件的安装,需要这么写:

install (TARGETS tutorial DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/config.h" DESTINATION include)

这就是安装所需要做的,编译后直接 make install 就安装了,普通用户默认安装在 /usr/local/bin 下,修改 CMAKE_INSTALL_PREFIX 可修改安装目录了,安装到此为止。

测试

CMake 内置了一个测试工具叫 CTest,可以在 Top level 的 CMakeLists 中引入它,并进行简单测试:

# 引入 CTest
include(CTest)# 能否正常执行
add_test(TutorialRuns tutorial 25)# 求 25 的平方根
add_test(TutorialComp25 tutorial 25)
set_tests_properties(TutorialComp25PROPERTIES PASS_REGULAR_EXPRESSION "25 的平方根是 5")# 求 -25 的平方根
add_test(TutorialNegative tutorial -25)
set_tests_properties(TutorialNegativePROPERTIES PASS_REGULAR_EXPRESSION "-25 的平方根是 0")# 求小数的平方根
add_test(TutorialSmall tutorial 0.0001)
set_tests_properties(TutorialSmallPROPERTIES PASS_REGULAR_EXPRESSION "0.0001 的平方根是 0.01")# 帮助是否正常
add_test(TutorialUsage tutorial)
set_tests_properties(TutorialUsagePROPERTIES PASS_REGULAR_EXPRESSION "用法:.*数")

编译后,直接运行 ctest 或者 make test 就可以进行测试了,add_test 添加测试用例,set_test 设置测试成功条件,如果有很多相同的测试用例,可以使用宏来定义测试函数:

# 定义测试宏
macro(do_test arg result)add_test(TutorialComp${arg} tutorial ${arg})set_tests_properties(TutorialComp${arg}PROPERTIES PASS_REGULAR_EXPRESSION ${result})
endmacro(do_test)do_test(25 "25 的平方根是 5")
do_test(-25 "-25 的平方根是 0")
do_test(100 "100 的平方根是 10")
do_test(0.0001 "0.0001 的平方根是 0.01")

Step 4:添加系统自检(System Introspection)

许多时候应用程序需要检查系统是否满足自己的运行条件,这时就需要用到系统自检。比如应用程序用到了 log 和 exp 函数,CMake 使用 CheckFunctionExists.cmake 宏来检查函数可见性:

# 引入函数检查
include(CheckFunctionExists)
check_function_exists(log HAVE_LOG)
check_function_exists(exp HAVE_EXP)

然后修改 config.h.in 来定义宏如果 CMake 在系统上找到的话:

#cmakedefine HAVE_LOG
#cmakedefine HAVE_EXP

很重要的一点是,检测函数必须得在 configure_file 命令之前完成,否则就不起作用了,然后就可以在代码中使用这两个宏了:

#if defined(HAVE_LOG) && defined(HAVE_EXP)
    result = exp(log(x) * 0.5);
#endif

Step 5:添加中间生成文件和生成器

本章将展示如何添加文件生成器代码并把生成的头文件配置在工程中,加入我们需要0~9的开方表,那么新建一个名为 maketable.cc 的文件:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int argc, char* argv[]) {// 确保有文件名传入
    if (argc < 2)return 1;// 创建文件
    FILE* fo = fopen(argv[1], "w");if (!fo)return 1;fprintf(fo, "double sqrtTable[] = \n");for (int i = 0; i < 10; ++i) {double result = sqrt(static_cast<double>(i));fprintf(fo, "%g,\n", result);}// 关闭文件
    fprintf(fo, "0};\n");fclose(fo);return 0;
}

可以看出,这个生成器产生了一段合法的 C++ 代码并根据输入参数保存成了一个文件,接下来将在 mymath 目录下的 CMakeLists.txt 中使用合适的命令来编译 maketable 并执行它来产生目标文件,命令如下:

# 定义添加可执行文件
add_executable(maketable maketable.cc)# 产生源代码的命令行
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/table.hCOMMAND maketable ${CMAKE_CURRENT_BINARY_DIR}/table.hDEPENDS maketable)# 添加至搜索路径
include_directories(${CMAKE_CURRENT_BINARY_DIR})# 添加至 main library
add_library(mymath mysqrt.cc ${CMAKE_CURRENT_BINARY_DIR}/table.h)# 安装
install(TARGETS mymath DESTINATION bin)
install(FILES mymath.h DESTINATION include)

首先添加 maketable 为可执行工程,然后添加了自定义命令来指定如何使用 maketable 生成 table.h,接下来让 CMake 知道 mysqrt.cc 依赖于生成的 table.h,把table.h 添加到 mymath 库的 source 下就可以了。同样,也需要把当前的二进制目录添加到 include 目录下去,这样 table.h 才能被 mysqrt.cc 看到并引用。

这样,当工程被编译时将先编译 maketable,然后产生 table.h,然后编译 mymath 库,然后编译 tutorial。

这时,root 下的 CMakeLists.txt 调整如下:

# 指定 cmake 最低版本
cmake_minimum_required(VERSION 2.6)# 指定工程名称
project(tutorial)# 引入 CTest
include(CTest)# 版本号
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)# 引入函数检查
include(${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
check_function_exists(log HAVE_LOG)
check_function_exists(exp HAVE_EXP)# 配置一个头文件来传递 CMake 的设置到源代码中
configure_file ("${PROJECT_SOURCE_DIR}/config.h.in""${PROJECT_BINARY_DIR}/config.h"
)# 把二进制目录树添加到引入路径的搜索路径上,
# 这样源代码中就可以找到上面配置的 config.h 了
include_directories("${PROJECT_BINARY_DIR}")# 定义宏
option (USE_MYMATH "使用自定义数学函数" ON)#
# 添加自定义 lib
if (USE_MYMATH)# 添加头文件(被源码引用)include_directories("${PROJECT_SOURCE_DIR}/mymath")# 添加子目录(好让 lib 被编译)add_subdirectory(mymath)set (EXTRA_LIBS ${EXTRA_LIBS} mymath)
endif (USE_MYMATH)# 指定工程输出为可执行文件 tutotial
add_executable(tutorial main.cc)
target_link_libraries(tutorial ${EXTRA_LIBS})#
# 安装配置
install (TARGETS tutorial DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/config.h" DESTINATION include)#
# 测试# 能否正常执行
add_test(TutorialRuns tutorial 25)# 定义测试宏
macro(do_test arg result)add_test(TutorialComp${arg} tutorial ${arg})set_tests_properties(TutorialComp${arg}PROPERTIES PASS_REGULAR_EXPRESSION ${result})
endmacro(do_test)do_test(25 "25 的平方根是 5")
do_test(-25 "-25 的平方根是 0")
do_test(100 "100 的平方根是 10")
do_test(0.0001 "0.0001 的平方根是 0.01")# 帮助是否正常
add_test(TutorialUsage tutorial)
set_tests_properties(TutorialUsagePROPERTIES PASS_REGULAR_EXPRESSION "用法:.*数")

Step 6: 创建安装包

使用 cmake 创建安装包是如此的简单, CMake 使用 CPack 制作安装包,支持二进制安装和安装包管理工具(cygwin,debian,RPMs等等)的安装,只需要在顶层目录下的 CMakeLists 中写入如下命令即可:

# 创建由 CPack 驱动的安装包
include(InstallRequiredSystemLibraries)
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/license.txt")
set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
include(CPack)

这就完事了,正常执行 cmake 命令,会发现多个几个文件:CPackConfig.cmake 和 CPackSourceConfig.cmake,然后使用 CPack 命令就可以做包了:

制作二进制包:

$ cpack --config CPackConfig.cmake

制作源发布包:

$ cpack --config CPackSourceConfig.cmake

恭喜!

cmake2 配合1相关推荐

  1. Dokku和Docker的完美配合

    看到一篇不错的文章,收藏一下: [编者的话]本文作者介绍了如何在单机上将Dokku和Docker结合.Dokku是一个小型的PaaS平台,只需使用Git将代码push到对应的仓库上就能自动触发部署,构 ...

  2. AI一分钟 | 小鹏汽车回应前苹果员工窃取商业机密:积极配合相关调查

    ▌苹果前华人工程师涉窃密被捕,小鹏汽车回应 今日(7月11日),有外媒报道称,苹果前雇员张晓浪因窃取商业机密罪被美国联邦调查局逮捕并被起,该员工即将加入小鹏汽车. 小鹏汽车的声明如下: 我们关注到 7 ...

  3. Django项目配合sentry实现浅析

    Django项目日志配合sentry概述 本文环境python3.5.2,Django版本1.10.2 Django项目中日志配合sentry的实现 sentry是一个错误跟踪网站,可以收集获取运行中 ...

  4. 服务端异步IO配合协程浅析

    服务端异步IO配合协程浅析 代码如下 #coding:utf-8 import socket from selectors import DefaultSelector, EVENT_READ, EV ...

  5. 在线协作沟通,以目标分解成任务树基础的团队配合

    信息传递是现代企业运转的重要工程,企业管理要特别重视沟通机制的建设,以保证信息传递的顺畅和沟通本身的效率. 那如何提高沟通效率呢?实现企业亦或是团队高效办公的需求呢? 大.中型企业为实现快速协作办公的 ...

  6. 怎么判断间隙过渡过盈配合_什么是配合间隙过盈过渡配合

    什么是配合 ? 什么是间隙.过盈.过渡配合 ? 答:基本尺寸相同的相互结合的孔和轴公差带之间的关系称为配合. 具有间隙 ( 包括最小间隙等于零 ) 的配合,称为间隙配合. 具有过盈 ( 包括最小过盈等 ...

  7. 公差基本偏差代号_《公差配合与技术测量》试题答案卷

    <公差配合与技术测量>试题 班级 姓名 学号 一.选择题(将下面题目中所有正确的论述选择出来)(每题2分,计20分) 题号 1 2 3 4 5 6 7 8 9 10 答案 1. 对于尺寸公 ...

  8. keep-alive的深入理解与使用(配合router-view缓存整个路由页面)

    原文来自: http://blog.myweb.kim/vue/keep-alive/?utm-source=origin 转载请注明出处. 在搭建 vue 项目时,有某些组件没必要多次渲染,所以需要 ...

  9. 未来货运:无人驾驶技术和卡车司机如何配合?

    来源:厚势 概要:看看你的周围.你看到的几乎所有东西都经过了卡车运输,无论是咖啡豆,还是你在使用的手机. 特斯拉刚刚发布了电动卡车,其实很多公司都对这一运输工具都在研究革新.Uber 本周(17.11 ...

最新文章

  1. C 的大致运行原理。
  2. 【云栖大会】阿里云成为全国首家云等保试点示范平台
  3. Android 的简介和体系结构中每个层的功能。
  4. 如何解决Windows Update错误80070003
  5. 全网最全!2021最新常用肿瘤生信数据库收藏级汇总!
  6. git-svn 在ubuntu deepin(Linux debian系)下的安装与应用
  7. 每天一道LeetCode-----最长无重复子串
  8. LINQ访问DataTable
  9. python爱心代码制作_Python之——爱心代码参与情人节
  10. 关于程序修改时(修改被调用的SQL时),注意关联性(也可以说是影响范围)。
  11. 背景虚化_背景虚化的效果用手机怎么拍?原来这样简单
  12. ASCII、Unicode、GBK和UTF-8字符编码的区别联系[转]
  13. 使用instsrv.exe+srvany.exe将应用程序安装为windows服务的方法
  14. iTween的用法总结
  15. HBase项目之微博系统
  16. 面向开发人员的 ChatGPT 提示词教程 - ChatGPT Prompt Engineering for Developers
  17. LumaQQ启动脚本
  18. Nginx性能调优,解决C10K问题
  19. Java编程那些事儿102——网络编程技术1
  20. MFC中关于UINT与USHORT

热门文章

  1. 类似华容道一类搜索中,状态的Hash方法(转)
  2. python制作表格的语句_python根据Excel自动生成创建表sql语句
  3. cocos2dx游戏开发简单入门视频教程 (cocos2d-x)-第2天
  4. 如何使用Android系统属性(SystemProperties)
  5. android4.0自定义锁屏总结【android锁屏研究一】
  6. 《『若水新闻』客户端开发教程》——03.设计新闻分类UI(1)
  7. Django框架简介-开头
  8. oracle rac升级补丁及中间的错误提示
  9. symantec:硝基***针对化工厂商
  10. 常见NetBackup通讯问题及排错一般步骤