实际开发中,我们有可能需要对程序的编译时间、版本号进行把控。
实现的方法可能有很多种,这里分享一种便捷的方法——使用cmake的自定义编译选项。
关于cmake的基础知识:Hello系列 | cmake简明基础知识
cmake支持自定义编译选项,我们可以根据项目需要自定义一些编译选项。cmake借助一个.h.in后缀的文件生成对应的.h头文件,而我们的代码中可以使用这个头文件。
假如,我们建立的demo工程结构如下:
CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
####################################### 编译模式设置 #######################################
set(DEBUG_VERSION "DebugMode")
set(RELEASE_VERSION "ReleaseMode")
set(COMPILE_MODE ${RELEASE_VERSION}) # 编译模式
set(TARGET_NAME "hello") # 目标可执行程序名称
string(TIMESTAMP COMPILE_TIME %m%d_%H%M) # 生成编译时间
# Debug模式(目标:工程名+编译时间)
if(${COMPILE_MODE} MATCHES ${DEBUG_VERSION})
message(STATUS "Compile mode: ${COMPILE_MODE}")
set(USE_RELEASE_MODE 0)
set(CMAKE_BUILD_TYPE "Debug")
set(target ${TARGET_NAME}_${COMPILE_TIME})
# Release模式(目标:工程名+版本号)
else()
message(STATUS "Compile mode: ${COMPILE_MODE}")
set(USE_RELEASE_MODE 1)
set(CMAKE_BUILD_TYPE "Release")
set(VERSION_MAJOR 0) # 一级版本号
set(VERSION_MINOR 0) # 二级版本号
set(VERSION_LEVEL3 1) # 三级版本号
set(target ${TARGET_NAME}_V${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_LEVEL3})
endif()
project(${target})
# 加入一个配置头文件,用于处理 CMake 对源码的设置
configure_file (
"config.h.in"
"../config.h"
)
####################################### 编译选项配置 #######################################
set(CMAKE_CXX_FLAGS "-std=c++11")
set(CMAKE_CXX_FLAGS_RELEASE "-O0 -Wall")
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
set(CMAKE_C_FLAGS "-fdata-sections -g -rdynamic -funwind-tables -ffunction-sections -Wall")
set(CMAKE_CXX_FLAGS "-fdata-sections -Wno-psabi")
####################################### 头文件 ############################################
include_directories(inc)
####################################### 源文件 ############################################
aux_source_directory(src SRCS)
message(STATUS "################## Compile time:${COMPILE_TIME} ##################")
add_executable(${PROJECT_NAME} ${SRCS} main.c)
我们设置:
- debug模式:输出的可执行程序名称带有时间戳。
- release模式:输出的可执行程序名称带有版本号。
我们可以在config.h.in文件里增加一些参数来编译生成对应的C/C ++的宏。
比如,config.h.in里的内容:
#define PROJECT_NAME "@TARGET_NAME@"
#define COMPILE_TIME "@COMPILE_TIME@"
#define VERSION_MAJOR @VERSION_MAJOR@
#define VERSION_MINOR @VERSION_MINOR@
#define VERSION_LEVEL3 @VERSION_LEVEL3@
#define USE_RELEASE_MODE @USE_RELEASE_MODE@
其中,@@符号包含起来的是CMakeLists.txt文件里的变量。
生成对应的头文件config.h:
#define PROJECT_NAME "hello"
#define COMPILE_TIME "0305_2055"
#define VERSION_MAJOR 0
#define VERSION_MINOR 0
#define VERSION_LEVEL3 1
#define USE_RELEASE_MODE 1
实现这一过程是借助configure_file命令生成的,输入config.h.in,输出config.h:
configure_file (
"config.h.in"
"../config.h"
)
我们的C源码中可以使用config.h里的内容,比如main.c:
#include "hello.h"
#include "config.h"
int main(void)
{
#if USE_RELEASE_MODE
printf("VERSION: %d.%d.%d\n", VERSION_MAJOR, VERSION_MINOR, VERSION_LEVEL3);
#endif
print_hello();
return 0;
}
包含了config.h,如果配置为release模式,我们就打印出版本号。
修改CMakeLists.txt里的COMPILE_MODE变量可以切换编译模式。
看看运行结果:
① debug模式:
② release模式: