user3927220
user3927220

Reputation:

-I flag in the makefile does not result in a header file being found (gtest/gtest.h)

Previously I was struggling with creating a makefile in root directory that would deal with source files being in src folder and headers in include folder. Following this I wanted to add another folder tests where I would keep .cpp files with tests. Unfortunately I have problems with this.

The folder structure is:

.
|__makefile
|
|__/src
|  |
|  |__[regular .cpp files]
|
|__/include
|  |
|  |__[.h files]
|  |
|  |__/gtest
|     |
|     |__gtest.h
|
|__/tests
   |
   |__test_factorial.cpp

./tests/test_factorial.cpp:

#include "gtest/gtest.h"
#include "factorial.h"

// some tests

makefile:

CC = g++

CFLAGS = -Wall

INCLUDES = -I./include

LIBS = -lgtest -lpthread

SOURCEDIR = ./src/
SRCS = $(shell find ./src/ -name '*.cpp')
SRCS += $(shell find ./tests/ -name '*.cpp')

.PHONY: clean depend

SRCS := $(filter-out ./tests/main_tests.cpp, $(SRCS))
OBJS = $(SRCS:.cpp=.o)
OBJS := $(OBJS:./src%=.%)

release: $(OBJS)
        $(CC) $(CFLAGS) -o app $(OBJS) $(LIBS)

VPATH = ./src:./tests

%.o: ./src/%.cpp
        $(CC) $(CFLAGS) $(INCLUDES) -c ./src/$*.cpp

%.o: ./tests/%.cpp
        $(CC) $(CFLAGS) $(INCLUDES) -c ./tests/$*.cpp

depend: .depend

.depend: $(SRCS)
        rm -f ./.depend
        $(CC) $(CFLAGS) $(INCLUDES) -MM $^ > ./.depend;

include .depend

When I execute make from the root directory all the files from /src compile fine (I end up having object files in the root directory for them) but I get an error for .cpp file from /tests directory:

g++    -c -o tests/test_factorial.o tests/test_factorial.cpp
tests/test_factorial.cpp:1:25: fatal error: gtest/gtest.h: No such file or directory
compilation terminated.
<builtin>: recipe for target 'tests/test_factorial.o' failed
make: *** [tests/test_factorial.o] Error 1

What might be important, the .depend file seems to have it all right:

test_factorial.o: tests/test_factorial.cpp include/gtest/gtest.h \
 include/factorial.h

What is wrong with the makefile?

EDIT

I believe this fragment of the error:

<builtin>: recipe for target 'tests/test_factorial.o' failed

suggests that something is wrong in this part of the makefile:

%.o: ./src/%.cpp
        $(CC) $(CFLAGS) $(INCLUDES) -c ./src/$*.cpp

%.o: ./tests/%.cpp
        $(CC) $(CFLAGS) $(INCLUDES) -c ./tests/$*.cpp

Why it's trying to do ./tests/test_factorial.o rather than ./test_factorial.o? Let me underline again that object files for ./src/*.cpp files end up in root directory, i.e. ./*.o, not ./src/*.o.

Upvotes: 0

Views: 97

Answers (1)

Ben Voigt
Ben Voigt

Reputation: 283773

Your makefile is building

tests/test_factorial.o

from

tests/test_factorial.cpp

and that doesn't match the rule

%.o: ./tests/%.cpp

So it is instead using a builtin rule. (As an aside, the convention is to build c++ files using $(CXX) and $(CXXFLAGS) not $(CC)).

Try a rule pattern of

./tests/%.o: ./tests/%.cpp

The reason that your Makefile uses the name tests/test_factorial.o is because

OBJS = $(SRCS:.cpp=.o)

which (it should be obvious) makes the path to the .o file the same as the path to the .cpp.

You have a subsequent rule stripping the path src/

OBJS := $(OBJS:./src%=.%)

and no similar rule for tests/

Upvotes: 0

Related Questions