多目录的makefile

  都已经21世纪了,怎么说程序也不能就一个文件不是,呵呵,郁闷几天,现在终于把这个问题解决了.

  问题描述:现有2个.cpp文件,1个.h文件 分别放在lib和sources文件夹下,顶层makefile如何解决.o所需依赖的文件之间的编译问题?

  解决方案:

    看了很多帖子,发现使用了.d,然后再include进来就可以了,不过我试了,好像不怎么好用,郁闷啊...毕竟是人家的风格,可能我还没读懂,呵呵,为了找到一个我认为最简便,最适合自己的方案,于是我放弃了这种高级模式,回归到原始的方法中(表鄙视偶啊,黑猫白猫,抓到老鼠才是好猫啊 ^_^).

    仔细查找编译器参数,发现一个"-I"参数很好用,可以指定文件的查找目录.不过文章里都提到VPATH变量和vpath命令,我怎么设置都只能找到.c/.cpp文件,就是找不到.h文件,郁闷啊!! = =||(经过实验测试表明vpath/VPAHT只对目标和依赖进行检查,实际语句需要绝对或相对路径才行,问题解决),不知道是不是make瞎了眼,那么明摆着的目录就是看不到,况且我还告诉它了...崩溃,还是回到刚才提到的-I参数上,只要在命令语句上添加上"-I [directory]",如果有多个需要查找的目录就继续添加"-I"参数就行了,我怎么看这个都比其他的容易....也不排除过几天就发现原来.d才是最好的....当然实践出真知啊,先慢慢用着,过一段时间就知道啦.

    历时1个小时的实验...终于把.d弄得差不多了,而且也终于实现了我的目的,多目录编译连接.OK,来看看成果吧:

    

    这里我解释下,我有4个目录,刚才新加了2个...分别是

    lib--存放头文件

    sources--存放源文件

    objs--存放.o

    include--存放.d文件

    这里为了可以使用.d方便的形成依赖关系,所以我们要先高清一个次序,.o依赖.c/.cpp和.d,.d依赖.c/.cpp,所以make检查到这些时,会第一个创建.d文件,这里根据指定的搜索目录进行查找,如果找到那么执行相应创建命令,值得注意的是这里我指定了LIB路径,要不这傻傻编译器又找不到头文件了,呵呵,.d生成完了,找到其对应的上一条依赖关系中的.c/.cpp然后生成相应的.o文件,所以我们看到的结果跟这个执行过程相同.然后这些文件也相应的输出到相应目录中去,方便管理,看着也好看啊.

    然后到了链接步骤了,这里因为所有的.o也被放在了相应的目录下,所以底层目录下是没有需要文件的,那么又需要我们来告诉这个傻傻的编译器去哪里找了,这里用到一个函数addprefix,可以对变量中的项目逐个的添加前缀,这样添加了目录,就可以链接程序了,SO...一个多目录的makefile 制作完成!哈哈,是不是特有成就感那,起码我是这么认为.剩下的就是进入项目中更多的训练了,嵌套make也是必须掌握的...好了今天有点太晚了,困鸟啊....洗洗睡了

  

对于多目录的情况,我们可以使用一个主makefile来管理整个项目,然后在每个子目录下再编写各自的makefile。以下是一个示例: 首先,我们创建一个名为`Makefile`的主makefile,并在其中定义一些变量和规则: ```makefile # 定义子目录 SUBDIRS := dir1 dir2 dir3 # 定义编译器和编译选项 CC := gcc CFLAGS := -Wall -Werror # 定义目标文件存放的目录 OBJDIR := obj # 定义目标文件和可执行文件 TARGET := myprogram OBJS := $(addprefix $(OBJDIR)/, file1.o file2.o file3.o) .PHONY: all clean $(SUBDIRS) all: $(TARGET) $(TARGET): $(OBJS) $(CC) $(CFLAGS) $^ -o $@ # 在每个子目录下执行make命令 $(SUBDIRS): $(MAKE) -C $@ # 生成目标文件的规则 $(OBJDIR)/%.o: %.c | $(OBJDIR) $(CC) $(CFLAGS) -c $< -o $@ # 创建目标文件存放的目录 $(OBJDIR): mkdir -p $@ clean: rm -rf $(TARGET) $(OBJDIR) ``` 然后,在每个子目录下创建各自的makefile,例如`dir1/Makefile`: ```makefile # 定义当前子目录下的源文件 SRCS := file1.c # 生成当前子目录下的目标文件 OBJS := $(addprefix $(OBJDIR)/, $(SRCS:.c=.o)) all: $(OBJS) $(OBJS): $(SRCS) | $(OBJDIR) $(CC) $(CFLAGS) -c $< -o $@ $(OBJDIR): mkdir -p $@ clean: rm -rf $(OBJS) ``` 其他子目录的`Makefile`可以类似地创建。 这样,通过在主makefile中定义需要编译的子目录,并在其中执行各自的make命令,可以实现多目录的编译。同时,每个子目录下的makefile会将编译生成的目标文件放入统一的目标文件存放目录中。 使用`make`命令执行主makefile即可开始编译整个项目。使用`make clean`命令可以清除编译生成的目标文件和可执行文件。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值