adding shared library path to Makefile - makefile

I want to add the shared library path to my Makefile. I have put in the export command in the makefile, it even gets called, but I still have to manually export it again.
What is the correct approach?
Makefile:
SOURCES = kwest_main.c fusefunc.c dbfuse.c logging.c dbbasic.c dbinit.c dbkey.c metadata_extract.c plugins_extraction.c import.c
LIBS = -L$(LIB) -lfuse -lsqlite3 -lkw_taglib -ltag_c -ltag -Wl,-rpath=.
INCLUDE = ../include
LIB = ../lib
EXE = kwest
CC = gcc
CCFLAGS = -g -Wall -Wextra -std=gnu99 -pedantic-errors -I$(INCLUDE)
OFLAGS = -c
ARCH = $(shell getconf LONG_BIT)
X = -D_FILE_OFFSET_BITS=$(ARCH)
OBJECTS = $(SOURCES:.c=.o)
$(EXE) : $(OBJECTS)
$(CC) -o $(EXE) $(OBJECTS) $(LIBS)
%.o: %.c
$(CC) $(OFLAGS) $(CCFLAGS) $<
fusefunc.o: fusefunc.c
$(CC) $(OFLAGS) $(CCFLAGS) $< $X
kwest_libs: kw_taglib
--->export LD_LIBRARY_PATH=$(LIB):$LD_LIBRARY_PATH
kw_taglib: plugin_taglib
plugin_taglib: plugin_taglib.o kwt_upd_meta.o
gcc -g -shared -I$(INCLUDE) -Wl,-soname,libkw_taglib.so -o $(LIB)/libkw_taglib.so -ltag -ltag_c plugin_taglib.o kwt_upd_meta.o
plugin_taglib.o:
gcc -c -g -I$(INCLUDE) -Wall -Wextra -pedantic-errors -std=gnu99 -fPIC -ltag_c -c plugin_taglib.c
kwt_upd_meta.o:
g++ -c -g -I$(INCLUDE) -Wall -Wextra -pedantic-errors -fPIC -ltag kwt_upd_meta.cpp
c: clean
clean:
rm -rf *.o
rm -rf *.db
ca: cleanall
cleanall: clean
rm -rf $(EXE)
ob: cleanall
rm -rf ~/.config/$(EXE)/
Execution:
$ ./kwest mnt
./kwest: error while loading shared libraries: libkw_taglib.so: cannot open shared object file: No such file or directory
$ export LD_LIBRARY_PATH=../lib:D_LIBRARY_PATH
$ ./kwest mnt
"executes correctly"

The usual way is to copy the dynamic library during the default make and to one of the standard library path
/usr/local/bin
or one of your project library path and add the library to executable using
-L/project/specific/path
during make install.

As already mentioned here, the thing you probably want is the linker option -rpath.
Like that, you can set a default search path for the binary. Looks like you even already use -rpath in your makefile, but you specify the wrong path:
LIBS = -L$(LIB) -lfuse -lsqlite3 -lkw_taglib -ltag_c -ltag -Wl,-rpath=.
So the binary will search in the current directory for dyn-libraries.
However, you add ../lib to your LD_LIBRARY_PATH later, for execution of the binary, so the given path . seems to be wrong.
Please take a try for the following fix:
LIBS = -L$(LIB) -lfuse -lsqlite3 -lkw_taglib -ltag_c -ltag -Wl,-rpath=../lib
Like that you should not need to specify a LD_LIBRARY_PATH for execution.

Related

Makefile cant find libraries

I'm trying to write my own makefile for a paho.mqtt project on a Raspberry Pi 4.
I've downloaded & tested the paho.mqtt install and its all working as expected.
So I'm now testing some C code but I just cant figure out the makefile (I'm new to this), my file so far,
NAME = mqtt_test
OBJ = $(NAME).o
LIBS = -libpaho-mqtt3c -libpaho-mqtt3cs
CFLAGS = -Wall -I/usr/local/include -L/usr/local/lib
CC = gcc
EXTENSION = .c
all: $(NAME)
%.o: %$(EXTENSION) $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
$(NAME): $(OBJ)
$(CC) -o $# $^ $(CFLAGS) $(LIBS)
.PHONY: clean
clean:
#rm -f *.o *~ core $(NAME)
This returns,
gcc -o mqtt_test mqtt_test.o -Wall -I/usr/local/include -L/usr/local/lib -libpaho-mqtt3c -libpaho-mqtt3cs
/usr/bin/ld: cannot find -libpaho-mqtt3c
/usr/bin/ld: cannot find -libpaho-mqtt3cs
collect2: error: ld returned 1 exit status
make: *** [makefile:14: mqtt_test] Error 1
I've checked & the includes and libraries are in the directories I put after the-I and -L flags.
When I look in /usr/bin there is no ld but there are paho files prefixed with paho_ but no library files.
What am I missing?
You don't use -libpaho-mqtt3c (etc.)
The option is -l so when you write -libpaho-mqtt3c the linker is looking for libraries named ibpaho-mqtt3c which of course do not exist: that would be either libibpaho-mqtt3c.a or libibpaho-mqtt3c.so.
You want to use -lpaho-mqtt3c: remove the lib at the front and the extension .a or .so, and add in the option -l.

