Почему LD_LIBRARY_PATH BAD и правильный способ загрузки динамических библиотек

Итак, у меня есть программа, которая работает с OpenBlas, и я хочу ее скомпилировать. Процесс компоновки выглядит следующим образом:

gcc -o prog prog.o -O3 -I/opt/OpenBLAS/include -L/opt/OpenBLAS/lib -lopenblas

Пока все хорошо. Если я удалю параметр -L, я получаю сообщение об ошибке в процессе компоновки

/usr/bin/ld: cannot find -lopenblas

С -L все ссылки без ошибок. Однако, когда я пытаюсь запустить его, я получаю следующую ошибку:

./prog: error while loading shared libraries: libopenblas.so.0: cannot open shared object file: No such file or directory

Если я установил переменную env LD_LIBRARY_PATH в /opt/OpenBlas/lib, я могу запустить программу, но многие источники, такие как http://xahlee.info/UnixResource_dir/_/ldpath.html, рассматривают это быть плохой практикой, и я могу понять почти все рассуждения. Другой метод, упомянутый в статье (изменение конфигурации ld), также считается довольно плохой практикой. Наконец, вы можете просто добавить символическую ссылку в библиотеку в /usr/lib. Большая проблема с двумя последними методами заключается в том, что вам нужен доступ sudo.

Итак, мой вопрос заключается в том, как я могу скомпилировать и запустить программу, связанную с общей библиотекой, которая не находится в пути по умолчанию (/usr/lib) без использования LD_LIBRARY_PATH и доступа sudo. В статье говорится, что вы можете просто "писать" в двоичном формате, где искать общие библиотеки, но я не знаю, как это сделать (флаг -L, похоже, не делает этого). Я был бы признателен, если бы кто-нибудь мог объяснить этот вопрос, так как я искал везде, и я очень смущен (некоторые ссылки, похоже, предполагают, что флаг "-L" должен это сделать, но я не работаю для меня). Заранее благодарю вас.

Ответ 1

Добавьте путь к пути поиска библиотеки времени выполнения.

gcc -Wl,-rpath=/opt/OpenBlas/lib ...

Что делает параметр -L во время соединения, параметр -rpath выполняется во время выполнения.

Ответ 2

В linux также можно использовать $ORIGIN в rpath для обозначения пути к каталогу для приложения и создания относительного пути rpath. Затем вы переместите библиотеку на известный относительный путь к двоичному.

gcc -o prog prog.o -O3 -I/opt/OpenBLAS/include -Wl,-rpath=\$ORIGIN/lib -L/opt/OpenBLAS/lib -lopenblas

Вы также можете использовать полный путь к libary, и он будет связан в:

gcc -o prog prog.o -O3 -I/opt/OpenBLAS/include /opt/OpenBLAS/lib/libopenblas.so

Если вы запустили "ldd" в исполняемом файле, вы должны увидеть полный путь, закодированный.