I am having some troubles getting my program to build using a makefile
inspired by the Recursive Makefile Considered Harmful paper.
I am quite new to makefile
s, and I am able to get it all to build fine, however there are a couple of things that aren't working that, from my understanding, should be working. I was hoping that you guys/gals would be able to either clarify that things for me!
I am running OSX. Using g++ to compile (or at least, intending to). Here is the relevant makefile
and depend.sh
makefile
CC = g++
MODULES := src Engine Engine/core Engine/render
# look for include files in
# each of the modules
CFLAGS := $(patsubst %,-I%,$(MODULES)) -I/usr/local/include/SDL2/
# extra libraries if required
LIBS := -lm -L/usr/local/lib/ -lSDL2 -lSDL2main -lSDL2_image
# each module will add to this
SRC :=
# include the description for
# each module
include $(patsubst %,%/module.mk,$(MODULES))
# determine the object files
OBJ := $(patsubst %.cpp,%.o, $(filter %.cpp,$(SRC))) #\
#$(patsubst %.y,%.o, \
#$(filter %.y,$(SRC)))
# link the program
main: $(OBJ)
$(CC) -o $@ $(OBJ) $(LIBS) $(CFLAGS)
# include the C++ include
# dependencies
include $(OBJ:.o=.d)
# calculate C++ include
# dependencies
%.d: %.cpp
./depend.sh ‘dirname $*.cpp‘ $(CFLAGS) $*.cpp > $@
clean:
find ./ -iname "*.o" -exec rm {} \;
find ./ -iname "*.d" -exec rm {} \;
rm main
depend.sh
#!/bin/sh
DIR="$1"
shift 1
case "$DIR" in
"" | ".")
g++ -MM -MG "$@" |
sed -e ’s@ˆ\(.*\)\.o:@\1.d \1.o:@’
;;
*)
g++ -MM -MG "$@" |
sed -e "s@ˆ\(.*\)\.o:@$DIR/\1.d $DIR/\1.o:@"
;;
esac
1. Include Directories
I am using SDL2 in my application to handle windows and other media functionality. I have my SDL2 include directory installed at /usr/local/include/SDL2/
. So in my CFLAGS I have -I/usr/local/include/SDL2/
. In a previous, very simple makefile
this worked. The SDL directory was included and my code files that were including SDL headers worked as expected. But using the makefile above, the SDL include directory seems to be completely ignored! I need to use absolute paths in my code files to include SDL (ie. Include directory ignored, correct?).
My work around has been to create a symlink in my working directory and use relative paths to access that, but that is far from ideal... Any ideas what I could be doing wrong here? Am I fundamentally misunderstanding something?
2. Modules
At this point it seems as though I need to update the top-level MODULES
variable to include pretty much every folder in my project. I have tried to append child folders to the respective module.mk
file but that had no effect. Eg. I also removed the Engine/core
and Engine/render
modules from the top-level makefile
, then in the module.mk
file found in the Engine
folder, I had:
MODULES += Engine/core Engine/render
My thinking is that the top-level makefile
would see that there is an Engine
module, it would check the Engine
folder, open up the module.mk
file, and see that there were 2 more modules. Is this incorrect?
A strange observation
In my makefile
I define CC
as g++
. I then use $(CC)
in the main
target. I also specify g++ in depend.sh
. However when I build successfully, I get a bunch of these errors:
./depend.sh ‘dirname src/main.cpp‘ -Isrc -IJEngine -IEngine/core -IEngine/render -I/usr/local/include/SDL2/ src/main.cpp > src/main.d
clang: error: no such file or directory: 'src/main.cpp‘'
Followed by success:
c++ -c -o src/main.o src/main.cpp
c++ -c -o Engine/Engine.o Engine/Engine.cpp
c++ -c -o Engine/core/Error.o Engine/core/Error.cpp
c++ -c -o Engine/core/Window.o Engine/core/Window.cpp
c++ -c -o Engine/render/Render.o Engine/render/Render.cpp
g++ -o main src/main.o Engine/Engine.o Engine/core/Error.o Engine/core/Window.o Engine/render/Render.o -lm -L/usr/local/lib/ -lSDL2 -lSDL2main -lSDL2_image -Isrc -IEngine -IEngine/core -IEngine/render -I/usr/local/include/SDL2/
Yay! It built! And it runs! But what were those errors? And why is c++
being used for everything except the last call and not g++
? I haven't specified c++
anywhere (i think!)
Any help will be greatly appreciated! Let me know if I am missing any necessary information.
The CC
variable refers to the c compiler not the C++ compiler. For cpp files, make will use the value of CXX
which defaults to c++
. That's why you see c++ in the output. CC
is also used for linking, which is why you see the value of CC
as the last line of output.
If you want to use g++ for the cpp files (assume you do?), set CXX
instead of (or addition to) CC
.
You can see all the implicit rules and variables by running make -p
in a directory with no makefiles.
I believe the dirname
argument to depend.sh
should have no quotes around it. You want to pass the directory in.
UPDATE: I should have noted that CFLAGS is used by the implicit .c file recipe, but not for the .cpp file recipe. So your CFLAGS -I is ignored when compiling your cpp files. You need to set CXXFLAGS instead.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.