C Gnu makefile I cannot make a static library with ar - c++

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.

Related

Simplifying the Makefile

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

Makefile ignores specific lines

I'm making a simple C++ project that uses two different programs (One sends information and the other receives it, if you're curious). I made a makefile to compile both programs and generate two executable files in one go, but when I execute my make instruction I get the following error:
makefile:51: atención: se anulan las instrucciones para el objetivo 'build/NetcpSend.o'
makefile:32: atención: se ignoran las instrucciones viejas para el objetivo 'build/NetcpSend.o'
g++ -c -o build/NetcpSend.o src/NetcpSend.cc -g -std=c++11
g++ -c -o build/generic_l.o src/generic_l.cc -g -std=c++11
g++ -c -o build/socket_c.o src/socket_c.cc -g -std=c++11
g++ -c -o build/file_c.o src/file_c.cc -g -std=c++11
g++ -o bin/NetcpSend build/NetcpSend.o build/generic_l.o build/socket_c.o build/file_c.o -g -std=c++11
make: *** No hay ninguna regla para construir el objetivo 'build/NetcpReceive.o', necesario para 'NetcpReceive'. Alto.
Translation:
makefile:51: warning: instructions cancelled for 'build/NetcpSend.o' objective.
makefile:51: warning: instructions cancelled for 'build/NetcpReceive.o' objective.
g++ -c -o build/NetcpSend.o src/NetcpSend.cc -g -std=c++11
g++ -c -o build/generic_l.o src/generic_l.cc -g -std=c++11
g++ -c -o build/socket_c.o src/socket_c.cc -g -std=c++11
g++ -c -o build/file_c.o src/file_c.cc -g -std=c++11
g++ -o bin/NetcpSend build/NetcpSend.o build/generic_l.o build/socket_c.o build/file_c.o -g -std=c++11
make: *** No rule to build 'build/NetcpReceive.o', needed for NetcpReceive. Stop.
And when I try to execute NetcpReceive, it obviously doesn't find the executable, because it hasn't compiled yet.
This is my makefile:
CC=g++
CFLAGS=-g -std=c++11
INCLUDE_DIR=include
OBJECTS_DIR=build
SRC_DIR=src
BIN_DIR=bin
_OBJ1 = NetcpSend.o generic_l.o socket_c.o file_c.o
OBJ1 = $(patsubst %,$(OBJECTS_DIR)/%,$(_OBJ1))
_OBJ2 = NetcpReceive.o generic_l.o socket_c.o file_c.o
OBJ2 = $(patsubst %,$(OBJECTS_DIR)/%,$(_OBJ2))
BIN_NAME1 = NetcpSend
BIN_NAME2 = NetcpReceive
all: All NetcpSend NetcpReceive
All:
$(OBJECTS_DIR)/NetcpSend.o: $(SRC_DIR)/NetcpSend.cc
$(CC) -c -o $# $< $(CFLAGS)
$(OBJECTS_DIR)/generic_l.o: $(SRC_DIR)/generic_l.cc
$(CC) -c -o $# $< $(CFLAGS)
$(OBJECTS_DIR)/socket_c.o: $(SRC_DIR)/socket_c.cc
$(CC) -c -o $# $< $(CFLAGS)
$(OBJECTS_DIR)/file_c.o: $(SRC_DIR)/file_c.cc
$(CC) -c -o $# $< $(CFLAGS)
NetcpSend: $(OBJ1)
$(CC) -o $(BIN_DIR)/$(BIN_NAME1) $^ $(CFLAGS)
NetcpReceive: $(OBJ2)
$(CC) -o $(BIN_DIR)/$(BIN_NAME2) $^ $(CFLAGS)
$(OBJECTS_DIR)/NetcpSend.o: $(SRC_DIR)/NetcpSend.cc
$(CC) -c -o $# $< $(CFLAGS)
run: #Runs the code
./$(BIN_DIR)/$(BIN_NAME1)
./$(BIN_DIR)/$(BIN_NAME2)
dbg: #Debugs the code
gdb ./$(BIN_DIR)/$(BIN_NAME)
.PHONY: clean
clean:
#rm -f $(OBJECTS_DIR)/*.o $(BIN_DIR)/* $(BIN_DIR)/*
I don't know what's causing ths issue, and if my makefile is correct according to standards. Could someone give me a hand?
There is no rule for NetcpReceive.o, only NetcpSend.o and others.
Since all your object build recipes look alike you could/should declare a pattern rule:
$(OBJECTS_DIR)/%.o: $(SRC_DIR)/%.cc
$(CC) -c -o $# $< $(CFLAGS)
Your recipe for the executables can be improved too. Declare the recipe and set prerequisites separately:
# Prerequisites
$(BIN_DIR)/NetcpSend: $(OBJ1)
$(BIN_DIR)/NetcpReceive: $(OBJ2)
# Recipes
$(BIN_DIR)/NetcpReceive $(BIN_DIR)/NetcpSend:
$(CC) -o $# $^ $(CFLAGS)
I personally try not to mess with object and bin folders when using make.

