Bionix1441 Bionix1441 - 1 month ago 12
C Question

Implicit rule skipped by makefile?

I have a Makefile for compiling some C source files, and put the output in different Build directory, it looks a bit like the makefile below:

OBJDIR=/home/test/alpha
SRCDIR=/home/test/beta
# make variable will be exanded when used (and not at declaration)
OBJECTS:= $(addprefix $(OBJDIR), $(notdir $(patsubst %.c,%.o,$(wildcard $(SRCDIR)/*.c))))

SOURCES:=$(wildcard $(SRCDIR)/*.c))

.PHONY: copySourcesOver linkSources sharedLibrary
copySourcesOver: $(SOURCES)
cp $(SOURCES) $(OBJDIR)/

# pattern
$(OBJECTS)/%.o : $(OBJECTS)/%.c
gcc -fPIC $< -o $@

linkSources: $(OBJECTS)
gcc -shared -o libshared.so $@

sharedLibrary: copySourcesOver \
linkSources \


So what is happening is that when I run the target:

make sharedLibrary


I get no rule for making
$(OBJECTS)
. The interesting part is when I make this target a second time I don't get this makefile error, and I get the shared library.

I have done a bit of research and I have found out that Makefile does not expand implicit rules for PHONY targets, that is why I have changed
linkSources
from a PHONY target to a normal file. But unfortunately it does not solve the issue.

I don't see why the pattern is only executed the second time I run
make sharedLibrary

Answer

Make executes in 2 phases. In the first phase it checks what targets are out-of-date and need updating. In the second phase it executes the commands that updates the targets. That means that it checks that the object files are up to date before it actually copies the source files.

So it checks and determines that the object files are up-to-date THEN it copies the (updated) source files to $(OBJDIR).

There is some good reading on this subject in the docs.

Comments