Trying to add a library to a make file - c++

Hi this is my make file (I have very little make file experience sorry)
PROJECT_ROOT = $(dir $(abspath $(firstword $(MAKEFILE_LIST))))
OBJS = Angle.o \
AppControlTimer.o \
CableAngle.o \
CFunctionObject.o \
SonarDGCUArrayData.o \
SonarDGCUCommsTCP.o \
SonarDGCUEthernetClient.o \
SonarDGCUFinsPacket.o \
SonarDGCUMotorMemoryArea.o \
SonarDGCUSensorsData.o \
SonarDGCUSensorsMemoryArea.o \
SonarDGCUThread.o
LIB = libFins.a
INCPATH = ../../
INSTALL_DIR = /opt/s2193/lib64
ifeq ($(BUILD_MODE),debug)
CFLAGS += -g
else ifeq ($(BUILD_MODE),run)
CFLAGS += -O2
else ifeq ($(BUILD_MODE),linuxtools)
CFLAGS += -g -pg -fprofile-arcs -ftest-coverage
LDFLAGS += -pg -fprofile-arcs -ftest-coverage
else
$(error Build mode $(BUILD_MODE) not supported by this Makefile)
endif
CFLAGS += -MMD -Wall -Wextra -Wpedantic -Wno-vla
CFLAGS += -I$(PROJECT_ROOT)../target/nar/log4cxx-0.11.0.TUS1-noarch/include/ -c -Wall
CFLAGS += -I${INCPATH}include -DLINUX
LDFLAGS += -L$(PROJECT_ROOT)../target/libs/ -llog4cxx
CXXFLAGS += -DBUILD_WITHOUT_HAL -DDBG_LVL=7
CXX += -std=c++11
CC += -std=c11
.PHONY: all clean install
all: $(LIB)
$(LIB): $(OBJS)
$(AR) $(ARFLAGS) -o $# $^
%.o: $(PROJECT_ROOT)src/%.cpp
#echo ".cpp.o!! "$<
$(CXX) -c $(CFLAGS) $(CXXFLAGS) $(CPPFLAGS) -o $# $<
%.o: $(PROJECT_ROOT)src/%.c
#echo ".c.o!! $<"
$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $# $<
clean:
rm -fr $(LIB) $(OBJS) $(OBJS:.o=.d)
install: $(LIB)
install -m 755 -d $(INSTALL_DIR)
install -m 644 $(LIB) $(INSTALL_DIR)
-include $(OBJS:.o=.d)
when I use the file I get undefined reflectances I'm trying to use the library
LDFLAGS += -L$(PROJECT_ROOT)../target/libs/ -llog4cxx
but I'm not sure how to add it to the file for reference when building libfins.a
thanks in advance

liblog4cxx supports pkg-config like any other sanely packaged library.
Stop writing flags by hand for libraries that you haven't made.
CXXFLAGS += $(shell pkg-config --cflags liblog4cxx)
LDFLAGS += $(shell pkg-config --libs liblog4cxx)
If you are really curious about flags your library needs, go ahead and run these two commands in your terminal, then leave it at that. Flags needed on your system are not necessarily flags needed on mine, that's why pkg-config exists, and people who made the library know better than you what it needs or does not need.
At the same time, pkg-config allows to expect a specific version of a library and all dependencies of your dependency are resolved transparently, without you having to do anything about it, and in fact you cannot do anything about it, because you don't know when or how the library or any of its dependencies will change, this becomes even more insane to manage yourself if you're linking statically. When using pkg-config, you just tack on --static and it gives you all the extra necessary flags.

Related

Error while loading shared libraries when running executable

