Как создать ссылку на абсолютный путь в dylib?

[Отказ от ответственности: я работаю с чужим кодом. Я никогда не создавал .dylib, поэтому обращаюсь к S.O.]

Я работаю над дистрибутивом, который создает .dylib. Выглядит нормально, но когда я связываюсь с ним, результирующий исполняемый файл вылетает с ошибкой:

dyld: Library not loaded: libstk.dylib.4.4.4
  Referenced from: /Users/r/Projects/Mu/examples/./mune31
  Reason: image not found 
Trace/BPT trap: 5

Когда я изучаю исполняемый файл с помощью otool, проблема ясна: libstk (предпоследняя запись) имеет относительный, а не абсолютный путь. (Кроме того, у него нет правильной установки совместимости или текущих версий.)

Mu[~/Projects/Mu/examples]$ otool -L ./mune31
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
        /System/Library/Frameworks/CoreAudio.framework/Versions/A/CoreAudio (compatibility version 1.0.0, current version 1.0.0)
        /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 855.16.0)
        /System/Library/Frameworks/CoreMIDI.framework/Versions/A/CoreMIDI (compatibility version 1.0.0, current version 73.0.0)
        /Users/r/Projects/Mu/usr/lib/libgsl.0.dylib (compatibility version 18.0.0, current version 18.0.0)
        libstk.dylib.4.4.4 (compatibility version 0.0.0, current version 0.0.0)
        /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)

вопрос

Этот дистрибутив использует для своего компилятора g++ (а не clang). Текущее заклинание, создающее .dylib:

g++  -fPIC -dynamiclib -o libstk.dylib.4.4.4 Release/*.o -lpthread -framework CoreAudio -framework CoreFoundation -framework CoreMidi
install -m 644 libstk.dylib.4.4.4 /Users/r/Projects/Mu/usr/lib

Что он должен прочитать вместо этого, чтобы создать .dylib с абсолютным путем?

Обновить

Из соображений обратной совместимости мы бы предпочли оставить dylib с относительным именем при его сборке (т. е. мы не хотим передавать аргумент -install_name команде g++ -fPIC ...).

Есть ли способ настроить dylib после того, как он будет создан, чтобы иметь абсолютный путь? Когда я запускаю otool -L для существующего файла, я вижу:

$ otool -L libstk.dylib.4.4.4
libstk.dylib.4.4.4:
    libstk.dylib.4.4.4 (compatibility version 0.0.0, current version 0.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
    /System/Library/Frameworks/CoreAudio.framework/Versions/A/CoreAudio (compatibility version 1.0.0, current version 1.0.0)
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 855.16.0)
    /System/Library/Frameworks/CoreMIDI.framework/Versions/A/CoreMIDI (compatibility version 1.0.0, current version 73.0.0)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)

Я бы хотел, чтобы эта первая строка была

    /MySandbox/whatever/libstk.dylib.4.4.4 (compatibility version 0.0.0, current version 0.0.0)

p.s.

Если кто-то нетерпелив, как я, вы можете использовать install_name_tool в качестве обходного пути для обновления исполняемого файла следующим образом:

install_name_tool -change libstk.dylib.4.4.4 ../usr/lib/libstk.dylib.4.4.4 mune31

... но было бы неплохо не делать этого каждый раз, когда я создаю исполняемый файл.


person fearless_fool    schedule 10.06.2014    source источник
comment
Вы пробовали просто использовать install_name_tool на самой dylib?   -  person nneonneo    schedule 11.06.2014
comment
@nneonneo: Спасибо, но я пробовал. с аргументом -change он не изменил dylib. И с аргументом -rname выдало ошибку.   -  person fearless_fool    schedule 11.06.2014
comment
Используйте опцию -id. Вы пытаетесь изменить собственный идентификатор dylib, чтобы компоновщик включил этот идентификатор в качестве ссылки в исполняемый файл.   -  person Ken Thomases    schedule 11.06.2014
comment
@KenThomases: Великолепно - спасибо. Пожалуйста, отправьте в качестве ответа, чтобы я мог дать ему чек.   -  person fearless_fool    schedule 11.06.2014


Ответы (1)


Вы можете использовать опцию -id для install_name_tool, чтобы изменить идентификатор dylib, прежде чем связать свой исполняемый файл. Компоновщик использует идентификатор как ссылку на библиотеку, которая запекается в исполняемый файл.

Если вы предполагаете использовать install_name_tool для изменения путей в двоичном файле, вы должны указать одну из следующих опций компоновщика: либо -headerpad <size>, либо -headerpad_max_install_names.

person Ken Thomases    schedule 11.06.2014
comment
+1 за подсказку -headerpad / -headerpad_max_install_names - иначе я бы не знал. - person fearless_fool; 12.06.2014