绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
玩转Makefile | 编译有共用文件的多个程序
2019-02-19 09:28:02
我是良许,世界500强外企 Linux 工程师,专业生产 Linux 干货,欢迎关注我的知乎「良许Linux」,欢迎点赞,收藏!

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


码字不易,如果您觉得有帮助,麻烦点个赞再走呗~

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

微信搜索公众号【良许Linux】,后台回复关键字:

  1. 回复【1024】:免费获取不断更新的海量技术资源;
  2. 回复【CSDN】:免费进入CSDN资源下载群;
  3. 回复【进群】:免费进入高手如云技术交流群。

干货分享 · 资源共享 · 认知提高 · 英语学习

分享好友

分享这个小栈给你的朋友们,一起进步吧。

Linux技术精选专区
创建时间:2020-07-08 10:30:23
Linux,全称GNU/Linux,是一套免费使用和自由传播的类UNIX操作系统,其内核由林纳斯·本纳第克特·托瓦兹于1991年次释出,它主要受到Minix和Unix思想的启发,是一个基于POSIX和Unix的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的Unix工具软件、应用程序和网络协议。
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

技术专家

查看更多
  • dapan
    专家
戳我,来吐槽~