【问题标题】:How to include GNU make auto dependecies with custom build steps如何在自定义构建步骤中包含 GNU make 自动依赖项
【发布时间】:2015-02-18 20:27:52
【问题描述】:

我正在尝试在多个目录中创建具有多个源的 Makefile。我非常接近,但依赖项无法正常工作。 .d 文件正在正确创建。它正确列出了sample.o:sample.c options.h。如果我更改 sample.c,它会重新编译和链接。如果我更改 options.h,它会说一切都是最新的。我认为问题在于将 .c 编译为 .o 的显式规则覆盖了 .d 文件中的规则。 问题是如何包含依赖项并定义自己的规则来构建它?

样本.c:

#include "options.h"
int main(int argc, char** argv) {return(0);}

options.h:

#define SAMPLE 1 

目录结构

     ---------- dir1
                options.h      
     ---------- dir2
                sample.c
     ---------- output
                sample.o
                sample.d

生成文件:

TARGET=output/sample
CC=gcc
CFLAGS=-Wall -O2 -g  
LDFLAGS=-g
LIBS+=-lm
PATHS=-Idir1 -Idir1/dir2
CORE_SRC += sample.c  
SRCS+= $(addprefix dir1/dir2/, $(CORE_SRC))  
OBJS:= $(addprefix output/, $(SRCS:.c=.o))
DEPS:= $(OBJS:.o=.d)

.PHONY: all
all: $(TARGET)

$(TARGET) : $(OBJS) $(DEPS)
    @echo "Linking ..."
    $(CC) $(LDFLAGS) -o $@  $(OBJS) 

output/%.d: %.c 
    @echo "generating dependency  $@"
    @mkdir -p output/$(dir $*.d)
    $(CC) -MM $(CFLAGS) $(PATHS) $^ > output/$*.d
    @mv -f output/$*.d output/$*.d.tmp
    @sed -e 's|.*:|$*.o:|' < output/$*.d.tmp > output/$*.d
    @sed -e 's/.*://' -e 's/\\$$//' < output/$*.d.tmp | fmt -1 | \
      sed -e 's/^ *//' -e 's/$$/:/' >> output/$*.d
    @rm -f output/$*.d.tmp

output/%.o: %.c output/%.d
    @echo "Compiling $@ from $*.c"
    @mkdir -p output/$(dir $*.o)
    $(CC) -c $(CFLAGS) $(PATHS) $*.c -o output/$*.o

-include $(DEPS)

【问题讨论】:

  • 我认为我编辑正确。如果我没有,请检查并修复它。

标签: makefile dependencies gnu


【解决方案1】:

问题似乎是您的sample.dsample.o 的规则:

sample.o: sample.c options.h

但该规则实际上并没有帮助,因为您尝试构建的目标不是sample.o,而是output/dir1/dir2/sample.o

您可以修改 output/%.d 规则,但我认为简化整个方案要容易得多。去掉output/%.d规则,修改这两条:

$(TARGET) : $(OBJS)
    @echo "Linking ..."
    $(CC) $(LDFLAGS) -o $@ $^

output/%.o: %.c
    @echo "Compiling $@ from $*.c"
    @mkdir -p output/$(dir $*.o)
    $(CC) -c $(CFLAGS) $(PATHS) -MMD $< -o $@

这样,Make 将构建 sample.d 作为构建 sample.o 的副作用,而这正是您真正需要的。

【讨论】:

  • @EtanReisner:它确实自动获取新的标头依赖项(但仅在需要时),它确实更正了.d 文件。试试看!
  • 老实说,我不确定.d 文件的内容。那是一个真正的(懒惰的)问题。哦,当然它只选择新的头文件...您必须修改 .c 文件才能添加它们。对不起,噪音。 =)
  • @EtanReisner:这是一个聪明的把戏,不是吗?我希望我可以说我发明了它,但功劳属于Tom Tromey
  • 是的。一旦你解释了它,我就记得当我首先阅读该页面时需要说服自己清楚地工作。我仍然想知道在该目标中专门列出 .d 文件是否会有一些好处,但还没有全部完成。
  • 这绝对更干净。唯一剩下的问题是它没有检测到我何时修改 options.h。如果您编辑/触摸 options.h,然后在不清理的情况下重新制作,则表示无需为所有人​​做任何事情。 “.d”文件正确地将 options.h 列为 sample.o 的依赖项,但它不起作用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-23
  • 1970-01-01
  • 2011-11-28
  • 1970-01-01
  • 2013-09-29
  • 2017-11-18
相关资源
最近更新 更多