使用 clang 链接成功但不是 gcc(Debian bullseye amd64 上的-llzma)
linking succeeds with clang but not gcc (-llzma on Debian bullseye amd64)
在 Debian bullseye(测试)上,安装了这些 xz/lzma-related 软件包:
ii liblzma-dev:amd64 5.2.4-1+b1 amd64
二 liblzma5:amd64 5.2.4-1+b1 amd64
ii lzma-dev 9.22-2.1 全部
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 -
但是,尝试使用 gcc 失败:
$>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 全局默认值 13 lzma_stream_decoder@@XZ_5.0
108: 00000000000039d0 701 FUNC 全局默认值 13 lzma_code@@XZ_5.0
117: 0000000000003c90 65 FUNC 全局默认值 13 lzma_end@@XZ_5.0
我做错了什么?
Clang 将 -llzma
放在链接器命令行的 --as-needed
区域之外:
[…] -L/usr/lib -llzma /tmp/--e00a22.o -lgcc --as-needed -lgcc_s […]
GCC 放在 --as-needed
:
之后
[…] --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 […]
-llzma /tmp/ccAZHRvb.o -lgcc --push-state
因此,链接器注意到命令行中的那个点不需要 -llzma
并将其删除。链接是顺序敏感的。
您可以按照 HolyBlackCat 的建议,使用 - -llzma
而不是 -llzma -
来解决此问题。
在 Debian bullseye(测试)上,安装了这些 xz/lzma-related 软件包:
ii liblzma-dev:amd64 5.2.4-1+b1 amd64 二 liblzma5:amd64 5.2.4-1+b1 amd64 ii lzma-dev 9.22-2.1 全部
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 -
但是,尝试使用 gcc 失败:
$>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 全局默认值 13 lzma_stream_decoder@@XZ_5.0 108: 00000000000039d0 701 FUNC 全局默认值 13 lzma_code@@XZ_5.0 117: 0000000000003c90 65 FUNC 全局默认值 13 lzma_end@@XZ_5.0
我做错了什么?
Clang 将 -llzma
放在链接器命令行的 --as-needed
区域之外:
[…] -L/usr/lib -llzma /tmp/--e00a22.o -lgcc --as-needed -lgcc_s […]
GCC 放在 --as-needed
:
[…] --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 […]
-llzma /tmp/ccAZHRvb.o -lgcc --push-state
因此,链接器注意到命令行中的那个点不需要 -llzma
并将其删除。链接是顺序敏感的。
您可以按照 HolyBlackCat 的建议,使用 - -llzma
而不是 -llzma -
来解决此问题。