Make error: The system cannot find the path specified

I'm getting a Make error when I run the mingw32-make command:
PS D:\> mingw32-make
cd src; mingw32-make
The system cannot find the path specified.
mingw32-make: *** [Makefile:4: all] Error 1
But when I list the actual command listed in the Makefile i.e. cd src; mingw32-make, the build is finished successfully.
PS D:\> cd src; mingw32-make
g++ -std=c++17 -Wall -Wextra -Wpedantic -Wformat -Wchkp -I../include -c account.cpp
g++ -std=c++17 -Wall -Wextra -Wpedantic -Wformat -Wchkp -I../include -c customer.cpp
g++ -std=c++17 -Wall -Wextra -Wpedantic -Wformat -Wchkp -I../include -c display.cpp
g++ -std=c++17 -Wall -Wextra -Wpedantic -Wformat -Wchkp -I../include -c main.cpp
g++ -std=c++17 -Wall -Wextra -Wpedantic -Wformat -Wchkp -I../include -c passbook.cpp
g++ -std=c++17 -Wall -Wextra -Wpedantic -Wformat -Wchkp -I../include -c security.cpp
g++ -std=c++17 -Wall -Wextra -Wpedantic -Wformat -Wchkp -I../include -c staff.cpp
g++ -o Bank account.o customer.o display.o main.o passbook.o security.o staff.o
However this issue is not present when I build using Make on Ubuntu.
This is the Makefile in my root directory:
DIR = src
all:
cd $(DIR); mingw32-make
clean:
cd $(DIR); mingw32-make clean
This is the Makefile in my src subdirectory:
# Compiler options
# -std=c++17 enables ISO C++ 17 standard
CC = g++
CCFLAGS = -std=c++17 -Wall -Wextra -Wpedantic -
Wformat -Wchkp
i = ../include
# LOCFLAGS used to set tell the compiler where to find a
# header that is not in the same directory as the source
file itself
# LOCFLAGS will be set in directory level makefiles as
needed
LOCFLAGS = -I../include
# The list of object files that can be made in this
subdirectory
# is assigned to the make macro named $OBJECTS
OBJECTS = account.o customer.o display.o main.o
passbook.o \
security.o staff.o
# This rule says that the target named "all" depends on
those
# files. Executing "make all" in this subdirectory will cause
# make to build the object files (.o) listed in the macro
$OBJECTS
# and create an executable named "Bank" by linking them
all: $(OBJECTS)
$(CC) -o Bank $(OBJECTS)
# rule that says how to make a .o object file from a .cpp
source file
# for a given source file in a given directory you could
compile it
# into an object file by executing "make filename.o"
# $< and $# are macros defined by make
# $< refers to the file being processed (i.e., compiled or
linked )
# $# refers to the generated file
%.o: %.cpp
$(CC) $(CCFLAGS) $(LOCFLAGS) -c $<
# target to clean up the object files, core files and
executables
# executing "make clean" in this subdirectory will remove
all
# files named core, "Bank" or any file ending in .o or
.stackdump
clean:
del $(OBJECTS) core *.stackdump Bank
On Windows you're running in a command.com shell, not a POSIX shell. In command.com, the syntax cd src; mingw32-make is not legal. For example if I open a command.com terminal on a Windows system I see:
C:\Users\build> cd src; echo hi
The system cannot find the path specified.
In Windows command.com the command separator is a single & not a semicolon.
If you want to change directories portably you can use the -C option to GNU make. Also you should always use the $(MAKE) variable, not write out the make command by hand:
all:
$(MAKE) -C $(DIR)

cmake: cannot find the shared library when coming to link stage

