Зависимости от библиотеки 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. Тем не менее, я пытаюсь понять, почему это происходит только для boost-библиотек и не происходит с другими зависимостями, от которых зависит моя библиотека?

ИЗМЕНИТЬ

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

Ответ 1

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

Техническая причина заключается в том, что система Boost build (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, накладывают нагрузку на зависимое устройство, чтобы найти его зависимость: depender хранит список путей, которые он попытается заменить "@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. Динамический компоновщик будет выглядеть в этих каталогах для библиотек, поэтому он найдет там библиотеки ускорения. В терминале, на котором будет выполняться проверка сборки:

export DYLD_FALLBACK_LIBRARY_PATH=/full/path/to/;$DYLD_FALLBACK_LIBRARY_PATH