2

我正在做一个基于递归(有毒但无关紧要)的构建系统。我遇到的主要问题是即使对 *o 文件没有任何更改,make 也会重新创建我指示它执行的库。

这是我的生成文件中处理静态库创建的部分。

all: $(DEPS) $(OBJS) $(LIB_TARGET)

### Archive into a library file (.a)
%.a: $(OBJS)
    @echo $(MSG_L)
    @echo 'Adding $< to library $@'
    $(AR) $(ARFLAGS) $(LIB_DIR)/$@ $^
    @echo $(MSG_L)

在它们各自的 makefile 中的某些目录下,$(LIB_TARGET) 是用库名称定义的,每个子目录使用前缀 makefile 来知道如何创建它的共享。现在我最大的问题是,第一次运行创建所有内容是正常的,但在第二次运行时,或者每次后续运行都没有对代码中的任何内容进行任何更改,重新创建库(但不是 *d 或 *o 文件,它们不是重新创建,它们没有被删除,它们的时间戳没有改变,这是正常的)。

make -C modules all
make[3]: Entering directory `F:/automata/tmp/remake/src/modules'
make -C interface all
make[4]: Entering directory `F:/automata/tmp/remake/src/modules/interface'
make -C cli all
make[5]: Entering directory `F:/automata/tmp/remake/src/modules/interface/cli'
------- make Lib -------
Adding cli.o to library libInterface.a
avr-ar rcs F:/automata/tmp/remake//tmp/app/brick/lib/atmega328p/libInterface.a c
li.o
------- make Lib -------

注意:这是第二次/第三次运行,这里可以看出 *d 和 *o 没有重新创建

我创建了使用文件的规则,我能看到的唯一问题是我将库放在一个特殊的目录中,而不是与它从中获取源的目录相同。关于如何解决这个问题而不让系统也重新创建库的任何想法?

谢谢你。

4

1 回答 1

3

每当您看到创建了不完全 $@目标文件的配方时,您就知道这是错误的,并且您将遇到此问题。

在这里,您告诉 make 您将创建一个与模式匹配的目标%.a。使该模式匹配libInterface.a并设置$@libInterface.a调用您的配方。

但是你的食谱没有构建$@,它构建$(LIBDIR)/$@的是一个完全不同的文件。所以下次你运行时make,它会寻找libInterface.a作为的先决条件all,发现它不存在,然后重新运行你提供的规则......这又不会创建你告诉它的目标$@,但是而是创建一些其他文件 make 对此一无所知。

你需要使用:

LIB_TARGET = $(LIB_DIR)/libInterface.a

....

### Archive into a library file (.a)
$(LIB_DIR)/%.a: $(OBJS)
        @echo $(MSG_L)
        @echo 'Adding $< to library $@'
        $(AR) $(ARFLAGS) $@ $^
        @echo $(MSG_L)
于 2014-04-23T14:04:43.263 回答