GNU make + GCC:让Makefile根据静态模式规则自动生成文件的依赖关系

问题描述 投票:0回答:1

在 GNU make 的

Makefile
中,依赖项的生成和使用如下。这是我在 mad-scientist.net 找到的一种方法,效果非常好(有关完整的 Makefile,请参阅此问题的结尾):

1。指定模块:

MODULES := main bar

2。添加疯狂科学家的魔法:

DEPDIR := .deps
DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.d

$(DEPDIR): ; @mkdir -p $@

DEPFILES := $(SRCS:%.c=$(DEPDIR)/%.d)
$(DEPFILES):

include $(wildcard $(DEPFILES))

3.在对象和可执行文件的规则中使用

DEPDIR
DEPFLAGS

main.x: $(OBJS)
    gcc $(OBJS) -o $@ -lm

%.obj: %.c
%.obj: %.c $(DEPDIR)/%.d | $(DEPDIR)
    gcc -c $< -O2 -o $@ $(DEPFLAGS)

现在我遇到的情况是,某些文件是自动生成的(从示例中的其他位置复制),例如从

bar.c
生成的
orig-bar.c
;与
bar.h
类似。这是使用静态模式规则完成的:

GEN_SRC := bar.c bar.h

$(GEN_SRC): % : orig-%
    cp $< $@

加上这一点,依赖项不完整,我由于不存在的文件而导致构建失败,例如

make
尝试在生成
main.obj
之前构建
bar.h
,但
main.c
包含该标头。

我可以手动添加所有依赖项,例如

bar.obj: bar.h
main.obj: bar.h
,但我想避免这种情况并使用自动依赖项生成。

问题:有没有办法让规则按正确的顺序应用,例如在编译

bar.h
之前生成
main.c


文件内容:

> head main.c orig-bar.[ch]

==> main.c <==
#include <stdio.h>
#include "bar.h"

int main (void)
{
    printf ("Hallo main.\n");
    return 0;
}

==> orig-bar.c <==
#include "bar.h"

==> orig-bar.h <==
/* empty */

生成文件

.SECONDARY: # Don't auto-delete intermediate files.

MODULES := main bar

all: main.x

.PHONY: all clean clean-all

###########################################################################
# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/

SRCS := $(MODULES:%=%.c)
OBJS := $(SRCS:%.c=%.obj)

DEPDIR := .deps
DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.d

$(DEPDIR): ; @mkdir -p $@

DEPFILES := $(SRCS:%.c=$(DEPDIR)/%.d)
$(DEPFILES):

include $(wildcard $(DEPFILES))
#############################################################

# Auto-generate some files.
GEN_SRC := bar.c bar.h

$(GEN_SRC): % : orig-%
    cp $< $@

#############################################################

EXTRA_DEP = Makefile

main.x: $(OBJS) $(EXTRA_DEP)
    gcc $(OBJS) -o $@ -lm

%.obj: %.c
%.obj: %.c $(EXTRA_DEP) $(DEPDIR)/%.d | $(DEPDIR)
    gcc -c $< -O2 -o $@ $(DEPFLAGS)

###########################################################

clean:
    rm -f $(wildcard *.x $(OBJS))

clean-all: clean
    rm -rf $(DEPDIR) $(wildcard $(GEN_SRC))
makefile
1个回答
0
投票

是的,这很不幸。 这与自动生成

version.h
时遇到的问题相同。 稍微次优的版本是在编译
any
源之前生成 version.h (或者在您的情况下生成任何标头)。

草图:

auto-gen-headers := $(filter-out %.c,${GEN_SRC})
${OBJS}: | ${auto-gen-headers}
© www.soinside.com 2019 - 2024. All rights reserved.