CMake 常用方法
CMake 允许开发者编写平台无关的 CMakeLists.txt 文件来定制整个编译流程,然后再根据目标用户的平台进一步生成所需的本地化 Makefile 和工程文件,如 Linux 的Makefile 或 Windows 的 Visual Studio 工程。从而做到 Write once, run everywhere。使用 CMake 的开源项目有 VTK、ITK、KDE、OpenCV等。
以下记录我在 Linux 下使用 CMake 的一些实践。
安装
官方网站:https://cmake.org/ 下载源码包,编译安装如下,
- $ ./bootstrap
- $ make
- $ sudo make install
为了使用方便,再安装一下 ccmake,这是一个更友好的界面化 cmake 配置工具,
- $ sudo apt-get install cmake3-curses-gui
使用方法
在 linux 下使用 CMake 生成 Makefile 并编译的流程如下:
- 编写 CMake 配置文件 CMakeLists.txt 。
- 执行命令 cmake PATH 或者 ccmake PATH 生成 Makefile(其中, PATH 是顶层 CMakeLists.txt 所在的目录)。
- 使用 make 命令进行编译。
1) 编译单个文件
main.c
- #include <stdio.h>
- #include <stdlib.h> // atof(), atoi()
- double power(double base, int exp)
- {
- if (exp == )
- return ;
- double result = base;
int i;- for (i = ; i < exp; i++)
- result *= base;
- return result;
- }
- int main(int argc, char * argv[])
- {
- if (argc < )
- {
- printf("Usage: %s base exp\n", argv[]);
- return -;
- }
- double base = atof(argv[]);
- int exp = atoi(argv[]);
- double result = power(base, exp);
- printf("%g ^ %d = %g\n", base, exp, result);
- return ;
- }
编辑 CMakeLists.txt
- # CMake minimum version required
- cmake_minimum_required (VERSION 3.0)
- # Project info
- project (DemoProj1)
- # Specify generate target
- add_executable (Demo main.c)
在当前目录下执行 cmake,将在当前目录下生成项目所需的 Makefile,
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo1_single_src$ 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
- -- Detecting C compile features
- -- Detecting C compile features - 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
- -- Detecting CXX compile features
- -- Detecting CXX compile features - done
- -- Configuring done
- -- Generating done
- -- Build files have been written to: /home/peterpan/Desktop/cmake_explorer/demo1_single_src
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo1_single_src$ ll
- total 40
- -rw-rw-r-- 1 peterpan peterpan 12848 Mar 16 20:56 CMakeCache.txt
- drwxrwxr-x 5 peterpan peterpan 4096 Mar 16 20:56 CMakeFiles/
- -rw-rw-r-- 1 peterpan peterpan 1554 Mar 16 20:56 cmake_install.cmake
- -rw-rw-rw- 1 peterpan peterpan 162 Mar 16 20:56 CMakeLists.txt
- -rw-rw-rw- 1 peterpan peterpan 567 Mar 16 17:17 main.c
- -rw-rw-r-- 1 peterpan peterpan 4811 Mar 16 20:56 Makefile
然后直接 make 即可编译当前工程,
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo1_single_src$ make
- Scanning dependencies of target Demo
- [ 50%] Building C object CMakeFiles/Demo.dir/main.c.o
- [100%] Linking C executable Demo
- [100%] Built target Demo
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo1_single_src$ ./Demo 2 10
- 2 ^ 10 = 1024
2) 编译多个文件
工程结构为,
.
├── main.c
├── mathFunc.c
└── mathFunc.h
main.c
- #include <stdio.h>
- #include <stdlib.h> // atof(), atoi()
- #include "mathFunc.h"
- int main(int argc, char * argv[])
- {
- if (argc < )
- {
- printf("Usage: %s base exp\n", argv[]);
- return -;
- }
- double base = atof(argv[]);
- int exp = atoi(argv[]);
- double result = power(base, exp);
- printf("%g ^ %d = %g\n", base, exp, result);
- return ;
- }
mathFunc.h
- double power(double base, int exp);
mathFunc.c
- double power(double base, int exp)
- {
- if (exp == )
- return ;
- double result = base;
- int i;
- for (i = ; i < exp; i++)
- result *= base;
- return result;
- }
编辑 CMakeLists.txt
- # CMake minimum version required
- cmake_minimum_required (VERSION 3.0)
- # Project info
- project (DemoProj2)
- # Specify generate target
- add_executable (Demo main.c mathFunc.c)
运行 cmake,生成 Makefile,
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo2_multi_src_ver1$ 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
- -- Detecting C compile features
- -- Detecting C compile features - 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
- -- Detecting CXX compile features
- -- Detecting CXX compile features - done
- -- Configuring done
- -- Generating done
- -- Build files have been written to: /home/peterpan/Desktop/cmake_explorer/demo2_multi_src_ver1
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo2_multi_src_ver1$ ll
- total 48
- -rw-rw-r-- 1 peterpan peterpan 12856 Mar 16 21:10 CMakeCache.txt
- drwxrwxr-x 5 peterpan peterpan 4096 Mar 16 21:10 CMakeFiles/
- -rw-rw-r-- 1 peterpan peterpan 1562 Mar 16 21:10 cmake_install.cmake
- -rw-rw-rw- 1 peterpan peterpan 199 Mar 16 17:17 CMakeLists.txt
- -rw-rw-rw- 1 peterpan peterpan 408 Mar 16 17:17 main.c
- -rw-rw-r-- 1 peterpan peterpan 5494 Mar 16 21:10 Makefile
- -rw-rw-rw- 1 peterpan peterpan 189 Mar 16 21:04 mathFunc.c
- -rw-rw-rw- 1 peterpan peterpan 37 Mar 16 17:17 mathFunc.h
make 编译工程
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo2_multi_src_ver1$ make
- Scanning dependencies of target Demo
- [ 33%] Building C object CMakeFiles/Demo.dir/main.c.o
- [ 66%] Building C object CMakeFiles/Demo.dir/mathFunc.c.o
- [100%] Linking C executable Demo
- [100%] Built target Demo
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo2_multi_src_ver1$ ./Demo 2 10
- 2 ^ 10 = 1024
如果存在多个源文件,则在 CMakeLists.txt 中逐个罗列显然不是个好方法,可以采用如下添加辅助文件夹的方式,替代上述 CMakeList.txt 为,
- # CMake minimum version required
- cmake_minimum_required (VERSION 3.0)
- # Project info
- project (DemoProj3)
- # add auxilary directory, parameter is (<dir> <variable>)
- aux_source_directory (. AUX_SRC_DIR)
- # Specify generate target
- add_executable (Demo ${AUX_SRC_DIR})
3) 编译多层次的多个源文件
工程结构为,
.
├── main.c
└── math
├── mathFunc.c
└── mathFunc.h
代码内容和上述工程 2) 相同,这种情况下,每一层都需要一个 CMakeLists.txt 文件。
根目录下的 CMakeLists.txt 为主,在其中要包含子文件夹,并要使最终的 target 文件链接子文件夹下的目标文件,
- # CMake minimum version required
- cmake_minimum_required (VERSION 3.0)
- # Project info
- project (DemoProj4)
- # add auxilary directory, parameter is (<dir> <variable>)
- aux_source_directory (. MAIN_SRC_DIR)
- # add subdirectory
- add_subdirectory (math)
- # Specify generate target
- add_executable (Demo ${MAIN_SRC_DIR})
- # Add static link lib
- target_link_libraries (Demo mathFunc)
子文件夹下的 CMakeLists.txt,编译生成静态目标文件,
- # add auxilary directory, parameter is (<dir> <variable>)
- aux_source_directory (. MATH_SRC_DIR)
- # generate static link lib
- add_library (mathFunc ${MATH_SRC_DIR})
执行 cmake
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo4_multi_src_multi_layer$ 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
- -- Detecting C compile features
- -- Detecting C compile features - 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
- -- Detecting CXX compile features
- -- Detecting CXX compile features - done
- -- Configuring done
- -- Generating done
- -- Build files have been written to: /home/peterpan/Desktop/cmake_explorer/demo4_multi_src_multi_layer
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo4_multi_src_multi_layer$ ll
- total 44
- -rw-rw-r-- 1 peterpan peterpan 12959 Mar 16 21:33 CMakeCache.txt
- drwxrwxr-x 5 peterpan peterpan 4096 Mar 16 21:33 CMakeFiles/
- -rw-rw-r-- 1 peterpan peterpan 1777 Mar 16 21:33 cmake_install.cmake
- -rw-rw-rw- 1 peterpan peterpan 445 Mar 16 21:28 CMakeLists.txt
- -rw-rw-rw- 1 peterpan peterpan 413 Mar 16 17:17 main.c
- -rw-rw-r-- 1 peterpan peterpan 5287 Mar 16 21:33 Makefile
- drwxrwxr-x 3 peterpan peterpan 4096 Mar 16 21:33 math/
make 编译工程,
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo4_multi_src_multi_layer$ make
- Scanning dependencies of target mathFunc
- [ 25%] Building C object math/CMakeFiles/mathFunc.dir/mathFunc.c.o
- [ 50%] Linking C static library libmathFunc.a
- [ 50%] Built target mathFunc
- Scanning dependencies of target Demo
- [ 75%] Building C object CMakeFiles/Demo.dir/main.c.o
- [100%] Linking C executable Demo
- [100%] Built target Demo
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo4_multi_src_multi_layer$ ./Demo 2 10
- 2 ^ 10 = 1024
4) 用户自定义编译,CMake 编译指令初试
工程结构为
.
├── main.c
└── math
├── mathFunc.c
└── mathFunc.h
编辑根目录下的 CMakeLists.txt,
其中 config.h.in 是用户编辑文件,CMake 会根据此生成 config.h 头文件,
如下也定义了 USE_MYMATH 变量,并默认为 ON,表示使用用户自定义的 power 函数,如果为 OFF,表示使用标准库的 pow 函数 (会在以下 .c 文件中体现),
- # CMake minimum version required
- cmake_minimum_required (VERSION 3.0)
- # Project info
- project (DemoProj5)
- # Add config header
- configure_file (
- "${PROJECT_SOURCE_DIR}/config.h.in"
- "${PROJECT_BINARY_DIR}/config.h"
- )
- # Add option for chose if use mathFunc lib
- option (USE_MYMATH "Use user defined math lib" ON)
- # Add judge condition
- if (USE_MYMATH)
- include_directories ("${PROJECT_SOURCE_DIR}/math")
- add_subdirectory (math)
- set (UDF_LIBS ${UDF_LIBS} mathFunc)
- endif (USE_MYMATH)
- # add auxilary directory, parameter is (<dir> <variable>)
- aux_source_directory (. MAIN_SRC_DIR)
- # Specify generate target
- add_executable (Demo ${MAIN_SRC_DIR})
- # Add static link lib
- target_link_libraries (Demo ${UDF_LIBS})
编辑 config.h.in
- #cmakedefine USE_MYMATH
编辑子目录下的 CMakeLists.txt
- # add auxilary directory, parameter is (<dir> <variable>)
- aux_source_directory (. MATH_SRC_DIR)
- # generate static link lib
- add_library (mathFunc ${MATH_SRC_DIR})
main.c
- #include <stdio.h>
- #include <stdlib.h> // atof(), atoi()
- #include "config.h"
- #ifdef USE_MYMATH
- #include "math/mathFunc.h"
- #else
- #include <math.h> // pow()
- #endif
- int main(int argc, char * argv[])
- {
- if (argc < )
- {
- printf("Usage: %s base exp\n", argv[]);
- return -;
- }
- double base = atof(argv[]);
- int exp = atoi(argv[]);
- #ifdef USE_MYMATH
- printf("Now with user defined math lib.\n");
- double result = power(base, exp);
- #else
- printf("Now with C standard math lib.\n");
- //double result = pow(base, exp); // NOTE, under Linux, should add -lm, or else cannot compile succeed
- double result = base + exp; // here is a stub, for above reason
- #endif
- printf("%g ^ %d = %g\n", base, exp, result);
- return ;
- }
mathFunc.h
- double power(double base, int exp);
mathFunc.c
- double power(double base, int exp)
- {
- if (exp == )
- return ;
- double result = base;
- int i;
- for (i = ; i < exp; i++)
- result *= base;
- return result;
- }
使用命令 ccmake 打开参数配置窗口,
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo5_user_defined_compile$ ccmake .
如下图,用方向键将光标移到 USE_MYMATH 按 Enter 可以 toggle 这个选项为 ON 或 OFF,然后如下图底部提示,按 c 开始配置,按 g 生成配置并退出,
可以看到已生成 Makefile 文件,直接 make 编译工程,从运行结果可以看到,当 USE_MYMATH 打开为 ON 时,编译采用用户定义的 power 函数,
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo5_user_defined_compile$ ll
- total 64
- -rw-rw-r-- 1 peterpan peterpan 13002 Mar 16 21:53 CMakeCache.txt
- drwxrwxr-x 5 peterpan peterpan 4096 Mar 16 21:59 CMakeFiles/
- -rw-rw-r-- 1 peterpan peterpan 1774 Mar 16 21:53 cmake_install.cmake
- -rw-rw-rw- 1 peterpan peterpan 802 Mar 16 21:40 CMakeLists.txt
- -rw-rw-rw- 1 peterpan peterpan 19 Mar 16 21:59 config.h
- -rw-rw-rw- 1 peterpan peterpan 24 Mar 16 17:17 config.h.in
- -rwxrwxr-x 1 peterpan peterpan 8670 Mar 16 21:54 Demo*
- -rw-rw-rw- 1 peterpan peterpan 798 Mar 16 21:40 main.c
- -rw-rw-r-- 1 peterpan peterpan 5282 Mar 16 21:59 Makefile
- drwxrwxr-x 3 peterpan peterpan 4096 Mar 16 21:59 math/
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo5_user_defined_compile$ make
- [ 50%] Built target mathFunc
- Scanning dependencies of target Demo
- [ 75%] Building C object CMakeFiles/Demo.dir/main.c.o
- [100%] Linking C executable Demo
- [100%] Built target Demo
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo5_user_defined_compile$ ./Demo 2 10
- Now with user defined math lib.
- 2 ^ 10 = 1024
查看一下 cmake 生成的头文件 config.h
- #define USE_MYMATH
然后重新运行 ccmake,将 USE_MYMATH 关闭,如下,
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo5_user_defined_compile$ ccmake .
重新生成了 Makefile,直接 make 编译,运行,从结果可以看到,USE_MYMATH 关闭为 OFF 后,编译使用标准库的 pow 函数 (注意,因为 Linux 编译包含 C 数学函数的文件,需要加额外的编译选项 -lm,所以,这里用了个桩函数),
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo5_user_defined_compile$ ll
- total 64
- -rw-rw-r-- 1 peterpan peterpan 13080 Mar 16 22:07 CMakeCache.txt
- drwxrwxr-x 5 peterpan peterpan 4096 Mar 16 22:07 CMakeFiles/
- -rw-rw-r-- 1 peterpan peterpan 1574 Mar 16 22:07 cmake_install.cmake
- -rw-rw-rw- 1 peterpan peterpan 802 Mar 16 21:40 CMakeLists.txt
- -rw-rw-rw- 1 peterpan peterpan 24 Mar 16 22:07 config.h
- -rw-rw-rw- 1 peterpan peterpan 24 Mar 16 17:17 config.h.in
- -rwxrwxr-x 1 peterpan peterpan 8735 Mar 16 22:00 Demo*
- -rw-rw-rw- 1 peterpan peterpan 798 Mar 16 21:40 main.c
- -rw-rw-r-- 1 peterpan peterpan 4861 Mar 16 22:07 Makefile
- drwxrwxr-x 3 peterpan peterpan 4096 Mar 16 21:59 math/
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo5_user_defined_compile$ make
- Scanning dependencies of target Demo
- [ 50%] Building C object CMakeFiles/Demo.dir/main.c.o
- [100%] Linking C executable Demo
- [100%] Built target Demo
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo5_user_defined_compile$ ./Demo 2 10
- Now with C standard math lib.
- 2 ^ 10 = 12
可以再查看一下 cmake 生成的 config.h 文件,
- /* #undef USE_MYMATH */
5) 制定安装规则
cmake 可以制定安装规则,
修改子目录 math 下的 CMakeLists.txt
- # add auxilary directory, parameter is (<dir> <variable>)
aux_source_directory (. MATH_SRC_DIR)- # generate static link lib
add_library (mathFunc ${MATH_SRC_DIR})- # specify mathFunc lib install path
install (TARGETS mathFunc DESTINATION bin)
install (FILES mathFunc.h DESTINATION include)
修改根目录下的 CMakeLists.txt
- # CMake minimum version required
cmake_minimum_required (VERSION 3.0)- # Project info
project (DemoProj6)- # Add config header
configure_file (
"${PROJECT_SOURCE_DIR}/config.h.in"
"${PROJECT_BINARY_DIR}/config.h"
)- # Add option for chose if use mathFunc lib
option (USE_MYMATH "Use user defined math lib" ON)- # Add judge condition
if (USE_MYMATH)
include_directories ("${PROJECT_SOURCE_DIR}/math")
add_subdirectory (math)
set (UDF_LIBS ${UDF_LIBS} mathFunc)
endif (USE_MYMATH)- # add auxilary directory, parameter is (<dir> <variable>)
aux_source_directory (. MAIN_SRC_DIR)- # Specify generate target
add_executable (Demo ${MAIN_SRC_DIR})- # Add static link lib
target_link_libraries (Demo ${UDF_LIBS})- # Specify install path
install (TARGETS Demo DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/config.h" DESTINATION include)
经过以上设置,最终生成的目标文件 Demo 和库函数 libmathFunc.a 将被复制到 /usr/local/bin 中,而 config.h 和 mathFunc.h 会被复制到 /usr/local/include 中。
重新 cmake,重新 make,之后如下执行安装,
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo6_package_install$ sudo make install
- [ 50%] Built target mathFunc
- [100%] Built target Demo
- Install the project...
- -- Install configuration: ""
- -- Installing: /usr/local/bin/Demo
- -- Installing: /usr/local/include/config.h
- -- Installing: /usr/local/bin/libmathFunc.a
- -- Installing: /usr/local/include/mathFunc.h
6) 支持 GDB
在顶层文件 CMakeLists.txt 添加 GDB 支持,
- # CMake minimum version required
- cmake_minimum_required (VERSION 3.0)
- # Project info
- project (DemoProj7)
- # Add config header
- configure_file (
- "${PROJECT_SOURCE_DIR}/config.h.in"
- "${PROJECT_BINARY_DIR}/config.h"
- )
- # Add option for chose if use mathFunc lib
- option (USE_MYMATH "Use user defined math lib" ON)
- # Add judge condition
- if (USE_MYMATH)
- include_directories ("${PROJECT_SOURCE_DIR}/math")
- add_subdirectory (math)
- set (UDF_LIBS ${UDF_LIBS} mathFunc)
- endif (USE_MYMATH)
- # add auxilary directory, parameter is (<dir> <variable>)
- aux_source_directory (. MAIN_SRC_DIR)
- # Specify generate target
- add_executable (Demo ${MAIN_SRC_DIR})
- # Add static link lib
- target_link_libraries (Demo ${UDF_LIBS})
- # Specify install path
- install (TARGETS Demo DESTINATION bin)
- install (FILES "${PROJECT_BINARY_DIR}/config.h" DESTINATION include)
- # for support GDB
- set (CMAKE_BUILD_TYPE "Debug")
- set (CMAEK_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
- set (CMAEK_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
清理工程,重新 cmake,重新 make,之后生成的 Target 文件就带有调试信息了。
7) 为工程添加测试
在顶层文件 CMakeLists.txt 添加对 test 的支持,
- # CMake minimum version required
- cmake_minimum_required (VERSION 3.0)
- # Project info
- project (DemoProj8)
- # Add config header
- configure_file (
- "${PROJECT_SOURCE_DIR}/config.h.in"
- "${PROJECT_BINARY_DIR}/config.h"
- )
- # Add option for chose if use mathFunc lib
- option (USE_MYMATH "Use user defined math lib" ON)
- # Add judge condition
- if (USE_MYMATH)
- include_directories ("${PROJECT_SOURCE_DIR}/math")
- add_subdirectory (math)
- set (UDF_LIBS ${UDF_LIBS} mathFunc)
- endif (USE_MYMATH)
- # add auxilary directory, parameter is (<dir> <variable>)
- aux_source_directory (. MAIN_SRC_DIR)
- # Specify generate target
- add_executable (Demo ${MAIN_SRC_DIR})
- # Add static link lib
- target_link_libraries (Demo ${UDF_LIBS})
- # Specify install path
- install (TARGETS Demo DESTINATION bin)
- install (FILES "${PROJECT_BINARY_DIR}/config.h" DESTINATION include)
- # for support GDB
- set (CMAKE_BUILD_TYPE "Debug")
- set (CMAEK_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
- set (CMAEK_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
- # for test
- enable_testing()
- add_test (test_usage Demo)
- set_tests_properties (test_usage PROPERTIES PASS_REGULAR_EXPRESSION "Usage: .* base exp")
- add_test (test_2_10 Demo 2 10)
- set_tests_properties (test_2_10 PROPERTIES PASS_REGULAR_EXPRESSION "1024")
- add_test (test_10_2 Demo 10 2)
- set_tests_properties (test_10_2 PROPERTIES PASS_REGULAR_EXPRESSION "100")
- add_test (test_5_3 Demo 5 3)
- set_tests_properties (test_5_3 PROPERTIES PASS_REGULAR_EXPRESSION "125")
清理工程,重新 cmake,重新 make,之后就运行命令 make test 执行上述测试。
如果测试用例太多,可以考虑定义如下宏函数来简化,
- # for convinence test, defien a macro
- macro (do_test arg1 arg2 result)
- add_test (test_${arg1}_${arg2} Demo ${arg1} ${arg2})
- set_tests_properties (test_${arg1}_${arg2} PROPERTIES PASS_REGULAR_EXPRESSION ${result})
- endmacro (do_test)
- do_test (2 10 "1024")
- do_test (10 2 "100")
- do_test (5 3 "125")
8) 为工程添加版本号
修改顶层文件,在 project 命令之后加入版本信息,
- # CMake minimum version required
- cmake_minimum_required (VERSION 3.0)
- # Project info
- project (DemoProj9)
- # Add version info
- set (Demo_VERSION_MAJOR 0)
- set (Demo_VERSION_MINOR 1)
- # Add config header
- configure_file (
- "${PROJECT_SOURCE_DIR}/config.h.in"
- "${PROJECT_BINARY_DIR}/config.h"
- )
- # Add option for chose if use mathFunc lib
- option (USE_MYMATH "Use user defined math lib" ON)
- # Add judge condition
- if (USE_MYMATH)
- include_directories ("${PROJECT_SOURCE_DIR}/math")
- add_subdirectory (math)
- set (UDF_LIBS ${UDF_LIBS} mathFunc)
- endif (USE_MYMATH)
- # add auxilary directory, parameter is (<dir> <variable>)
- aux_source_directory (. MAIN_SRC_DIR)
- # Specify generate target
- add_executable (Demo ${MAIN_SRC_DIR})
- # Add static link lib
- target_link_libraries (Demo ${UDF_LIBS})
- # Specify install path
- install (TARGETS Demo DESTINATION bin)
- install (FILES "${PROJECT_BINARY_DIR}/config.h" DESTINATION include)
- # for support GDB
- set (CMAKE_BUILD_TYPE "Debug")
- set (CMAEK_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
- set (CMAEK_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
- # for test
- enable_testing()
- add_test (test_usage Demo)
- set_tests_properties (test_usage PROPERTIES PASS_REGULAR_EXPRESSION "Usage: .* base exp")
- add_test (test_2_10 Demo 2 10)
- set_tests_properties (test_2_10 PROPERTIES PASS_REGULAR_EXPRESSION "1024")
- add_test (test_10_2 Demo 10 2)
- set_tests_properties (test_10_2 PROPERTIES PASS_REGULAR_EXPRESSION "100")
- add_test (test_5_3 Demo 5 3)
- set_tests_properties (test_5_3 PROPERTIES PASS_REGULAR_EXPRESSION "125")
为了在代码中获取版本信息,如下编辑 config.h.in
- #cmakedefine USE_MYMATH
- // for version info
- #define Demo_VERSION_MAJOR @Demo_VERSION_MAJOR@
- #define Demo_VERSION_MINOR @Demo_VERSION_MINOR@
修改 main.c 增加版本信息输出
- // test cmake, demo5.
- #include <stdio.h>
- #include <stdlib.h> // atof(), atoi()
- #include "config.h"
- #ifdef USE_MYMATH
- #include "math/mathFunc.h"
- #else
- #include <math.h> // pow()
- #endif
- int main(int argc, char * argv[])
- {
- if (argc < )
- {
- printf("%s version %d.%d\n", argv[], Demo_VERSION_MAJOR, Demo_VERSION_MINOR);
- printf("Usage: %s base exp\n", argv[]);
- return -;
- }
- double base = atof(argv[]);
- int exp = atoi(argv[]);
- #ifdef USE_MYMATH
- printf("Now with user defined math lib.\n");
- double result = power(base, exp);
- #else
- printf("Now with C standard math lib.\n");
- //double result = pow(base, exp); // NOTE, under Linux, should add -lm, or else cannot compile succeed
- double result = base + exp; // here is a stub, for above reason
- #endif
- printf("%g ^ %d = %g\n", base, exp, result);
- return ;
- }
重新 cmake,重新 make,执行结果如下,
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo9_add_version_num$ ./Demo
- ./Demo version 0.1
- Usage: ./Demo base exp
9) 打包工程为安装包
cmake 提供 cpack 工具,可以将工程打包成二进制安装包或源码安装包。
在工程顶层 CMakeLists.txt 添加如下语句,
- # for package installer
- include (InstallRequiredSystemLibraries)
- set (CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
- set (CPACK_PACKAGE_VERSION_MAJOR "${Demo_VERSION_MAJOR}")
- set (CPACK_PACKAGE_VERSION_MINOR "${Demo_VERSION_MINOR}")
- include (CPack)
在工程顶层添加一个合适的 License.txt 文件,例如,
- The MIT License (MIT)
- Copyright (c) 2018 Peter pan (http://www.cnblogs.com/gaowengang)
- Permission is hereby granted, free of charge, to any person obtaining a copy of
- this software and associated documentation files (the "Software"), to deal in
- the Software without restriction, including without limitation the rights to
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- the Software, and to permit persons to whom the Software is furnished to do so,
- subject to the following conditions:
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
清理工程,重新 cmake,重新 make,
生成二进制安装包,命令如下,
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo10_package_installer$ cpack -C CPackConfig.cmake
- CPack: Create package using STGZ
- CPack: Install projects
- CPack: - Run preinstall target for: DemoProj10
- CPack: - Install project: DemoProj10
- CPack: Create package
- CPack: - package: /home/peterpan/Desktop/cmake_explorer/demo10_package_installer/DemoProj10-0.1.1-Linux.sh generated.
- CPack: Create package using TGZ
- CPack: Install projects
- CPack: - Run preinstall target for: DemoProj10
- CPack: - Install project: DemoProj10
- CPack: Create package
- CPack: - package: /home/peterpan/Desktop/cmake_explorer/demo10_package_installer/DemoProj10-0.1.1-Linux.tar.gz generated.
- CPack: Create package using TZ
- CPack: Install projects
- CPack: - Run preinstall target for: DemoProj10
- CPack: - Install project: DemoProj10
- CPack: Create package
- CPack: - package: /home/peterpan/Desktop/cmake_explorer/demo10_package_installer/DemoProj10-0.1.1-Linux.tar.Z generated.
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo10_package_installer$ ll
- total 124
- -rw-rw-r-- 1 peterpan peterpan 15393 Mar 17 09:37 CMakeCache.txt
- drwxrwxr-x 5 peterpan peterpan 4096 Mar 17 09:37 CMakeFiles/
- -rw-rw-r-- 1 peterpan peterpan 2802 Mar 17 09:37 cmake_install.cmake
- -rw-rw-r-- 1 peterpan peterpan 1916 Mar 17 09:34 CMakeLists.txt
- -rw-rw-r-- 1 peterpan peterpan 103 Mar 17 09:36 config.h
- -rw-rw-r-- 1 peterpan peterpan 141 Mar 17 09:23 config.h.in
- -rw-r--r-- 1 peterpan peterpan 3623 Mar 17 09:37 CPackConfig.cmake
- drwxrwxr-x 3 peterpan peterpan 4096 Mar 17 09:37 _CPack_Packages/
- -rw-r--r-- 1 peterpan peterpan 4108 Mar 17 09:37 CPackSourceConfig.cmake
- -rw-rw-r-- 1 peterpan peterpan 799 Mar 17 09:37 CTestTestfile.cmake
- -rwxrwxr-x 1 peterpan peterpan 10070 Mar 17 09:37 Demo*
- -rwxrwxrwx 1 peterpan peterpan 9096 Mar 17 09:37 DemoProj10-0.1.1-Linux.sh*
- -rw-rw-r-- 1 peterpan peterpan 4121 Mar 17 09:37 DemoProj10-0.1.1-Linux.tar.gz
- -rw-rw-r-- 1 peterpan peterpan 5478 Mar 17 09:37 DemoProj10-0.1.1-Linux.tar.Z
- -rw-rw-r-- 1 peterpan peterpan 506 Mar 17 09:37 install_manifest.txt
- -rw-rw-r-- 1 peterpan peterpan 1112 Mar 17 09:31 License.txt
- -rw-rw-r-- 1 peterpan peterpan 885 Mar 17 09:23 main.c
- -rw-rw-r-- 1 peterpan peterpan 8392 Mar 17 09:37 Makefile
- drwxrwxr-x 3 peterpan peterpan 4096 Mar 17 09:37 math/
二进制安转包内容如下,
DemoProj10-0.1.1-Linux
├── bin
│ ├── Demo
│ └── libmathFunc.a
└── include
├── config.h
└── mathFunc.h
生成源码安装包,命令如下,
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo10_package_installer$ cpack -C CPackSourceConfig.cmake
- CPack: Create package using STGZ
- CPack: Install projects
- CPack: - Run preinstall target for: DemoProj10
- CPack: - Install project: DemoProj10
- CPack: Create package
- CPack: - package: /home/peterpan/Desktop/cmake_explorer/demo10_package_installer/DemoProj10-0.1.1-Linux.sh generated.
- CPack: Create package using TGZ
- CPack: Install projects
- CPack: - Run preinstall target for: DemoProj10
- CPack: - Install project: DemoProj10
- CPack: Create package
- CPack: - package: /home/peterpan/Desktop/cmake_explorer/demo10_package_installer/DemoProj10-0.1.1-Linux.tar.gz generated.
- CPack: Create package using TZ
- CPack: Install projects
- CPack: - Run preinstall target for: DemoProj10
- CPack: - Install project: DemoProj10
- CPack: Create package
- CPack: - package: /home/peterpan/Desktop/cmake_explorer/demo10_package_installer/DemoProj10-0.1.1-Linux.tar.Z generated.
- peterpan@Rescuer:~/Desktop/cmake_explorer/demo10_package_installer$ ll
- total 124
- -rw-rw-r-- 1 peterpan peterpan 15393 Mar 17 09:37 CMakeCache.txt
- drwxrwxr-x 5 peterpan peterpan 4096 Mar 17 09:44 CMakeFiles/
- -rw-rw-r-- 1 peterpan peterpan 2802 Mar 17 09:37 cmake_install.cmake
- -rw-rw-r-- 1 peterpan peterpan 1916 Mar 17 09:34 CMakeLists.txt
- -rw-rw-r-- 1 peterpan peterpan 103 Mar 17 09:36 config.h
- -rw-rw-r-- 1 peterpan peterpan 141 Mar 17 09:23 config.h.in
- -rw-r--r-- 1 peterpan peterpan 3623 Mar 17 09:37 CPackConfig.cmake
- drwxrwxr-x 3 peterpan peterpan 4096 Mar 17 09:37 _CPack_Packages/
- -rw-r--r-- 1 peterpan peterpan 4108 Mar 17 09:37 CPackSourceConfig.cmake
- -rw-rw-r-- 1 peterpan peterpan 799 Mar 17 09:37 CTestTestfile.cmake
- -rwxrwxr-x 1 peterpan peterpan 10070 Mar 17 09:37 Demo*
- -rwxrwxrwx 1 peterpan peterpan 9098 Mar 17 09:44 DemoProj10-0.1.1-Linux.sh*
- -rw-rw-r-- 1 peterpan peterpan 4122 Mar 17 09:44 DemoProj10-0.1.1-Linux.tar.gz
- -rw-rw-r-- 1 peterpan peterpan 5481 Mar 17 09:44 DemoProj10-0.1.1-Linux.tar.Z
- -rw-rw-r-- 1 peterpan peterpan 506 Mar 17 09:44 install_manifest.txt
- -rw-rw-r-- 1 peterpan peterpan 1112 Mar 17 09:31 License.txt
- -rw-rw-r-- 1 peterpan peterpan 885 Mar 17 09:23 main.c
- -rw-rw-r-- 1 peterpan peterpan 8392 Mar 17 09:37 Makefile
- drwxrwxr-x 3 peterpan peterpan 4096 Mar 17 09:37 math/
源码安装包内容如下 (好像不太好使……依然是二进制打包的)
DemoProj10-0.1.1-Linux
├── bin
│ ├── Demo
│ └── libmathFunc.a
└── include
├── config.h
└── mathFunc.h
=========================================================================================
注:本文来自原创作者网站: http://www.hahack.com/codes/cmake/
完。
CMake 常用方法的更多相关文章
- 使用cmake自动构建工程
公司引擎是用cmake根据目标平台来构建工程的,刚接触的时候深深体会到cmake的方便:如果目标平台是windows,它可以帮你自动构建出vs工程:如果是安卓,自动构建出eclipse工程,如果是IO ...
- 前端开发:Javascript中的数组,常用方法解析
前端开发:Javascript中的数组,常用方法解析 前言 Array是Javascript构成的一个重要的部分,它可以用来存储字符串.对象.函数.Number,它是非常强大的.因此深入了解Array ...
- Jquery元素选取、常用方法
一:常用的选择器:(李昌辉) 基本选择器 $("#myDiv") //匹配唯一的具有此id值的元素 $("div") //匹配指定名称的所有元素 $(" ...
- python浅谈正则的常用方法
python浅谈正则的常用方法覆盖范围70%以上 上一次很多朋友写文字屏蔽说到要用正则表达,其实不是我不想用(我正则用得不是很多,看过我之前爬虫的都知道,我直接用BeautifulSoup的网页标签去 ...
- C# Webbrowser 常用方法及多线程调用
设置控件的值 /// <summary> /// 根据ID,NAME双重判断并设置值 /// </summary> /// <param name="tagNa ...
- list,tuple,dict,set常用方法
Python中list,tuple,dict,set常用方法 collections模块提供的其它有用扩展类型 from collections import Counter from collect ...
- CMake
使用CMake编译跨平台静态库 http://www.tuicool.com/articles/3uu2Yj cmake命令 安装.用法简介 https://fukun.org/archives/04 ...
- 记录yii2-imagine几个常用方法
记录yii2-imagine几个常用方法: //压缩 Image::thumbnail('@webroot/img/test-image.jpg', 120, 120)->save(Yii::g ...
- CMake学习笔记
C++开发者必备技能CMake 先简单介绍一下,CMake是一个跨平台的编译工具,它可以根据不用的平台,不同的编译环境,生成不同的MakeFile,从而控制编译的过程. 使用CMake的步骤: 1. ...
随机推荐
- 洛谷P2868 [USACO07DEC]观光奶牛Sightseeing Cows(01分数规划)
题意 题目链接 Sol 复习一下01分数规划 设\(a_i\)为点权,\(b_i\)为边权,我们要最大化\(\sum \frac{a_i}{b_i}\).可以二分一个答案\(k\),我们需要检查\(\ ...
- 一位ML工程师构建深度神经网络的实用技巧
一位ML工程师构建深度神经网络的实用技巧 https://mp.weixin.qq.com/s/2gKYtona0Z6szsjaj8c9Vg 作者| Matt H/Daniel R 译者| 婉清 编辑 ...
- [Intellij] 在IntelliJ IDEA 中创建运行web项目
安装工具 1.JDK7+ 2.IntelliJ Idea 工具(下载安装后,网上找注册码破解即可) 3.tomcat7+ 解压缩版 明确两个概念: 1.Project:类似于eclipse的works ...
- [Android][Framework]裁剪SystemServer服务以及关闭SystemFeature
本文链接 http://wossoneri.github.io/2018/08/30/[Android][Framework]crop-SystemServer-and-SystemFeature/ ...
- git 入门教程之 git 私服搭建教程
git 私服搭建教程 前几节我们的远程仓库使用的是 github 网站,托管项目大多是公开的,如果不想让任何人都能看到就需要收费,而且 github 网站毕竟在国外,访问速度太慢,基于上述两点原因,我 ...
- split 分割 字符串(分隔符如:* ^ : | , .)
[1]单个符号作为分隔符 String address="上海|上海市|闵行区|吴中路"; String[] splitAddress=address.split("\\ ...
- JHipster生成单体架构的应用示例
本文演示如何用JHipster生成一个单体架构风格的应用. 环境需求:安装好JHipster开发环境的CentOS 7.4(参考这里) 应用名:app1 实体名:role 主机IP:192.168.2 ...
- windows网络编程中文 笔记(一)
OSI网络模型 OSI(Open System Interconnection)开放系统互联 第七层 应用层 为用户提供相应的界面,以便使用提供的连网功能 第六层 表示层 完成数据的格式化 第五层 会 ...
- SQL中触发器的使用
创建触发器 是特殊的存储过程,自动执行,一般不要有返回值 类型: 1.后触发器 (AFTER,FOR)先执行对应语句,后执行触发器中的语句 2.前触发器 并没有真正的执行触发语句(insert,up ...
- mssql sqlserver 使用脚本输出excel文件的方法分享
转自:http://www.maomao365.com/?p=6683 摘要: 下文将分享使用sql脚本输出excel的方法 此脚本可以应用于 表或视图生成excel的方法,若需使用sql脚本输出ex ...