Как правильно установить пути запуска, пути поиска и установить имена?
У меня есть набор проектов, которые я компилирую как динамические библиотеки. Каждый из этих .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)