how to link static library to makefile in linux - c++

I have created a static library using database makefile project/database/Makefile like this
rm -rf libdatabase.a
database.o: database.cpp database.h
g++ -c -o database.o database.cpp
ar rvs libdatabase.a database.o
if [ -f libdatabase.a ];
then
echo "Database-Library Build Success"
cp libdatabase.a ../LIBs/
else
echo "databse-Library Build Failure"
fi
then i going to link it in main make file project/Main/Makefile like this
rm -rf testdate
INCPATH = -I../database
LIBPATH = -L../LIBs
testdate:main.o libdatabase.a
g++ -o testdate libdatabase.a main.o
main.o: main.cpp database.h
g++ -c -o main.o main.cpp
but its throwing error like :
make: * No rule to make target database.h', needed bymain.o'. Stop.
Plese some one coluld help me out of this. i am new to linux.

You have an extra backslash in your makefile at the end of the LIBPATH variable assignment. That's causing the next line (the testdate:... target) to be considered part of the variable value for LIBPATH. That in turn means the recipe line after that (the g++ -o testdate ... line) has no target defined, which is why you get that error.
Remove the backslash:
LIBPATH = -L../LIBs

Related

passing optional arguments to a makefile

I have a program and i have this make file and im trying to run my program with this makefile, and it compiles well the problem is when i run the program i what to run it like this ./user -n tejo.tecnico.ulisboa.pt -p 58011 with this -n tejo.tecnico.ulisboa.pt or this -p 58011 being optional.
I saw this post Passing arguments to "make run" and im not understanding what im doing wrong in the make run command
So can anyone tell me whats wrong in my makefile?
btw im fairly new at making makefiles and using the command line.
Program:
# Makefile
CC = g++
LD = g++
AUXLIB = auxiliar_code/aux_functions.h
SOCKETLIB = socket_operations/socket_functs.h
COMMANDSLIB = commands/commands.h
.PHONY: all clean run
all: client
client: socket_operations/socket.o auxiliar_code/aux.o commands/commands.o commands/client.o main.o
$(LD) -o user socket_operations/socket.o auxiliar_code/aux.o commands/commands.o commands/client.o main.o
auxiliar_code/aux.o: auxiliar_code/aux_functions.cpp $(AUXLIB) client_constants.h
$(CC) -o auxiliar_code/aux.o -c auxiliar_code/aux_functions.cpp
commands/client.o: commands/Client.cpp $(COMMANDSLIB) $(SOCKETLIB) $(AUXLIB) client_constants.h
$(CC) -o commands/client.o -c commands/Client.cpp
commands/commands.o: commands/commands.cpp $(COMMANDSLIB) $(SOCKETLIB) $(AUXLIB) client_constants.h
$(CC) -o commands/commands.o -c commands/commands.cpp
socket_operations/socket.o: socket_operations/socket_functs.cpp $(SOCKETLIB) $(AUXLIB) client_constants.h
$(CC) -o socket_operations/socket.o -c socket_operations/socket_functs.cpp
main.o: main.cpp $(COMMANDSLIB) $(AUXLIB) client_constants.h
$(CC) $(CFLAGS) -o main.o -c main.cpp
clean:
#echo Cleaning files generated
rm -f auxiliar_code/*.o commands/*.o socket_operations/*.o *.o user
run: user
#echo ./user $(filter-out $#,$(MAKECMDGOALS))
%:
#:
What you should do is to declare a variable (possibly with default):
# Fill in your default here, setting from command line will override
USER_OPTIONS ?=
run: user
./user $(USER_OPTIONS)
Then invoke make setting the option from the command line:
make run USER_OPTIONS="-n tejo.tecnico.ulisboa.pt -p 58011"

Makefile missing include path Although the path exists and defined

i have make file which i try to make them generic
but it keeps to compline it missing include directory
this is the makefile :
CXX=g++
CPPFAGS= -Wall -O0 -g -std=c++14
INCLUDES = -I/home/vagrant/libuv/include -Isrc
LIBS_DIRS = -L/home/vagrant/libuv/build
LDFLAGS= -lssl -lcrypto
LIB_STATIC = -Wl,--no-as-needed -Bstatic -luv_a -ldl -lpthread
SOURCE = $(wildcard echo.cpp) \
$(wildcard src/*.cpp)
OBJ = $(SOURCE:.cpp=.o)
DEP = $(OBJ:.o=.d)
TARGET = myproj
$(TARGET) : $(OBJ)
$(CXX) $(CPPFLAGS) $(INCLUDES) -o $# $^ $(LIBS_DIRS) $(LDFLAGS) $(LIB_STATIC)
all: $(TARGET)
clean:
rm -f $(OBJ) $(TARGET)
cleandep:
rm -f $(DEP)
.PHONY:all clean cleandep
when i make : make -n :
make -n
g++ -c -o echo.o echo.cpp
g++ -c -o src/base64.o src/base64.cpp
g++ -c -o src/Server.o src/Server.cpp
g++ -c -o src/sha1.o src/sha1.cpp
g++ -c -o src/Client.o src/Client.cpp
g++ -I/home/vagrant/libuv/include -Isrc -o myproj echo.o src/base64.o src/Server.o src/sha1.o src/Client.o -L/home/vagrant/libuv/build -lssl -lcrypto -Wl,--no-as-needed -Bstatic -luv_a -ldl -lpthread
when i invoke make , im getting this error:
make
g++ -c -o echo.o echo.cpp
In file included from src/Server.h:9:0,
from echo.cpp:1:
src/Client.h:6:10: fatal error: uv.h: No such file or directory
#include <uv.h>
^~~~~~
compilation terminated.
make: *** [echo.o] Error 1
but the uv do exist in : /home/vagrant/libuv/include
You have no rule to build your object files: you've only defined a rule to link your object files into a final executable. As mentioned in the comments, adding $(INCLUDES) into that recipe is useless because header file directories are only used during compiling (creating object files) not linking (converting object files and libraries into executables).
Because you haven't defined your own rule to build object files, you're using make's built-in rule. But make's built-in rule doesn't know anything about a variable named INCLUDES, so that variable is not used during compilation. You can easily see this by looking at the compiler commands generated by make.
You need to either (a) create your own rule for compiling object files that uses your personal make variables, or (b) use the normal built-in variables that make expects to be used with its built-in rules.
For (b), as described in the manual, you should take your current CPPFAGS [sic] variable and rename it to CXXFLAGS, take your current INCLUDES variable and rename it CPPFLAGS, take your current LIBS_DIRS variable and rename it LDFLAGS, and take your current LDFLAGS variable and rename it to LDLIBS.
Also just to note, you have DEPS etc. but there is nothing in your makefile that does anything with them or to create them so they're useless.

Boost & makefile

i'm trying to use the boost_math libs on OS X (i'm not using Xcode), specifically the one containing the error function
I downloaded and compiled boost_1_60_0 myself (using bootstrap.sh and following the instructions.) I didn't use home-brew or something else, which might be why my installation seems so screwed up.
What i'm trying to include in my Szabo.hpp is this:
#include <boost/math/special_functions/erf.hpp>
My makefile goes like this:
LIB_FLAGS = -L/Documents/boost_1_60_0/stage/lib -lboost_math
ALL_OBJECTS = main.o Gaussienne.o Grille.o Szabo.o
all: $(ALL_OBJECTS)
g++ -o hydrogene $(ALL_OBJECTS) $(LIB_FLAGS)
Gaussienne.o: Gaussienne.cpp
g++ -o Gaussienne.o -c Gaussienne.cpp -W -Wall -ansi
main.o: Gaussienne.hpp Grille.hpp main.cpp Szabo.o
g++ -o main.o -c main.cpp -W -Wall -ansi
Grille.o: Grille.cpp Gaussienne.cpp
g++ -o Grille.o -c Grille.cpp -W -Wall -ansi
Szabo.o: Szabo.cpp Gaussienne.cpp
g++ -o Szabo.o -c Szabo.cpp -W -Wall -ansi
clean:
rm -rf *.o
mrproper: clean
rm -rf hydrogene
I get no linking error from g++, however i got:
In file included from Szabo.cpp:12:
./Szabo.hpp:21:10: fatal error: 'boost/math/special_functions/erf.hpp' file not found
#include <boost/math/special_functions/erf.hpp>
^
1 error generated.
Can you please provide help on how to fix this? Thanks in advance
Ok so apparently likes this, it works:
LIB_FLAGS = -L/Users/devolution/Documents/boost_1_60_0/stage/lib -lboost_math_tr1
I_FLAGS = -I/Users/devolution/Documents/boost_1_60_0/
ALL_OBJECTS = main.o Gaussienne.o Grille.o Szabo.o
all: $(ALL_OBJECTS)
g++ -o hydrogene $(ALL_OBJECTS) $(LIB_FLAGS)
Gaussienne.o: Gaussienne.cpp
g++ -o Gaussienne.o -c Gaussienne.cpp -ansi ${I_FLAGS}
main.o: Gaussienne.hpp Grille.hpp main.cpp Szabo.o
g++ -o main.o -c main.cpp -ansi ${I_FLAGS}
Grille.o: Grille.cpp Gaussienne.cpp
g++ -o Grille.o -c Grille.cpp -ansi ${I_FLAGS}
Szabo.o: Szabo.cpp Gaussienne.cpp
g++ -o Szabo.o -c Szabo.cpp -ansi ${I_FLAGS}
.PHONY: clean mrproper
clean:
rm -rf *.o
mrproper: clean
rm -rf hydrogene
Is there a way to pass I_FLAGS?
You've compiled Boost's separately-compiled libraries, which is great, but you didn't copy the headers to your toolchain's include path. Indeed, most of Boost is comprised of header-only libraries, so this is arguably the more crucial step of installing Boost.
The internet tells me you may be able to find the default header search path with the following command at shell:
gcc -x c++ -v -E /dev/null
(https://stackoverflow.com/a/19852298/560648)
When you find it, copy the distribution's boost subdirectory to it.
And, yes, having home-brew install Boost for you would have been much easier… probably one command!

Extending a simple makefile to support different implicit compiler flags

I have been using a makefile that was fairly straightforward. I defined OBJS with a list of .cc files. I set up dependencies and include flags and appended all of those to $CXXFLAGS. It looks something like this:
SRCS = file1.cc file2.cc file3.cc
OBJS = $(SRCS:.cc=.o)
CXXFLAGS=some flags
CXXFLAGS+=some include dirs
$(mylib.so): $OBJS
$CXX -shared -o $# $^
mylib.so uses the CXXFLAGS (implicitly) and everything builds just fine.
I have recently had the need to have mylib_1.so and mylib_2.so, in addition to mylib.so. Each .so depend on all the same .cc files, but the compiler flags are all different (including include directories).
How do I get it so I can set the compiler flags based on the target .so? The problem that I have is that if I set CXXFLAGS more than once it gets overwritten. It's almost like I need an if/else situation.
I tried doing something like setting three different flags, $CXXFLAGS1, $CXXFLAGS2, $CXXFLAGS3, and using those in the line
$(mylib1.so): $OBJS
$CXX $(CXXFLAGS1) -shared -o $# $^
but that does not work.
How do I accomplish what I am trying to do? Is it better to have 3 separate makefiles? I did find a way to get it to work. I can stop using $OBJS and spell out the flags explicitly for each source file but this seems like a horrible idea in terms of scaling to size.
Your CXXFLAGS1 in your example is only used at the stage of creating the .so file, not for compilation of the actual C++ sources (which is what you are trying to do, I assume).
To achieve the above, consider making the Makefile invoke itself 3 times for 3 different targets and pass CXXFLAGS (with different values) as part of MAKEFLAGS or in the command line.
Update: here's an example
all: build-lib1 build-lib2 build-lib3
build-lib1:
$(MAKE) $(MAKEFLAGS) CXXFLAGS="$(CXXFLAGS1)" lib1.so
build-lib2:
$(MAKE) $(MAKEFLAGS) CXXFLAGS="$(CXXFLAGS2)" lib2.so
build-lib3:
$(MAKE) $(MAKEFLAGS) CXXFLAGS="$(CXXFLAGS3)" lib3.so
$(lib1.so): $OBJS
$(CXX) -shared -o $# $^
etc...
Makefiles can have target-specific variable values. Something like:
$(mylib1.so): CXXFLAGS += -lib1flags
$(mylib2.so): CXXFLAGS += -lib2flags
$(mylib3.so): CXXFLAGS += -lib3flags
According to the documentation, the flags will propagate to prerequisite targets.
There is one more special feature of target-specific variables: when
you define a target-specific variable that variable value is also in
effect for all prerequisites of this target, and all their
prerequisites, etc. (unless those prerequisites override that variable
with their own target-specific variable value). So, for example, a
statement like this:
prog : CFLAGS = -g
prog : prog.o foo.o bar.o
will set CFLAGS to ‘-g’ in the recipe for prog, but it will also set
CFLAGS to ‘-g’ in the recipes that create prog.o, foo.o, and bar.o,
and any recipes which create their prerequisites.
I would do this with a recursive call to make. I would use two makefiles:
In Makefile:
all: mylib1.so mylib2.so
SRCS := file1.cc file2.cc file3.cc
mylib1.so: $(SRCS)
test -d mylib1 || mkdir mylib1
$(MAKE) -f ../lib.mak -C mylib1 TARGET=mylib1.so CXXFLAGS=-DMYLIB=1
cp mylib1/mylib1.so mylib1.so
mylib2.so: $(SRCS)
test -d mylib2 || mkdir mylib2
$(MAKE) -f ../lib.mak -C mylib2 TARGET=mylib2.so CXXFLAGS=-DMYLIB=2
cp mylib2/mylib2.so mylib2.so
In lib.mak, in the same directory:
VPATH = ..
SRCS := file1.cc file2.cc file3.cc
OBJS := $(SRCS:.cc=.o)
$(TARGET): $(OBJS)
$(CXX) -shared -o $# $^
The second makefile actually builds the library, but only uses one set of CXXFLAGS. The primary makefile calls the first makefile for each version with separate CXXFLAGS and in a separate directory. The VPATH makes it easier to compile source files that aren't in the same directory.
I tested this setup with a dry run,
test -d mylib1 || mkdir mylib1
make -f ../lib.mak -C mylib1 TARGET=mylib1.so CXXFLAGS=-DMYLIB=1
make[1]: Entering directory `/home/depp/Maketest2/mylib1'
g++ -DMYLIB=1 -c -o file1.o ../file1.cc
g++ -DMYLIB=1 -c -o file2.o ../file2.cc
g++ -DMYLIB=1 -c -o file3.o ../file3.cc
g++ -shared -o mylib1.so file1.o file2.o file3.o
make[1]: Leaving directory `/home/depp/Maketest2/mylib1'
cp mylib1/mylib1.so mylib1.so
test -d mylib2 || mkdir mylib2
make -f ../lib.mak -C mylib2 TARGET=mylib2.so CXXFLAGS=-DMYLIB=2
make[1]: Entering directory `/home/depp/Maketest2/mylib2'
g++ -DMYLIB=2 -c -o file1.o ../file1.cc
g++ -DMYLIB=2 -c -o file2.o ../file2.cc
g++ -DMYLIB=2 -c -o file3.o ../file3.cc
g++ -shared -o mylib2.so file1.o file2.o file3.o
make[1]: Leaving directory `/home/depp/Maketest2/mylib2'
cp mylib2/mylib2.so mylib2.so

make: c: command not found

I am attempting to run my make file however i am getting the following two errors:
make: c: command not found
and
make: o: command not found
I am attempting to do this inside of cygwin. I have g++ and make installed on it, however when I run the make file I receive these errors.
Any ideas?
The makefile:
all: MergeSort clean
MergeSort: main.o MergeSort.o
$g++ -o MergeSort main.o MergeSort.o
main.o: main.cpp MergeSort.h
$g++ -c main.cpp
MergeSort.o: MergeSort.cpp MergeSort.h
$g++ -c MergeSort.cpp
clean:
rm -rf *o
cleanall:
rm -rf *o *exe
You need to remove the $ from the $g++ lines. It's trying to expand some variable that doesn't exist, and is swallowing up the "$g++ -" from your commands.
The syntax for using a variable is:
$(CXX) -c main.cpp
In this case, CXX is the path to the C++ compiler, which is defined for you. You can change it by adding the following line to your makefile:
CXX = g++
If you are trying to avoid echoing back the command make is running, use # instead of $.
$g++ is not defined in that makefile, so the command becomes
-o MergeSort main.o MergeSort.o
and
-c main.cpp
Either drop the $ from $g++ and use g++, or define the variable in your makefile.
CXX = g++
all: MergeSort clean
MergeSort: main.o MergeSort.o
$CXX -o MergeSort main.o MergeSort.o
main.o: main.cpp MergeSort.h
$CXX -c main.cpp
MergeSort.o: MergeSort.cpp MergeSort.h
$CXX -c MergeSort.cpp
clean:
rm -rf *o
cleanall:
rm -rf *o *exe