8

協力したいソフトウェアのベンダーがいます。彼らは、IAR Embedded Workbench を使用してのみコンパイルできるコード ベースを持っています (私の知る限り、彼らのコードは GCC でコンパイルされません)。残念ながら、彼らのハードウェアはソフトウェア スタックでしか動作しないため、それを使用するかどうかについての選択肢はありません。.aこのコードは、ARM Cortex-M4 CPU 用にコンパイルされた静的ライブラリ ファイル (および付随するヘッダー) として配布されます。(彼らはソースを配布したくありません。) この議論のために、それを と呼びましょうevil_sw_stack.a

このコードを使用したいのですが、IAR ライセンスを持っておらず、IAR に関する専門知識もありません。GCCを使いたいです。

GCC がリンクできる静的ライブラリを IAR で作成する方法はありますか? そのようなバイナリを生成するために、ベンダーはどのようなコンパイラ オプションを使用する必要がありますか?
(結果のバイナリの ABI を何らかの方法で指定し、GCC を満たす設定に設定できると思います。)

GCCの使用例

彼らのデフォルトのソフトウェア スタックは GCC に非常に適しています。一般に、次のものがあれば、単純なサンプル コードをコンパイルできます。

  • startup_(devicename).S: GCC 固有のアセンブリ ファイル
  • system_(devicename).c
  • (devicename).ld: リンカー スクリプト
  • 特定のデバイス用のいくつかのヘッダー ファイル

たとえば、次のような単純な例をコンパイルできます。

$ arm-none-eabi-gcc helloworld.c startup_(devicename).S system_(devicename).c -T (devicename).ld -o helloworld -D(devicename) -I. -fno-builtin -ffunction-sections -fdata-sections -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mcpu=cortex-m4 -mthumb -mno-sched-prolog -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group

ここまでは順調ですね。警告もエラーもありません。

スタティック ライブラリの使用方法

この議論のために、それを と呼びましょうevil_sw_stack.a
これは私がそれを使用しようとした方法です:

$ arm-none-eabi-gcc evil_sw_stack.a helloworld.c startup_(devicename).S system_(devicename).c -T (devicename).ld -o helloworld -D(devicename) -I. -fno-builtin -ffunction-sections -fdata-sections -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mcpu=cortex-m4 -mthumb -mno-sched-prolog -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group

残念ながら、これは で定義されている一連の関数の複数の定義について不平を言っていますsystem_(devicename).c。たぶん彼らはそれをこのライブラリに誤ってコンパイルしたのでしょうか? それとも、IAR がこのようにコンパイルしただけなのでしょうか? ここでsystem_(devicename).c、GCC コマンド ラインからファイルを削除して単純に.aファイルにリンクしようとすると、次のエラーが発生します。

/usr/lib/gcc/arm-none-eabi/5.2.0/../../../../arm-none-eabi/bin/ld: warning: thelibrary.a(startup_chipname.o) uses 2-byte wchar_t yet the output is to use 4-byte wchar_t; use of wchar_t values across objects may fail
undefined reference to `__iar_program_start'
undefined reference to `CSTACK$$Limit'
undefined reference to `__iar_program_start'

ファイルを突き刺しreadelfてもどこにも行きません:

$ readelf -h evil_sw_stack.a 
readelf: Error: evil_sw_stack.a: did not find a valid archive header

興味深いことに、これはどこかに行き着いているようです:

$ arm-none-eabi-ar x evil_sw_stack.a

今、私は ELF ヘッダーを持っているオブジェクト ファイルの束を持っていますreadelf.は間違いです。

これも機能します:

$ arm-none-eabi-objdump -t evil_sw_stack_objfile.o

ここで問題は、GCC を使用してこれらのオブジェクト ファイルを自分のアプリケーションにコンパイルしようとしても安全かということです。this other SO questionによると、オブジェクトファイル形式には互換性がありません。

起動コードが間違ってライブラリにコンパイルされていると思います。削除できます:

$ arm-none-eabi-ar d evil_sw_stack.a startup_(otherdevicename).o
$ arm-none-eabi-ar d evil_sw_stack.a system_(otherdevicename).o

これで、evil_sw_stack.a文句を言わずに gcc が入力として受け入れることができる が得られました。

ただし、まだ気になることが 1 つあります。スタティック ライブラリの代わりにオブジェクト ファイルを使用すると、次の警告が表示されます。

/usr/lib/gcc/arm-none-eabi/5.2.0/../../../../arm-none-eabi/bin/ld: warning: evil_objfile.o uses 2-byte wchar_t yet the output is to use 4-byte wchar_t; use of wchar_t values across objects may fail
/usr/lib/gcc/arm-none-eabi/5.2.0/../../../../arm-none-eabi/bin/ld: warning: evil_objfile.o uses 32-bit enums yet the output is to use variable-size enums; use of enum values across objects may fail

したがって、は (IAR に相当する)およびevil_sw_stack.aでコンパイルされたようです。コマンド ラインで使用する場合、GCC はこれについて文句を言いませんが、ライブラリから抽出したオブジェクト ファイルを使用しようとすると文句を言います。これについて心配する必要がありますか?-fno-short-enums-fshort-wcharevil_sw_stack.a

私は自分のコードで使用wchar_tしていないので、問題はないと思いますが、コードとライブラリの間で列挙型を渡したいと思います。

アップデート

リンカーは文句を言いませんが、静的ライブラリから実際にいくつかの関数を呼び出すと機能しません。その場合、リンカーを呼び出すときにライブラリを正しい順序で配置してください。この質問に対する受け入れられた回答によると、それらは依存関係の逆順である必要があります。これを行った後でも、IAR がらくたを見逃しています。

undefined reference to `__aeabi_memclr4'
undefined reference to `__aeabi_memclr'
undefined reference to `__aeabi_memmove'
undefined reference to `__aeabi_memset4'
undefined reference to `__aeabi_memset'
undefined reference to `__iar_vla_alloc2'
undefined reference to `__iar_vla_dealloc2'
undefined reference to `__aeabi_memclr4'

__aeabi関数が で定義されていることがわかりましたが、libgcclibgcc にもリンクしていますが、 の定義はlibgcc内の関数には十分ではないようですevil_sw_stack.a

編集:いくつかのグーグルで調べた後、これらの特定の機能arm-none-eabi-gccをサポートしていないようです。この問題__aeabiを見てください。

とにかく、ARM のランタイム ABI ドキュメントを見た後、欠落している__aeabi関数は、標準の C ライブラリの同等物を使用して簡単に実装できます。__iar_vla_alloc2しかし、どのように動作するのか、また動作するべきなのかよくわから__iar_vla_dealloc2ず、それらに関するドキュメントをオンラインで見つけることができませんでした。私が見つけた唯一のことは、VLAが「可変長配列」を意味することです。

したがって、チップ ベンダーがこれらのシンボルを使用しないように静的ライブラリをコンパイルできない限り、これは機能しないようです。そうですか?

免責事項

ベンダーが誰であるか、またどの製品を扱っているかは明らかにしたくありません。彼らは、これが適切に機能しないことを誇りに思っておらず、私にそうしないように頼んだ. 私は彼らの信用を傷つけるのではなく、助けるためにこの質問をしています.

4

0 に答える 0