如何使用自定义构建步骤包含GNU make auto dependencies

时间:2014-12-19 21:07:47

标签: makefile dependencies gnu

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

sample.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)

1 个答案:

答案 0 :(得分: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的副作用,这是您真正需要的。