简体   繁体   中英

Makefile - cannot find shared library

I have a Makefile for a c++ Linux project:

MODE ?= dbg
DIR = ../../../../../somdir/$(MODE)

SRC_FILES = a.cpp b.cpp
H_FILES = a.h

LDFLAGS += -L$(DIR)/lib/linux '-Wl,-R$$ORIGIN'
CPPFLAGS = -I$(DIR)/include
LIBRARIES = -lsomeso

ifeq (rel, $(MODE))
  CFLAGS = -Wall -g -DNDEBUG
else
  CFLAGS = -Wall -ansi -pedantic -Wconversion -g -DDEBUG -D_DEBUG
endif

sample: $(SRC_FILES) $(H_FILES) Makefile
    g++ $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(LIBRARIES) $(SRC_FILES) -o sample

when i run 'make' it builds the project, with no errors. but when i run the project it complains that:

error while loading shared libraries: libsomeso.so: cannot open shared object file: No such file or directory

The path that i give in DIR goes to the folder where the shared object is held(relatively to where the makefile is placed), and if it was the wrong path why didn't it complain during the make process.

does someone know what am i missing?

Thanks Matt

LDFLAGS += -L$(DIR)/lib/linux '-Wl,-R$$ORIGIN'

The above should be:

LDFLAGS += -L$(DIR)/lib/linux -Wl,-R$(DIR)/lib/linux '-Wl,-R$$ORIGIN'

That is, for each non-standard dynamic library location -L a corresponding -Wl,-R should be specified. $ORIGIN is needed to locate dynamic libraries relative to the executable, not sure if you need it here.

People often advise using LD_LIBRARY_PATH . This is a bad advice, in my opinion, because it makes deployment more complicated.

When you run your application, location of libsomeso.so should be in LD_LIBRARY_PATH environment variable. Try running program like this:

LD_LIBRARY_PATH="path_to_libsomeso_so:$LD_LIBRARY_PATH" myprogram

Here path_to_libsomeso_so is full path to a directory where libsomeso.so is located, and myprogram is your program executable. Note, that you should specify path to a directory containing libsomeso.so , not to libsomeso.so file itself.

The trouble is not during compilation time. Everything goes fine. There's a problem at runtime.

Indeed, your program has been linked with a shared object library. Therefore, at runtime, it need to load this shared object file. During compilation, you instructs the compiler where this file was with the -L flag.

For the runtime, you have to set the LD_LIBRARY_PATH environment variable to point to the directory where your libsomeso.so file resides.

Alternatively, you can place this file in one of the standard directory where these shared object files are searched for: /usr/local/lib , /usr/lib , /lib , but this should be what you'll do for the final distributed version of your library.

As told from Maxim Egorushkin, LD_LIBRARY_PATH is a bad choice. Meanwhile, using -L$(your lib path) -l$(your lib name) gcc/g++ argument to link shared library isn't a good choice. Because, after build the exe, you should told exe where the shared library directory is. By default, executable file only search shared library at /usr/lib or /usr/local/lib . Although, you have told makefile where the shared library is when build the executable file. But when you execute this exe file, they are different. However, link static library don't have such problem.

So, the best way to deal with your problem is change the way you link your custom shared file. Like this:

DYNAMIC_LIB_DIR = ../lib (your lib path ,this is a example)

OBJLIBS = xxx.so (your lib name)

gcc/g++ -o exe_name sourcefile/object_file $(DYNAMIC_LIB_DIR)/$(OBJLIBS)

Refresh that dynamic library cache!

After adding a custom, non-standard library to /usr/local/lib , first check that /usr/local/lib is listed under /etc/ld.so.conf.d/libc.conf .

Then, finish off with a dynamic link library cache refresh:

$ sudo ldconfig

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM