I am doing a build system based on recursive(toxic but not matter) make. The main problem I have is that make recreates the libraries I instruct it to do even if there were no changes to an of the *o files.

Here is the section in on of my makefiles that handles the static library creation.

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)

Under certain directories in their respective makefiles, the $(LIB_TARGET) is defined with the library name and each subdir uses the prefixes makefile to know how to create it's share. Now my biggest problem is that first run it is normal to create everything but on the second run, or every subsequent run without any changes to anything in the code, the libraries are recreated(but not *d or *o files, they are not recreated, they are not deleted, their timestamp is not changed, which is normal).

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 -------

NOTE: this is from the second/third run, here it can be seen that *d and *o are not recreated

I created the rule to use files, the only problem that I can see is that I put the libraries in a special directory and not in the same as the one it gets the sources from. Any idea on how to have to solve this and not have the system also recreate the libraries?

Thank you.

有帮助吗?

解决方案

Anytime you see a recipe which creates a target file which is not exactly $@, you know it's wrong and you're going to have this problem.

Here, you tell make you're going to create a target that matches the pattern %.a. make matches that pattern to libInterface.a and sets $@ to libInterface.a and invokes your recipe.

But your recipe doesn't build $@, it builds $(LIBDIR)/$@ which is a totally different file. So the next time you run make, it will look for libInterface.a as the prerequisite to all, see that it doesn't exist, and re-run the rule you provided... which again will not create the target you told make it would, $@, but instead create some other file make doesn't know anything about.

You need to use:

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)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top