- 写CMake配置文件CMakeLists.txt
- 执行命令
cmake PATH
或者ccmake PATH
生成 Makefile(ccmake
和cmake
的区别在于前者提供了一个交互式的界面)。其中,PATH
是 CMakeLists.txt 所在的目录。 - 使用
make
命令进行编译。
1、单目录,单文件
#include <stdio.h>
#include <stdlib.h>
/**
* power - Calculate the power of number.
* @param base: Base value.
* @param exponent: Exponent value.
*
* @return base raised to the power exponent.
*/
double power(double base, int exponent)
{
int result = base;
int i;
if (exponent == 0) {
return 1;
}
for(i = 1; i < exponent; ++i){
result = result * base;
}
return result;
}
int main(int argc, char *argv[])
{
if (argc < 3){
printf("Usage: %s base exponent \n", argv[0]);
return 1;
}
double base = atof(argv[1]);
int exponent = atoi(argv[2]);
double result = power(base, exponent);
printf("%g ^ %d is %g\n", base, exponent, result);
return 0;
}
# 指定cmake最低版本
cmake_minimum_required (VERSION 2.8)
# 指定项目名为Demo1
project (Demo1)
# 将main.cpp编译为Demo的可执行文件
add_executable (Demo main.cpp)
cmake .
make (linux)
devenv.com ./Demo1.sln /Build "Debug|32" (windows)
2、单目录,多文件
# 指定cmake最低版本
cmake_minimum_required (VERSION 2.8)
# 指定项目名为Demo1
project (Demo1)
# 将main.cpp编译为Demo的可执行文件
add_executable(Demo main.cpp MathFunc.cpp)
使用 aux_source_directory (dir variable),存储某一目录下所有 source file
# 指定cmake最低版本
cmake_minimum_required (VERSION 2.8)
# 指定项目名为Demo1
project (Demo1)
# 存储某一目录下所有 source file
aux_source_directory(. DIR_SRC)
# 将main.cpp编译为Demo的可执行文件
add_executable(Demo ${DIR_SRC})
3、多目录,多文件
将其他目录下的库编译为lib库,由main link调用
假定存在math目录
# math 目录的CMakeLists.txt
aux_source_directory (. DIR_LIB_SRCS)
# 生成静态链接库
add_library(MathFunctions ${DIR_LIB_SRCS})
外部目录的
# 指定cmake最低版本
cmake_minimum_required (VERSION 2.8)
# 指定项目名为Demo1
project (Demo1)
# 存储某一目录下所有 source file
aux_source_directory(. DIR_SRC)
# 添加编译math目录下的CMakeLists.txt和源文件
add_subdirectory(math)
# 将main.cpp编译为Demo的可执行文件
add_executable(Demo ${DIR_SRC})
# 链接MathFuncions.lib
target_link_libraries(Demo MathFuncions)
4、配置宏,控制使用我们的math或者math.h的
# 指定cmake最低版本
cmake_minimum_required (VERSION 2.8)
# 指定项目名为Demo1
project (Demo1)
# 在cmake目录搞一个文件 config.h.in
# 在项目目录搞一个文件 config.h
# cmake根据config.h.in 生成 config.h, 生成定义宏
configure_file(
"${PROJECT_SOURCE_DIR}/config.h.in"
"${PROJECT_BINARY_DIR}/config.h"
)
# 添加一个 USE_MYMATH的宏定义,默认为 ON
option(
USE_MYMATH
"use provided math impl" ON
)
if (USE_MYMATH)
# 将math的头文件目录包含
include_directories("${PROJECT_SOURCE_DIR}/math")
# 添加编译math目录下的CMakeLists.txt和源文件
add_subdirectory(math)
# 给EXTRA_LIBS赋值MathFuncions
set (EXTRA_LIBS ${EXTRA_LIBS} MathFuncions)
endif (USE_MYMATH)
# 存储某一目录下所有 source file
aux_source_directory(. DIR_SRC)
# 将main.cpp编译为Demo的可执行文件
add_executable(Demo ${DIR_SRC})
# 链接MathFuncions.lib
target_link_libraries(Demo ${EXTRA_LIBS})
# config.h.in 文件
#cmakedefine USE_MYMATH
#include <stdio.h>
#include <stdlib.h>
#include "config.h"
#ifdef USE_MYMATH
#include "MathFunc.h"
#else
#include <math.h>
#endif
int main(int argc, char *argv[])
{
if (argc < 3){
printf("Usage: %s base exponent \n", argv[0]);
return 1;
}
double a = atof(argv[1]);
int b = atoi(argv[2]);
#ifdef USE_MYMATH
printf("power: %f ^ %d = %f\n", a, b, MathFunc::power(a, b));
#else
printf("power: %f ^ %d = %f\n", a, b, pow(a, b));
#endif
return 0;
}
5、指定install位置
like makefile (make install)
# 将MathFuncions.lib 拷贝到 /usr/local/bin
install(TARGETS MathFuncions DESTINATION bin)
# 将MathFuncions.h 拷贝到 /usr/local/include
install(FILES MathFuncions.h DESTINATION include)
# 将MathFuncions.lib 拷贝到 /usr/local/bin
install(TARGETS Demo DESTINATION bin)
# 将MathFuncions.h 拷贝到 /usr/local/include
install(FILES config.h DESTINATION include)
6、添加测试
# 启动测试
enable_testing()
add_test(test_run Demo 5 2)
add_test(test_usage Demo)
set_tests_properties(test_usage PROPERTIES PASS_REGULAR_EXPRESSION "Usage: .* base exponent")
# 测试 5 的 2 次方
add_test(test_5_2 Demo 5 2)
set_tests_properties(test_5_2 PROPERTIES PASS_REGULAR_EXPRESSION "is 25.0")
# 测试 10 的 5 次方
add_test(test_10_5 Demo 10 5)
set_tests_properties(test_10_5 PROPERTIES PASS_REGULAR_EXPRESSION "is 100000.0")
# 测试 2 的 10 次方
add_test (test_2_10 Demo 2 10)
set_tests_properties (test_2_10
PROPERTIES PASS_REGULAR_EXPRESSION "is 1024.0")
使用函数宏
enable_testing()
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 arg1 arg2 result)
do_test(5 2 "is 25")
do_test(10 5 "is 100000")
7、检查系统环境
CheckFunctionExist 宏
# 检查系统是否存在pow函数,存在则 HAV_POW ON
include(${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
check_function_exists (pow HAV_POW)
# configure_file
# config.h.in
#cmakedefine HAVE_POW
#ifdef HAVE_POW
printf("Now we use the standard library. \n");
double result = pow(base, exponent);
#else
printf("Now we use our own Math library. \n");
double result = power(base, exponent);
#endif
8、项目版本号
# project ...
set (Demo_VERSION_MAJOR 1)
set (Demo_VERSION_MINOR 0)
# config.h.in
#define Demo_VERSION_MAJOR @Demo_VERSION_MAJOR@
#define Demo_VERSION_MINOR @Demo_VERSION_MINOR@
printf("%s Version %d.%d\n",
argv[0],
Demo_VERSION_MAJOR,
Demo_VERSION_MINOR);
9、生成安装包
使用CPack
在顶层CMakeLists.txt添加
# 构建一个 CPack 安装包
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)
cmake .
# 生成二进制安装包
cpack -C CPackConfig.cmake
# 生成源码安装包
cpack -C CPackSourceConfig.cmake