某些版本gcc使用-flto选项编译生成的静态库无法正常被链接的问题解决

本文介绍了一个在使用特定版本的GCC交叉编译工具链时遇到的问题:使用LTO选项生成的lib文件在链接时提示找不到库内的函数。通过详细分析及查找文档,最终确定了解决方案:需要将liblto_plugin.so复制到特定路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题引入

最近在使用某个版本的交叉编译工具链gcc时发现一个问题,示例如下:
首先创建一个lto.c文件,内容如下:

int issue_func(int a0, int a1)
{
    return a0+a1;
}

创建main.c

extern int issue_func(int a0, int a1);

int main()
{
    return issue_func(5,6);
}

然后按照如下方式编译代码

riscv-nuclei-elf-gcc -flto -o lto.o -c lto.c
riscv-nuclei-elf-gcc -flto -o main.o -c main.c
riscv-nuclei-elf-ar rc liblto.a lto.o
riscv-nuclei-elf-gcc  -flto -fuse-linker-plugin main.o -L. -llto -u issue_func -o main.elf

此时就会发现,ar时报警告,最后链接报错

/gcc/bin/riscv-nuclei-elf-ar: lto.o: plugin needed to handle lto object
/gcc/bin/../lib/gcc/riscv-nuclei-elf/9.2.0/../../../../riscv-nuclei-elf/bin/ld: /tmp/main.elf.uPsr4n.ltrans0.ltrans.o: in function `main':
<artificial>:(.text+0xc): undefined reference to `issue_func'
collect2: error: ld returned 1 exit status

问题就是这样,即使用flto选项生成的lib文件会在链接时提示找不到库内的函数,但是曾经在以前的版本gcc时没有这个问题,那么究竟是怎么回事(⊙o⊙)?

资料查找

仔细对比就会发现,在生成的lib文件中存在的符号表不正确,而.o文件则是正确的,那么ar的打包警告就很可疑,警告一番查找在gcc文档中对-flto系列的选项有如下说明:

-fno-fat-lto-objects improves compilation time over plain LTO, but requires the complete toolchain to be aware of LTO. It requires a linker with linker plugin support for basic functionality. Additionally, nm, ar and ranlib need to support linker plugins to allow a full-featured build environment (capable of building static libraries etc). GCC provides the gcc-ar, gcc-nm, gcc-ranlib wrappers to pass the right options to these tools. With non fat LTO makefiles need to be modified to use them.
Note that modern binutils provide plugin auto-load mechanism. Installing the linker plugin into $libdir/bfd-plugins has the same effect as usage of the command wrappers (gcc-ar, gcc-nm and gcc-ranlib).
The default is -fno-fat-lto-objects on targets with linker plugin support.

(原文链接:https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html)
gcc在使用ar处理lto的文件时是需要使用gcc-ar来代替ar的,但为什么有些编译器仍使用ar也可以正确生成lib,那是因为在工具链的$libdir/bfd-plugins路径下包含liblto_plugin.so(liblto_plugin.dll)的动态库来提供给ar,使用插件功能,而有些编译器并没有从libexec路径内拷贝该动态库到$libdir/bfd-plugins路径下。

问题解决

确认了原因,那么解决起来就很容易了,从/gcc/libexec/gcc/riscv-nuclei-elf/9.2.0/liblto_plugin.so拷贝到/gcc/lib/bfd-plugins路径下,再次编译,顺利编译成功,没有任何报错误。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Quard_D

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值