Зависимости от библиотеки boost не имеют полного пути

Моя динамическая библиотека успешно построена с зависимостями от библиотек повышения, которые были созданы и установлены с пользовательским префиксом (./b2 install --prefix=PREFIX). Однако, когда я запускаю otool -L в своей библиотеке, я получаю следующий вывод:

...
libboost_regex.dylib (compatibility version 0.0.0, current version 0.0.0)
libboost_system.dylib (compatibility version 0.0.0, current version 0.0.0)
...

Что, в отличие от других зависимостей, представлено без полного пути к этим библиотекам повышения. Это приводит к ошибкам времени выполнения, когда моя библиотека загружается приложениями. Я знаю, что можно использовать install_name_tool, чтобы решить эту проблему вручную. Однако я пытаюсь понять, почему это происходит только для библиотек повышения и не происходит с другими зависимостями, от которых зависит моя библиотека?

ИЗМЕНИТЬ

Меня попросили привести пример команды сборки, но, как обычно, пример из «реальной жизни» немного сложнее. В моем случае есть библиотека libA.dylib которая зависит от буста. Затем есть моя библиотека libMy.dylib, которая также зависит от libA.dylib и буста. Проблема возникает на шаге configure, когда выполняется простая проверка существования библиотеки (специальная тестовая программа, аналогичная AC_CHECK_LIB). Эта проверка пытается создать небольшую тестовую программу, которая связана с libA.dylib, чтобы доказать доступность libA.dylib, и она терпит неудачу из-за ошибки, связанной с невозможностью найти библиотеки повышения. Конечно, он их не найдет, потому что otool -L libA.dylib дает мне буст-библиотеки без полного пути.


person peetonn    schedule 12.11.2015    source источник
comment
Не могли бы вы опубликовать команду сборки? Вы указали -L, чтобы сохранить путь к библиотеке boost в вашей dll, иначе он может просто посмотреть ваш путь LD.   -  person VladimirS    schedule 18.11.2015
comment
@ user3545806 пожалуйста, смотрите обновление выше   -  person peetonn    schedule 25.11.2015


Ответы (1)


Чтобы ответить на вопрос:
почему это происходит только для библиотек повышения и не происходит с другими зависимостями, от которых зависит моя библиотека?

Техническая причина заключается в том, что система сборки Boost (bjam) явно присваивает имя установки библиотеки только имя файла. Это могло быть сделано внутри с помощью параметра компилятора -install_name.
Что касается обоснования этого, я не могу говорить за разработчиков Boost, поэтому я мог только строить догадки (что является плохой формой инвестиции): жесткое кодирование локального пути установки в библиотеке только откладывает ошибку времени выполнения библиотеки до времени распространения, поэтому они могут просто захотеть, чтобы вы правильно устранили ее, как только время разработки. (Или это могло быть просто устаревшее поведение, которое они не хотели тратить на переработку;)

Возможные решения

Давайте представим, что ваша динамическая библиотека (которая зависит от Boost) называется myLib. Как вы уже указали в своем вопросе, вы вполне можете изменить имя установки для библиотек Boost, записанное в myLib:

 install_name_tool myLib -change libboost_regex.dylib /full/path/to/libboost_regex.dylib

Альтернативой является изменение имени установки самих библиотек Boost:

install_name_tool libboost_regex.dylib -id $new_name

При таком подходе имя установки $new_name теперь будет записано в myLib при сборке с модифицированным libboost_regex.dylib.

Вы знаете, что должны решить, какое значение присвоить $new_name. Конечно, это может быть полный путь к библиотеке, и таким образом библиотеки Boost будут вести себя как другие ваши зависимости.

Альтернативой, которую легче распространять, является использование RPath. (Имена установки на основе RPath возлагают на зависимого бремя поиска своей зависимости: зависимый хранит список путей, которыми он попытается заменить @rpath):

install_name_tool libboost_regex.dylib -id @rpath/libboost_regex.dylib #assign a rpath dependant install name to a boost library
 install_name_tool myLib -add_rpath $a_rpath_prefix # adds a candidate to substitute @rpath with, stored in myLib

$a_rpath_prefix может быть путем к папке, содержащей ваши библиотеки Boost, которые будут хорошо работать в вашей среде разработки. И если однажды вам понадобится распространить свою библиотеку, вы можете встроить зависимости Boost в относительный путь (или в пакет OS X) и добавить значение RPath, которое будет следовать этому относительному пути.

Изменить вопрос

Для конкретного описанного вами случая автоматической проверки, которая не может найти Boost, вы, вероятно, можете решить ее с помощью альтернативного решения, предложенного выше. Он изменяет имя установки библиотеки Boost, которая хранится в самой библиотеке (и, таким образом, будет скопирована в libA.dylib):

install_name_tool libboost_regex.dylib -id /full/path/to/libboost_regex.dylib

В этом конкретном случае использования еще более простым решением может быть заполнение DYLD_FALLBACK_LIBRARY_PATH путем к каталогу, содержащему вашу библиотеку Boost. Динамический компоновщик будет искать библиотеки в этих каталогах, поэтому он найдет там библиотеки boost. В терминале, в котором будет запускаться проверка сборки:

export DYLD_FALLBACK_LIBRARY_PATH=/full/path/to/;$DYLD_FALLBACK_LIBRARY_PATH
person Ad N    schedule 24.11.2015
comment
Спасибо за понимание. Я запускаю install_name_tool для исполняемых и всех зависимых библиотек, когда хочу их распространять. Эта проблема касается этапа разработки (см. обновление моего вопроса выше) и затрагивает новых разработчиков, которые хотят настроить среду разработки и пытаются создать мой проект. - person peetonn; 25.11.2015
comment
@peetonn Спасибо за ваш комментарий. Я думаю, вы можете исправить любую среду разработки, используя одно из решений в части редактирования. Кроме того, если это не отвечает на ваше беспокойство, я мог неправильно понять ваш вопрос (в этом случае, не могли бы вы попытаться перефразировать его?) - person Ad N; 25.11.2015
comment
Что ж, я полагаю, что реальная проблема здесь заключается в том, как предоставить наиболее простую в развертывании среду разработки для сторонних разработчиков, которые хотят создать мою библиотеку/приложение. Первоначально я пытался решить корень проблемы (т. е. библиотеки boost не имеют путей установки), но теперь кажется, что мне придется предоставить дополнительный шаг перед сборкой libA.dylib, после сборки boost - что-то вроде шага подготовки библиотек boost, где пользователям придется использовать ручной подход, который вы описали сами. Я все еще не уверен, что это лучшее решение, однако я отмечу ваш ответ как возможное решение. Спасибо! - person peetonn; 26.11.2015
comment
Большое спасибо. Это лучшее объяснение этой проблемы, которое я видел до сих пор. Я бы хотел, чтобы разработчики Boost это прочитали. - person Slava; 02.02.2016