Simplifying the Makefile

I use this Makefile to build a small C++ application:

BIN_CPP=Main
CPP=g++
INCLUDES_APR=/usr/local/apr/include/apr-1
LIB_SRC = $(wildcard My*.cpp)
LIB_OBJ = $(LIB_SRC:.cpp=.o)
RM=rm

all: Main

MyClass.o: MyClass.cpp
    $(CPP) -I$(INCLUDES_APR) -c $< -o $@

MyModel.o: MyModel.cpp
    $(CPP) -I$(INCLUDES_APR) -c $< -o $@

libMyLibrary.so: $(LIB_OBJ)
    $(CPP) -fPIC -shared -o $@ $^

Main.o: Main.cpp
    $(CPP) -o $@ -c $^ -I$(INCLUDES_APR)

Main: libMyLibrary.so Main.o
    $(CPP) $^ -o $@  -L/usr/local/apr/lib -L. -lapr-1 -lMyLibrary

.PHONY: clean
clean:
    $(RM) -f *.o *.so $(BIN_CPP)

When I remove then first two targets and extend the libMyLibrary.so one, it fails:

# MyClass.o: MyClass.cpp
#   $(CPP) -I$(INCLUDES_APR) -c $< -o $@

# MyModel.o: MyModel.cpp
#   $(CPP) -I$(INCLUDES_APR) -c $< -o $@

libMyLibrary.so: $(LIB_OBJ)
    $(CPP) -fPIC -shared -o $@ $^ -I$(INCLUDES_APR)

and the error message is this:

g++    -c -o MyClass.o MyClass.cpp
In file included from MyClass.cpp:1:
MyClass.hpp:3:10: fatal error: apr_general.h: No such file or directory
    3 | #include <apr_general.h>
      |          ^~~~~~~~~~~~~~~
compilation terminated.
make: *** [<builtin>: MyClass.o] Error 1

The -I$(INCLUDES_APR) is missing from the automake output. What is wrong with this build file?

Upvotes: 0

Views: 34

Answers (1)

MadScientist
MadScientist

Reputation: 100781

By removing the explicit rules, you are relying on GNU make's built-in rules to compile your files, which is good. But GNU make's built-in rules can't possibly know about your local variable INCLUDES_APR, so when it compiles the source files that variable is not used.

You should add the -I flag to the standard variable CPPFLAGS (the "CPP" here stands for "C preprocessor", not "C++"), which is what make uses to compile in its built-in rules.

Example:

BIN_CPP=Main
CPP=g++
INCLUDES_APR=/usr/local/apr/include/apr-1
CPPFLAGS=-I$(INCLUDES_APR)
LIB_SRC = $(wildcard My*.cpp)
LIB_OBJ = $(LIB_SRC:.cpp=.o)
RM=rm

all: Main

libMyLibrary.so: $(LIB_OBJ)
        $(CPP) -fPIC -shared -o $@ $^

Main: Main.o libMyLibrary.so
        $(CPP) $< -o $@  -L/usr/local/apr/lib -L. -lapr-1 -lMyLibrary

.PHONY: clean
clean:
        $(RM) -f *.o *.so $(BIN_CPP)

Possible make output

g++  -I/usr/local/apr/include/apr-1  -c -o Main.o Main.cpp
g++  -I/usr/local/apr/include/apr-1  -c -o MyClass.o MyClass.cpp
g++  -I/usr/local/apr/include/apr-1  -c -o MyModel.o MyModel.cpp
g++ -fPIC -shared -o libMyLibrary.so MyClass.o MyModel.o
g++ Main.o -o Main  -L/usr/local/apr/lib -L. -lapr-1 -lMyLibrary

Upvotes: 1

Related Questions