Reputation:
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
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