玩转Makefile | 编译有共用文件的多个程序

0. 相关阅读

    玩转Makefile | 系列综述

    玩转Makefile | 基础入门

    玩转Makefile | 四步教你从零开始写Makefile

    玩转Makefile | 企业项目Makefile实例

    玩转Makefile | 编译有共用文件的多个程序

    玩转Makefile | 一次编译多个目标

 

1. 使用场景

在企业项目中,经常有这样的场景:多个应用程序同时共用某几个文件。如果把这几个应用程序分别用一个文件夹管理的话,将出现文件冗余的情况。而且不易管理,譬如,当共用文件需要修改时,每个程序所对应的那个共同文件都应该修改一遍,以保证一致。

针对这样的问题,完全可以把共用的代码放在一个文件夹,另外每个应用程序再单独放在自己的文件夹里。编译的时候每个应用程序编译自己的文件及共用文件即可。这样结构比较明了,也比较容易管理。

 

2. 代码展示

在此我们模拟了上述的情景,有两个应用程序,分别为application1及application2,分别共用了common.h及common.c这两个文件。完整代码可以从这里获取。

 

文件夹的结构如下:

源代码如下:

//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. 编译完毕执行效果

 

 

---------------

码字不易,点个赞再走呗~

我是良许,世界500强外企 Linux 开发工程师,专业生产 Linux 干货。欢迎关注我的公众号「良许Linux」,回复「1024」获取最新最全的技术资料,回复「入群」进入高手如云技术交流群;提供永久免费 CSDN 资料下载服务。

 

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

良许Linux

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值