2010-05-18 5 views
81

Когда я скомпилирую что-то на своем компьютере Ubuntu Lucid 10.04, он связан с glibc. Lucid использует 2.11 glibc. Когда я запускаю этот двоичный файл на другом ПК с более старым glibc, команда не работает, если нет glibc 2.11 ...Как я могу связать конкретную версию glibc?

Насколько я знаю, glibc использует управление версиями символов. Могу ли я заставить gcc ссылаться на конкретную версию символа?

В моем конкретном использовании я пытаюсь скомпилировать gcc cross toolchain для ARM.

+44

Argh это одна из тех действительно раздражающих проблем с Linux, например, когда решение всегда «вы не должны этого делать», что, конечно, означает, что «это не работает, и никто еще не исправил его». – Timmmm

+0

Люди жаловались на аддон DLL на Windows. Я помню, что Linux * some * aficionados пытается принести это как ужасный пример из мира Windows. Когда я впервые столкнулся с * этим * развитием Linux более десяти лет назад, все, что я делал, - это похоронить мое лицо в моих руках. – 0xC0000022L

ответ

54

Вы правы в том, что glibc использует управление версиями символов. Если вам интересно, реализация версии управления символами, представленная в glibc 2.1, описана here и является расширением схемы управления версиями символов Sun, описанной here.

Один из вариантов - статически связать ваш двоичный файл. Вероятно, это самый простой вариант.

Вы также можете создать свой исполняемый файл в среде сборки корневой, или с помощью glibc- нового => glibc- старого кросса-компилятора.

Согласно сообщению Linking to Older Versioned Symbols (glibc) в http://www.trevorpounds.com блоге, можно заставить любой символ быть связан с более старой, так долго, как это действует, используя один и тот же .symver псевдо-оп, который используется для определения о версиях символов в первую очередь. Следующий пример вычитается из blog post.

В следующем примере используется реальный путь glibc, но он уверен, что он связан с более старой версией 2.2.5.

#include <limits.h> 
#include <stdlib.h> 
#include <stdio.h> 

__asm__(".symver realpath,[email protected]_2.2.5"); 
int main() 
{ 
    char* unresolved = "/lib64"; 
    char resolved[PATH_MAX+1]; 

    if(!realpath(unresolved, resolved)) 
     { return 1; } 

    printf("%s\n", resolved); 

    return 0; 
} 
+10

glibc не поддерживает статическое связывание - статически связанные программы glibc не работают в системе с разными версиями libc. –

+2

'libc.a' glibc продолжает существовать, glibc поддерживает это в * некоторых * случаях, хотя [не рекомендуется (Drepper)] (http://www.akkadia.org/drepper/no_static_linking.html). У вас возникнут проблемы с нетривиальными программами, например, с использованием NSS (обходной путь в [FAQ] (https://sourceware.org/glibc/wiki/FAQ)). –

15

Связь с -static. Когда вы связываетесь с -static, компоновщик встраивает библиотеку в исполняемый файл, поэтому исполняемый файл будет больше, но он может быть выполнен в системе со старой версией glibc, потому что программа будет использовать собственную библиотеку, а не система.

+47

Часто причина, по которой вы хотите сделать это, - это то, что вы распространяете приложение с закрытым исходным кодом. В этом случае часто не разрешается связывать статически по причинам лицензирования (для этого потребуется выпустить весь исходный код), поэтому вам нужно быть осторожным с -статическим. – Malvineous

+1

Между тем, по крайней мере, можно часто прибегать к musl-libc, но с программами на C++ все может усложниться, поэтому необходимость в символьной версии может понадобиться. – 0xC0000022L

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