Подтвердить что ты не робот

Как использовать dylib в Mac OS X (С++)

Я сделал приложение (исполняемый файл), вызвав некоторый dylib успешно, однако файлы dylib и исполняемый файл находятся в другом каталоге. Я добавил, что каталог содержит файлы dylib для переменной среды $PATH, однако она по-прежнему не загружается. Я копирую все файлы dylib в исполняемый файл, программа, наконец, запускается. Это подтверждает, что файлы dylib не имеют проблем. Однако, как я могу сказать OS, чтобы найти его? В Windows мне просто нужно добавить путь к каталогу, содержащий файлы dll, в $PATH. Что мне нужно сделать для Mac OS X? Большое спасибо!

4b9b3361

Ответ 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)
    ...

Ответ 2

Вам нужно установить переменную среды DYLD_LIBRARY_PATH.

На странице dyld man:

      This  is  a  colon  separated  list  of directories that contain libraries. The dynamic linker
      searches these directories before it searches the default locations for libraries.  It  allows
      you to test new versions of existing libraries.

      For  each  library  that  a program uses, the dynamic linker looks for it in each directory in
      DYLD_LIBRARY_PATH in turn. If it still can't find the library,  it  then  searches  DYLD_FALL-
      BACK_FRAMEWORK_PATH and DYLD_FALLBACK_LIBRARY_PATH in turn.

Ответ 4

Если dylib находится в месте, указанном INSTALL_NAME библиотеки, он будет просто работать *.

В противном случае вы можете добавить местоположение dylib в DYLD_LIBRARY_PATH. Возможно, вы захотите прочитать документацию dyld.

*), чтобы быть полностью точным, это должно быть в DYLD_ROOT_PATH/INSTALL_NAME, но суета с DYLD_ROOT_PATH довольно редка.