binutils では、このエラー メッセージは次の場所にありますbfd/elf32-arm.c
。
「警告: %B は %u-byte wchar_t を使用しますが、出力は %u-byte 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
- bar.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 値を使用すると失敗する場合がある
ご覧のとおり、これは入力と出力の非互換性の問題ではなく、リンクされた 2 つのオブジェクト ファイル間の (認識された) 非互換性の問題です。
私たちはそれについて何ができますか?
2008 の時点で、この警告を抑制するフラグがld
サポートされています。--no-wchar-size-warning
しかし、あなたが言ったように、警告を無差別に抑制することには欠点があります。
-fshort-wchar を使用してツールチェーンを再構築できます。
Tag_ABI_PCS_wchar_t
それらが非依存的であると本当に信じている場合は、内部 gcc オブジェクト バイナリからタグを取り除くことができますsizeof(wchar_t)
。これは、ツールチェーンを再構築するよりも簡単かもしれません。そのために、私がかつて書いたこのユーティリティを使用できます。(libgcc.a を解凍し、そのオブジェクト ファイルを変更して再パックする必要がある場合があります。)