2017-01-26 12 views
1

При связывании программы с общим объектом ld гарантирует, что символы могут быть разрешены. Это в основном гарантирует совместимость интерфейсов между программой и ее общими объектами. Прочитав Linking with dynamic library with dependencies, я узнал, что ld спустится в связанные общие объекты и попытается разрешить их символы.Не проверяется ли ld проверка нерешенных символов в общих библиотеках?

Не связаны ли ссылки моего общего объекта, когда сами связанные объекты связаны?

Я могу понять привлекательность выяснения во время ссылки, есть ли у программы все части, которые она требует для начала, но кажется ли это неактуальным в контексте создания пакетов, где общие объекты могут быть распределены отдельно (Debian's lib * пакеты, например). Он вводит рекурсивные зависимости построения для систем, не заинтересованных в выполнении встроенных программ.

Могу ли я доверять зависимостям, разрешенным при создании общего объекта? Если да, то насколько безопасно использовать - unresolved-symbols = ignore-in-shared-libs при создании моей программы?

ответ

2

Вы задаетесь вопросом, почему связь программа, должна беспокоить разрешить символы, возникающие в разделяемые библиотеки, это связано с тем, потому:

ли не ссылки моего общего объекта уже проверено, когда общие объекты сами по себе связано?

Нет, они не, если вы явно не настаивают на этом, когда вы связать общую библиотеку,

Здесь я собираюсь построить общую библиотеку libfoo.so:

foo.c

extern void bar(); 

void foo(void) 
{ 
    bar(); 
} 

компилировать и плановом порядке ссылка:

$ gcc -fPIC -c foo.c 
$ gcc -shared -o libfoo.so foo.o 

Нет проблем, и bar не определено:

$ nm --undefined-only libfoo.so | grep bar 
       U bar 

Я должен попробовать довольно энергично, чтобы получить компоновщик возразить, что:

$ gcc -shared -o libfoo.so foo.o -Wl,--no-allow-shlib-undefined,--unresolved-symbols=report-all 
foo.o: In function `foo': 
foo.c:(.text+0xa): undefined reference to `bar' 

Конечно:

основной .c

extern void foo(void); 

int main(void) 
{ 
    foo(); 
    return 0; 
} 

это не позволит мне связать libfoo с программы:

$ gcc -c main.c 
$ gcc -o prog main.o -L. -lfoo 
./libfoo.so: undefined reference to `bar' 

, если я также не разрешать bar в той же связи:

bar.c

#include <stdio.h> 

void bar(void) 
{ 
    puts("Hello world!"); 
} 

возможно, получая его из другой разделяемой библиотеки:

gcc -fPIC -c bar.c 
$ gcc -shared -o libbar.so bar.o 
$ gcc -o prog main.o -L. -lfoo -lbar 

И тогда все в порядке.

$ export LD_LIBRARY_PATH=.; ./prog 
Hello world! 

Это из Ессенции разделяемой библиотеки, что не делает по умолчанию имеют , чтобы все его символы решенных в linktime. Таким образом, что программа - которая обычно делает нужна все его символы разрешила linktime - может получить все свои символы решенных они связаны с более одной библиотекой.

+0

С тестами, которые я выполнил, у меня осталась ссылка на показы при создании общего объекта. Мне стало интересно, почему это не так, но в случае, представленном @yugr, проверка ссылок, когда библиотеки строятся, приведет к проблеме курица и яйцо. – elik

1

ли не ссылки моего общего объекта уже проверили когда общие объекты сами связаны?

Ну, общие библиотеки могут быть связаны с -Wl,--allow-shlib-undefined или с фиктивными зависимостями, поэтому имеет смысл проверить их.

Могу ли я доверять зависимостям, разрешенным при создании общего объекта?

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

Если да, то как это безопасно использовать -unresolved-символы = игнорировать-в-разделяемых-LIBS при создании моей программы?

Возможно, в этом случае могут отсутствовать потенциальные ошибки (или, скорее, отсрочить их на время выполнения, которое все еще плохо). Представьте ситуацию, когда некоторые символы, необходимые для общих объектов, должны поступать из самого исполняемого файла или из одной из библиотек, которые связаны исполняемым файлом (но не от shlib, которому не хватает символов).

EDIT

Хотя выше правильный, ответ Майк Kinghan дает сильный аргумент в пользу разрешения символов в библиотеках во исполняемой ссылке.

+0

Но если вы создаете программное обеспечение для распространения, ваша среда сборки может отличаться от развернутой среды. Что касается библиотек, построенных с помощью allow-undefined, в данном случае я бы тоже контролировал их сборку. +1 для символов, определенных в самом исполняемом файле, не думал об этом. Это звучит как использование ниши (в основном, интерфейс плагина). Это распространено? – elik

+0

@elik «Но если вы создаете программное обеспечение для распространения, ваша среда сборки может отличаться от развернутой среды» - да, вы получите ошибку во время выполнения в этом случае. Но лучше обнаружить несовместимости как можно раньше. «Это похоже на использование ниши (в основном, интерфейс плагина). Это обычное дело?» - Не очень распространены, но я добавил еще один случай использования, который довольно часто встречается. – yugr

+0

@elik В целом, я думаю, что ответ Майка более правильный - его аргумент в пользу разрешения символов во время исполняемой ссылки сильнее моего (хотя мой до сих пор сохраняется). – yugr