2013-02-25 5 views
4

У меня есть Makefile для C++ проекта Linux:Makefile - не могут найти общий библиотеку

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 

, когда я запускаю «сделать» он строит проект, без ошибок. , но когда я запускаю проект он жалуется, что:

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

Путь, который я даю в DIR идет к папке, в которой проводится общий объект (относительно где Makefile находится), и если это было неправильный путь, почему он не жаловался во время процесса.

Кто-то знает, чего я не хватает?

Благодаря Matt

ответ

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

выше должна быть:

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

То есть, для каждого нестандартного места -L динамической библиотеки должен быть указан соответствующий -Wl,-R. $ORIGIN необходим для нахождения динамических библиотек относительно исполняемого файла, но не уверен, нужен ли он здесь.

Люди часто советуют использовать LD_LIBRARY_PATH. Это плохой совет, на мой взгляд, потому что он усложняет развертывание.

2

При запуске приложения, расположение libsomeso.so должно быть в LD_LIBRARY_PATH переменной окружения. Попробуйте запустить программу, как это:

LD_LIBRARY_PATH="path_to_libsomeso_so:$LD_LIBRARY_PATH" myprogram 

Здесь path_to_libsomeso_so полный путь к директории где libsomeso.so находится, и myprogram ваша программа исполняемым. Обратите внимание, что вы должны указать путь к каталогу, содержащему libsomeso.so, а не к файлу libsomeso.so.

1

Проблема не во время компиляции. Все идет хорошо. Во время работы есть проблема.

Действительно, ваша программа связана с общей библиотекой объектов. Поэтому во время выполнения необходимо загрузить этот файл общих объектов. Во время компиляции вы инструктируете компилятор, где этот файл был с флагом -L.

Для среды выполнения вы должны установить переменную окружения LD_LIBRARY_PATH, чтобы указать на каталог, в котором находится ваш файл libsomeso.so.

В качестве альтернативы, вы можете поместить этот файл в одном из стандартного каталога, где эти общие объектные файлы искали: /usr/local/lib, /usr/lib, /lib, но это должно быть то, что вы будете делать для окончательной распространяемой версии вашей библиотеки.

0

Как сказал Максим Егорушкин, LD_LIBRARY_PATH - это плохой выбор. Между тем, использование аргумента gcc/g ++ -L$(your lib path) -l$(your lib name) для связи с общей библиотекой не является хорошим выбором. Потому что после сборки exe вы должны сообщить exe, где находится каталог разделяемой библиотеки. По умолчанию исполняемый файл выполняет поиск только общей библиотеки по адресу /usr/lib или /usr/local/lib.Хотя, вы сказали makefile, где общая библиотека при сборке исполняемого файла. Но когда вы выполняете этот exe-файл, они разные. Однако ссылка на статическую библиотеку не имеет такой проблемы.

Таким образом, лучший способ справиться с вашей проблемой - изменить способ связывания вашего пользовательского общего файла. Пример:

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) 
0

Обновить этот динамический библиотечный кеш!

После добавления пользовательской нестандартной библиотеки в /usr/local/lib, сначала проверьте, что /usr/local/lib указан ниже /etc/ld.so.conf.d/libc.conf.

Затем закончить с динамическим обновлением кэша подключаемой библиотеки:

$ sudo ldconfig 
Смежные вопросы