Search code examples
makefilecompilationg++

Make omits '-I' flag g++


I have a makefile to make a project with 2 source files and one header.

.PHONY: clean delete run                                                                                                                                                                                                                                                                            

CC = g++                                                                                                                                          

CFLAGS = -g -Wall                                                                                   

CXXFLAGS = $(CFLAGS)                                                                                                                                                                                                                                                                                

SRC = /home/hk_grub/dev/nCPrograms/Flagger/src/theclass.cpp /home/hk_grub/dev/nCPrograms/Flagger/src/main.cpp                                     

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

INC = -I/home/user/dev/nCPrograms/Flagger/header                                                                                                                              

EXECUTABLE = Flagger                                                                                                                                                                                                                                                                                

all: $(EXECUTABLE)  
                                                                                                                                                                                                                                                                                
$(EXECUTABLE): $(OBJ)  
  $(CC) $(CFLAGS) $(INC) -o $@ $^

%%.o: %%.cpp                                                                                                                                              
  $(CC) $(CFLAGS) $(INC) -c -o $@ $<                                                                                                                                                                                                                                                                 

clean:                                                                                                                                                    
  rm -rf $(OBJ)                                                                                                                                                                                                                                                                               

delete:                                                                                                                                                   
  rm -rf $(OBJ) $(EXECUTABLE)                                                                                                                                                                                                                                                                 

run:                                                                                                                                                      
  ./$(EXECUTABLE)   

When I run it with make, it outputs this command that it is running (without the -I flag):

g++ -g -Wall   -c -o /home/user/dev/nCPrograms/Flagger/src/theclass.o /home/user/dev/nCPrograms/Flagger/src/theclass.cpp

and then fails with an error because one of the includes relies on a -I flag.

/home/user/dev/nCPrograms/Flagger/src/theclass.cpp:1:10: fatal error: theclass.h: No such file or directory                                        1 | #include <theclass.h>                                                                                                                           |          ^~~~~~~~~~~~                                                                                                                     compilation terminated.                                                                                                                           make: *** [<builtin>: /home/user/dev/nCPrograms/Flagger/src/theclass.o] Error 1  

I have tried @echo'ing the $(INC) variable (worked fine), and moving around parameters and adding/removing quotations everywhere. I'm not super familiar with make syntax, so any help as to why the -I flag is not appearing would be appreciated. For what it's worth, the include path and #include directive work fine with clangd and when manually compiling.


Solution

  • It seems you are using GNU Make.

    This:

    %%.o: %%.cpp
        $(CC) $(CFLAGS) $(INC) -c -o $@ $<
    

    is not a pattern-rule. It is a rule for making a file literally called %%.o from a file literally called %%.cpp. This rule has no application and is not used.

    Instead, make falls back on its built-in rule to compile an .o from a .cpp file, which is:

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

    Your variable INC is not used in that recipe (it is not one of the make-variables used by implicit rules) so your -I path is not passed. It would be conventional to pass -I-paths in CPPFLAGS (preprocessor flags).

    The pattern rule you need is:

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