Problem finding header with C ++ makefile
I started working with my first makefile. I am writing a roguelike in C ++ using the libtcod library and have the following global hello program to test if my environment is working:
#include "libtcod.hpp"
int main()
{
TCODConsole::initRoot(80, 50, "PartyHack");
TCODConsole::root->printCenter(40, 25, TCOD_BKGND_NONE, "Hello World");
TCODConsole::flush();
TCODConsole::waitForKeypress(true);
}
My project structure looks like this:
/CppPartyHack
----/libtcod-1.5.1 # this is the libtcod root folder
--------/include
------------libtcod.hpp
----/PartyHack
--------makefile
--------partyhack.cpp # the above code
(While we're here, how do I indent correctly? Using these dashes is silly.)
and here is my makefile:
SRCDIR = .
INCDIR = ../libtcod-1.5.1/include
CFLAGS = $(FLAGS) -I$(INCDIR) -I$(SRCDIR) -Wall
CC = gcc
CPP = g++
.SUFFIXES: .o .h .c .hpp .cpp
$(TEMP)/%.o : $(SRCDIR)/%.cpp
$(CPP) $(CFLAGS) -o $@ -c $<
$(TEMP)/%.o : $(SRCDIR)/%.c
$(CC) $(CFLAGS) -o $@ -c $<
CPP_OBJS = $(TEMP)partyhack.o
all : partyhack
partyhack : $(CPP_OBJS)
$(CPP) $(CPP_OBJS) -o $@ -L../libtcod-1.5.1 -ltcod -ltcod++ -Wl,-rpath,.
clean :
\rm -f $(CPP_OBJS) partyhack
I am using Ubuntu and my terminal is giving me the following errors:
max @ max-desktop: ~ / Desktop / Development / CppPartyhack / PartyHack $ make
g ++ -c -o partyhack.o partyhack.cpp
partyhack.cpp: 1: 23: error: libtcod.hpp: No such file or directory
partyhack. cpp: In function 'int main ():
partyhack.cpp: 5: error: "TCODConsole not declared
partyhack.cpp: 6: error:" TCODConsole not declared partyhack.cpp: 6: error: "TCOD_BKGND_NONE was not declared in this scope
partyhack.cpp: 7: error: "TCODConsole not declared
partyhack.cpp: 8: error:" TCODConsole not declared
make: *** [partyhack.o] Error 1
So, makefile cannot find libtcod.hpp. I've double checked and I'm sure the relative path to libtcod.hpp in INCDIR is correct, but since I'm just starting out with makefiles I'm not sure what else might be wrong. My makefile is based on a template that the libtcod developers provided along with the library itself, and although I looked at several online makefile tutorials, the code in that makefile is a little more complex than any of the examples the tutorials showed, so I I'm guessing I messed up something basic in conversion. Thanks for any help.
a source to share
What's going on here is that
1) evaluates the goal all
that resolves partyhack
.
2) makes an assessment of the goal partyhack
that resolves$(CPP_OBJS)
3) computes a goal $(CPP_OBJS)
that resolves$(TMP)partyhack.o
4) makes an assessment of the goal $(TMP)partyhack.o
that resolvespartyhack.o
This is because TMP is not defined. Also note that the forward slash is missing $(TMP)
.
5) makes an estimate of the target partyhack.o
and applies the implicit ruleg++ -c -o partyhack.o partyhack.cpp
It does not apply the rule you specified, namely $(TEMP)/%.o : $(SRCDIR)/%.cpp
because TEMP is not defined, so it evaluates to /partyhack.o : ./partyhack.cpp
, and we do not build /partyhack.o
because we are not in the root directory.
6) g ++ doesn't find the include file because the include directories were not passed to it because your rule was not applied.
To fix this:
First, you need to define TEMP (see Nick Myers answer).
TEMP = .
Second, you need to change the definition of CPP_OBJS (as Pavel R. suggested).
CPP_OBJS = %(TEMP)/partyhack.o
This will work if you call make inside the CppPartyHack / PartyHack directory.
a source to share
Make seems to use a built-in rule as opposed to your custom rule for * .cpp files. (See order of options -c
and -o
in make output is not the same as what you wrote). Check your C ++ file rule definition.
My best guess is that references to $ (TEMP) are dropping it. Where is it defined?
Also note that for C ++ it is common to use variables CXX
and CXXFLAGS
are used for compiler program and flags, respectively. CPP
used for the C preprocessor program, CPPFLAGS
for the preprocessor flags, and CFLAGS
used for the C compiler flags, which is probably why it make
doesn't use yours CFLAGS
when using its built-in C ++ rules.
a source to share