2013-06-19 4 views
4

У меня есть библиотека: libfoo.dylib. Проблема проиллюстрирована в командах:Как я могу указать rpath в dylib?

$ install_name_tool -id "@rpath/libfoo.dylib" libfoo.dylib 
$ install_name_tool -add_rpath "@executable_path/" libfoo.dylib 
$ gcc -o foo foo.c -lfoo 
$ ./foo #<==== I want this to work 
dyld: Library not loaded: @rpath/libfoo.dylib 
    Referenced from: ~/./foo 
    Reason: image not found 
$ install_name_tool -add_rpath "@executable_path/" foo #<=== I dont want to have to specify here where to look for the library 
$ ./foo 
Hello World 

Как достичь цели, не имея, чтобы указать на исполняемый компиляции, где находится библиотека?

+0

I * think * вам нужно скомпилировать и связать 'libfoo.dylib' с' -headerpad_max_install_names', чтобы убедиться, что есть достаточно места для имен, которые вы пытаетесь добавить. Если 'libfoo.dylib' имеет свое имя для установки, то' foo' сможет ссылаться на него независимо от местоположения программы. – jww

ответ

0

Единственное, что вам нужно - это рассказать компоновщику, чтобы добавить rpath в ваш двоичный файл. На самом деле, вы говорите gcc сказать линкера следующим образом:

$ gcc -o foo foo.c -lfoo -Wl,-rpath=/some/path 

Теперь, если вы используете objdump, чтобы увидеть, что там:

$ objdump -x ./foo | less 

Вы увидите под Dynamic Section Somthing как RPATH /some/path.

Если необходимости вводить тот же -Wl,-rpath=... слишком громоздким, ld принимает опцию @file (я не знаю, о dyld, но я предполагаю, что это делает тоже самое):

$ echo "-rpath=/some/path" > ./ld-options 
$ gcc ./foo.c -o foo -Wl,@ld-options 
+1

Я думаю, я должен был объяснить немного дальше, но дело в том, что у меня много компиляции исполняемых файлов и только одна библиотека. Я хочу сохранить команду для создания исполняемого файла в пределах 1 строки, чтобы было легко увидеть предупреждения. Добавление 'rpath = ...' к каждой исполняемой команде компиляции делает команду очень длинной и проходит мимо метки 1 строки. Это скорее вопрос удобства, чем необходимость. – chacham15

+0

См. Отредактированный ответ – rectummelancolique

+0

didt work, поэтому я попробовал это оригинальным способом: 'ld: unknown option: -rpath = @ executable_path /' – chacham15

2

Я должен признаться, что я немного смущенный относительно того, чего вы пытаетесь достичь. Весь смысл использования пути поиска пути - это то, что изображения, загружающие библиотеку, определяют путь поиска, который будет использоваться при загрузке библиотеки. То, о чем вы просите, - это определить библиотеку, где должен найти исполняемый файл. Это можно выполнить без использования пути поиска пути, просто установив имя установки dylib на соответствующее значение. На основе вашего конкретного примера кажется, что вы хотите установить имя для установки примерно на @loader_path/libfoo.dylib. Рассмотрим следующий, который по тем же линиям вашего образца:

$ cat a.c 
int a(void) 
{ 
    return 1; 
} 
$ cc -install_name "@loader_path/liba.dylib" -dynamiclib -o liba.dylib a.c 
$ cat main.c 
#include <stdio.h> 

extern int a(void); 

int main(int argc, char **argv) 
{ 
    fprintf(stderr, "A: %d\n", a()); 
    return 0; 
} 
$ cc -L. -la -o main main.c 
$ ./main 
A: 1 
$ 

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

+0

Да, ваш пример делает то, что я хочу (имея набор библиотек, где он должен быть найден, а не исполняемый файл). Единственная проблема (и причина, по которой я хотел использовать rpath) - это то, что я хочу указать 3 местоположения для поиска: '/ usr/lib',' ../ Framework/'и исполняемый путь, как вы показали. Из моего чтения, которое невозможно использовать только с именем install_, правильно? – chacham15

+0

Правильно, если вы хотите указать несколько местоположений, вам нужно использовать пути поиска пути, и, таким образом, исполняемый файл будет определять, где искать библиотеку. Обратите внимание, что '/ usr/lib' будет искать по умолчанию, если библиотека не может быть найдена в местоположении, указанном командой load, поэтому может быть необязательно явно ссылаться на это местоположение. – bdash

Смежные вопросы