GCC linking a static library

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)

OpenMP Makefile, -fopenmp won't work

I'm trying to compile my project using a Makefile, but somehow the -fopenmp flag won't work.
Here's the Makefile:
TARGET=isaac
CC=g++
CFLAGS=-Wall -O2 -fopenmp
LDFLAGS=-lm -lpthread -lrt
OBJ=src/main.o src/bhtree.o src/body.o src/configreader.o src/diagnostics.o src/output.o src/quad.o src/timing.o src/vector2.o
isaac: $(OBJ)
$(CC) $(CFLAGS) -o $(TARGET) $(OBJ) $(LDFLAGS)
%.o: src/%.cpp
$(CC) $(CFLAGS) -c $<
clean:
rm src/*.o src/*~ isaac
and here is the output when calling "make"
g++ -c -o src/main.o src/main.cpp
g++ -c -o src/bhtree.o src/bhtree.cpp
g++ -c -o src/body.o src/body.cpp
g++ -c -o src/configreader.o src/configreader.cpp
g++ -c -o src/diagnostics.o src/diagnostics.cpp
g++ -c -o src/output.o src/output.cpp
g++ -c -o src/quad.o src/quad.cpp
g++ -c -o src/timing.o src/timing.cpp
g++ -c -o src/vector2.o src/vector2.cpp
g++ -Wall -O2 -fopenmp -o isaac src/main.o src/bhtree.o src/body.o src/configreader.o src/diagnostics.o src/output.o src/quad.o src/timing.o src/vector2.o -lm -lpthread -lrt
the -fopenmp flag is missing when the source files are compiled, so the finished executable is serial, not parallel.
How can I fix this?
The problem is that your rule does not apply at all. You are free to remove
%.o: src/%.cpp
$(CC) $(CFLAGS) -c $<
and you'll get the same result as before. That's because some predefined rule is used instead of yours (I'm not great makefile expert though).
The core of the problem is that your rule is for ./*.o files, but you need ./src/*.o for isaac. You can change your rule
src/%.o: src/%.cpp
$(CC) $(CFLAGS) -c $<
Or (better) move all autogenerated staff somewhere from src.

Having issues with a Makefile for a c++ project written in Xcode

I wrote this c++ project in Xcode, and now I have to create a Makefile so that it compiles properly. Here is the Makefile:
CC = g++
CFLAGS =
PROG = TrainStation
MAIN = main.cpp
OBJS = ArrivalEvent.o DepartureEvent.o Event.o EventCoordinator.o InSwitchEvent.o ListItem.o OrderedList.o OutSwitchEvent.o PriorityQueue.o Train.o
# compiling rules
# WARNING: *must* have a tab before each definition
$(PROG): $(OBJS) main.o # The error was leaving out main.o from this line
$(CC) $(CFLAGS) $(OBJS) main.o -o $(PROG)
ArrivalEvent.o: ArrivalEvent.cpp ArrivalEvent.h EventCoordinator.h InSwitchEvent.h Event.h EventCoordinator.h Train.h
$(CC) $(CFLAGS) -c ArrivalEvent.cpp -o ArrivalEvent.o
DepartureEvent.o: DepartureEvent.cpp DepartureEvent.h OutSwitchEvent.h Event.h EventCoordinator.h Train.h
$(CC) $(CFLAGS) -c DepartureEvent.cpp -o DepartureEvent.o
Event.o: Event.cpp Event.h EventCoordinator.h ListItem.h
$(CC) $(CFLAGS) -c Event.cpp -o Event.o
EventCoordinator.o: EventCoordinator.cpp EventCoordinator.h OrderedList.h Event.h Train.h PriorityQueue.h ArrivalEvent.h InSwitchEvent.h
$(CC) $(CFLAGS) -c EventCoordinator.cpp -o EventCoordinator.o
InSwitchEvent.o: InSwitchEvent.cpp InSwitchEvent.h DepartureEvent.h Event.h EventCoordinator.h Train.h
$(CC) $(CFLAGS) -c InSwitchEvent.cpp -o InSwitchEvent.o
ListItem.o: ListItem.cpp ListItem.h
$(CC) $(CFLAGS) -c ListItem.cpp -o ListItem.o
OrderedList.o: OrderedList.cpp OrderedList.h ListItem.h
$(CC) $(CFLAGS) -c OrderedList.cpp -o OrderedList.o
OutSwitchEvent.o: OutSwitchEvent.cpp OutSwitchEvent.h Train.h InSwitchEvent.h Event.h EventCoordinator.h
$(CC) $(CFLAGS) -c OutSwitchEvent.cpp -o OutSwitchEvent.o
PriorityQueue.o: PriorityQueue.cpp PriorityQueue.h OrderedList.h
$(CC) $(CFLAGS) -c PriorityQueue.cpp -o PriorityQueue.o
Train.o: Train.cpp Train.h ListItem.h
$(CC) $(CFLAGS) -c Train.cpp -o Train.o
main.o: $(MAIN) Train.h OrderedList.h PriorityQueue.h EventCoordinator.h
$(CC) $(CFLAGS) -c $(MAIN) -o main.o
clean:
rm -f $(PROG) $(OBJS)
I have written Makefiles before, but never one with so many files to coordinate, and it seems that it is skipping the rule for main.o [EDIT: I updated my Makefile but now receive this different error]
$ make
g++ -c ArrivalEvent.cpp -o ArrivalEvent.o
g++ -c DepartureEvent.cpp -o DepartureEvent.o
g++ -c Event.cpp -o Event.o
g++ -c EventCoordinator.cpp -o EventCoordinator.o
g++ -c InSwitchEvent.cpp -o InSwitchEvent.o
g++ -c ListItem.cpp -o ListItem.o
g++ -c OrderedList.cpp -o OrderedList.o
g++ -c OutSwitchEvent.cpp -o OutSwitchEvent.o
g++ -c PriorityQueue.cpp -o PriorityQueue.o
g++ -c Train.cpp -o Train.o
g++ main.o ArrivalEvent.o DepartureEvent.o Event.o EventCoordinator.o InSwitchEvent.o ListItem.o OrderedList.o OutSwitchEvent.o PriorityQueue.o Train.o -o TrainStation
i686-apple-darwin11-llvm-g++-4.2: main.o: No such file or directory
make: *** [TrainStation] Error 1
I know this is an error with g++, and that it probably has to do with me leaving out a file somewhere or not linking it, but I can't seem to figure out what is going wrong. Perhaps someone with fresh eyes may be able to spot the problem?
EDIT: PROBLEM SOLVED
My problem was that $(OBJS) doesn't contain main.o, so the rule for $(PROG) doesn't depend on main.o at all. Once I added main.o to the rule for $(PROG), then the rule for main.o is executed correctly.
After MAIN = main.cpp you do never use this variable to compile and link the main.cpp file.
Change this:
$(CC) $(CFLAGS) $(OBJS) -o $(PROG)
to this:
$(CC) $(CFLAGS) $(OBJS) main.o -o $(PROG)