yamada_masa
2024年7月6日 1時03分
Armdilllo-840で作成したC言語プログラムをX2で動作させるためクロスコンパイルを試みています。
まず、シンプルなhellow woldプログラムでATDE9でクロスコンパイルを試してみましたが、Armadillo-X2で実行できませんでした。
コンテナ開発が推奨されていることは承知していますがクロスコンパイルすることはできないでしょうか。
●ATDE9でのクロスコンパイルと実行結果
arm-linux-gnueabihf-gcc 、aarch64-linux-gnu-gcc でクロスコンパイル
aarch64-linux-gnu-gcc でコンパイルしたバイナリが動作している。
arm64向けにビルドされているおりATDE9上では動作しない認識でしたが誤っていますでしょうか。
atmark@atde9:/mnt/hgfs/shared_atde9/hello$ arm-linux-gnueabihf-gcc -o eabihf.out hello.c atmark@atde9:/mnt/hgfs/shared_atde9/hello$ ls eabihf.out hello.c atmark@atde9:/mnt/hgfs/shared_atde9/hello$ aarch64-linux-gnu-gcc -o aarch64.out hello.c atmark@atde9:/mnt/hgfs/shared_atde9/hello$ ls aarch64.out eabihf.out hello.c atmark@atde9:/mnt/hgfs/shared_atde9/hello$ ./eabihf.out arm-binfmt-P: Could not open '/lib/ld-linux-armhf.so.3': No such file or directory atmark@atde9:/mnt/hgfs/shared_atde9/hello$ ./aarch64.out hellow world x2
●Armdillo-X2での実行結果
not found とされる原因をご教授いただけると助かります。
armadillo:~/hello$ ls -al total 28 drwxr-sr-x 2 atmark atmark 100 Jul 6 00:29 . drwxr-sr-x 1 atmark atmark 120 Jul 6 00:29 .. -rwxr-xr-x 1 atmark atmark 9416 Jul 6 00:26 aarch64.out -rwxr-xr-x 1 atmark atmark 8264 Jul 6 00:26 eabihf.out -rwxr-xr-x 1 atmark atmark 66 Jul 6 00:26 hello.c armadillo:~/hello$ ./eabihf.out -ash: ./eabihf.out: not found armadillo:~/hello$ ./aarch64.out -ash: ./aarch64.out: not found armadillo:~/hello$
●hellow woldプログラム
#include<stdio.h> void main() { printf("hellow world x2\n"); }
コメント
yamada_masa
yamada_masaです。
古賀さん
休日にありがとうございます。
ATDE9上でコンパイルしたバイナリをArmadillo-x2上で実行することができました。
提示いただいた参考URLで下記のコメントがありましたので、ATDE9上にalpineのコンテナを作成しコンパイルしました。
https://armadillo.atmark-techno.com/forum/armadillo/15163#comment-13067
>ATDE で podman を使って docker.io/arm64v8/alpine のコンテナで(クロスではなくエミュレーション)のビルドもできます
Dockerfileや実行手順は下記となります。
●Dockerfile
#--------コンテナイメージA作成------------ #使用するコンテナイメージを記載する(A6Eの場合はarch=armv7と指定する) #実際に使用するArmadillo本体で実行する場合は${arch}は省略も可能 #ここではコンテナイメージAを"tmp_image"とする ARG arch=arm64v8 #FROM docker.io/${arch}/debian:bullseye As tmp_image FROM docker.io/${arch}/alpine:3.19 As tmp_image #コンテナ内にファイルをコピーする #ここではDockerfileと同階層にある”hello.c”をコンテナ内の”/root/”にコピー COPY hello.c /root/ #コンテナ内で実行するコマンドを記載する #ここではコンパイルツールをインストールし、コンパイルまで行う #RUN apt update && apt upgrade -y RUN apk update && apk upgrade #RUN apt install build-essential -y RUN apk add alpine-sdk RUN cd && gcc -o hello.exe hello.c
●コンテナイメージのビルドとコンテナの起動
コンテナ起動時にホスト側にhello.exeを取り出すために-vオプションでホスト側のディレクトリ/home/atmark/work/disk01をコンテナの/mntにマウントする。
atmark@atde9:~/work/dockerfile_alpinegcc$ pwd /home/atmark/work/dockerfile_alpinegcc atmark@atde9:~/work/dockerfile_alpinegcc$ ls Dockerfile hello.c atmark@atde9:~/work/dockerfile_alpinegcc$ podman build -t localhost/alpinegcc:1.0.0 . atmark@atde9:~/work/dockerfile_alpinegcc$ podman run -it -v /home/atmark/work/disk01:/mnt localhost/alpinegcc:1.0.0
●Armadillo-x2実行結果
FTPで実行ファイルを実機に転送し実行。
armadillo:~$ ./hello.exe hellow world x2
koga
2024年7月6日 6時22分
アットマークテクノの古賀(休日モード)です。
yamada_masaさん:
>Armdilllo-840で作成したC言語プログラムをX2で動作させるためクロスコンパイルを試みています。
>
>まず、シンプルなhellow woldプログラムでATDE9でクロスコンパイルを試してみましたが、Armadillo-X2で実行できませんでした。
>コンテナ開発が推奨されていることは承知していますがクロスコンパイルすることはできないでしょうか。
可能です。ただし、ATDE9 (: Debian) 上で普通にクロスコンパイルすると、X2 の OS である Armadillo Base OS (ABOS) とは標準 C ライブラリが違うため、クロスコンパイルしてできたバイナリが動作しないのです。
Debian の標準 C ライブラリは、一般的な Linux ディストリビューションで使われている glibc ですが、ABOS では musl libc であり、glibc の共有ライブラリは配置されていません。
https://ja.wikipedia.org/wiki/Musl
そのため、glibc をリンクライブラリとしてビルドされた実行ファイルは Armadillo Base OS で動作しない、というわけです。
ATDE9 で、ABOS 上で直接動作する実行ファイルをビルドする方法については、このフォーラムで過去に何度か質問を頂いています。以下の質問スレッドのコメントをご覧になってみてください:
C言語での開発について
https://armadillo.atmark-techno.com/index.php/forum/armadillo/16379#com…
ライブラリが見つからないエラー
https://armadillo.atmark-techno.com/forum/armadillo/14009#comment-12363
クロスコンパイルした実行ファイルをArmadilloで実行できない
https://armadillo.atmark-techno.com/forum/armadillo/15163#comment-13067
ということで、以下の質問については、「実行ファイルが起動時リンクする glibc の共有ライブラリが、ABOS に存在しないから」というのが回答です:
>●Armdillo-X2での実行結果
>not found とされる原因をご教授いただけると助かります。
次に、aarch64-linux-gnu-gcc でクロスコンパイルした実行ファイルが ATDE9 で動作する件ですが、これは、「aarch64 の QEMU ユーザーモードエミュレーションで実行されるから」というのが回答です。
>●ATDE9でのクロスコンパイルと実行結果
>arm-linux-gnueabihf-gcc 、aarch64-linux-gnu-gcc でクロスコンパイル
>aarch64-linux-gnu-gcc でコンパイルしたバイナリが動作している。
>arm64向けにビルドされているおりATDE9上では動作しない認識でしたが誤っていますでしょうか。
以下のようにすると、ATDE9 上で動作しなくなります:
つまり、/usr/libexec/qemu-binfmt/aarch64-binfmt-P が存在しない状態で起動した ATDE9 では、aarch64-linux-gnu-gcc でクロスビルドしたバイナリは、(期待通り)動作しません。
/usr/libexec/qemu-binfmt/aarch64-binfmt-P が存在する状態で起動した場合は、このファイルにより、aarch64 用のバイナリが aarch64 の QEMU ユーザーモードエミュレーションで実行されるので、動作するのです。
>
>
>●hellow woldプログラム
ここで、/usr/libexec/qemu-binfmt/aarch64-binfmt-P を ls -l で見てみると、このファイルが /usr/bin/qemu-aarch64-static へのシンボリックリンクであることが分かります。/usr/bin/qemu-aarch64-static、つまり aarch64 の QEMU ユーザーモードエミュレータが aarch64 用のバイナリを実行した時に割り当てられるのは、Linux カーネルの binfmt_misc という機能によるものです:
https://en.wikipedia.org/wiki/Binfmt_misc
https://qiita.com/lnznt/items/c729d80d0800a8f78298
上記の hellow world プログラムで、printf() の後に sleep(10) などでスリープするようにしてみてください。
それを aarch64-linux-gnu-gcc でクロスビルドしてできたバイナリを、バックグラウンドで実行して ps T でプロセス表示すると、バイナリが /usr/libexec/qemu-binfmt/aarch64-binfmt-P (上述した通り、実体は /usr/bin/qemu-aarch64-static)によって実行されているのが分かると思います。
この QEMU ユーザーモードエミュレーションについては、以下のページも参考になるかと思います:
Debian の qemu-user-binfmt パッケージ
https://packages.debian.org/bullseye/qemu-user-binfmt
QemuUserEmulation
https://wiki.debian.org/QemuUserEmulation
QEMUのもうひとつの使い方: ユーザーモードエミュレーションとbinfmtとchrootの組み合わせ
http://blog.kmckk.com/archives/2342452.html
以上、参考になりましたら幸いです。