Before correcting that particular error, you have other errors in your makefile. First, VPATH
you declare but you do not use it.
Second, CPP
is not the C ++ compiler, it is the preprocessor executable ( cpp
, the program that gcc
calls internally to deal with #include
, #define
, etc, before starting the compilation). Your C ++ compiler should go in CXX
.
It works for you because you have explicitly written $(CPP)
in the body of the rule, and you are replacing the value of the variable, which effectively contains g++
. But it goes against the purpose of the variable (and in addition, you can load the implicit rules of GNU Make
).
The same with CPPFLAGS
, which are the preprocessor options. Yours should go in CXXFLAGS
:
CXX = g++
CXXFLAGS = -std=c++14 -g -Wall -pedantic
VPATH = ../P0:.:..
test-consola: test-P0-consola.o fecha.o cadena.o
$(CXX) $(CXXFLAGS) -o [email protected] $^ # ¿.ex?
test-P0-consola.o: test-P0-consola.cpp fecha.hpp cadena.hpp
$(CXX) -c $(CXXFLAGS) $< -o $@
fecha.o: fecha.hpp
cadena.o: cadena.hpp
Now, the error so you ask. In the makefile you have to put the complete relative path of the files that you put as dependency:
CXX = g++
CXXFLAGS = -std=c++14 -g -Wall -pedantic
# VPATH = ../P0:.:..
test-consola: test-P0-consola.o P0/fecha.o P0/cadena.o
$(CXX) $(CXXFLAGS) -o $@ $^
test-P0-consola.o: test-P0-consola.cpp P0/fecha.hpp P0/cadena.hpp
$(CXX) -c $(CXXFLAGS) $< -o $@
P0/fecha.o: P0/fecha.hpp
P0/cadena.o: P0/cadena.hpp
And even then this will not solve your problem. By putting the test-consola.cpp
file out of the P0
folder, and assuming that in the first lines of test-P0-consola.cpp
you will have something like:
#include "fecha.hpp"
#include "cadena.hpp"
It will turn out that the compiler can not find where the files fecha.hpp
and cadena.hpp
are from test-P0-consola.cpp
, and it will give you a fatal error of nonexistent file.
Assuming that the folder from where you are compiling is /home/tu_usario/POO/practicas/
, and from that folder, you compile with:
g++ -opciones test-P0-consola.cpp -o test-P0-consola.o
Any file that you include in said .cpp
must include the relative path with respect to the folder where test-P0-consola.cpp
is found. If it is in the same folder, you can directly put #include "fecha.hpp"
. If you are in a different folder ( P0
in your case), you have to modify test-P0-consola.cpp
with the correct relative path:
#include "P0/fecha.hpp"
#include "P0/cadena.hpp"
But in case that test-P0-consola.cpp
you can not modify it -the teachers' code, right? ;), the easiest thing is that you indicate to g++
, that internally invokes the preprocessor, PATH
s alternative where you can find more files in case that, by relative routes, you do not find them. It is done with the -I
option (once for each folder):
CXX = g++
CXXFLAGS = -std=c++14 -g -Wall -pedantic
CPPFLAGS = $(CPPFLAGS) -IP0
# VPATH = ../P0:.:..
test-consola: test-P0-consola.o P0/fecha.o P0/cadena.o
$(CXX) $(CXXFLAGS) -o $@ $^
test-P0-consola.o: test-P0-consola.cpp P0/fecha.hpp P0/cadena.hpp
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@
P0/fecha.o: P0/fecha.hpp
P0/cadena.o: P0/cadena.hpp
And VPATH
I mentioned it to you because I guess it will have been one of the attempts to add new folders to the path (what you have to do with -I
). Unfortunately, VPATH
is none of the implicit variables of GNU Make
, and even if it were, if you create your own rules and do not use the variable, the variable is not used. The implicit variables only serve for the implicit rules, or the explicit rules in which you manually write them (as CXX
, which by default is worth g++
, and CXXFLAGS
, which by default is empty).
NOTE: When changing the variable CPP
, you are not changing the call that gcc
does internally to the preprocessor. Simply, it is for internal use of the makefile (in case you want to create rules to preprocess files manually instead of making gcc
preprocess it for you).