如何安装适配16位编译的libgcc?x86_64环境编译报错
系统环境
- CPU架构:
x86_64 - 内核版本:
4.15.0-041500-generic
问题场景
我尝试编译一段获取系统内存映射的代码,要求以16位模式编译。执行编译命令:
gcc -m16 smapentry.c -o smap
后出现如下报错:
usr/bin/x86_64-linux-gnu-ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/7/libgcc.a when searching for -lgcc /usr/bin/x86_64-linux-gnu-ld: cannot find -lgcc
目前系统里的64位libgcc能正常支持-m64和-m32模式编译,但-m16模式始终跑不起来,想问下得装哪个版本的libgcc才能支持16位代码编译?
解决思路与方案
其实你不用纠结找特定版本的libgcc——核心问题是GCC的-m16选项本质上不是生成纯16位代码,它只是让编译器生成适配16位运行环境的32位代码(调整指令前缀和地址生成规则),但常规x86_64系统的libgcc根本没有针对这种模式编译的版本,自然找不到。
给你几个实用的解决办法:
1. 跳过标准库依赖编译
如果你的16位代码是类似引导程序这类不需要依赖标准库的程序,可以直接让编译器跳过libgcc和标准库的链接:
gcc -m16 -ffreestanding -nostdlib smapentry.c -o smap
-ffreestanding表示编译独立环境的代码,-nostdlib会禁用标准库和libgcc的自动链接,刚好适配16位代码的场景。
2. 使用i386交叉编译工具链
如果你的代码确实需要libgcc的支持,建议安装针对32位x86的交叉编译工具链,它包含了能适配-m16模式的libgcc版本:
首先安装工具链:
sudo apt install gcc-i686-linux-gnu
然后用这个工具链编译:
i686-linux-gnu-gcc -m16 smapentry.c -o smap
这个工具链的libgcc是针对32位x86架构编译的,配合-m16选项就能生成符合要求的代码,链接器也能顺利找到依赖文件。
3. 手动编译适配16位的libgcc(不推荐)
如果一定要用原生gcc,也可以手动编译支持16位的libgcc,但这个过程需要重新配置GCC编译参数,步骤繁琐且容易出问题,除非你有特殊需求,否则不建议这么做。
另外提醒一句:就算编译成功,现代64位系统也没法直接运行16位代码,你得用QEMU这类虚拟机或者模拟器来测试运行。
内容的提问来源于stack exchange,提问作者BODDU MANOHAR REDDY

