在Linux系统下Makefile和C/C++语言都有提供条件选择编译的语法,就是在编译源码的时候,可以选择性地编译指定的代码。这种条件选择编译的使用场合有好多,例如我们开发一个兼容标准版本与定制版本兼容的项目,那么,一些与需求密切相关的代码,就需要进行选择性编译;再比如我们开发一个兼容windows系统和Linux系统运行的项目,那么,一些与操作系统密切相关的代码,就需要进行选择性编译。在这篇文章就简单地讲一下基于Linux系统下通过Makefile实现条件选择编译的方法,下面将以两个功能模块module1,module2之间的条件选择编译为例子。
1.首先,在Linux目录下创建一个名为“proj”的目录。运行指令:mkdir -p proj
2.在该目录下依次创建如下文件:
module1.c内容如下所示:
#include<stdio.h>
#include<stdlib.h>
void module_1_func()
{
printf("run module 1\n");
}
module2.c内容如下所示:
#include<stdio.h>
#include<stdlib.h>
void module_2_func()
{
printf("run module 2\n");
}
main.c内容如下所示:
#include<stdio.h>
#include<stdlib.h>
void main()
{
printf("start test demo!\n");
printf("start module1 demo!\n");
module_1_func();
printf("start module2 demo!\n");
module_2_func();
}
Makefile内容如下所示:
include ./config
CPROG = test
BIN = $(CPROG)
CC= gcc
OBJS=main.o module1.o module2.o
all: $(BIN)
clean:
rm -f $(OBJS) $(BIN)
$(BIN): $(OBJS)
$(CC) -o $(BIN) $(OBJS) $(CFLAGS) $(LDFLAGS) $(CFLAGS_EXTRA)
3.使用“make clean;make”编译之后生成一个名为“test”的可执行文件,运行这个可执行文件,结果如下图所示:

4.在当前目录下新增一个名为”config”的配置文件,在这个文件加入module1和module2的控制开关,内容如下所示(默认module1,module2功能模块关闭):
CONFIG_MODULE1=n
CONFIG_MODULE2=n
修改Makefile,内容如下:
#包含当前目录下的config文件
include ./config
CPROG = test
BIN = $(CPROG)
CC= gcc
OBJS=main.o
#新增module1编译选项的条件判断
ifeq ($(CONFIG_MODULE1),y)
CFLAGS += -DHAVE_MODULE1
OBJS+=module1.o
endif
#新增module2编译选项的条件判断
ifeq ($(CONFIG_MODULE2),y)
CFLAGS += -DHAVE_MODULE2
OBJS+=module2.o
endif
all: $(BIN)
clean:
rm -f $(OBJS) $(BIN)
$(BIN): $(OBJS)
$(CC) -o $(BIN) $(OBJS) $(CFLAGS) $(LDFLAGS) $(CFLAGS_EXTRA)
修改main.c,内容如下所示:
#include<stdio.h>
#include<stdlib.h>
void main()
{
printf("start test demo!\n");
#ifdef HAVE_MODULE1
printf("start module1 demo!\n");
module_1_func();
#endif
#ifdef HAVE_MODULE2
printf("start module2 demo!\n");
module_2_func();
#endif
}
5.修改config文件,并进行多次编译运行测试。
CONFIG_MODULE1=y
CONFIG_MODULE2=y

CONFIG_MODULE1=n
CONFIG_MODULE2=y

CONFIG_MODULE1=y
CONFIG_MODULE2=n

CONFIG_MODULE1=n
CONFIG_MODULE2=n

由以上一系列测试可知,通过修改”config”配置文件,可以很方便的根据不同的需求实现对代码进行条件编译。
总结:
条件编译使得我们可以按不同的条件编译不同的代码段,通过编译器命令行能够定义预处理器使用的宏,因而可以产生不同的目标代码,不仅可以根据需求对代码进行裁剪,缩小目标文件的体积,与此同时也可以将代码移植到不同的平台或不同的操作系统,提高软件开发效率。