免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 15389 | 回复: 11
打印 上一主题 下一主题

Makefile如何动态改变.o生成路径 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-04-13 19:33 |只看该作者 |倒序浏览
本帖最后由 lli_njupt 于 2011-04-13 19:34 编辑

只是用一个Makefile如何动态改变.o生成路径呢。
比如一个源码目录为src, 其中包含两个目录a和b,分别又包含a.c 和b.c,与src同目录有一个Makefile,
a和b中没有单独的Makefile。Makefile通过VPATH自动查找。

src/a/a.c
src/b/b.c

如何写Makefile使临时文件.o .d等自动生成到
build/a/a.o 和a.d
build/b/b.o 和b.d

通常可以做到所有临时文件都生成到build下,研究了一下午了,
如下规则:

......
OBJECTDIR=build

......
$(OBJECTDIR)/%.o: %.c $(DEPS_DIR)       
        @$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $<

在Makefie的命令行中$@就是.o .d的输出路径,但是它是自动变量,但是在命令中又无法动态改变自定义的变量。
如何做呢? 请高人赐教!

论坛徽章:
0
2 [报告]
发表于 2011-04-14 10:15 |只看该作者
搞定,OBJS是所有要生成的build下.o的绝对路径
  1. all:$(OBJS)
  2.    @echo -n ""  #此行必须的,不然依赖会去找all.o

  3. %.o: %.c       
  4.         @$(CC) $(CFLAGS) -o $@ -c $(subst build,src,$<) #更改$<中的build为src,因为$<的值是根据$@取得的

  5. %.c:
  6.         @[ ! -e $@ ] && mkdir -p $(dir $@) #如果不存在,则自动创建build下的路径
复制代码
从此只需要一个Makefile,而无论如何在src下添加.c和创建目录,特别是不同的目录创建同名的.c文件也不会出问题了。

论坛徽章:
1
黑曼巴
日期:2020-02-27 22:54:26
3 [报告]
发表于 2011-04-14 10:16 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
4 [报告]
发表于 2011-04-14 19:07 |只看该作者
本帖最后由 lli_njupt 于 2011-04-14 19:16 编辑

刚刚发现这个写法会导致依赖检查无效,因为OBJS中的src路径全替换为了build路径,再小改动一下:

使OBJS依然为src路径,
  1. %.o:%.c #这里的%代表的依然是真正的src,所以检查依赖有效
  2.         @$(CC) $(CPPFLAGS) $(CFLAGS) -o $(subst $(SRCDIR),$(OBJECTDIR),$@) -c $< #这里替换生成的.o路径

  3. %.c:       
  4.         @[ ! -e $@ ] && $(MKDIR) -p $(dir $(subst $(SRCDIR),$(OBJECTDIR),$@))#这里检查需要生成的.o路径是否存在,gcc不会自动创建,必须手动创建
复制代码

论坛徽章:
0
5 [报告]
发表于 2011-04-16 11:15 |只看该作者
南邮滴?  支持一下。。。

论坛徽章:
0
6 [报告]
发表于 2011-04-18 22:29 |只看该作者
本帖最后由 npucwj 于 2011-04-18 22:31 编辑

请教楼主两个问题:
1.如何实现增量编译(即仅编译发生变化的文件)?
2.楼主的方法将.o和.c建立了依赖关系,有没有办法使.o再同.c中的包含的.h建立依赖关系?

论坛徽章:
2
天蝎座
日期:2014-03-28 10:18:052015年亚洲杯之乌兹别克斯坦
日期:2015-02-10 11:32:25
7 [报告]
发表于 2011-04-19 09:11 |只看该作者
请教楼主两个问题:
1.如何实现增量编译(即仅编译发生变化的文件)?
2.楼主的方法将.o和.c建立了依赖关系 ...
npucwj 发表于 2011-04-18 22:29



1. makefile本来就是增量编译

2. 有点复杂,用gcc本身的选项,可以参考http://bbs.chinaunix.net/thread-2293695-1-1.html

论坛徽章:
0
8 [报告]
发表于 2011-04-19 13:17 |只看该作者
%.o:%.c
        @$(CC) $(CPPFLAGS) $(CFLAGS) -o $(subst $(SRCDIR),$(OBJECTDIR),$@) -c $<


目标%.o和最终生成的-o $(subst $(SRCDIR),$(OBJECTDIR),$@)并不是一个文件,所以每次make时,都会重新编译,没有实现增量编译。

论坛徽章:
0
9 [报告]
发表于 2011-04-19 14:45 |只看该作者
回复 5# baiyang0817
  1. %.o:%.c #这里的%代表的依然是真正的src,所以检查依赖有效
  2.         @$(CC) $(CPPFLAGS) $(CFLAGS) -o $(subst $(SRCDIR),$(OBJECTDIR),$@) -c $< #这里替换生成的.o路径

  3. %.c:        
  4.         @[ ! -e $@ ] && $(MKDIR) -p $(dir $(subst $(SRCDIR),$(OBJECTDIR),$@))#这里检查需要生成的.o路径是否存在,gcc不会自动创建,必须手动创建
复制代码
请教楼主两个问题:
1.如何实现增量编译(即仅编译发生变化的文件)?
==>请仔细看上面的代码,只要理解了$<和$@是什么意思,就可以看懂了, 这里在生成./src/a/a.o的时候,要依赖./src/a/a.c,只要a.c更新了,那么就会自动编译a.o了。
SRCDIR指代的是./src  OBJECTDIR指代的是./build。所以@[ ! -e $@ ] && $(MKDIR) -p $(dir $(subst $(SRCDIR),$(OBJECTDIR),$@))这句话的意思就是根据需要生成的
./src/a/a.o 如果不存在./build/a/,则创建路径./build/a/。@$(CC) $(CPPFLAGS) $(CFLAGS) -o $(subst $(SRCDIR),$(OBJECTDIR),$@) -c $<中的-o后的路径是将
创建的.o放到$(subst $(SRCDIR),$(OBJECTDIR),$@) 中。所以你所说的增量编译已经实现了。

2.楼主的方法将.o和.c建立了依赖关系,有没有办法使.o再同.c中的包含的.h建立依赖关系?
关于.h的依赖,你需要熟悉gcc 的-MM -MD,通常Makefile会自动解决.h依赖的依赖问题。

最好你写个间的的Makefile用上面的依赖测试一下,用echo打出中间的变量,就理解了。

论坛徽章:
0
10 [报告]
发表于 2011-04-19 19:45 |只看该作者
1.如何实现增量编译(即仅编译发生变化的文件)?
==>请仔细看上面的代码,只要理解了$<和$@是什么意思,就可以看懂了, 这里在生成./src/a/a.o的时候,要依赖./src/a/a.c,只要a.c更新了,那么就会自动编译a.o了。

前面关于增量编译的表述可能不是很清楚,应该是指若a.c没有修改(假设相关的头文件也没有修改),则就不需要再编译a.o了,由于./src/a/a.o没有生成(每次make之后是生成./build/a/a.o),岂不是每次make之后还会继续编译生成./build/a/a.o?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP