соединение успешно выполняется с помощью clang, но не g cc (-llzma на Debian bullseye amd64) - PullRequest
1 голос
/ 27 марта 2020

В Debian bullseye (тестирование) с установленными пакетами, связанными с xz / lzma:

ii  liblzma-dev:amd64                     5.2.4-1+b1                           amd64
ii  liblzma5:amd64                        5.2.4-1+b1                           amd64
ii  lzma-dev                              9.22-2.1                             all

Clang создает рабочий ./a.out без проблем:

$>gunzip < /usr/share/doc/liblzma-dev/examples/02_decompress.c.gz | sed -s 's/extern int/int' | clang -std=c18 -Wall -Wextra -x c -llzma -

Однако попытка использовать g cc не удалась:

$>gunzip < /usr/share/doc/liblzma-dev/examples/02_decompress.c.gz | sed -s 's/extern int/int' | gcc -std=c18 -Wall -Wextra -x c -llzma -

/usr/bin/ld: /tmp/ccl8uTG0.o: in function `init_decoder':
:(.text+0x20): undefined reference to `lzma_stream_decoder'
/usr/bin/ld: /tmp/ccl8uTG0.o: in function `decompress':
:(.text+0x1e1): undefined reference to `lzma_code'
/usr/bin/ld: /tmp/ccl8uTG0.o: in fuction `main':
:(.text+0x4e4): undefined reference to `lzma_end'
collect2: error: ld returned 1 exit status

g++ --version отчеты 9.3.0-3

clang++ --version отчеты 9.0.1-10

(оба компилятора устанавливаются через apt-get.)

/etc/ld.so.conf.d/x86_64-linux-gnu.conf содержит

# Multiarch support
/usr/local/lib/x86_64-linux-gnu
/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu

Я проверил, что /usr/lib/x86_64-linux-gnu/liblzma.so.5.2.4 (и его .so.5 и .so символические ссылки, а также связанный файл .a) существуют.

Кроме того, вывод readelf --symbols /usr/lib/x86_64-linux-gnu/liblzma.so.5.2.4 | grep 'lzma_[sec]' показывает, что эти три символа существуют (наряду со многими другими):

67: 000000000000c720   106 FUNC    GLOBAL DEFAULT   13 lzma_stream_decoder@@XZ_5.0
   108: 00000000000039d0   701 FUNC    GLOBAL DEFAULT   13 lzma_code@@XZ_5.0
   117: 0000000000003c90    65 FUNC    GLOBAL DEFAULT   13 lzma_end@@XZ_5.0

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

1 Ответ

1 голос
/ 27 марта 2020

Clang помещает -llzma вне области --as-needed командной строки компоновщика:

[…] -L/usr/lib -llzma /tmp/--e00a22.o -lgcc --as-needed -lgcc_s […]

G CC ставит его после --as-needed:

[…] --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 […]
  -llzma /tmp/ccAZHRvb.o -lgcc --push-state

В результате компоновщик замечает, что -llzma не требуется в этой точке в командной строке, и удаляет его. Связывание зависит от порядка.

Это можно исправить, используя - -llzma вместо -llzma -, как предложено HolyBlackCat .

...