Используйте как статические, так и динамически связанные библиотеки в gcc

Мне нужно распространять двоичный файл, который будет работать как можно больше из дистрибутивов Linux x86. Это означает, что мне приходится статически связывать некоторые библиотеки, например glibc, потому что у пользователя может не быть той версии, которую я использую. Другие библиотеки должны быть динамически связаны, например fontconfig, потому что они зависят от формата файла кэша и жестко закодированных местоположений, которые могут различаться в каждой системе.

Каковы параметры командной строки для этого? Если я укажу -статический, то gcc откажется от динамической привязки каких-либо библиотек вообще.

Ответ 1

Статическая привязка к любой системной библиотеке, особенно к libc, в современных системах UNIX или Linux делает двоичный файл значительно менее переносимым. Просто не делай этого.

Вместо этого используйте обратную совместимость (двоичные файлы, связанные с более старой системой, продолжают работать на всех более новых) в вашу пользу, либо путем связывания вашего двоичного файла с старой системой (я использую RedHat 6.2, и я не видел систему Linux где мой бинарный файл не будет работать за последние 8 лет), или используя что-то вроде autopackage.

Чтобы ответить на ваш оригинальный вопрос:

gcc main.o -Wl,-Bstatic -lfoo -Wl,-Bdynamic

заставит компоновщик использовать версию архива libfoo. [Важно иметь конечную -Wl,-Bdynamic именно так, чтобы вы не заставляли статический libc.]

Ответ 2

Следует отметить, что в Linux вы можете (безопасно) статически связывать библиотеку, если ни одна из динамических библиотек не зависит от нее. Это означает, что если вы вообще используете какие-либо динамические библиотеки, вы можете забыть о статической привязке libc. Просто используйте довольно старую версию для сборки против libc case; В течение последних лет libc поддерживала прочную совместимость с ABI.

Ответ 3

Попробуйте передать пути к библиотечным файлам, на которые вы ссылаетесь, в командной строке компоновщика (будь то библиотеки .a или .so) и drop -static. Это должно сделать трюк.