在 binutils 中,您可以在以下位置找到此错误消息bfd/elf32-arm.c
:
“警告:%B 使用 %u 字节 wchar_t 但输出是使用 %u 字节 wchar_t;跨对象使用 wchar_t 值可能会失败”
但是,如果您进一步查看 binutils,您会发现输出的 wchar_t 大小并未在任何地方初始化为 4。那么是什么决定了“输出 wchar_t 大小”呢?实际上,给定的第一个对象ld
初始化输出属性。下一个对象将它们的属性合并到其中。如果你用 gcc/g++ 链接,它会在ld
内部执行,所以试着gcc -v
看看ld
是如何执行的。这将使您深入了解它隐式链接到可执行文件的内部对象文件(除了您自己的)。
例如,与 gcc (eg gcc -v -shared -o libfoobar.so foo.o bar.o
) 链接会导致调用:
ld ... crtbegin_so.o foo.o bar.o crtend_so.o ...
即以下对象实际上是链接的(按顺序):
- crtbegin_so.o(隐式)
- foo.o
- 酒吧.o
- crtend_so.o(隐式)
这是 ld 的作用:
- 输出属性集一开始是空的。
- 合并crtbegin_so.o属性。现在输出属性包含
out_attr[Tag_ABI_PCS_wchar_t] == 4
- 合并foo.o属性。如果 foo.o 是用 构建的
-fshort-wchar
,那么in_attr[Tag_ABI_PCS_wchar_t] == 2
这将导致冲突和您看到的警告。
如果您要在 ld 命令行上交换 crtbegin_so.o 和 foo.o,则会收到以下警告:
ld:警告:android-ndk-r9d/platforms/android-16/arch-arm/usr/lib/crtbegin_so.o 使用 4 字节 wchar_t 但输出是使用 2 字节 wchar_t;跨对象使用 wchar_t 值可能会失败
如您所见,这不是输入与输出不兼容的问题,而是链接在一起的两个目标文件之间(感知到的)不兼容问题。
我们对于它可以做些什么呢?
截至 2008 年,ld
支持--no-wchar-size-warning
标志来禁止此警告。但正如你所说,不分青红皂白地压制警告有其缺点。
您可以使用 -fshort-wchar 重建您的工具链。
Tag_ABI_PCS_wchar_t
如果你真的相信它们是不可知的,你可以从你的内部 gcc 对象二进制文件sizeof(wchar_t)
中去除标签。这可能比重建工具链更容易。为此,您可以使用我曾经编写的这个实用程序。(您可能需要解压缩 libgcc.a,更改其目标文件并重新打包。)