web-dev-qa-db-ja.com

Raspberry Piでクロスコンパイルされたプログラムを実行すると、「そのようなファイルやディレクトリはありません」

最近Raspberry Piを購入しました。私はすでにそれを構成しており、自分のデスクトップ(AMD64)にarm用のクロスコンパイラーをインストールしています。単純な "hello world"プログラムをコンパイルしてから、scp ./hello [email protected]:~/helloを使用してデスクトップからPiにコピーしました。 Piにログインした後、ls -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
8
David Martínez

lddが動的実行可能ファイルではないと表示する場合は、間違ったターゲット用にコンパイルされています。

fileは32ビットARM実行可能ファイルです。ただし、「ARM」アーキテクチャが複数あるため、ツールチェーンが構成されている可能性があります。間違って。

Crosstool-NGを使用している場合は、.configの値はCT_Arch_ARCH。 Raspberry Piの場合、「armv6j」である必要があります1 -または、少なくとも、それが私にとって効果的です。他にも詳細はありますが、私は十分だと思います。残念ながら、それが間違っている場合は、再構築する必要があります。

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

1 私はarmv7がはるかに一般的なArch(多くの電話など)であると考えているため、単に何かを使用している場合は、一般的なARMクロスコンパイラであると考えます。それがおそらく問題です。これらの数値たとえば、piのプロセッサは ARM11 ですが、(そのページのとおり)ARM11ファミリのプロセッサはARMv6アーキテクチャを使用しています。つまり、ARM11はARMv6の実装です。

5
goldilocks

問題を特定する方法

file cross_compiled_executable

次のようなものが含まれています:

interpreter /lib/ld-uClibc.so.0

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

問題を解決する方法は?

適切なコンパイラーを使用します。

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

    また、QEMUなどの機能エミュレーターを使用してビルドし、プログラムを低速のプラットフォーム(例: gem5または遅いボード。

interpreterをハックアップするだけでは十分ではない可能性があります。特に、プログラムとターゲットlibc、またはプログラムとカーネルインターフェイス(syscalls、/procなど)-static(ターゲットカーネルが古すぎて、必要なインターフェースが含まれていない可能性があります)。唯一の堅牢なソリューションは、正しいツールチェーンを使用することです。

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

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

0
Kevin Parker