Линковка своих динамических библиотек к исполняемому файлу

Линковка своих динамических библиотек к исполняемому файлу

31.08.2016 01:59:44 Просмотров 38 Источник

Пишу Makefile для проекта, который использует стороннюю динамическую библиотеку. Библиотека лежит в определённой директории, не входящей в список дефолтных.

Компиляция проходит успешно. Проблемы, очевидно, с запуском - не может найти библиотеку.

Можно ли составить Makefile так, чтобы он выполнял функцию, аналогичную функции link_directories в CMake? То есть, чтобы в исполняемый файл был как бы "зашит" путь до библиотеки.

У вопроса есть решение - Посмотреть?

Ответы - Линковка своих динамических библиотек к исполняемому файлу / Линковка своих динамических библиотек к исполняемому файлу

aleksandr barakin

31.08.2016 02:43:59

к программе make (и, тем более, cmake) как таковой вопрос отношения, насколько я понимаю, не имеет.

ведь link_directories — это указание сборщику, который запускается на этапе компиляции.

вы же хотите дать указания загрузчику. но системный загрузчик во время загрузки (т.е., даже до выполнения программы) разыскивает библиотеки по именам, указанным в исполняемом файле, в тех каталогах, в которых он (загрузчик) сконфигурирован их искать. переконфигурировать системынй загрузчик можно с помощью прогрммы ldconfig (см. man ldconfig).

без переконфигурации же загрузчика вы можете дать такое указание с помощью переменной окружения, например, запуская не программу непосредственно, а скрипт на любом удобном вам языке программирования (например, на языке оболочки), в котором вызывать вашу программу, указав с помощью переменной окружения LD_LIBRARY_PATH путь (пути) к вашей библиотеке (библиотекам):

LD_LIBRARY_PATH=путь программа

чтобы в исполняемый файл был как бы "зашит" путь до библиотеки

динамически загрузить во время выполнения библиотеку (указав относительный или полный путь к ней) можно с помощью функции dlopen().

https://ru.stackoverflow.com/questions/561380/%d0%9b%d0%b8%d0%bd%d0%ba%d0%be%d0%b2%d0%ba%d0%b0-%d1%81%d0%b2%d0%be%d0%b8%d1%85-%d0%b4%d0%b8%d0%bd%d0%b0%d0%bc%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b8%d1%85-%d0%b1%d0%b8%d0%b1%d0%bb%d0%b8%d0%be%d1%82%d0%b5%d0%ba-%d0%ba-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d0%bd%d1%8f%d0%b5%d0%bc%d0%be%d0%bc%d1%83-%d1%84%d0%b0%d0%b9%d0%bb%d1%83/561398#comment730129_561398
Да, этот метод я знаю, спасибо. Но интересует именно возможность написания команды-аналога CMake-овского link_directories.
https://ru.stackoverflow.com/questions/561380/%d0%9b%d0%b8%d0%bd%d0%ba%d0%be%d0%b2%d0%ba%d0%b0-%d1%81%d0%b2%d0%be%d0%b8%d1%85-%d0%b4%d0%b8%d0%bd%d0%b0%d0%bc%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b8%d1%85-%d0%b1%d0%b8%d0%b1%d0%bb%d0%b8%d0%be%d1%82%d0%b5%d0%ba-%d0%ba-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d0%bd%d1%8f%d0%b5%d0%bc%d0%be%d0%bc%d1%83-%d1%84%d0%b0%d0%b9%d0%bb%d1%83/561398#comment730166_561398
Я подозревал, что так оно и есть. Но всё же CMake, которая генерирует Makefile, генерирует его так, что дальнейшая сборка программы утилитой Make приводит к созданию исполняемого файла, в котором уже "вшиты" пути к библиотекам. Разве не в Makefile-е это должно быть как-то прописано?
https://ru.stackoverflow.com/questions/561380/%d0%9b%d0%b8%d0%bd%d0%ba%d0%be%d0%b2%d0%ba%d0%b0-%d1%81%d0%b2%d0%be%d0%b8%d1%85-%d0%b4%d0%b8%d0%bd%d0%b0%d0%bc%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b8%d1%85-%d0%b1%d0%b8%d0%b1%d0%bb%d0%b8%d0%be%d1%82%d0%b5%d0%ba-%d0%ba-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d0%bd%d1%8f%d0%b5%d0%bc%d0%be%d0%bc%d1%83-%d1%84%d0%b0%d0%b9%d0%bb%d1%83/561398#comment730210_561398
Понял. Но всё же CMake как-то с этим справляется... Как-то эти пути всё-таки указываются именно в исполняемом файле. Спасибо за dlopen, но это тоже не то. Я не идеален в формулировании вопросов, но всё же надеюсь, что Вы понимаете, что я хочу получить.
https://ru.stackoverflow.com/questions/561380/%d0%9b%d0%b8%d0%bd%d0%ba%d0%be%d0%b2%d0%ba%d0%b0-%d1%81%d0%b2%d0%be%d0%b8%d1%85-%d0%b4%d0%b8%d0%bd%d0%b0%d0%bc%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b8%d1%85-%d0%b1%d0%b8%d0%b1%d0%bb%d0%b8%d0%be%d1%82%d0%b5%d0%ba-%d0%ba-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d0%bd%d1%8f%d0%b5%d0%bc%d0%be%d0%bc%d1%83-%d1%84%d0%b0%d0%b9%d0%bb%d1%83/561398#comment730244_561398
Да, спасибо, в этом Вы правы, это аналог флага -L компилятора. Но суть вопроса в другом, и Вы скорее всего это понимаете)
https://ru.stackoverflow.com/questions/561380/%d0%9b%d0%b8%d0%bd%d0%ba%d0%be%d0%b2%d0%ba%d0%b0-%d1%81%d0%b2%d0%be%d0%b8%d1%85-%d0%b4%d0%b8%d0%bd%d0%b0%d0%bc%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b8%d1%85-%d0%b1%d0%b8%d0%b1%d0%bb%d0%b8%d0%be%d1%82%d0%b5%d0%ba-%d0%ba-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d0%bd%d1%8f%d0%b5%d0%bc%d0%be%d0%bc%d1%83-%d1%84%d0%b0%d0%b9%d0%bb%d1%83/561398#comment730254_561398
перенёс содержимое своих комментариев в текст ответа. надеюсь, так «общая картина» станет вам «виднее».
https://ru.stackoverflow.com/questions/561380/%d0%9b%d0%b8%d0%bd%d0%ba%d0%be%d0%b2%d0%ba%d0%b0-%d1%81%d0%b2%d0%be%d0%b8%d1%85-%d0%b4%d0%b8%d0%bd%d0%b0%d0%bc%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b8%d1%85-%d0%b1%d0%b8%d0%b1%d0%bb%d0%b8%d0%be%d1%82%d0%b5%d0%ba-%d0%ba-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d0%bd%d1%8f%d0%b5%d0%bc%d0%be%d0%bc%d1%83-%d1%84%d0%b0%d0%b9%d0%bb%d1%83/561398#comment730279_561398
Окей. Спасибо за ответ!
https://ru.stackoverflow.com/questions/561380/%d0%9b%d0%b8%d0%bd%d0%ba%d0%be%d0%b2%d0%ba%d0%b0-%d1%81%d0%b2%d0%be%d0%b8%d1%85-%d0%b4%d0%b8%d0%bd%d0%b0%d0%bc%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b8%d1%85-%d0%b1%d0%b8%d0%b1%d0%bb%d0%b8%d0%be%d1%82%d0%b5%d0%ba-%d0%ba-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d0%bd%d1%8f%d0%b5%d0%bc%d0%be%d0%bc%d1%83-%d1%84%d0%b0%d0%b9%d0%bb%d1%83/561398#comment730362_561398
@AccumPlus, гуглите RPATH, cmake именно им и пользуется. Но это уродское решение, мягко говоря.
Является ответом!
sercxjo

