Как правило, вы должны использовать правильную среду сборки, которая содержит все целевые библиотеки с необходимыми или совместимыми версиями. Разница между вариантами libc заключается не только в самом имени связанной библиотеки. Например, требуемые файлы конфигурации могут отличаться. Некоторые интерфейсы могут быть снабжены встроенными оболочками на уровне заголовка, которые изменяются между версиями. Обычно безопасно запускать двоичный файл с более новой версией библиотеки, но не со старой.
Но, если у вас есть пакет разработки целевого libc, установленный дополнительно к вашей системе, вы можете создать двоичный файл непосредственно с ним, используя ключи -nostdinc и -nostdlib (или явно вызывать компоновщик), и явно указав необходимые библиотеки. Пример можно получить из вывода gcc -v
. В моей системе это последняя команда компоновщика:
/usr/bin/ld --eh-frame-hdr -V -dynamic-linker /libexec/ld-elf.so.1 \
-o t /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtbegin.o \
-L/usr/lib -L/usr/lib /tmp//ccCb5j33.o -lgcc --as-needed -lgcc_s \
--no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed \
/usr/lib/crtend.o /usr/lib/crtn.o
В зависимости от специфики целевой libc, вы должны заменить некоторые из этих инструкций на другие. В частности, должен быть заменен запуск (crt1.o и crti.o), очистка (crtend.o, crtn.o), сам libc (явный путь вместо -lc); по желанию, так же должен встречаться динамический компоновщик.
P.S. Я вижу, что это слишком старый вопрос, но он был переиздан только сейчас:)