У меня есть следующий 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
теперь можно вызывать извне
построить каталог.