CMake 容許開發者編寫平臺無關的 CMakeLists.txt 文件來定製整個編譯流程,而後再根據目標用戶的平臺進一步生成所需的本地化 Makefile 和工程文件,如 Linux 的Makefile 或 Windows 的 Visual Studio 工程。從而作到 Write once, run everywhere。使用 CMake 的開源項目有 VTK、ITK、KDE、OpenCV等。linux
如下記錄我在 Linux 下使用 CMake 的一些實踐。c++
安裝bootstrap
官方網站:https://cmake.org/ 下載源碼包,編譯安裝以下,ide
$ ./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.cui
#include <stdio.h> #include <stdlib.h> // atof(), atoi() double power(double base, int exp) { if (exp == 0) return 1; double result = base;
int i; for (i = 1; i < exp; i++) result *= base; return result; } int main(int argc, char * argv[]) { if (argc < 3) { printf("Usage: %s base exp\n", argv[0]); return -1; } double base = atof(argv[1]); int exp = atoi(argv[2]); double result = power(base, exp); printf("%g ^ %d = %g\n", base, exp, result); return 0; }
編輯 CMakeLists.txtthis
# 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 < 3) { printf("Usage: %s base exp\n", argv[0]); return -1; } double base = atof(argv[1]); int exp = atoi(argv[2]); double result = power(base, exp); printf("%g ^ %d = %g\n", base, exp, result); return 0; }
mathFunc.h
double power(double base, int exp);
mathFunc.c
double power(double base, int exp) { if (exp == 0) return 1; double result = base; int i; for (i = 1; 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 < 3) { printf("Usage: %s base exp\n", argv[0]); return -1; } double base = atof(argv[1]); int exp = atoi(argv[2]); #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 0; }
mathFunc.h
double power(double base, int exp);
mathFunc.c
double power(double base, int exp) { if (exp == 0) return 1; double result = base; int i; for (i = 1; 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 < 3) { printf("%s version %d.%d\n", argv[0], Demo_VERSION_MAJOR, Demo_VERSION_MINOR); printf("Usage: %s base exp\n", argv[0]); return -1; } double base = atof(argv[1]); int exp = atoi(argv[2]); #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 0; }
從新 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/
完。