web-dev-qa-db-ja.com

Eclipseを使用したCプロジェクトでのリンカーエラー

STM32F217IGマイクロコントローラー用のプロジェクトを作成します。

その後、Eclipseと GNU for ARM組み込みGCCクロスコンパイラ をインストールしました。これはCode Sourceryのものではないと思います。ポイントとコードSourceryはありません。

私はそれをやった後、2つのソースファイルだけで本当に小さなプロジェクトを作成しようとしました:test.cとmain.cは両方に書かれているだけです:

#include <stdlib.h>
#include <stdio.h>

int main (void)
{
    printf("Hello, World!");
    return 0;
}

プロジェクトプロパティの行コマンドを変更してGCCをarm-none-eabi-gccに置き換えてから、プロジェクトをコンパイルしようとしました。

自分でメイクファイルを作成しませんでした。 Eclipseで自動作成を使用しました。

建物は問題ないようですが、リンカに関しては、コンソールで次のエラーが発生しました。

make all
'Building target: test3'
'Invoking: Cross GCC Linker'
arm-none-eabi-gcc  -o"test3"  ./main.o ./test3.o

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0x18): undefined reference to `_sbrk'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x20): undefined reference to `_write'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0x18): undefined reference to `_close'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0x1c): undefined reference to `_fstat'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0x18): undefined reference to `_isatty'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x20): undefined reference to `_lseek'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x20): undefined reference to `_read'

collect2: ld returned 1 exit status

make: *** [test3] Erreur 1

インターネットで調べたところ、システムコールの問題である可能性がありました。しかし、このライブラリをLinuxのプロジェクトにどのように追加すればよいかわかりません。

ほんとに?はいの場合、どうすれば修正できますか?そうでない場合、それはどこから来ますか?

誰かが示唆したように、私はCランタイムライブラリを「リンク」しようとしました。 Eclipseでは、2つの解決策があるようです。

まずプロジェクトのプロパティ→C/C++Build設定クロスリンカーlibraries。文字cを追加するだけで、エラーは変わりませんが、-lcコマンドラインの最後:

 make all
'Building target: test3'
'Invoking: Cross GCC Linker'
arm-none-eabi-gcc  -o"test3"  ./main.o ./test3.o   -lc

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0x18): undefined reference to `_sbrk'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x20): undefined reference to `_write'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0x18): undefined reference to `_close'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0x1c): undefined reference to `_fstat'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0x18): undefined reference to `_isatty'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x20): undefined reference to `_lseek'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x20): undefined reference to `_read'

collect2: ld returned 1 exit status
make: *** [test3] Erreur 1

しかし、それが本当にCランタイムライブラリを追加することであるかどうかはわかりません。

次に、プロジェクトプロパティにlibc.aライブラリを追加しました→C/C++ generalPath and symbolsライブラリー、ここに私が得るものがあります(完全に異なる):

make all
'Building target: test3'
'Invoking: Cross GCC Linker'
arm-none-eabi-gcc  -o"test3"  ./main.o ./test3.o   -l"C:/Program\ Files/GNU\ Tools\ ARM\ Embedded/4.6\ 2012q4/arm-none-eabi/lib/armv7-m/libc.a"

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/bin/ld.exe: cannot find -lC:/Program\ Files/GNU\ Tools\ ARM\ Embedded/4.6\ 2012q4/arm-none-eabi/lib/armv7-m/libc.a

collect2: ld returned 1 exit status
make: *** [test3] Erreur 1

その後、まだ機能しませんが、検索するのに良い方法ですか?

ああ、非常に興味深い事実:

デバッグモードでのみエラーが発生しました。私がリリースモードにいる場合、すべてが問題なく、エラーはありません(libc.aを追加する場合を除き、これは良いことではないと思います)。それは、問題が.elfファイルの作成であることを意味していますか?

25
damien

_readme.txt_で次を読むために、リンクしたツールキットを見ました:

このツールチェーンは、Cortex-R/Mベアメタル開発向けに構築および最適化されています。

言い換えれば、このツールチェーンは組み込みシステム用に特別に構成されており、オペレーティングシステムがまったく実行されていない可能性があります。このような場合、提供するシステムはありません。 printf()が記述する標準出力、ファイルシステムなどはありません。これらの基本サービスを使用する場合は、これらの基本サービスを提供するライブラリとリンクする必要があります。

ただし、ツールキットは、これらのすべての基本サービスを提供する_librdimon.a_ライブラリを提供します。このライブラリは、実際には libgloss コンパイルの一部です。リンクする場合は、次のコマンドを試してください。

_arm-none-eabi-gcc --specs=rdimon.specs   -Wl,--start-group -lgcc -lc -lm -lrdimon -Wl,--end-group -o test test.c
_

これは私のPCではうまくリンクしますが、それが本当に欲しいものであるかどうかは別の話です(とにかくprintf()の出力はどこで見られますか?).

チップについては、標準出力をシリアルポートにリダイレクトするか、JTAG経由でデバッグ出力を提供するライブラリを探す必要があります。または、カスタム関数を使用できます。デバッグ出力をprintf()ではなくシリアルコンソールに送信します-あなた次第です。 printf()を使用することに決めた場合は、libglossのドキュメントを読むことをお勧めします。

また、STM32ファミリ用に特別にバンドルされているツールチェーンを探してみることをお勧めします。このすべての基本的なもの(Cライブラリ、リンカースクリプトなど)を適切に構成するには、多少の経験が必要です。

編集:多くの組み込みシステムは、標準のCライブラリを実際には使用せず、ほとんどゼロから始めています。このようにしたい場合は、gcc呼び出しに_-nostdlib_を渡す必要があります。もちろん、printf()のようなものは利用できなくなります。

編集2:別の方法は、newlibなしで標準ライブラリ(libgloss、つまり)を使用し、適切なスタブを提供することですあなたが必要としないもののために。 このチュートリアル に従うことをお勧めします。ここで、__read_と__write_はシリアルポートを介して実装され、他のすべてはスタブ化されます。これはおそらくあなたが本当に望むものです。

29
Code Painters

これは古い質問であることは知っていますが、今日、STM32ボード用にビルドしようとしたときにこれに遭遇しました。私が持っているプロジェクトには、いくつかのリンカースクリプト(具体的にはlibs.ld)があります。これにlibnosys.aのエントリを追加すると、リンカが満たされ、続行できました。

libs.ld:

 GROUP(
   libgcc.a
   libg.a
   libc.a
   libm.a
   libnosys.a
 )
9
Shane

Cプログラムを「myprint.c」として保存し、次のようにコンパイルします。

arm-none-eabi-gcc myprint.c -lc -specs = nosys.specs

エラーはなく、出力は正常です。

6
Peter Teoh

Eclipseプロジェクトのmalloc()およびfree()関数呼び出しにもこのような問題がありました。 Eclipse [+] GNU for ARM組み込みGCCクロスコンパイラ+ STM32CubeMXを使用して、STM32マイクロコントローラー用のファームウェアを作成しました。

欠落している文字列libg.a(*)およびlibnosys.a(*)を[〜#〜] discard [〜#〜].ldのセクションに追加した場合スクリプト、私のプロジェクトは正常にビルドされました。

3

OpenOCDを使用したデバッグ中に、CubeMXを使用してRTOSプロジェクトを作成し、printfを追加し、リンクに関して同じ問題を抱えていました。

Printf( "Hello ARM World!")をtrace_puts( "Hello ARM World!");に置き換え、デバッグコンソールにメッセージを表示しました。 。

0