gcc и ld отказываются статически связывать библиотеку - PullRequest
0 голосов
/ 01 ноября 2019

Просто для забавы (и для обучения компиляции в целом) я поставил себе задачу построить xorg-сервер со всеми статически связанными библиотеками, кроме glibc. По какой-то причине gcc просто игнорирует некоторые из моих статических библиотек.

Когда я запускаю что-то вроде этого (последние две строки соответствуют):

gcc -DHAVE_DIX_CONFIG_H -Wall -Wpointer-arith -Wmissing-declarations -Wformat=2 -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Wbad-function-cast \
-Wold-style-definition -Wdeclaration-after-statement -Wunused -Wuninitialized -Wshadow -Wmissing-noreturn -Wmissing-format-attribute -Wredundant-decls \
-Wlogical-op -Werror=implicit -Werror=nonnull -Werror=init-self -Werror=main -Werror=missing-braces -Werror=sequence-point -Werror=return-type -Werror=trigraphs \
-Werror=array-bounds -Werror=write-strings -Werror=address -Werror=int-to-pointer-cast -Werror=pointer-to-int-cast -fno-strict-aliasing -fno-strict-aliasing \
-D_DEFAULT_SOURCE -D_BSD_SOURCE -DHAS_FCHOWN -DHAS_STICKY_DIR_BIT -I/usr/include/libdrm -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 \
-I/usr/include/X11/dri -I../../include -I../../include -I../../Xext -I../../composite -I../../damageext -I../../xfixes -I../../Xi -I../../mi -I../../miext/sync \
-I../../miext/shadow -I../../miext/damage -I../../render -I../../randr -I../../fb -I../../dbe -I../../present -fvisibility=hidden -DHAVE_XORG_CONFIG_H \
-fvisibility=hidden -I/usr/include/libdrm -g -O2 -pthread -o Xorg sdksyms.o \
   /lib/arm-linux-gnueabihf/libz.a ../../dix/.libs/libmain.a ../../dix/.libs/libdix.a loader/.libs/libloader.a common/.libs/libcommon.a  os-support/.libs/libxorgos.a \
parser/.libs/libxf86config.a dixmods/.libs/libdixmods.a modes/.libs/libxf86modes.a ramdac/.libs/libramdac.a ddc/.libs/libddc.a i2c/.libs/libi2c.a \
../../composite/.libs/libcomposite.a ../../xfixes/.libs/libxfixes.a ../../Xext/.libs/libXext.a ../../dbe/.libs/libdbe.a ../../record/.libs/librecord.a \
../../randr/.libs/librandr.a ../../render/.libs/librender.a ../../damageext/.libs/libdamageext.a ../../present/.libs/libpresent.a \
../../miext/damage/.libs/libdamage.a ../../Xi/.libs/libXi.a ../../xkb/.libs/libxkb.a xkb/.libs/libxorgxkb.a dri/.libs/libdri.a dri2/.libs/libdri2.a \
../../dri3/.libs/libdri3.a ../../glx/.libs/libglxvnd.a ../../miext/sync/.libs/libsync.a ../../mi/.libs/libmi.a ../../os/.libs/libos.a -lcrypto \
../../Xext/.libs/libXvidmode.a \
-Wl,-Bstatic -lpciaccess -ldrm -lpixman-1 -lXau -lxshmfence -lm -lbz2 -lfontenc -ludev \
-Wl,-Bdynamic -lXdmcp -lXfont2 -lrt -ldl -lpthread

Он создает двоичный файл сследующие ссылки:

(sid)root@localhost:/opt/xorg-server-1.20.5/hw/xfree86# ldd Xorg
        libcrypto.so.1.1 => /lib/arm-linux-gnueabihf/libcrypto.so.1.1 (0xf6a8b000)
        libXdmcp.so.6 => /lib/arm-linux-gnueabihf/libXdmcp.so.6 (0xf6a77000)
        libXfont2.so.2 => /lib/arm-linux-gnueabihf/libXfont2.so.2 (0xf6a4b000)
        librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0xf6a35000)
        libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0xf6a22000)
        libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0xf69fd000)
        libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xf6902000)
        /lib/ld-linux-armhf.so.3 (0xf6ec7000)
        libbsd.so.0 => /lib/arm-linux-gnueabihf/libbsd.so.0 (0xf68df000)
        libz.so.1 => /lib/arm-linux-gnueabihf/libz.so.1 (0xf68bc000)
        libbz2.so.1.0 => /lib/arm-linux-gnueabihf/libbz2.so.1.0 (0xf68a0000)
        libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0xf6837000)
        libfontenc.so.1 => /lib/arm-linux-gnueabihf/libfontenc.so.1 (0xf6822000)
        libfreetype.so.6 => /lib/arm-linux-gnueabihf/libfreetype.so.6 (0xf67a2000)
        libpng16.so.16 => /lib/arm-linux-gnueabihf/libpng16.so.16 (0xf6770000)

