То, что вы просите, может быть сделано в некоторых системах, но не с опцией GCC -static
. Эта опция имеет глобальное влияние на связывание:
В системах, которые поддерживают динамическое связывание, это переопределяет -pie и предотвращает связывание с общими библиотеками. В других системах этот параметр не действует.
( GCC 9.2, руководство )
Чтобы получить требуемый уровень контроля над связыванием, необходимо пройтиуказывает на компоновщик. Вы можете сделать это с помощью опции -Wl
в GCC. Если вы используете GCC, то, вероятно, вы также используете компоновщик GNU, и для целей сборки, которые поддерживают как статическое, так и динамическое связывание, у него есть множество механизмов для их смешивания. В частности, флаг -Bstatic
компоновщика GNU и его аналог -Bdynamic
вступают в силу только для библиотек, названных в их честь в командной строке, до следующего такого флага. То есть они позволяют вам переключаться между назначением библиотек для статического и динамического связывания.
Пример:
This CПрограмма требует, чтобы математическая библиотека была связана, что не является автоматическим с GCC:
link_test.c :
#include <stdio.h>
#include <math.h>
int main(void) {
printf("The square root of 2 is approximately %f\n", sqrt(2.0));
}
Эта команда gcc
вызовет -lm
для статического связывания, но libc для динамического связывания:
gcc -o link_test link_test.c -Wl,-Bstatic -lm -Wl,-Bdynamic
Любое количество дополнительных -l
опций, имен библиотек и имен объектных файлов может быть помещено между -Wl,-Bstatic
и -Wl,-Bdynamic
варианты вместе с -lm
;все такие объекты будут связаны статически. Хотя libc
не является явно связанным (GCC не требует этого), оставление переключенного типа ссылки на «динамический» в конце списка явных аргументов, для меня, приводит к динамическому связыванию libc:
$ ldd link_test
linux-vdso.so.1 => (0x00007ffe185af000)
libc.so.6 => /lib64/libc.so.6 (0x00002b775f059000)
/lib64/ld-linux-x86-64.so.2 (0x00002b775ee35000)
(Обратите внимание, что libm не появляется в списке динамических библиотек, в отличие от того, когда -Wl,-Bstatic
не используется, но libc делает.)
Обратите внимание, что ваша цель «Запуск ldd» в финаледвоичный файл должен показывать только динамически скомпонованный glibc "не обязательно жизнеспособен, как демонстрирует вышеприведенный вывод ldd
. Если ваш исполняемый файл вообще динамически связан, то в дополнение к динамическим библиотекам он будет связан с динамическим загрузчиком и, возможно, также с платформозависимыми псевдобиблиотеками, такими как linux-vdso.so.1
.
Вы запрашиваетепример makefile, но это все равно, что просто спросить «напиши мне программу». Ничего об этом не является make
-специфичным, и существует бесчисленное множество способов включить вышеуказанный подход в make-файл. Но так как вы спросили, это один из самых простых вариантов:
Makefile
link_test: link_test.c
gcc -o $@ $< -Wl,-Bstatic -lm -Wl,-Bdynamic