I'm trying to move my Makefile to cmake. The problem is that when it comes to linking stage, it cannot find the shared library.
My cmake is:
set(PROJECT_LINK_LIBS libsr_tps.so)
link_directories(absolute/path/to/the/library)
I also tried:
find_library(PROJECT_LINK_LIBS NAMES sr_tps PATHS "${PROJECT_SOURCE_DIR}/lib")
and then:
add_executable(project ${SOURCE})
target_link_libraries(project ${PROJECT_LINK_LIBS})
The sources can be cross-compiled successfully. But after compiling, it always says:
/absolute/path/to/ld: cannot find -lsr_tps
collect2: ld returned 1 exit status
given that libsr_tps.so has already been pre-cross-compiled.
Makefile works fine for both compiling and generating the final executable.
I have been looking for the potential issue for many hours. The solutions just don't work.
What could be wrong?
Thanks.
Update:
The way for build with make:
Set some environment parameters, i.e. some export.
Makefile:
LDFLAGS += -L./lib
CFLAGS += -Wall -Wno-pointer-sign
LDLIBS = -lsr_tps
all: $(TARGET)
$(TARGET): $(OBJS) $(OBJS_ROS)
$(CC) $(LDFLAGS) $(OBJS) $(OBJS_ROS) $(LDLIBS) -o $(TARGET)
cp $^ ./$(BINARY)/$(OBJ_DIR)
mv $# ./$(BINARY)
.c.o: $(CC) $(CFLAGS) -o $# -c $<
Update 2:
Here is my Makefile:
TARGET = ros
LDFLAGS += -L./lib
CFLAGS += -Wall -Wno-pointer-sign -DWSU_5001 -I./include -I./include/WSU-5001_include -I./include/J2735 -I./ -pthread -O
LDLIBS = -lsr_tps -lrisapi -lrt -lipc -lm -ldot2 -ldot3 -lcrypto -lgps -ltpsapi
SHARED_FLAGS = -fPIC -shared
BINARY= bin
SRC_DIR = ./src
J2735_DIR = ./src/J2735
#OBJ_DIR = ./binary/obj
OBJ_DIR = obj
OBJS_TEST=${ASN_MODULE_SOURCES:.c=.o} ${ASN_CONVERTER_SOURCES:.c=.o}
OBJS=${ASN_MODULE_SOURCES:.c=.o}
OBJS_ROS = ros.o tx.o rx.o util.o config.o
all: $(TARGET)
mkdir -p $(BINARY)
mkdir -p $(BINARY)/$(OBJ_DIR)
$(TARGET): $(OBJS) $(OBJS_ROS)
$(CC) $(LDFLAGS) $(OBJS) $(OBJS_ROS) $(LDLIBS) -o $(TARGET)
cp $^ ./$(BINARY)/$(OBJ_DIR)
mv $# ./$(BINARY)
# $(TARGET): $(OBJS)
# $(CC) $(OBJS) $(CFLAGS) -o $#
.SUFFIXES:
.SUFFIXES: .c .o
.c.o:
$(CC) $(CFLAGS) -o $# -c $<
Command line after executing make:
path/to/powerpc-e300c3-linux-gnu-gcc -L./lib <all .o files> -lsr_tps -lrisapi -lrt -lipc -lm -ldot2 -ldot3 -lcrypto -lgps -ltpsapi -o ros
And below is my CMakeList:
cmake_minimum_required(VERSION 3.5.1)
project(Denso-ROS)
set(CMAKE_SYSTEM_NAME Denso-linux)
set(CMAKE_SYSTEM_PROCESSOR "^(powerpc|ppc)")
set(GCC_COVERAGE_COMPILE_FLAGS "-static -Wall -Wno-pointer-sign -DWSU_5001 -pthread -O")
#################
#problem
#set(GCC_COVERAGE_LINK_FLAGS "libsr_tps.so -lrisapi -lrt -lipc -lm -ldot2 -ldot3 -lcrypto -lgps -ltpsapi")
#set(GCC_COVERAGE_LINK_FLAGS "-L./lib")
#set(CMAKE_LINK_LIBRARY_FLAG "-lsr_tps -lrisapi -lrt -lipc -lm -ldot2 -ldot3 -lcrypto -lgps -ltpsapi")
#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}" )
set(PROJECT_LINK_LIBS libsr_tps.so)
link_directories(home/yufeiyan/DENSO-WSU5K1-SDK_VM_Ubuntu_Peloton/Denso/lib)
#################
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}" )
set(tools ${PROJECT_SOURCE_DIR}/toolchain/bin)
set(CMAKE_C_COMPILER ${tools}/powerpc-e300c3-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER ${tools}/powerpc-e300c3-linux-gnu-g++)
find_library(DENSO_LIB NAMES sr_tps PATHS "${PROJECT_SOURCE_DIR}/lib")
message(STATUS "${DENSO_LIB}")
include_directories(
${PROJECT_SOURCE_DIR}
include
include/J2735
include/WSU-5001_include)
file(GLOB SOURCE ${PROJECT_SOURCE_DIR}/*.c src/*.c src/J2735/*.c)
list(REMOVE_ITEM SOURCE ${PROJECT_SOURCE_DIR}/src/J2735/converter-example.c)
list(REMOVE_ITEM SOURCE ${PROJECT_SOURCE_DIR}/src/J2735/test.c)
#add_executable(ros ${SOURCE1} ${SOURCE2} ${SOURCE3})
add_executable(ros ${SOURCE})
target_link_libraries(ros ${PROJECT_LINK_LIBS})
Command line after executing make:
path/to/powerpc-e300c3-linux-gnu-gcc -static -Wall -Wno-pointer-sign -DWSU_5001 -pthread -O <all .o files> -L/path/to/project/lib -lsr_tps -Wl,-rpath, path/to/project/lib path/tp/powerpc-e300c3-linux-gnu/bin/ld: cannot find -lsr_tps
Many thanks to Tsyvarev.
Let me sum up the issue and solution:
The linker can not find the library due to the incorrect path. I used link_directories(absolute/path/to/lib), and it returned a duplicate path. Instead, using link_directories(${PROJECT_SOURCE_DIR}/lib) solved the problem. The linker has the correct path and find the library.
In the meantime, I remove the -static option for CFLAGS. This option may also cause the linker not finding the library.

Why does make delete my temporary files?

I have a simple Makefile,
.PHONY: clean
PROGRAMS=$(patsubst main%.cpp,example%,$(wildcard main*.cpp))
all: ${PROGRAMS}
GCCVERSION=$(shell gcc -dumpversion)
GLCFLAGS=$(shell pkg-config --cflags gl)
CPPFLAGS=-Wall -O2 ${GLCFLAGS}
ifeq "${GCCVERSION}" "4.5.2"
CXXFLAGS=-std=c++0x
else
CXXFLAGS=-std=c++11
endif
GLLIBS=$(shell pkg-config --libs gl)
LIBS=${GLLIBS} -lglut
example%: main%.o shaders.o fileutils.o
${CXX} $^ ${LIBS} -o $#
clean:
rm -f *.o ${PROGRAMS}
But when I executed it, it delete the *.o files as last command. I don't know why:
$ make
g++ -std=c++11 -Wall -O2 -I/usr/include/libdrm -c -o main01.o main01.cpp
g++ -std=c++11 -Wall -O2 -I/usr/include/libdrm -c -o shaders.o shaders.cpp
g++ -std=c++11 -Wall -O2 -I/usr/include/libdrm -c -o fileutils.o fileutils.cpp
g++ main01.o shaders.o fileutils.o -lGL -lglut -o example01
rm main01.o fileutils.o shaders.o
Is there anything wrong with my Makefile?
Intermediate files are deleted by design: see Chained Rules in GNU make manual.
Use .SECONDARY or .PRECIOUS targets to keep your precioussss temp files.
Just to clarify the previous response, you need to add a special rule like
.PRECIOUS: myfile.o

How to use gcc to compile multiple files

I have several files needed to be compiled.
here is the command. the sample_client.c dependent on the lsp.o. Now I changed the lsp.c and lsp.h. How can I compile to get this change effective to lsp.o?
the main function is in the sample_client.c, lsp.c does not have a main function.
gcc -g -I/usr/include -g sample_client.c lsp.o lspmessage.pb-c.o -o sample_client -L/usr/lib -lprotobuf-c
Here is my makefile,
CC = gcc
TARGET = sample_client sample_server
CFLAGS += -g -I/usr/include
LDFLAGS += -g -lprotobuf-c -L/usr/lib
all: $(TARGET)
$(TARGET): lsp.o lspmessage.pb-c.o
%.o: %.c
$(CC) -c $(CFLAGS) $< -o $#
clean:
rm -f *.o
rm -f $(TARGET)
However, the lprotobuf-c can not be correctly linked.
run make -f Makefile
I can get the following,
lspmessage.pb-c.o: In function `lspmessage__get_packed_size':
...: undefined reference to `protobuf_c_message_get_packed_size'
lspmessage.pb-c.o: In function `lspmessage__pack':
...: undefined reference to `protobuf_c_message_pack'
I know that I can run this command,
gcc -g -I/usr/include -g sample_client.c lsp.o lspmessage.pb-c.o -o sample_client -L/usr/lib -lprotobuf-c
But what if I change the lsp.c and lsp.h ?
It looks to me like your LDFLAGS isn't correct. Try the following:
LDFLAGS += -L/usr/lib -lprotobuf-c
It looks like you had the directory -L and the library out of order.
Also, I removed the additional call to -g for you.

Resources