Home > other >  Simplifying the Makefile
Simplifying the Makefile

Time:10-18

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?

CodePudding user response:

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
  • Related