Ответ 1
После прочтения ссылки, предоставленной Джастином, я успешно смог использовать токен @executable_path
, чтобы изменить мое имя dylib install_name, чтобы указать на тот же каталог, где находится мой исполняемый файл.
@executable_path Абсолютные пути раздражают. Иногда вы хотите внедрить фреймворк в приложение вместо того, чтобы устанавливать рамки в /Library или аналогичное местоположение.
Решение Mac для этого - @executable_path. Это волшебный токен что при размещении в начале имени установки библиотеки получает расширяется до пути исполняемого файла, который загружает его, минус последний компонент. Например, скажем, что ссылки Bar.app против Foo.framework. Если в/Приложения установлен Bar.app, @executable_path будет расширяться до /Applications/Bar.app/Contents/MacOS. Если вы намерены внедрить фреймворк в Content/Frameworks, то вы может просто установить имя установки Foo.framework @executable_path/../Каркасы/Foo.framework/Версии/А/Foo. динамический компоновщик будет расширяться, что /Applications/Bar.app/Contents/MacOS/../Frameworks/Foo.framework/Versions/A/Foo и найдет там рамки.
http://www.mikeash.com/pyblog/friday-qa-2009-11-06-linking-and-install-names.html
Я продемонстрирую пример.
Скажем, у меня есть следующий исполняемый файл /opt/local/bin/convert, а его dylib находятся в /opt/local/lib. Я хочу скопировать его в другой каталог и загрузить его dylib из того же каталога, где я скопировал исполняемый файл.
> mkdir ~/tmp/bin
> cp /opt/local/bin/convert ~/tmp/bin
Получить список исполняемых файлов dylibs
> otool -L ~/tmp/bin/convert
~/tmp/bin/convert:
/opt/local/lib/libtiff.3.dylib (compatibility version 13.0.0, current version 13.5.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
/opt/local/lib/libjpeg.8.dylib (compatibility version 12.0.0, current version 12.0.0)
/opt/local/lib/libfontconfig.1.dylib (compatibility version 6.0.0, current version 6.4.0)
/opt/local/lib/libiconv.2.dylib (compatibility version 8.0.0, current version 8.1.0)
/opt/local/lib/libfreetype.6.dylib (compatibility version 15.0.0, current version 15.0.0)
/opt/local/lib/libexpat.1.dylib (compatibility version 7.0.0, current version 7.2.0)
/opt/local/lib/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.6)
/opt/local/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.6)
...
Я только забочусь о dylib в каталоге /opt/local/lib, поэтому мы вытаскиваем только dylib в /opt. Я хочу, чтобы все другие ссылки dylib не были сохранены, особенно в /usr/lib/libSystem.
> DYLIBS=`otool -L ~/tmp/bin/convert | grep "/opt" | awk -F' ' '{ print $1 }'`
Скопируйте все dylib, которые исполняемый файл ссылается на тот же каталог, где был скопирован исполняемый файл.
> for dylib in $DYLIBS; do cp $dylib ~/tmp/bin/; done;
Используйте install_name_tool
, чтобы изменить имя установки всех выводов, которые мы вытащили на предыдущем шаге, и замените их, добавив @executable_path
к имени dylib. Это заставит динамический компоновщик искать dylib в том же каталоге, где находится исполняемый файл.
> for dylib in $DYLIBS; do install_name_tool -change $dylib @executable_path/`basename $dylib` ~/tmp/bin/convert; done;
Подтвердите, что имена установки были изменены и что libSystem все еще указывает на /usr/lib/libSystem.
> otool -L ~/tmp/bin/convert
~/tmp/bin/convert:
@executable_path/libtiff.3.dylib (compatibility version 13.0.0, current version 13.5.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
@executable_path/libjpeg.8.dylib (compatibility version 12.0.0, current version 12.0.0)
@executable_path/libfontconfig.1.dylib (compatibility version 6.0.0, current version 6.4.0)
@executable_path/libiconv.2.dylib (compatibility version 8.0.0, current version 8.1.0)
@executable_path/libfreetype.6.dylib (compatibility version 15.0.0, current version 15.0.0)
@executable_path/libexpat.1.dylib (compatibility version 7.0.0, current version 7.2.0)
@executable_path/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.6)
@executable_path/libz.1.dylib (compatibility version 1.0.0, current version 1.2.6)
...