Search code examples
gnu-makearchive

Make rule using `$<` only adding one object to archive library


I feel stupid, but I cannot find the solution myself:

I have a Makefile that correctly builds objects from C source, and I want to place $(OBJECTS) in an archive library. I'm using GNU Make 4.0.

x.a: $(OBJECTS)
        echo "$< ($(OBJECTS))"
        $(AR) $(ARFLAGS) $@ $<

(Lines are indented with TABs in original. The echo was added for debugging purposes only, The $(AR) $(ARFLAGS) $@ $< was copied from make's internal rules)

Make outputs (at the end after the objects were built):

echo "log_thread/log_thread.o (log_thread/log_thread.o log_thread/thread.o)"
log_thread/log_thread.o (log_thread/log_thread.o log_thread/thread.o)
ar rv x.a log_thread/log_thread.o
ar: creating x.a
a - log_thread/log_thread.o

So I expect both objects modules to be added to the library x.a, but $< only contains one object module, as opposed to $(OBJECTS)).

My Make knowledge may be a little rusty, maybe that's why I don't get it. Of course both object modules exist, and the output was created after having removed x.a (the original file is a bit more complex).


Solution

  • I'm not sure where the confusion lies: The $< automatic variable contains the first prerequisite only, as per definition. See the GNU make manual.

    To get all prerequisites newer than the target, $? is the correct automatic variable. So the correct rule probably is:

    x.a: $(OBJECTS)
            echo "$? ($(OBJECTS))"
            $(AR) $(ARFLAGS) $@ $?