I am new to Makefiles. I am using opencv and lpthread libraries in a project. The following makefile code dont seems to work. It seems the linking process is failing. Please point out the mistake I made here.
OS: Ubuntu 18.04
CC=g++
LIBS=`pkg-config --cflags --libs opencv`
CXXFLAGS= -c -Wall -std=c++17 -lpthread -march=native -mtune=native -O2
CXXFLAGS2= -Wall -std=c++17 -lpthread -march=native -mtune=native -O2
all: a.out
a.out: main.o brain_starter.o brain_class.o segment_class.o \
logic_core.o data_package_class.o core_class.o
$(CC) $(CXXFLAGS2) $(LIBS) -o a.out main.o brain_starter.o brain_class.o \
segment_class.o logic_core.o data_package_class.o core_class.o
main.o: main.cpp dependency_functions.h
$(CC) $(CXXFLAGS) main.cpp
brain_starter.o: brain_starter.cpp
$(CC) $(CXXFLAGS) brain_starter.cpp
brain_class.o: brain_class.cpp
$(CC) $(CXXFLAGS) brain_class.cpp
segment_class.o: segment_class.cpp
$(CC) $(CXXFLAGS) segment_class.cpp
logic_class.o: logic_class.cpp
$(CC) $(CXXFLAGS) logic_class.cpp
data_package_class.o: data_package_class.cpp
$(CC) $(CXXFLAGS) $(LIBS) data_package_class.cpp
core_class.o: core_class.cpp
$(CC) $(CXXFLAGS) core_class.cpp
clean:
rm -rf *o a.out
I rearranged libs in the linking code and the makefile worked. Here is the working code.
CC=g++
OPENCVLIBS=`pkg-config --cflags --libs opencv`
LIBS= -lpthread
CXXFLAGS= -c -Wall -std=c++17 -march=native -mtune=native -O2
CXXFLAGS2= -Wall -std=c++17 -lpthread -march=native -mtune=native -O2
all: a.out
a.out: main.o brain_starter.o brain_class.o segment_class.o \
logic_core.o data_package_class.o core_class.o
$(CC) $(CXXFLAGS2) -o a.out main.o brain_starter.o brain_class.o segment_class.o logic_core.o data_package_class.o core_class.o $(LIBS) $(OPENCVLIBS)
main.o: main.cpp dependency_functions.h
$(CC) $(CXXFLAGS) $(LIBS) main.cpp
brain_starter.o: brain_starter.cpp
$(CC) $(CXXFLAGS) $(LIBS) brain_starter.cpp
brain_class.o: brain_class.cpp
$(CC) $(CXXFLAGS) $(LIBS) brain_class.cpp
segment_class.o: segment_class.cpp
$(CC) $(CXXFLAGS) $(LIBS) segment_class.cpp
logic_class.o: logic_class.cpp
$(CC) $(CXXFLAGS) $(LIBS) logic_class.cpp
data_package_class.o: data_package_class.cpp
$(CC) $(CXXFLAGS) $(LIBS) $(OPENCVLIBS) data_package_class.cpp
core_class.o: core_class.cpp
$(CC) $(CXXFLAGS) core_class.cpp
clean:
rm -rf *o a.out
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
Good day. I need to write makefile for my program. I only have ukol2.cpp. When i compile in terminal i write:
g++ -Wall ukol2.cpp -lcrypto -o prog; ./prog d
Also i have template:
CC = gcc
CFLAGS = -g
LDFLAGS = -lcrypto
all: hash stream
run:
#run your tests here...
hash: hash.o
$(CC) -o $# $< $(LDFLAGS)
stream: stream.o
$(CC) -o $# $< $(LDFLAGS)
%.o: %.c
$(CC) -c -o $# $< $(CFLAGS)
Can you help to write my own makefile with same C and LD flags?
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.
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.
I have the following makefile:
CC = gcc
SRC = source1.c
EXE = source1
FLAGS = -fopenmp
all: $(src)
$(CC) -o $(EXE) $(SRC) $(FLAGS)
clean:
rm $(EXE)
How can I modify it so I can use multiple sources, some of them compiled with the flag -fopenmp, some of them compiled without. Thanks a lot.
This should get you started: Note how -fopenmp gets added just for source2.c
CC=gcc
SRC=source1.c source2.c
OBJ=$(patsubst %.c,%.o,$(SRC))
EXE=source1
FLAGS= -g -O2
source2.o: FLAGS+=-fopenmp
all: $(EXE)
$(EXE): $(OBJ)
$(CC) -o $# $^ $(FLAGS)
%.o: %.c
$(CC) -c -o $# $^ $(FLAGS)
clean:
rm $(EXE)$
Output of make -Bsn:
gcc -o source1.o source1.c -g -O2
gcc -o source2.o source2.c -g -O2 -fopenmp
gcc -o source1 source1.o source2.o -g -O2
You can define for example, EXTFLAGS=$(FLAGS) -fopenmp, and use EXTFLAGS for some rules.