Bionix1441
Bionix1441

Reputation: 2319

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.

Upvotes: 1

Views: 431

Answers (2)

AdRiX
AdRiX

Reputation: 79

The library rule

sharedlib: $(OBJECTS)/%.o

is not enough to tell Make which objs are needed for the library.

This should work, and gives explicit control on which are the sources/objs pairs you want in the library:

SOURCESDIR=/home/test/project/sources
OBJECTDIR=/home/test/project/objects

OBJLIST = \
    $(OBJECTS)/file1.o \
    $(OBJECTS)/file2.o

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

sharedlib: $(OBJLIST)
    $(CC) -shared -o libsharedlib.so $<

Upvotes: 1

G. Sliepen
G. Sliepen

Reputation: 7984

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.

Upvotes: 5

Related Questions