Makefile如何动态改变.o生成路径

发布于 2022-10-15 10:11:57 字数 695 浏览 28 评论 0

本帖最后由 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的输出路径,但是它是自动变量,但是在命令中又无法动态改变自定义的变量。
如何做呢? 请高人赐教!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

兲鉂ぱ嘚淚 2022-10-22 10:11:57

搞定,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文件也不会出问题了。

你丑哭了我 2022-10-22 10:11:57

本帖最后由 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不会自动创建,必须手动创建

复制代码

寄人书 2022-10-22 10:11:57

南邮滴?  支持一下。。。

吃颗糖壮壮胆 2022-10-22 10:11:57

本帖最后由 npucwj 于 2011-04-18 22:31 编辑

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

慕巷 2022-10-22 10:11:57

请教楼主两个问题:
1.如何实现增量编译(即仅编译发生变化的文件)?
2.楼主的方法将.o和.c建立了依赖关系 ...
npucwj 发表于 2011-04-18 22:29

1. makefile本来就是增量编译

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

已下线请稍等 2022-10-22 10:11:57

%.o:%.c
        @$(CC) $(CPPFLAGS) $(CFLAGS) -o $(subst $(SRCDIR),$(OBJECTDIR),$@) -c $<

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

痴情换悲伤 2022-10-22 10:11:57

回复 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打出中间的变量,就理解了。

江挽川 2022-10-22 10:11:57

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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文