简体   繁体   中英

How to write a Makefile (for a c++ project) with a header in the parent directory?

I am currently struggling with make, any tip or tutorial is very much appreciated. My project folder structure looks like this:

/project
  bar.hpp
  /folder1
    main.cpp // #include "foo.hpp"  #include "bar.hpp"
    foo.cpp  // #include "foo.hpp"  #include "bar.hpp"
    foo.hpp  // #include "bar.hpp"
    Makefile

This compiles when called from folder1.

g++-10 -std=c++2a -O3 -fno-pic -no-pie -Wall -I../ main.cpp foo.cpp

I have written the following Makefile but It doesn't work as I expect:

CXX = g++-10
CXXFLAGS = -std=c++2a -O3 -fno-pic -no-pie -Wall
CPPFLAGS = -I../

.PHONY : all clean distclean

EXE = a.out
SRC = main.cpp foo.cpp
OBJ = $(SRC: .cpp=.o)
INC = $(wildcard *.hpp) ../bar.hpp

all : $(EXE)

clean :
    $(RM) *.o

distclean : clean
    $(RM) $(EXE)

$(EXE) : $(OBJ)
    $(CXX) $(CXXFLAGS) $^ -o $@

$(OBJ) : $(INC) // I hope this means that all object files depend on all header files?

%.o : %.cpp $(INC)
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@ 

I am calling make all from within folder1, but it does not work.

I tried to look for c++ make tutorials but couldn't find any with implicit and pattern rules in depth.

This is the error I get

g++-10 -std=c++2a -O3 -fno-pic -no-pie -Wall main.cpp foo.cpp -o a.out
main.cpp:1:10: fatal error: bar.hpp: No such file or directory
    1 | #include "bar.hpp"
      |          ^~~~~~~~~
compilation terminated.
In file included from foo.cpp:1:
foo.hpp:1:10: fatal error: bar.hpp: No such file or directory
    1 | #include "bar.hpp"
      |          ^~~~~~~~~
compilation terminated.

I tried in folder1 to run these commands, and it compiles properly.

g++-10 -std=c++2a -O3 -fno-pic -no-pie -Wall -c foo.cpp -o foo.o -I../
g++-10 -std=c++2a -O3 -fno-pic -no-pie -Wall -c main.cpp -o main.o -I../
g++-10 -std=c++2a -O3 -fno-pic -no-pie -Wall -o main main.o foo.o

This line is wrong:

OBJ = $(SRC: .cpp=.o)

By adding a space before the .cpp you're saying that OBJ should replace all words in the variable SRC that end in " .cpp " with an ending of .o . But there are no words in the variable SRC that end in " .cpp ", so no changes are made, and the value of OBJ is the same as the value of SRC .

So, your rule is:

a.out : main.cpp foo.cpp

so no .o files are built because your target doesn't depend on them.

Remove the space:

OBJ = $(SRC:.cpp=.o)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM