Raspberry Piでクロスコンパイルされたプログラムを実行すると、「ファイルまたはディレクトリが存在しません」と表示されます。

Raspberry Piでクロスコンパイルされたプログラムを実行すると、「ファイルまたはディレクトリが存在しません」と表示されます。

最近ラズベリーパイを購入しました。私のデスクトップにarm's Crossコンパイラ(amd64)を設定してインストールしました。単純な「hello world」プログラムをコンパイルした後。scp ./hello [email protected]:~/hellols -l hello

-rwxr-xr-x 1 david david 6774 Nov 16 18:08 hello

ただし、実行しようとすると、次の結果が表示されます。

david@raspberry-pi:~$ ./hello
-bash: ./hello: No such file or directory

david@raspberry-pi:~$ file hello
hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.26, BuildID[sha1]=0x6a926b4968b3e1a2118eeb6e656db3d21c73cf10, not stripped
david@raspberry-pi:~$ ldd hello 
    not a dynamic executable

答え1

動的実行可能ファイルではない場合は、無効なターゲット用lddにコンパイルされます。

file32ビットARM実行可能ファイルなので、クロスコンパイルしたようです。ただし、「ARM」アーキテクチャが複数あるため、ツールチェーンが正しく構成されていない可能性があります。

crosstool-NGを使用している場合は、.config値を確認してくださいCT_ARCH_ARCH。 Raspberry Piの場合は、「armv6j」1でなければなりません。または少なくとも私にとってこれはうまくいきます。その他の詳細もありますが、私は考えるこれだけで十分です。残念ながら問題が発生した場合は、もう一度ビルドする必要があります。

IMOがクロスコンパイラツールチェーンを機能させるのは面倒でイライラするかもしれませんが、ホストが大きな要素ではないと仮定すると(そうではありません)、この場合に行うことができます。 Crosstool-ngはTLIコンフィギュレータを使用しているため、複数のビルドを試す必要がある場合は、毎回選択内容を記録してどのように機能するかを確認できます。

1私はarmv7がより一般的なアーキテクチャ(多くの携帯電話など)であると考えているので、一般的なARMクロスコンパイラであると思うものを使用している場合は問題になる可能性があります。数字は混乱しています。たとえば、piのプロセッサは次のようになります。ARM11ただし、このページによれば、ARM11プロセッサフ​​ァミリはARMv6アーキテクチャを使用しています。つまり、ARM11はARMv6の実装です。

答え2

問題を特定する方法は?

file cross_compiled_executable

次のようなコンテンツが含まれています。

interpreter /lib/ld-uClibc.so.0

問題は、ファイルがターゲットに存在しないことです。

問題を解決するには?

正しいコンパイラを使用すると、次のことができます。

  • ディスクイメージを作成した人は、クロスコンパイラを提供するか、ビルド方法を正確に知らせる必要があります。クロスツール-ng。 RPIを取得する方法ここに尋ねました
  • 独自のイメージとクロスコンパイラをコンパイルします。ルート構築。これは一般的なQEMUの例。ルート構築RPIサポート
  • ターゲットでデフォルトのコンパイラを使用します。ただし、通常、ターゲットはホストよりはるかに遅く、スペースが限られているため、おそらくこれをしたくないでしょう。

    QEMUなどの機能エミュレータを使用してビルドし、gem5以下のスローマザーボードなどのスロープラットフォームでのみプログラムを実行できます。

亀裂だけではinterpreter十分ではないかもしれません。特に/procこれを使用しようとする場合は-staticさらにそうです(ターゲットカーネルが古すぎるため、必要なインターフェイスが含まれていない可能性があります)。信頼できる唯一の解決策は、正しいツールチェーンを使用することです。

答え3

まず--static、オプションを使用してプログラムをコンパイルしてからテストします。ラズベリーパイで静的に動作する場合

cat "programname" | grep "lib*"
/lib/ld-linux.so.3
libc6.so 

次に、すべてのライブラリがあることを確認します。

私はこう解決しました。私は持っていますが、/lib/ld-linux-armhf-so.3その間には何も/lib/ld-linux.so.3 効果がありませんでした。ln -s

答え4

ターゲットシステムのライブラリは、実行可能ファイルがコンパイルされたホストシステムのライブラリとは異なります。

makeを使用している場合は、CFLAGSとLDGLAGSに--staticオプションを含める必要があります。直接gccを使用している場合は、--staticオプションを使用して実行可能ファイルを移植できます。

関連情報