【Linux】如何生成编译版本及编译时间?


实际开发中,我们有可能需要对程序的编译时间、版本号进行把控。

实现的方法可能有很多种,这里分享一种便捷的方法——使用cmake的自定义编译选项。

关于cmake的基础知识:Hello系列 | cmake简明基础知识

cmake支持自定义编译选项,我们可以根据项目需要自定义一些编译选项。cmake借助一个.h.in后缀的文件生成对应的.h头文件,而我们的代码中可以使用这个头文件。

假如,我们建立的demo工程结构如下:

image-20220306100601848

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模式:

image-20220306102415337

② release模式:

image-20220306102736895



文章作者: 杂烩君
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 杂烩君 !
  目录