Как видно на выходе, "libz" динамически связан. Поэтому я подумал, что попытаюсь заставить gcc / ld использовать статический libz. Но ничего не работает. Я попытался добавить "-lz" в список -Bstatic, и я также попытался с "-l: libz.a", а также с полным путем к файлу "/ lib / arm-linux-gnueabihf / libz. а». Ничего не работает, и последний двоичный файл все еще связан с динамической библиотекой .so. gcc не выдает никаких ошибок, просто игнорирует мой запрос статической компоновки некоторых библиотек.

Что я делаю не так?

Кроме того, когда я перемещаю две библиотеки "-lXdmcp-lXfont2 "из динамического списка в статический список, gcc завершается ошибкой с некоторыми ошибками, которые выглядят так, будто библиотеки ссылаются на то, что не включено? Как бы я отлаживал такие проблемы со ссылками?

/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabihf/9/../../../arm-linux-gnueabihf/libXdmcp.a(Key.o): in function `XdmcpGenerateKey':
(.text+0x2): undefined reference to `arc4random_buf'
/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabihf/9/../../../arm-linux-gnueabihf/libXfont2.a(ftfuncs.o): in function `sfnt_get_ushort':
(.text+0x1a): undefined reference to `FT_Load_Sfnt_Table'
/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabihf/9/../../../arm-linux-gnueabihf/libXfont2.a(ftfuncs.o): in function `FreeTypeFreeFace.part.3':
(.text+0x412): undefined reference to `FT_Done_Face'
/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabihf/9/../../../arm-linux-gnueabihf/libXfont2.a(ftfuncs.o): in function `FreeTypeFreeFont':
(.text+0x4aa): undefined reference to `FT_Done_Size'
/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabihf/9/../../../arm-linux-gnueabihf/libXfont2.a(ftfuncs.o): in function `FreeTypeActivateInstance':
(.text+0x686): undefined reference to `FT_Activate_Size'
/usr/bin/ld: (.text+0x6b4): undefined reference to `FT_Set_Transform'
/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabihf/9/../../../arm-linux-gnueabihf/libXfont2.a(ftfuncs.o): in function `FreeTypeLoadFont':
(.text+0x8f8): undefined reference to `FT_Get_Sfnt_Table'
/usr/bin/ld: (.text+0xb6e): undefined reference to `FT_Get_PS_Font_Info'
/usr/bin/ld: (.text+0xc7c): undefined reference to `FT_New_Size'
/usr/bin/ld: (.text+0xcb8): undefined reference to `FT_Set_Char_Size'
/usr/bin/ld: (.text+0xcc6): undefined reference to `FT_Done_Size'
/usr/bin/ld: (.text+0xe70): undefined reference to `FT_Set_Pixel_Sizes'
/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabihf/9/../../../arm-linux-gnueabihf/libXfont2.a(ftfuncs.o): in function `FT_Do_SBit_Metrics.isra.6':
(.text+0xf9c): undefined reference to `FT_Set_Pixel_Sizes'
/usr/bin/ld: (.text+0xfaa): undefined reference to `FT_Load_Glyph'
/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabihf/9/../../../arm-linux-gnueabihf/libXfont2.a(ftfuncs.o): in function `ft_get_very_lazy_bbox':
(.text+0x10a4): undefined reference to `FT_Load_Sfnt_Table'
/usr/bin/ld: (.text+0x10d8): undefined reference to `FT_MulFix'
/usr/bin/ld: (.text+0x10e8): undefined reference to `FT_MulFix'
/usr/bin/ld: (.text+0x10f2): undefined reference to `FT_MulFix'
/usr/bin/ld: (.text+0x10fc): undefined reference to `FT_MulFix'
/usr/bin/ld: (.text+0x116a): undefined reference to `FT_Vector_Transform'
/usr/bin/ld: (.text+0x1172): undefined reference to `FT_Vector_Transform'
/usr/bin/ld: (.text+0x117a): undefined reference to `FT_Vector_Transform'
/usr/bin/ld: (.text+0x1182): undefined reference to `FT_Vector_Transform'
/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabihf/9/../../../arm-linux-gnueabihf/libXfont2.a(ftfuncs.o): in function `FreeTypeRasteriseGlyph':
(.text+0x1530): undefined reference to `FT_Outline_Get_BBox'
/usr/bin/ld: (.text+0x1704): undefined reference to `FT_Outline_Get_BBox'
/usr/bin/ld: (.text+0x17d0): undefined reference to `FT_Load_Glyph'
/usr/bin/ld: (.text+0x1810): undefined reference to `FT_Outline_Get_BBox'
/usr/bin/ld: (.text+0x1c56): undefined reference to `FT_Load_Glyph'
/usr/bin/ld: (.text+0x1d0e): undefined reference to `FT_Render_Glyph'
/usr/bin/ld: (.text+0x1dd0): undefined reference to `FT_Outline_Get_BBox'
/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabihf/9/../../../arm-linux-gnueabihf/libXfont2.a(ftfuncs.o): in function `FreeTypeLoadXFont':
(.text+0x3042): undefined reference to `FT_New_Face'
/usr/bin/ld: (.text+0x3088): undefined reference to `FT_Init_FreeType'
/usr/bin/ld: (.text+0x33f6): undefined reference to `FT_Get_Sfnt_Table'
/usr/bin/ld: (.text+0x3af0): undefined reference to `FT_Get_Sfnt_Table'
/usr/bin/ld: (.text+0x3afc): undefined reference to `FT_Get_Sfnt_Table'
/usr/bin/ld: (.text+0x3b08): undefined reference to `FT_Get_PS_Font_Info'
/usr/bin/ld: (.text+0x3e8a): undefined reference to `FT_Get_Postscript_Name'
/usr/bin/ld: (.text+0x3f04): undefined reference to `FT_Get_X11_Font_Format'
/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabihf/9/../../../arm-linux-gnueabihf/libXfont2.a(fttools.o): in function `FTGetName':
(.text+0x22): undefined reference to `FT_Get_Sfnt_Name_Count'
/usr/bin/ld: (.text+0x40): undefined reference to `FT_Get_Sfnt_Name'
/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabihf/9/../../../arm-linux-gnueabihf/libXfont2.a(gunzip.o): in function `BufZipFileClose':
(.text+0x48): undefined reference to `inflateEnd'
/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabihf/9/../../../arm-linux-gnueabihf/libXfont2.a(gunzip.o): in function `BufZipFileFill':
(.text+0xcc): undefined reference to `inflate'
/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabihf/9/../../../arm-linux-gnueabihf/libXfont2.a(gunzip.o): in function `BufFilePushZIP':
(.text+0x1cc): undefined reference to `inflateInit2_'
/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabihf/9/../../../arm-linux-gnueabihf/libXfont2.a(bunzip2.o): in function `BufBzip2FileClose':
(.text+0x48): undefined reference to `BZ2_bzDecompressEnd'
/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabihf/9/../../../arm-linux-gnueabihf/libXfont2.a(bunzip2.o): in function `BufBzip2FileFill':
(.text+0xce): undefined reference to `BZ2_bzDecompress'
/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabihf/9/../../../arm-linux-gnueabihf/libXfont2.a(bunzip2.o): in function `BufFilePushBZIP2':
(.text+0x1c2): undefined reference to `BZ2_bzDecompressInit'
/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabihf/9/../../../arm-linux-gnueabihf/libXfont2.a(ftenc.o): in function `FTPickMapping':
(.text+0x20): undefined reference to `FontEncFromXLFD'
/usr/bin/ld: (.text+0x68): undefined reference to `FT_Get_BDF_Charset_ID'
/usr/bin/ld: (.text+0xd0): undefined reference to `FT_Get_BDF_Charset_ID'
/usr/bin/ld: (.text+0xe2): undefined reference to `FT_Select_Charmap'
/usr/bin/ld: (.text+0xf4): undefined reference to `FontEncFind'
/usr/bin/ld: (.text+0x10a): undefined reference to `FontEncFind'
/usr/bin/ld: (.text+0x118): undefined reference to `FT_Has_PS_Glyph_Names'
/usr/bin/ld: (.text+0x18c): undefined reference to `FT_Get_BDF_Charset_ID'
/usr/bin/ld: (.text+0x19c): undefined reference to `FontEncFind'
/usr/bin/ld: (.text+0x242): undefined reference to `FontEncFind'
/usr/bin/ld: (.text+0x282): undefined reference to `FT_Get_Sfnt_Table'
/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabihf/9/../../../arm-linux-gnueabihf/libXfont2.a(ftenc.o): in function `FTRemap':
(.text+0x2d6): undefined reference to `FontEncName'
/usr/bin/ld: (.text+0x2ea): undefined reference to `FontEncRecode'
/usr/bin/ld: (.text+0x2f6): undefined reference to `FT_Set_Charmap'
/usr/bin/ld: (.text+0x316): undefined reference to `FT_Set_Charmap'
/usr/bin/ld: (.text+0x2e6): undefined reference to `FT_Get_Name_Index'
/usr/bin/ld: (.text+0x304): undefined reference to `FT_Get_Char_Index'
/usr/bin/ld: (.text+0x326): undefined reference to `FT_Get_Char_Index'
collect2: error: ld returned 1 exit status 

Ответы [ 2 ]

1 голос
/ 01 ноября 2019

Краткий ответ: Если вы выбираете статические библиотеки (при условии, что доступны «.a»), порядок библиотек имеет значение - в значении командной строки!

Длинный ответ: Если у вас есть двабиблиотеки (A, B), связанные с основным (M) кодом, где есть вызовы M-> A и A-> B, вы должны указывать библиотеки в таком порядке: M, A, B. Ссылка на статическую библиотеку, компоновщик будет пытаться найти любую неразрешенную ссылку (функцию, переменную, метод, ...) в указанной библиотеке и извлечь только файлы .o, которые разрешают эти ссылки из .a'в исполняемый файл.

Если библиотеки указаны как M, B, A, компоновщик изучит библиотеку' B 'и не определит ни одного' .o 'для включения (поскольку существует только ссылкаM-> A). Затем он извлечет «.o» из библиотеки A, чтобы удовлетворить вызов M-> A, и сообщит об ошибке по вновь обнаруженным вызовам A-> B.

При использовании общих объектов весь.so 'является связанным (посредством ссылки), и все глобально определенные символы в «.so» будут доступны любому модулю в исполняемом файле, включая модули, связанные с другим .so. Следовательно, порядок указания '.so' обычно не имеет значения

0 голосов
/ 01 ноября 2019

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

Маловероятно per se .

Что яделаете неправильно?

Вы неправильно понимаете природу динамического связывания. По крайней мере, эти факторы находятся в игре:

  • Общие объекты, которые вы связываете, могут иметь свои собственные зависимости от других динамических объектов.

  • В зависимостив деталях платформы и реализации ссылка может успешно завершиться, даже если некоторые из собственных зависимостей динамических объектов не разрешены ни одним из названий в командной строке.

  • Статические библиотеки, которые вы связываетевесьма вероятно, что не не обеспечивает жизнеспособных разрешений для чего-либо в любой из динамических библиотек.

  • Общие динамические зависимости программы, например, представленные ldd, является транзитивным закрытием зависимостей всех совместно используемых объектов. На них не обязательно все ссылаются непосредственно SO, который содержит точку входа в программу, и они могут даже со временем измениться, если реализации разделяемой библиотеки поменяются.

Итог: это оченьВероятно, что, по крайней мере, некоторые из ваших неожиданных динамических зависимостей происходят от общих объектов, которые вы связываете, вероятно, от libXdmcp и libXfont2. Статические библиотеки связаны и используются для разрешения символов в основной программе и в статических библиотеках, предшествующих им в командной строке, но они не могут удовлетворить ссылки общих объектов на динамические символы, независимо от того,где что-либо появляется в командной строке.

Кроме того, когда я перемещаю две библиотеки "-lXdmcp -lXfont2" из динамического списка в статический список, происходит сбой gcc с некоторыми ошибками, похожими на библиотекиссылки на вещи, которые не включены? Как бы я отлаживал такие проблемы со ссылками?

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

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

...