一、问题描述
由于工作需要,本人需要同时维护多套代码(不同场景版本、debug版、release版等),同时每套代码之间大同小异,因此想通到设置宏定义进行条件编译,实现代码的多版本管理。
二、解决思路
1、思路一:在头文件和源文件中,直接定义宏定义。
宏定义的定义和使用都在一个文件内
//a.cpp
//步骤1、定义宏定义
#define SAVE_EXCL_AND_VIDEO
int func()
{
//...
//步骤2、使用宏定义
#ifdef SAVE_EXCL_AND_VIDEO
//耗时信息保存到txt里
m_outtxt<<"数据验证耗时:" << timeDelay<< "ms" << std::endl;
#endif
//...
}
优点:写法简单,即插即用。
缺点:宏定义作用域有限,当工程较大、多个文件都需要进行条件编译时,需要逐个文件定义宏定义,效率低、容易出错。
2、思路二 在makefile中定义宏定义(适用中大工程)
步骤1、makefile中定义宏定义
#保存检测结果视频、检测结果excl开关
SAVE_EXCL_AND_VIDEO_ENABLE :=0
ifeq (1, ${SAVE_EXCL_AND_VIDEO_ENABLE})
$(info *******************-DSAVE_EXCL_AND_VIDEO*********************)
CFLAGS += -DSAVE_EXCL_AND_VIDEO#重要!注意:格式为:-D+宏定义名,因此宏定义实际为VERSION_1
endif
#编译版本(场景)选择,#1:功能场景1; 2:功能场景2;
VERSION_CONTROL :=1
ifeq (1, ${VERSION_CONTROL})
$(info *******************-DVERSION_1*********************)
CFLAGS += -DVERSION_1#重要
else
$(info *******************-DVERSION_2
endif
//步骤2、源码中使用宏定义
//...
#ifdef SAVE_EXCL_AND_VIDEO
//耗时信息保存到txt里
m_outtxt<<"数据验证耗时:" <<timeDelay<< "ms" << std::endl;
#endif
//...
优点:该种方法,只需要在makefile中定义好宏定义,其他地方不需要再定义,直接使用就好,因为此时宏定义作用域为工程的所有文件。效率高、不容易出错。
缺点:不是很直观
======================================
补充1、宏定义定义字符串、命名空间使用
//conditional compilationlinger
#ifdef VERSION_1
namespace name1{ //使用相应命名空间
#define VERSION_STR(IN_STRING) #IN_STRING //#为传递字符串的标记符
#define VERSION_NAME_STRING VERSION_STR(AAA) //#后续代码中的VERSION_NAME_STRING ,会在预处理阶段被替换为字符串类型的AAA
#elif VERSION_2
namespace name2{
#define VERSION_STR(IN_STRING) #IN_STRING
#define VERSION_NAME_STRING VERSION_STR(BBB)
#endif
补充2、makefile中变量值后面的空格问题
链接跳转