makefile 子目录管理

这是针对makefile的一次实验,主要针对于makefile如何管理子路径以及头文件依赖。

1.工程目录组织

    工程目录下包含一个子目录sub以及main.c文件,sub包含文件add.c、add.h。该工程编译后产生一个可执行main文件,该文件实现加法功能,在执行时需要将做加法的参数传入程序。

|-->root

|--------->main.c

|--------->sub

|           --------->add.c

|           ---------->add.h

2.编写makefile

     编译过程都是先生成.o文件,再使用.o文件生成可执行文件。编译过程需要指定需要编译的源文件、头文件路径以及源文件与头文件的依赖关系。

2.1 指定源文件

obj-c =
obj-c += $(wildcard *.c)      #将根目录下所有c文件添加到源文件列表中,obj-c本身为一个字符串。
obj-c += $(wildcard sub/*.c) #将子目录sub下所有c文件添加到源文件列表中。每个文件带相对更文件的路径
obj-o = 
obj-o += $(patsubst %.c, %.o, $(obj-c)) #根据c列表生成o列表

2.2 指定头文件路径

INCLUDES = -Isub  # 将根目录下头文件路径添加到路径列表中

2.3 源文件与头文件依赖

    如果没有此项操作,会出现头文件变更但是依赖于该头文件的c文件不会被编译的问题。

a. DEPENDENCY_LIST = $(patsubst %.o,%.d,$(obj-o)) # 依赖文件加入到依赖文件列表中,依赖文件后缀为.d

b. @gcc   $(INCLUDES) -w -c $< -MMD -MT $@ -o $@ #  -MMD 生成依赖文件 -MT $@ 指定当前依赖文件中目标名称 -o $@ .o文件生成到源文件目录下

c. -include $(DEPENDENCY_LIST) #将所有依赖文件包含到当前makefile中

3.编译过程步骤

1、读入所有的 Makefile。 
2、读入被 include 的其它 Makefile。 
3、初始化文件中的变量。 
4、推导隐晦规则,并分析所有规则。 
5、为所有的目标文件创建依赖关系链。 
6、根据依赖关系,决定哪些目标要重新生成。 
7、执行生成命令。

 

4.源文件

4.1 main.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include "add.h"

int main(int argc, void *argv[])
{    
    printf("%s + %s = %d\r\n", argv[1], argv[2], add(atoi(argv[1]), atoi(argv[2])));
    return 0;
}

4.2 add.c

#include <stdio.h>
#include <stdlib.h>

int add(int a, int b)
{
    return a + b;
}

4.3 add.h

int add(int a, int b);
 

4.4 Makefile

#1.带1级子目录的工程,makefile规则先生成.o文件然后使用所有.o文件生成可执行文件。
#2.自动生成源文件对应.o文件的依赖
#3.使用静态模式生成.o文件
#4.最后链接所有第3步生成文件
#5.将.o .d文件放在out路径下
obj-c =
obj-c += $(wildcard *.c)
obj-c += $(wildcard sub/*.c)
obj-o = 
obj-o += $(patsubst %.c, %.o, $(obj-c))

INCLUDES = -Isub
out-dir = out
obj-list = $(addprefix $(out-dir)/,$(obj-o))
DEPENDENCY_LIST = $(patsubst %.o,%.d,$(obj-o))

all: path $(obj-o)
    @gcc -o main $(obj-o)

#后缀静态模式
.SUFFIXES: .c .o
.c.o:
    @echo "building file "$@    
    @mkdir -p $(out-dir)/$(subst $(notdir $@),,$@)
    @gcc   $(INCLUDES) -w -c $< -MMD -MT $@ -o $@
    @cp $@ $(out-dir)/$@

-include $(DEPENDENCY_LIST)

path:
    @mkdir -p $(out-dir)
    
clean:
    rm *.o *.d
    rm sub/*.o sub/*.d main
    rm -rf $(out-dir)
    
#静态模式
#$(obj-o): %.o:%.c
#    echo $0
#    gcc $(INCLUDES) -c -w $< -MMD -MT $@ -o $@
#-include $(dependency_list)

.PHONY: all path clean

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值