9

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"
coolharsh55
  • 1,179
  • 4
  • 12
  • 27
  • 1
    Your command runs a shell which defines the variable, exports it (i.e. makes its visible to its own children), then exits. It cannot control subsequent shells or the internal state of Make. You want to define this as a Makefile variable instead; in GNU Make, you can `export` variables just like in the shell. But @Pradheep's answer already describes how this is usually done instead. – tripleee Dec 13 '14 at 08:40
  • Possible duplicate of [Setting path to shared library inside a makefile for compile](http://stackoverflow.com/questions/32200799/setting-path-to-shared-library-inside-a-makefile-for-compile) – Alex Jun 22 '16 at 13:48

2 Answers2

6

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.

Pradheep
  • 3,553
  • 1
  • 27
  • 35
6

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.

Alex
  • 1,602
  • 20
  • 33