Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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?

>Solution :

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
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading