Bionix1441 Bionix1441 - 1 month ago 6
C Question

Rule not recognized in makefile?

I have a basic makefile to compile C files necessary for compiling a shared library, I have an error because the makefile is not recognized:

SOURCES=/home/test/project/sources
OBJECTS=/home/test/project/objects

$(OBJECTS)/%.o:$(SOURCES)/%.c
$(CC) -fPIC -c $^ -o $@

sharedlib: $(OBJECTS)/%.o
$(CC) -shared -o libsharedlib.so $<


When I run make I get that there is no rule for target:
$(OBJECTS)/%.o
needed by
sharedlib
. While the rule is written right before sharedlib.

Answer

The main problem is that nowhere you are explicitly telling make what your source files are. Start by doing that:

SOURCEDIR=/home/test/project/sources
SOURCES=$(wildcard $(SOURCEDIR)/*.c)

Then, derive the object file names from the source file names by substituting .c for .o:

OBJECTDIR=/home/test/project/objects
OBJECTS=$(patsubst $(SOURCEDIR)/%.c,$(OBJECTDIR)/%.o,$(SOURCES))

You can still keep your generic rule to build object files:

$(OBJECTDIR)/%.o: $(SOURCEDIR)/%.c
        $(CC) -fPIC -c $^ -o $@

But you give the explicit list of object files to the rule to make sharedlib:

libsharedlib.so: $(OBJECTS)
        $(CC) -shared -o $@ $<

Note that I made the name of the rule the same as the file that is being generated. That's important, because calling make twice in a row will then skip building the library a second time. You can always add an alias if you want:

sharedlib: libsharedlib.so

In that case, it's also good to tell make that sharedlib is not a real file:

.PHONY sharedlib

This prevents weird things from happening if you ever did have a file called sharedlib in the directory.