Using the following as an example makefile:
CC=g++
CFLAGS=-c -Wall
LDFLAGS=-lfoobar
SOURCES=main.cpp foo.cpp bar.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=hello
all: $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
$(OBJECTS):
$(CC) $(CFLAGS) $< -o $#
$< always expands to nothing.
I've tried changing it to the following:
CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp foo.cpp bar.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=hello
all: $(OBJECTS) # or main.o foo.o bar.cpp
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
This tells me that there's no rule for main.o
Am I missing something here? I see a lot of make files using these syntaxes and/or variables and dependencies.
Try this:
CXX=g++
CXXFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp foo.cpp bar.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=hello
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS) # or main.o foo.o bar.cpp
$(CXX) -o $# $(LDFLAGS) $(OBJECTS) $(LIBS)
The rule to build each object file is built-in anyway, so there is no need to define it.
Related
INC_DIR = ./include
SRC_DIR = ./src
OBJ_DIR = ./obj
SRC_FILES = $(wildcard $(SRC_DIR)/*.cpp))
H_FILES = $(wildcard $(INC_DIR)/*.cpp)
OBJ_FILES=$(patsubst $(SRC_DIR)/%.cc,$(OBJ_DIR)/%.o,$(SRC_FILES)
TARGET = PT3
CC = g++
CFLAGS = - fPIC -c -Wall -Werror -pedantic -std=c++11 -Wno-c++11-extensions
CPPFLAGS = $(addprefix -I, $(INC_DIR))
clean:
rm -f $(OBJECTS) $(TARGET)
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(CC) $(CFLAGS) $(CPPFLAGS) -o $# $^
%.o: %.cc
$(CC) $(CFLAGS) $(CPPFLAGS) -o $# -c $<
g++ -shared -fPIC -o libtest.so $(OBJECTS)
main.o: main.cc
$(CC) $(CFLAGS) $(CPPFLAGS) -L/pt3/lib -o maintest main.cc -libtest
this is currently what I have and i know its not syntactically right or remotely working but Im getting stuck on creating the shared library so I dont even know what else wouldnt compile.**
INC_DIR = ./include
SRC_DIR = ./src
SRC_FILES = $(sort $(shell find $(SRC_DIR) -name '*.cc'))
OBJ_FILES = $(SRC_FILES:.cc=.o)
TARGET = PT3
CC = g++
CFLAGS = -fPIC -Wall -Werror -pedantic -std=c++11 -Wno-c++11-extensions
CPPFLAGS = $(addprefix -I, $(INC_DIR))
#clean:
# rm -f $(OBJECTS) $(TARGET)
all: $(TARGET)
$(TARGET): $(OBJ_FILES)
$(CC) $(CFLAGS) $(CPPFLAGS) -o $# $^
%.o: %.cc
$(CC) $(CFLAGS) $(CPPFLAGS) -o $# -c $<
libtest.so: $(OBJ_FILES)
$(CC) -shared -fPIC -o $# $^
maintest: main.o libtest.so
$(CC) $(CFLAGS) $(CPPFLAGS) -L. -o maintest main.o -libtest
this is what i rewrote the code to however Im getting a no input files error, but Im not sure if thats coming from a wrong read / failure to get into the required folders, or due to possibly missing a -o or -c?
Ive worked on the code some more following the suggestions and have come to this:
CXX = g++
CXXFLAGS := -Wall -Werror -pedantic -std=c++11 -Wno-c++11-extensions
SRC_FILES = $(wildcard $(SRC_DIR)/*.cpp)
OBJECTS=$(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES))
INC_DIR = include
SRC_DIR = src
OBJ_DIR = obj
TEST_DIR = tests
LIB_DIR = lib
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) -fPIC -Iinclude -o $# -c $<
clean:
rm -f $(OBJECTS) $(TEST_DIR)/main.o
$(LIB_DIR)/libtest.so: $(OBJECTS)
#echo frank
$(CXX) -shared -fPIC -o $# $^
$(TEST_DIR)/main.o: $(TEST_DIR)/main.cc
$(CXX) $(CXXFLAGS) -Iinclude -o $# -c $<
maintest: $(TEST_DIR)/main.o $(LIB_DIR)/libtest.so
$(CXX) $(CXXFLAGS) -Llib -Iinclude -o $# $< -ltest
everything seems to compile fine however when running the maintest program it returns an error saying: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory
thanks for the suggestions so far I feel like Im on the verge of actually getting the makefile working as intended
You've already written the recipe for the library (which builds it in the working directory -- we can change that later if you want):
g++ -shared -fPIC -o libtest.so $(OBJECTS)
The next step is to put it into a rule:
libtest.so: $(OBJECTS)
g++ -shared -fPIC -o libtest.so $(OBJECTS)
Then clean it up:
libtest.so: $(OBJECTS)
g++ -shared -fPIC -o $# $^
It looks as if you want the executable to be maintest, so let's write a rule for that:
maintest: main.o libtest.so
$(CC) $(CFLAGS) $(CPPFLAGS) -L. -o maintest main.o -ltest
Give that a try. We can make further adjustments once that much works.
EDIT: I see that there are a few other problems in your makefile. Your variables won't work as written. Do you name your source files "foo.cc" or "foo.cpp"?
EDIT: I can see that we'll have to do this in stages.
Step 1. Try this:
CXX = g++
CXXFLAGS := -Wall -Werror -pedantic -std=c++11 -Wno-c++11-extensions
INC_DIR = include
SRC_DIR = src
OBJ_DIR = obj
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) -Iinclude -o $# -c $<
Try to build one or two object files with this, as in make obj/foo.o.
Step 2. Add a rule for main.o, and test it:
$(OBJ_DIR)/main.o: main.cc
$(CXX) $(CXXFLAGS) -Iinclude -o $# -c $<
Step 3. Add a "do nothing" rule for the library, and verify that it builds all of the objects:
SRC_FILES = $(wildcard $(SRC_DIR)/*.cpp)
OBJECTS=$(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES))
libtest.so: $(OBJECTS)
#echo doing nothing
Step 4. Change the library rule to actually build the library:
libtest.so: $(OBJECTS)
$(CXX) -shared -fPIC -o $# $^
Step 5. Add a rule to build the test:
maintest: main.o libtest.so
$(CXX) $(CXXFLAGS) -L. -o $# $< -ltest
So I'm trying to re-build a 4 year old project that was working, but now is having issues building. I was able to address some of the compile related issues, but now I'm having linker issues with the openGL calls.
In terms of what's different, now instead of freeglut it's now freeglut3 and instead of libsdl-mixer it's libsdl-mixer1.2.
Is there anything I need to update in the LDFLAGS section???
Here segments of the makefile:
CC=g++
# The _POSIX_* symbols only come into play on systems that are POSIX
# but not SUS.
# SUS3=-D_POSIX_SOURCE -D_POSIX_C_SOURCE=200112L -D_XOPEN_SOURCE=600
HARDEN=-D_FORTIFY_SOURCE
TESTING=-D_FLAT_WORLD
CFLAGS= -pg -g `sdl-config --cflags --libs` -fpermissive
LDFLAGS=-lGLEW -lGL -lGLU -lglut -lpthread -lSDL_mixer
ALL=mech
mech: $(ALL)
# -------------------------------------------------------
run.o: ../run.cc ../commonStrc.h
$(CC) $(CFLAGS) -c $<
debug.o: ../debug.cc ../debug.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<
world.o: ../world.cc ../world.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<
gameRoot.o: ../gameRoot.cc ../gameRoot.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<
gameState.o: ../gameState.cc ../gameState.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<
initGame.o: ../initGame.cc ../initGame.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<
controls.o: ../controls.cc ../controls.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<
levelManager.o: ../levelManager.cc ../levelManager.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<
thread.o: ../thread.cc ../thread.h
$(CC) $(CFLAGS) -c $<
# ------------------------------------------------------- soundMngr
gmAudioPlayer.o: ../soundMngr/gmAudioPlayer.cc ../soundMngr/gmAudioPlayer.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<
gmAudioLoader.o: ../soundMngr/gmAudioLoader.cc ../soundMngr/gmAudioLoader.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<
# ------------------------------------------------------- MD5
md5anim.o: ../md5/md5anim.cc ../md5/MD5Model.h ../commonStrc.h ../md5/md5head.h
$(CC) $(CFLAGS) -c $<
md5mesh.o: ../md5/md5mesh.cc ../md5/MD5Model.h ../commonStrc.h ../md5/md5head.h
$(CC) $(CFLAGS) -c $<
MD5Model.o: ../md5/MD5Model.cc ../md5/MD5Model.h ../commonStrc.h ../md5/md5head.h
$(CC) $(CFLAGS) -c $<
# ------------------------------------------------------- myLib
myCorePoint.o: ../myLib/myCorePoint.cc ../myLib/myCorePoint.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<
myVec.o: ../myLib/myVec.cc ../myLib/myVec.h
$(CC) $(CFLAGS) -c $<
myVert.o: ../myLib/myVert.cc ../myLib/myVert.h
$(CC) $(CFLAGS) -c $<
myCam.o: ../myLib/myCam.cc ../myLib/myCam.h
$(CC) $(CFLAGS) -c $<
myTexMngr.o: ../myLib/myTexMngr.cc ../myLib/myTexMngr.h
$(CC) $(CFLAGS) -c $<
myVerBall.o: ../myLib/myVerBall.cc ../myLib/myVerBall.h
$(CC) $(CFLAGS) -c $<
MyCoor3.o: ../myLib/MyCoor3.cc ../myLib/MyCoor3.h
$(CC) $(CFLAGS) -c $<
MyMatr4.o: ../myLib/MyMatr4.cc ../myLib/MyMatr4.h
$(CC) $(CFLAGS) -c $<
.... some more stuff I cut out .....
bbFinder.o: ../org/bbFinder.cc ../org/bbFinder.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<
pathFinder.o: ../org/pathFinder.cc ../org/pathFinder.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<
# --------------------------------------------------------
mech: run.o debug.o world.o gameRoot.o gameState.o initGame.o controls.o levelManager.o thread.o gmAudioLoader.o gmAudioPlayer.o md5anim.o md5mesh.o MD5Model.o myVert.o myVec.o myCorePoint.o myCam.o myTexMngr.o myVerBall.o MyCoor3.o MyMatr4.o hud.o pauseScreen.o rotSeg.o mechLeg.o gameBound.o particle.o particleGroup.o BBHier.o BBox.o bSphere.o Missile.o drunk.o homing.o pHoming.o miniMis.o hydra.o buildingBlock.o Projectile.o explosion.o bBin.o bCone.o binIndices.o tiltBlock.o core.o blast.o pseudoModel.o pseudoReader.o pseudoParts.o pseudoMech.o turret.o actor.o hover.o pseudoPlayer.o mechAI.o misCan.o font.o flatFog.o env.o healZone.o amoZone.o itemGen.o materialPreset.o mainMenu.o controlMenu.o menuMngr.o lvlSelect.o shader.o mouseFix.o ctrlBox.o linThread.o winThread.o bbFinder.o pathFinder.o
$(CC) -pg $(LDFLAGS) -o $# $^
clean:
rm -rf core* *.o *.gch $(ALL)
I believe the link flags are in the wrong order.
This doesn't look right to me…
LDFLAGS = -lGLEW -lGL -lGLU -lglut -lpthread -lSDL_mixer
What happens is that the linker searches in order, so if you write X Y Z, then X can use symbols from Y and Z, but Y can only use symbols from Z, and Z can't use symbols from any other library. Any "base" library which everything depends on should go at the end.
Sometimes, putting things in the wrong order will still work, depending on whether the libraries are static or dynamic libraries, which version of the libraries you are using, how the libraries were compiled, et cetera. It's a serious misfeature, in my opinion, that the order is important at all! Some other toolchains, like the Darwin (macOS, iOS) toolchain, do not generally care what order you specify libraries in.
Your LIBS variable should end up looking like this:
LIBS = -lGLEW -lglut -lGLU -lGL -lSDL_mixer -pthread
But you should probably write it in the makefile like this:
LIBS := -lglut $(shell pkg-config --libs gl glu glew SDL_mixer) -pthread
And the build rule should look like this:
LDFLAGS := -pg
mech: ...
$(CC) $(LDFLAGS) -o $# $^ $(LIBS)
I've made a few changes.
Libraries go in LIBS not in LDFLAGS.
Libraries in $(LIBS) go at the end of the command line, after $^.
Use := to avoid expanding $(shell ...) multiple times.
Use pkg-config to get most of the libraries right. I don't think glut has a pkg-config file (it doesn't on my system), so that one is manual. The pkg-config --libs command will put libraries in the correct order for you so you don't have to think as much about it.
Use -pthread instead of -lpthreads (should be in your CFLAGS too).
I'm planning on posting an article explaining all of this, as these errors are somewhat common in Makefiles.
I am trying to write a makefile to compile and generate only object files from the source code. I have this so far:
CC=g++
CFLAGS=-c -Wall -std=c++11
SOURCES=$(wildcard *.h)
OBJECTS=$(SOURCES:.cpp=.o)
all: $(OBJECTS)
$(OBJECTS):
$(CC) $(CFLAGS) $< -o $#
when I call it, it prints:
make: Nothing to be done for `all'.
Obviously I am making a mistake, but I don't know which one, because I am seeing in the GNU make documentation page a very similar example.
Any help would be very appreciated.
Replace: SOURCES=$(wildcard *.h) with SOURCES=$(wildcard *.cpp)
and:
$(OBJECTS):
$(CC) $(CFLAGS) $< -o $#
with:
%.o: %.cpp
$(CC) $(CFLAGS) $< -o $#
This means that each {file}.o is depend on existence of {file}.cpp.
Is there a specific way to do this? I'm speaking in general purposes. When I try to launch my program in GDB for example, I get this notification:
Reading symbols from /home/amsterdam/Code/c++/opengl_03/bin/opengl_03...(no debugging symbols found)...done.
It makes me wonder if I have to find a specific file for this?
Update
Note: I have already tried the following command:
nm --debug-sym <your_executable> | grep debug
with no success; it refuses to display anything.
Here is my Makefile:
BIN = bin/
OBJ = obj/
TARGET = opengl_03
DEPS = main.o displayinit.o initializer.o algorithms.o matrix3f.o window.o vertex3.o
CC = g++
CFLAGS = -g -ggdb
LIBS = -lglut -lGLEW -lGL
INCLUDEPATH = -L/usr/include/ -L/usr/lib/ -L/usr/lib/x86_64-linux-gnu/
$(TARGET) : $(DEPS)
$(CC) $(CFLAGS) -o $(BIN)$(TARGET) $(DEPS) $(LIBS) $(INCLUDEPATH)
displayinit.o : displayinit.cpp displayinit.h
$(CC) $(CFLAGS) -c displayinit.cpp $(LIBS) $(INCLUDEPATH) #&& mv displayinit.o $(OBJ)displayinit.o
initializer.o : initializer.cpp initializer.h
$(CC) $(CFLAGS) -c initializer.cpp $(OBJ) $(LIBS) $(INCLUDEPATH)
algorithms.o : algorithms.cpp algorithms.h
$(CC) $(CFLAGS) -c algorithms.cpp $(OBJ) $(LIBS) $(INCLUDEPATH)
matrix3f.o : matrix3f.cpp matrix3f.h
$(CC) $(CFLAGS) -c matrix3f.cpp $(OBJ) $(LIBS) $(INCLUDEPATH)
vertex3.o : vertex3.cpp vertex3.h
$(CC) $(CFLAGS) -c vertex3.cpp $(OBJ) $(LIBS) $(INCLUDEPATH)
window.o : window.cpp window.h
$(CC) $(CFLAGS) $(LIBS) $(INCLUDEPATH) -c window.cpp $(OBJ)
main.o : main.cpp
$(CC) $(CFLAGS) $(LIBS) $(INCLUDEPATH) -c main.cpp $(OBJ)
You need to include debugging symbols when you compile. For example if you are using gcc add the flag -ggdb.
You need to compile with debug symbols included gcc -g option and make sure you don't strip your executable. More details in this link.
-------------------------------------------------Edit-------------------------------------------
Your Makefile does not look good, why don't you use
boilerplate Makefiles. You can find it here, works well for me.
Currently, I have my makefile set up to compile and make a fairly large project. I have written a second cpp file with main function for running tests. I want these to run separately, but build together and they use the same files. How is this accomplished?
edit: As reference, here is my current makefile. I'm not sure how to adjust it.
CC=g++
CFLAGS=-c -Wall -DDEBUG -g
LDFLAGS=
SOURCES=main.cpp Foo.cpp Bar.cpp Test.cpp A.cpp B.cpp C.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=myprogram
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
Normally you would just have multiple targets and do something like this:
.PHONY: all target tests
all: target tests
target: ...
...
tests: ...
...
Then you can just make (defaults to make all), or just make target or make tests as needed.
So for your makefile example above you might want to have something like this:
CC = g++
CFLAGS = -c -Wall -DDEBUG -g
LDFLAGS =
COMMON_SOURCES = Foo.cpp Bar.cpp A.cpp B.cpp C.cpp
TARGET_SOURCES = main.cpp
TEST_SOURCES = test_main.cpp
COMMON_OBJECTS = $(COMMON_SOURCES:.cpp=.o)
TARGET_OBJECTS = $(TARGET_SOURCES:.cpp=.o)
TEST_OBJECTS = $(TEST_SOURCES:.cpp=.o)
EXECUTABLE = myprogram
TEST_EXECUTABLE = mytestprogram
.PHONY: all target tests
all: target tests
target: $(EXECUTABLE)
tests: $(TEST_EXECUTABLE)
$(EXECUTABLE): $(COMMON_OBJECTS) $(TARGET_OBJECTS)
$(CC) $(LDFLAGS) $^ -o $#
$(TEST_EXECUTABLE): $(COMMON_OBJECTS) $(TEST_OBJECTS)
$(CC) $(LDFLAGS) $^ -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
Here's one way to do it:
CXXFLAGS += -std=c++11 -Wall -O3
all: myprog mytest
myprog.cpp: main.cpp
cp -vf $< $#
myprog: myprog.o Foo.o Bar.o Test.o A.o B.o C.o
mytest.cpp: main.cpp
cp -vf $< $#
mytest.o: CPPFLAGS += -DDEBUG
mytest.o: CXXFLAGS += -O0 -g
mytest: mytest.o Foo.o Bar.o Test.o A.o B.o C.o
This works because built-in rules exist for compiling objects from c++ source (%.o: %.cpp) and linking main programs (%: %.o).
Also note the use of target-specific values for the variables CPPFLAGS and CXXFLAGS.