31.08.2016 10:41:46

Согласно man ld нужно сообщить линкеру параметр -rpath=тот_самый_путь к библиотекам, который нужно зашить в бинарник. Сделать это можно двумя способами. Через опцию gcc -Xlinker -rpath=тот_самый_путь. Если вы используете правила сборки make по-умолчанию, для этих опций подходит переменная LDFLAGS в Makefile:

LDFLAGS+= -Xlinker -rpath=тот_самый_путь

Второй способ -- минуя gcc через переменную окружения LD_RUN_PATH которую ld читает сам в случае, если опции -rpath не было. В Makefile для этого можно написать:

export LD_RUN_PATH=тот_самый_путь

Или написать LD_RUN_PATH=тот_самый_путь перед $(CC) непосредственно в правиле для линковки.

В пути может присутствовать подстрока $ORIGIN, вместо которой будет подставлен путь к каталогу, содержащему исполняемый файл. См. man ld-linux.so. Пример строки в Makefile:

myprogram: LDFLAGS+= -Xlinker -rpath='$$ORIGIN/'
myprogram: myprogram.o
https://ru.stackoverflow.com/questions/561380/%d0%9b%d0%b8%d0%bd%d0%ba%d0%be%d0%b2%d0%ba%d0%b0-%d1%81%d0%b2%d0%be%d0%b8%d1%85-%d0%b4%d0%b8%d0%bd%d0%b0%d0%bc%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b8%d1%85-%d0%b1%d0%b8%d0%b1%d0%bb%d0%b8%d0%be%d1%82%d0%b5%d0%ba-%d0%ba-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d0%bd%d1%8f%d0%b5%d0%bc%d0%be%d0%bc%d1%83-%d1%84%d0%b0%d0%b9%d0%bb%d1%83/561568#comment730654_561568
Благодарю! Буду пробовать!
https://ru.stackoverflow.com/questions/561380/%d0%9b%d0%b8%d0%bd%d0%ba%d0%be%d0%b2%d0%ba%d0%b0-%d1%81%d0%b2%d0%be%d0%b8%d1%85-%d0%b4%d0%b8%d0%bd%d0%b0%d0%bc%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b8%d1%85-%d0%b1%d0%b8%d0%b1%d0%bb%d0%b8%d0%be%d1%82%d0%b5%d0%ba-%d0%ba-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d0%bd%d1%8f%d0%b5%d0%bc%d0%be%d0%bc%d1%83-%d1%84%d0%b0%d0%b9%d0%bb%d1%83/561568#comment731456_561568
Всё отлично работает! Спасибо!
Закрыть X