Как правильно установить пути запуска, пути поиска и установить имена?

У меня есть набор проектов, которые я компилирую как динамические библиотеки. Каждый из этих .dylibs зависит от других различных .dylib, которые я хотел бы разместить в разных других каталогах (например, некоторые на исполняемом пути, некоторые на пути загрузчика, некоторые на фиксированном пути).

Когда я запускаю otool -L в скомпилированных библиотеках, я получаю список путей к этим зависимостям, но я знаю, как эти пути устанавливаются/определяются. Они почти кажутся псевдослучайными. Я потратил несколько часов на использование "Настройки сборки" в Xcode, чтобы попытаться изменить эти пути (w/@rpath, @executable_path, @loader_path и т.д.), Но я не могу ничего изменить (как проверено при запуске otool -L). Я даже не совсем уверен, где добавить эти флаги и не понимаю разницу между следующим или как правильно их использовать:

Связывание - "Имя установки динамической библиотеки"
Связывание - "Пути поиска пути"
Связывание - "Другие связанные флагов"
Пути поиска - "Пути поиска библиотеки"

Когда я запускаю install_name_tool -change в различных библиотеках, я могу успешно изменить пути поиска пути выполнения (опять же, как это подтверждается при запуске otool -L для подтверждения).

Я запускаю Xcode 4.2, и я очень близок к тому, чтобы отказаться от него и просто использовать post-build script, который запускает имя_страницы_приложения, чтобы внести изменения. Но это исправление халата, и я бы предпочел не делать этого.

Где я могу узнать, как устанавливаются пути поиска/запуска для зависимостей dylib?
У кого-нибудь есть идеи о том, что я могу делать неправильно?

Ответ 1

Как правило, в моей цели dylib я устанавливаю INSTALL_PATH aka "Каталог установки" на префикс, который я хочу (например, @executable_path/../Frameworks).

Я оставляю LD_DYLIB_INSTALL_NAME aka "Dynamic Library Install Name" установленное по умолчанию значение, которое равно $(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH).

Xcode расширяет это на основе вашего целевого имени, поэтому может оказаться, например, @executable_path/../Frameworks/MyFramework.framework/Versions/A/MyFramework.

Важно понять, что путь установки встроен в dylib, как часть процесса сборки. Позже, когда вы связываете B.dylib, который ссылается на A.dylib, путь установки A.dylib копируется в B.dylib. (То, что показывает otool - эти скопированные пути установки.) Поэтому лучше всего получить правильный путь установки, встроенный в dylib, в первую очередь.

Прежде чем пытаться объединить все dylib, проверьте каждый из них отдельно. Постройте его, затем otool -L на встроенном dylib. Первая строка для каждой архитектуры должна быть тем, что показывал вам LD_DYLIB_INSTALL_NAME.

После того, как вы организовали это мероприятие, попробуйте подключить dylibs друг к другу. Это должно быть гораздо более простым.

Ответ 2

install_name_tool очень полезен для установки имен и путей. Его особенно полезно, если программа запускает свои самотестирования в каталоге сборки, а затем вещи меняются во время make install. В этом случае вы можете использовать install_name_tool без необходимости отдельной сборки.

install_name_tool также полезен, потому что Apple LD не чтит rpath параметры компоновщика, такие как Linux/GCC. То есть вам нужно использовать другой набор команд для их установки.

Вот справочная страница для него. Он включен полностью, потому что он обсуждает другие варианты, такие как -headerpad_max_install_names.

INSTALL_NAME_TOOL(1)                                      INSTALL_NAME_TOOL(1)

NAME
       install_name_tool - change dynamic shared library install names

SYNOPSIS
       install_name_tool  [-change  old  new  ]  ...  [-rpath  old  new  ] ...
       [-add_rpath new ] ... [-delete_rpath new ] ... [-id name] file

DESCRIPTION
       Install_name_tool changes the dynamic shared library install names  and
       or  adds,  changes  or  deletes the rpaths recorded in a Mach-O binary.
       For this tool to work when the install names or rpaths are  larger  the
       binary  should  be  built  with  the ld(1) -headerpad_max_install_names
       option.

       -change old new
              Changes the dependent shared library install name old to new  in
              the specified Mach-O binary.  More than one of these options can
              be specified.  If the Mach-O binary does  not  contain  the  old
              install  name  in  a  specified  -change  option  the  option is
              ignored.

       -id name
              Changes the shared library  identification  name  of  a  dynamic
              shared  library  to name.  If the Mach-O binary is not a dynamic
              shared library and the -id option is specified it is ignored.

       -rpath old new
              Changes the rpath path name old to new in the  specified  Mach-O
              binary.   More  than  one of these options can be specified.  If
              the Mach-O binary does not contain the old rpath path name in  a
              specified -rpath it is an error.

       -add_rpath new
              Adds  the  rpath  path  name new in the specified Mach-O binary.
              More than one of these options can be specified.  If the  Mach-O
              binary  already  contains  the  new rpath path name specified in
              -add_rpath it is an error.

       -delete_rpath old
              deletes the rpath path name old in the specified Mach-O  binary.
              More  than one of these options can be specified.  If the Mach-O
              binary does not contains the old rpath path  name  specified  in
              -delete_rpath it is an error.

SEE ALSO
       ld(1)