When I make the Makefile everything works fine, I get a library in the directory dir. And when I run "Make test" I get a testfile that I want to run. But when I want to run this file I get this weird error: ./programma: error while loading shared libraries: libprogramma.so: cannot open shared object file: No such file or directory. I have tried running the program on both WSL and Linux, but nothing makes this error go away. Can anyone help me?
Here I have my Makefile which makes the library and the executable:
INC_DIR = include
SRC_DIR = src
SOURCES = $(sort $(shell find $(SRC_DIR) -name '*.cc'))
OBJECTS = $(SOURCES:.cc=.o)
DEPS = $(OBJECTS:.o=.d)
TARGET = programma
CXX = g++
CFLAGS = -Wall -Wextra -Wpedantic -std=c++11
CPPFLAGS = $(addprefix -I, $(INC_DIR))
.PHONY: all clean debug release
release: CFLAGS += -O3 -DNDEBUG
release: all
debug: CFLAGS += -O0 -DDEBUG -ggdb3
debug: all
all: $(TARGET)
clean:
rm -f $(OBJECTS) $(DEPS) lib/*.so programma *.d
$(TARGET): $(OBJECTS)
$(CXX) $(CFLAGS) $(CPPFLAGS) -fPIC -shared -o lib/lib$#.so $^
-include $(DEPS)
%.o: %.cc
$(CXX) $(CFLAGS) $(CPPFLAGS) -fPIC -MMD -o $# -c $<
test:
$(CXX) $(CFLAGS) -L./lib $(CPPFLAGS) -MMD -o programma tests/main.cc -l$(TARGET)
Executables on Linux don't look for shared libraries in the directory they're located in, at least by default.
You can either fix that at link-time, by passing -Wl,-rpath='$ORIGIN', or at runtime, by setting LD_LIBRARY_PATH env variable to the directory with the library. (LD_LIBRARY_PATH=path/to/lib ./programma)

Makefile unable to link libraries during runtime

So I am using nvidia's deepstream sdk and trying to modify the makefile of one of the sample examples given as I wish to link and add my own libraries. This is the makefile being employed where I am setting the path of the CUSTOM_LIB to point to the location of my library. The issue is the project gets compiled successfully but during run time, its unable to find the custom library. I performed ldd on the executable generated and there also it was showing the library as 'not found'. I think it's something to do with rpath but I am not sure about that.
APP:= sample
TARGET_DEVICE = $(shell gcc -dumpmachine | cut -f1 -d -)
NVDS_VERSION:=4.0
LIB_INSTALL_DIR?=/opt/nvidia/deepstream/deepstream-$(NVDS_VERSION)/lib/
ifeq ($(TARGET_DEVICE),aarch64)
CFLAGS:= -DPLATFORM_TEGRA
endif
CUDA_VER:=10.0
CC:=g++
SRCS:= $(wildcard ../src/*.c)
#SRCS+= $(wildcard ../../apps-common/src/*.c)
#SRCS+=
INCS:= $(wildcard ../include/*.h)
PKGS:= gstreamer-1.0 gstreamer-video-1.0 x11 opencv
OBJS:= $(SRCS:.c=.o)
CFLAGS+= -I../include -I/usr/include -I$(CUSTOM_LIB)/include -I/usr/local/cuda-10.0/targets/aarch64-linux/include/ -I/usr/include/jsoncpp -DDS_VERSION_MINOR=0 -DDS_VERSION_MAJOR=4 -fpermissive -Wnarrowing
LIBS+= -L$(LIB_INSTALL_DIR) -L/usr/lib/aarch64-linux-gnu -L$(CUSTOM_LIB)/lib -L/usr/lib/aarch64-linux-gnu/ -lcurl -letlic -letolm -lssl -lcrypto -llogger -lpthread -lsqlite3 -ljsoncpp -lnvdsgst_meta -lnvbufsurface -lnvbufsurftransform -lnvds_meta -lnvdsgst_helper -lnvds_utils -lm -L/usr/local/cuda-$(CUDA_VER)/lib64/ -lcudart \
-lgstrtspserver-1.0 -Wl,-rpath,$(LIB_INSTALL_DIR)
CFLAGS+= `pkg-config --cflags $(PKGS)`
LIBS+= `pkg-config --libs $(PKGS)`
all: $(APP)
debug: CXXFLAGS += -DDEBUG -g
debug: CFLAGS += -DDEBUG -g
debug: $(APP)
%.o: %.c $(INCS) Makefile
$(CC) -c -o $# $(CFLAGS) $<
$(APP): $(OBJS) Makefile
$(CC) -o $(APP) $(OBJS) $(LIBS)
clean:
rm -rf $(OBJS) $(APP)
You need to set rpath to a colon-separated list of directories where your libraries are found. You only add LIB_INSTALL_DIR but not CUSTOM_LIB_DIR. Generally everything you pass to -L you need to pass to -rpath too, unless there is a specific reason not to. For example, if you are building a package that has more than a single library and you are going to install in a standard place like /usr/lib, you don't have to add the directory where libraries temporarily live to -rpath. If you are going to install to a non-standard directory, add that directory.

Shared library with freeglut - undefined symbol

I'm actually experiencing some issues while linking an OpenGL/freeglut shared library (.so) with a C++ project. I'm sure that the problem is in my Makefile since the code I use to load (using the dlopen/dlsym/dlclose functions) works fine with other shared libraries.
I thought it comes from headers inclusions but the OpenGL project I'm trying to work with compiles when I create an executable of it. I've also checked the glut FAQ but the solution now redirect to a dead link So there is my Makefile content, does anyone see where I am wrong ?
TARGET = lib_opengl.so
CC = g++
SRC = GL_Handler.cpp \
GL_Utils.cpp
DEVIL_CFLAGS := $(shell pkg-config --cflags IL)
DEVIL_LIBS := $(shell pkg-config --libs IL)
LIBS += -lGL -lGLU -lglut $(DEVIL_CFLAGS) $(DEVIL_LIBS)
CFLAGS = -W -Werror -Wall -ansi -pedantic -fPIC -shared -L/usr/X11R6/lib/ $(LIBS)
SRCDIR = src
OBJDIR = obj
SOURCES := $(addprefix src/, $(SRC))
OBJECTS := $(SOURCES:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)
rm = rm -rf
mkdir = mkdir -p
$(TARGET): $(OBJECTS)
#$(CC) $(CFLAGS) -o $# $(OBJECTS)
#echo $(TARGET)" compiled !"
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.cpp
#$(mkdir) $(OBJDIR)
#$(CC) $(CFLAGS) -c $< -o $#
all : $(TARGET)
clean :
#$(rm) $(OBJDIR)
#echo "Binary files deleted"
fclean : clean
#$(rm) $(TARGET) $(LINK)
#echo "Binary and executable files are deleted"
re : fclean all
.PHONY: all clean fclean re
And there is the result when I'm trying to link it with my shared libraries loader.
./so_loader ./lib/lib_opengl.so
./so_loader: symbol lookup error: ./lib/lib_opengl.so: undefined symbol: glutInit
I hope that my problem is understandable and thanks for reading.
As a start, use variable LDFLAGS for linking instead of CFLAGS which is meant for compilation. Something like this:
LDFLAGS = -L/usr/X11R6/lib
...
$(TARGET): LDFLAGS += -shared -Wl,--no-undefined
$(TARGET): $(OBJECTS)
#$(CC) $(LDFLAGS) -o $# $(OBJECTS) ${LIBS}

makefile for boost crossplatform

I have created a makefile for a library I am compiling.
I have already got the makefile working on windows and linux , but there is a different makefile for each OS.
How could I allow this to work on both OS without hardcoding the path to the boost library and boost headers below:
Do I need to add the boost folder to the path variable? do I need to add the library directory to some OS variable?
makefile windows:
# source files.
SRC = protoService.cpp protocolBaseServer.cpp client.cpp
OBJ = $(SRC:.cpp=.o)
OUT = ../libutils.a
# include directories
INCLUDES = -I. -I../include/ -IC:\boost_1_59_0\
# C++ compiler flags (-g -O2 -Wall)
CCFLAGS = -g -MD -MP -std=c++0x -Wall -c
# compiler
CCC = g++
# library paths
LIBS = -LC:\boost_1_59_0\libs -lboost_serialization
# compile flags
LDFLAGS = -g
.SUFFIXES: .cpp
default: $(OUT)
.cpp.o:
$(CCC) $(INCLUDES) $(CCFLAGS) $< -o $#
$(OUT): $(OBJ)
ar rcs $(OUT) $(OBJ)
#depend: dep
#dep:
# makedepend -- $(CFLAGS) -- $(INCLUDES) $(SRC)
clean:
rm -f $(OBJ) $(OUT) Makefile.bak
-include $(DEPS:%.o=%.d)
makefile linux:
# source files.
SRC = protoService.cpp protocolBaseServer.cpp client.cpp
OBJ = $(SRC:.cpp=.o)
OUT = ../libutils.a
# include directories
INCLUDES = -I. -I../include/ -I/usr/local/include -I/usr/share/boost_1_58_0/
# C++ compiler flags (-g -O2 -Wall)
CCFLAGS = -g -MD -MP -std=c++0x -Wall -c
# compiler
CCC = g++
# library paths
LIBS = -L/usr/share/boost_1_58_0/lib/ -lboost_serialization
# compile flags
LDFLAGS = -g
.SUFFIXES: .cpp
default: $(OUT)
.cpp.o:
$(CCC) $(INCLUDES) $(CCFLAGS) $< -o $#
$(OUT): $(OBJ)
ar rcs $(OUT) $(OBJ)
#depend: dep
#dep:
# makedepend -- $(CFLAGS) -- $(INCLUDES) $(SRC)
clean:
rm -f $(OBJ) $(OUT) Makefile.bak
-include $(DEPS:%.o=%.d)
Make passes environment variables to the makefile processor, so you can create make variables based on them.
INC_PATHS := ../include/ .
LIBS += boost_serialization
ifeq ($(OS),"Windows_NT")
INC_PATHS += ../include/ C:/boost_1_59_0/libs
LIBS += boost_serialization
else
INC_PATHS += /usr/local/include /usr/share/boost_1_58_0/lib/
endif
And then
INCLUDES = $(prepend -I,$(INC_PATHS))
or something like that. I'm not in front of make to ensure the syntax is exactly correct, but it should get you moving in the right direction.

Building multiple shared libraries with one Makefile

I'm trying to build multiple shared libraries in one makefile. This is what I'm using to build one shared library:
CC = gcc # C compiler
PWD := $(shell pwd)
CFLAGS = -fPIC -Wall -Wextra -O2 -g # C flags
LDFLAGS = -shared # linking flags
RM = rm -f # rm command
CFLAGS += $(DFLAGS)
TARGET_LIB := lib1.so # target lib
#TARGET_LIB += lib2.so
SRCS := lib1.c # source files
#SRCS += lib2.c # source files
OBJS = $(SRCS:.c=.o)
.PHONY: all
all: $(TARGET_LIB)
$(TARGET_LIB): $(OBJS)
$(CC) $(INC) $(LDFLAGS) $(CFLAGS) -o $# $^
However, I can't just uncomment the lines for lib2 and have it being built as well. It's likely because $(TARGET_LIB): $(OBJS) expands to lib1.so lib2.so : lib1.o lib2.o which isn't what I want.
Instead, I want something like
lib1.so : lib1.o
lib2.so : lib2.o
But I'm not sure how to do so or what it is called. Can someone tell me what to do to achieve what I'm looking for?
EDIT: I should have been more clear. I realize you can add more targets to build these. But is there a way to do it without having to write a new target everytime I want to add a new library?
Thanks.
You can do something like this -
all : lib1.so lib2.so
and provide rules to make lib1.so and lib2.so
You can separate sources of two libraries into different directories. It also may help in further maintenance of your libraries. Then use one make file which will trigger corresponding sub-makefiles. I may be better than one big makefile
You can do it by separating targets like this:
CC = gcc # C compiler
PWD := $(shell pwd)
CFLAGS = -fPIC -Wall -Wextra -O2 -g # C flags
LDFLAGS = -shared # linking flags
RM = rm -f # rm command
CFLAGS += $(DFLAGS)
TARGET_LIB1 = lib1.so # target lib
TARGET_LIB2 = lib2.so
TARGET_LIBS = $(TARGET_LIB1) $(TARGET_LIB2)
SRCS1 = lib1.c # source files
SRCS2 = lib2.c # source files
SRCS = $(SRCS1) $(SRCS2)
OBJS1 = $(SRCS1:.c=.o)
OBJS2 = $(SRCS2:.c=.o)
OBJS = $(OBJS1) $(OBJS2)
.PHONY: all
all: $(TARGET_LIBS)
$(TARGET_LIB1): $(OBJS1)
$(CC) $(INC) $(LDFLAGS) $(CFLAGS) -o $# $^
$(TARGET_LIB2): $(OBJS2)
$(CC) $(INC) $(LDFLAGS) $(CFLAGS) -o $# $^
The implicit rules are for that. Read about them in the GNU Make manual.
Replace
$(TARGET_LIB): $(OBJS)
with
%.so: %.c