1. 使用场景
在企业项目中,经常有这样的场景:多个应用程序同时共用某几个文件。如果把这几个应用程序分别用一个文件夹管理的话,将出现文件冗余的情况。而且不易管理,譬如,当共用文件需要修改时,每个程序所对应的那个共同文件都应该修改一遍,以保证一致。
针对这样的问题,完全可以把共用的代码放在一个文件夹,另外每个应用程序再单独放在自己的文件夹里。编译的时候每个应用程序编译自己的文件及共用文件即可。这样结构比较明了,也比较容易管理。
2. 代码展示
在此我们模拟了上述的情景,有两个应用程序,分别为application1及application2,分别共用了common.h及common.c这两个文件。完整代码可以在公众号内回复mk3免费获取。
文件夹的结构如下:
源代码如下:
//common.h 就一个共用变量及函数声明 #define COMMON_VAR 1024 void common_fun(); //common.c 就一个共用函数 void common_fun() { printf("this is a common function.\n"); } //application1.h #define APP1_GREETING "this is app1" //application1.c int main() { printf("hello, %s\n", APP1_GREETING); printf("common var is: %d\n", COMMON_VAR); //此处用到了共用变量 common_fun(); //此处调用了共用函数 } //application2.h #define APP2_GREETING "this is app2" //application2.c int main() { printf("hello, %s\n", APP2_GREETING); printf("common var is: %d\n", COMMON_VAR); //此处用到了共用变量 common_fun(); //此处调用了共用函数 }
Makefile如下:
NAME_APP1 = app1 NAME_APP2 = app2 TARGETS = $(NAME_APP1) $(NAME_APP2) SOURCE_COMMON = $(wildcard ./00_Common/*.c) SOURCE_APP1 = $(SOURCE_COMMON) $(wildcard ./01_Application1/*.c) SOURCE_APP2 = $(SOURCE_COMMON) $(wildcard ./02_Application2/*.c) OBJ_APP1 = $(patsubst %.c, %.o, $(SOURCE_APP1)) OBJ_APP2 = $(patsubst %.c, %.o, $(SOURCE_APP2)) INCLUDE_COMMON = -I./00_Common/ CFLAGS = -Wall -c CC = gcc all: $(TARGETS) $(NAME_APP1): $(OBJ_APP1) @mkdir -p output/ $(CC) $(OBJ_APP1) -o output/$(NAME_APP1) $(NAME_APP2): $(OBJ_APP2) @mkdir -p output/ $(CC) $(OBJ_APP2) -o output/$(NAME_APP2) %.o: %.c $(CC) $(INCLUDE_COMMON) $(CFLAGS) $< -o $@ .PHONY: clean clean: rm -rf $(OBJ_APP1) $(OBJ_APP2) output/
3. 编写思路
1. 使用wildcard函数将共用文件及各自的文件全部找出。各个应用程序还应加上共用文件,否则编译不过。
SOURCE_COMMON = $(wildcard ./00_Common/*.c) SOURCE_APP1 = $(SOURCE_COMMON) $(wildcard ./01_Application1/*.c) SOURCE_APP2 = $(SOURCE_COMMON) $(wildcard ./02_Application2/*.c)
2. 使用patsubst将应用程序的.c文件转化为.o文件,如下:
OBJ_APP1 = $(patsubst %.c, %.o, $(SOURCE_APP1)) OBJ_APP2 = $(patsubst %.c, %.o, $(SOURCE_APP2))
3. 加上共用头文件路径:
INCLUDE_COMMON = -I./00_Common/
4. 编写规则:
all: $(TARGETS) #主要目标为所有将要编译的程序 $(NAME_APP1): $(OBJ_APP1) #各个要编译的目标,依赖从以上几步已经获取完毕 @mkdir -p output/ $(CC) $(OBJ_APP1) -o output/$(NAME_APP1) $(NAME_APP2): $(OBJ_APP2) @mkdir -p output/ $(CC) $(OBJ_APP2) -o output/$(NAME_APP2)
4. 编译完毕执行效果