Динамическая библиотека не может загружаться при запуске программы вне директории сборки - PullRequest
0 голосов
/ 05 января 2019

У меня есть следующий Makefile:

OBJ=main.o other.o other1.o other2.o
LINKDIVSUF=-L libdivsufsort-master/build/lib/ -ldivsufsort64 -Wl,-R libdivsufsort-master/build/lib/  
INCDIVSUF=-I libdivsufsort-master/build/include -ldivsufsort64                                       
EXE=program                                                                                             
COMPFLAGS=-MMD -fopenmp -std=c++17 -O3                                                   
CXX=g++                                                                                              

$(EXE):$(OBJ)                                                                                        
  $(CXX) $(COMPFLAGS) $(OBJ) -o $(EXE) $(LINKDIVSUF) -lz -lboost_regex -lboost_program_options       

%.o: %.cpp                                                                                           
  $(CXX) $(COMPFLAGS) $(INCDIVSUF) -c $<                                                             
-include $(OBJ:.o=.d)                                                                                      

program ссылается на динамическую библиотеку libdivsufsort64.so.3, расположенную в каталоге сборки в ./libdivsufsort-master/build/lib/. Использование -Wl,-R libdivsufsort-master/build/lib/ позволяет избежать объединения от absolute/path/to/libdivsufsort-master/build/lib/ до LD_LIBRARY_PATH для запуска program. Действительно, когда я make program без -Wl, -R libdivsufsort-master/build/lib/ и без установки LD_LIBRARY_PATH, как указано, и последующего запуска program, я получаю следующее сообщение об ошибке:

./program: error while loading shared libraries: libdivsufsort64.so.3: cannot open shared object file: No such file or directory 

С -Wl, -R libdivsufsort-master/build/lib/, program работает успешно, без изменения LD_LIBRARY_PATH, но только когда Я запускаю program из того же каталога, в котором он был построен . Если я пытаюсь запустить program при компиляции с -Wl, -R libdivsufsort-master/build/lib/ из любого другого каталога, он не запускается, завершается с вышеупомянутое сообщение об ошибке.

Как изменить параметры компиляции g++ (или что-либо еще во время компиляции), чтобы program мог запускаться из любой каталог, избегая необходимости изменять LD_LIBRARY_PATH? Единственное найденное мной «решение» - объединить libdivsufsort-master/build/lib/ в LD_LIBRARY_PATH. Таким образом, я могу запустить program с любого каталог, таким образом устраняя необходимость компиляции с Wl,-R libdivsufsort-master/build/lib/, однако, это, конечно, требует от пользователя program установки своих LD_LIBRARY_PATH вручную, чего я специально хочу избегать.

Решение Читая этот пост , в котором обсуждается использование относительных или абсолютных путей с -R (-rpath) , я придумал это решение.

Добавьте следующие строки, чтобы Makefile был теперь:

libdivsufsort_lib = $(addprefix $(shell pwd), /libdivsufsort-master/build/lib/)        
libdivsufsort_include = $(addprefix $(shell pwd), /libdivsufsort-master/build/include/)
OBJ=main.o other.o other1.o other2.o
LINKDIVSUF=-L libdivsufsort-master/build/lib/ -ldivsufsort64 -Wl,-R libdivsufsort-master/build/lib/  
INCDIVSUF=-I libdivsufsort-master/build/include -ldivsufsort64                                       
EXE=program                                                                                             
COMPFLAGS=-MMD -fopenmp -std=c++17 -O3                                                   
CXX=g++                                                                                              

$(EXE):$(OBJ)                                                                                        
  $(CXX) $(COMPFLAGS) $(OBJ) -o $(EXE) $(LINKDIVSUF) -lz -lboost_regex -lboost_program_options       

%.o: %.cpp                                                                                           
  $(CXX) $(COMPFLAGS) $(INCDIVSUF) -c $<                                                             
-include $(OBJ:.o=.d)    

Это позволяет избежать использования $ORIGIN, чтобы получить абсолютный путь к program с. каталог, который не поддерживается в некоторых системах. Два дополнительных линии производят абсолютный путь независимо от местоположения двоичного файла - это просто нужно сохранить в каталоге сборки и скомпилировать снова, если сборка Каталог перемещается. Важно отметить, что program теперь можно вызывать извне построить каталог.

1 Ответ

0 голосов
/ 05 января 2019

Вам нужно использовать $ORIGIN с -Wl,-R, чтобы найти библиотеку в относительном пути:

LINKDIVSUF = ... -Wl,-R,'$ORIGIN/libdivsufsort-master/build/lib'
...