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?
Related
I use this Makefile to build a small C++ application:
BIN_CPP=Main
CPP=g++
INCLUDES_APR=/usr/local/apr/include/apr-1
LIB_SRC = $(wildcard My*.cpp)
LIB_OBJ = $(LIB_SRC:.cpp=.o)
RM=rm
all: Main
MyClass.o: MyClass.cpp
$(CPP) -I$(INCLUDES_APR) -c $< -o $#
MyModel.o: MyModel.cpp
$(CPP) -I$(INCLUDES_APR) -c $< -o $#
libMyLibrary.so: $(LIB_OBJ)
$(CPP) -fPIC -shared -o $# $^
Main.o: Main.cpp
$(CPP) -o $# -c $^ -I$(INCLUDES_APR)
Main: libMyLibrary.so Main.o
$(CPP) $^ -o $# -L/usr/local/apr/lib -L. -lapr-1 -lMyLibrary
.PHONY: clean
clean:
$(RM) -f *.o *.so $(BIN_CPP)
When I remove then first two targets and extend the libMyLibrary.so one, it fails:
# MyClass.o: MyClass.cpp
# $(CPP) -I$(INCLUDES_APR) -c $< -o $#
# MyModel.o: MyModel.cpp
# $(CPP) -I$(INCLUDES_APR) -c $< -o $#
libMyLibrary.so: $(LIB_OBJ)
$(CPP) -fPIC -shared -o $# $^ -I$(INCLUDES_APR)
and the error message is this:
g++ -c -o MyClass.o MyClass.cpp
In file included from MyClass.cpp:1:
MyClass.hpp:3:10: fatal error: apr_general.h: No such file or directory
3 | #include <apr_general.h>
| ^~~~~~~~~~~~~~~
compilation terminated.
make: *** [<builtin>: MyClass.o] Error 1
The -I$(INCLUDES_APR) is missing from the automake output. What is wrong with this build file?
By removing the explicit rules, you are relying on GNU make's built-in rules to compile your files, which is good. But GNU make's built-in rules can't possibly know about your local variable INCLUDES_APR, so when it compiles the source files that variable is not used.
You should add the -I flag to the standard variable CPPFLAGS (the "CPP" here stands for "C preprocessor", not "C++"), which is what make uses to compile in its built-in rules.
Example:
BIN_CPP=Main
CPP=g++
INCLUDES_APR=/usr/local/apr/include/apr-1
CPPFLAGS=-I$(INCLUDES_APR)
LIB_SRC = $(wildcard My*.cpp)
LIB_OBJ = $(LIB_SRC:.cpp=.o)
RM=rm
all: Main
libMyLibrary.so: $(LIB_OBJ)
$(CPP) -fPIC -shared -o $# $^
Main: Main.o libMyLibrary.so
$(CPP) $< -o $# -L/usr/local/apr/lib -L. -lapr-1 -lMyLibrary
.PHONY: clean
clean:
$(RM) -f *.o *.so $(BIN_CPP)
Possible make output
g++ -I/usr/local/apr/include/apr-1 -c -o Main.o Main.cpp
g++ -I/usr/local/apr/include/apr-1 -c -o MyClass.o MyClass.cpp
g++ -I/usr/local/apr/include/apr-1 -c -o MyModel.o MyModel.cpp
g++ -fPIC -shared -o libMyLibrary.so MyClass.o MyModel.o
g++ Main.o -o Main -L/usr/local/apr/lib -L. -lapr-1 -lMyLibrary
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.
When I try this;
VPATH= ./src
CXXFLAGS= -I "./include"
program: ListNode.o LinkedList.o TreeNode.o Tree.o Test.o
g++ lib\ListNode.o lib\LinkedList.o lib\TreeNode.o lib\Tree.o lib\Test.o -o bin\program
ListNode.o: ListNode.cpp
g++ -c $(CXXFLAGS) $< -o lib\ListNode.o
LinkedList.o: LinkedList.cpp
g++ -c $(CXXFLAGS) $< -o lib\LinkedList.o
TreeNode.o: TreeNode.cpp
g++ -c $(CXXFLAGS) $< -o lib\TreeNode.o
Tree.o: Tree.cpp
g++ -c $(CXXFLAGS) $< -o lib\Tree.o
Test.o: Test.cpp
g++ -c $(CXXFLAGS) $< -o lib\Test.o
clean:
del *.exe
del *.o
It all works without any problem.But for my homework I have to create a static library.Anyway when I add this command to the makefile;
VPATH= ./src
CXXFLAGS= -I "./include"
program: ListNode.o LinkedList.o TreeNode.o Tree.o Test.o
g++ lib\ListNode.o lib\LinkedList.o lib\TreeNode.o lib\Tree.o lib\Test.o -o bin\program
ListNode.o: ListNode.cpp
g++ -c $(CXXFLAGS) $< -o lib\ListNode.o
LinkedList.o: LinkedList.cpp
g++ -c $(CXXFLAGS) $< -o lib\LinkedList.o
TreeNode.o: TreeNode.cpp
g++ -c $(CXXFLAGS) $< -o lib\TreeNode.o
Tree.o: Tree.cpp
g++ -c $(CXXFLAGS) $< -o lib\Tree.o
Test.o: Test.cpp
g++ -c $(CXXFLAGS) $< -o lib\Test.o
clean:
del *.exe
del *.o
libclass.a: ListNode.o LinkedList.o
ar -rcs libclass.a lib\ListNode.o lib\LinkedList.o
It doesn't do anything.There is no file or there is no error.Its like it doesn't exist :/
By the way I think it'd be good to mention about that if I use first makefile and then I put this code on terminal;
ar -rcs libclass.a lib\*.o
It works like magic i mean perfectly.So I need a little bit help cuz I'm about to go insane.Any help would be appreciated.
Add:
all: program libclass.a
to the beginning of your makefile. By default, make builds only the first target it finds in your makefile. This declares a fake target named "all" that depends on "program" and "libclass.a", so make ends up building both.
I have seen questions like these on SO but everyone has different answers and directory structures that aren't working for me.
My makefile:
CC = g++
DEBUG = -g -std=c++11
TARGET = main
OBJECT_FILES = BingResultSet.o main.o
INC_PATH = -I HTTPClientLib/include
LIB_PATH = -L HTTPClientLib/lib/
start: clean BingResultSet.o main.o
$(CC) $(DEBUG) $(INC_PATH) $(LIB_PATH) $(OBJECT_FILES) -o $(TARGET)
rm -f *.o
BingResultSet.o: BingResultSet.cpp BingResultSet.h
$(CC) $(DEBUG) $(INC_PATH) $(LIB_PATH) -c BingResultSet.cpp
main.o: main.cpp
$(CC) $(DEBUG) $(INC_PATH) $(LIB_PATH) -c main.cpp
clean:
rm -f $(OBJECT_FILES) $(TARGET)
My file structure:
/Desktop/DataMiner/.cpp, .h, and makefile
/Desktop/DataMiner/HTTPClientLib/include/HTTPClient.h
/Desktop/DataMiner/HTTPClientLib/lib/HTTPClient.a
What's the correct way to link my static lib in my makefile?
Here's my $0.02:
there was no static library involved. Assuming you meant the .o files
you mix dependencies and build rules, instead, avoid repeating build rules:
$(TARGET): $(OBJECT_FILES)
$(CXX) $(DEBUG) $(INC_PATH) $^ -o $# $(LIB_PATH)
%.o: %.cpp
$(CXX) $(DEBUG) $(INC_PATH) -c $< -o $#
You used CC for a C++ compiler. That's strange. Use CXX
You used LDFLAGS when you were just compiling
You hardcoded the source and destination paths. Instead use the automatic variables ($^, $< for source; $# for destination)
You tried to hardcode header dependencies. That's error-prone and messes up source specification (you don't want $^ to list .h files in your command line...). Instead, use gcc -MM¹ to generate the dependencies for you!
Next, do a conditional include of those dependencies:
.depends:
$(CXX) -MM $(CXXFLAGS) -c *.cpp > $#
-include .depends
It's usually handy to keep the .o files so you can speed up builds. Of course, this was not a good plan until you generated the header dependencies automatically. If you insist, you can comment the .PRECIOUS target. Intermediate targets are automatically deleted by GNU Make
Here's the integrated offering I ended up with:
CXX = g++
TARGET = main
OBJECT_FILES = BingResultSet.o main.o
INC_PATH = -I HTTPClientLib/include
LIB_PATH = -L HTTPClientLib/lib/
CPPFLAGS = -g -std=c++11
CPPFLAGS+= $(INC_PATH)
# standard derived flags:
CXXFLAGS+=$(CPPFLAGS)
LDFLAGS+=$(LIB_PATH)
start: .depends $(TARGET)
$(TARGET): $(OBJECT_FILES)
$(CXX) $(CXXFLAGS) $^ -o $# $(LDFLAGS)
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $#
clean:
rm -f .depends $(OBJECT_FILES) $(TARGET)
# to keep the .o files:
.PRECIOUS: $(OBJECT_FILES)
.depends:
$(CXX) -MM $(CXXFLAGS) -c *.cpp > $#
-include .depends
On a very simple sample set of files you get:
$ make clean
rm -f .depends BingResultSet.o main.o main
$ make
g++ -MM -g -std=c++11 -I HTTPClientLib/include -c *.cpp > .depends
g++ -I HTTPClientLib/include -c BingResultSet.cpp -o BingResultSet.o
g++ -I HTTPClientLib/include -c main.cpp -o main.o
g++ -I HTTPClientLib/include BingResultSet.o main.o -o main -L HTTPClientLib/lib/
$ cat .depends
BingResultSet.o: BingResultSet.cpp BingResultSet.h
main.o: main.cpp BingResultSet.h
test.o: test.cpp
¹ (or similar, see man-page)