"When in Rome, do as the Romans do."
初めまして、今年4月に入社したHirosakiです。
前は携帯事業機関システムの開発をしておりました。
当時はJava一本でしたが、入社してから様々な言語に触れる機会が増えました。
Python、CおよびC++、CUDA(CUDA C、PyCUDA)、LISP(!)......などなど。
今回は中でもC言語における開発時に詰まった
「コンパイル」の話をしたいと思います。
事の始まりは「GPU端末で開発してDRIVE PX2で実行しよう!」と
考えたところからでした・・・
①簡単なHello WorldプログラムをC言語にて作成
②GPU端末上でコンパイル
③実行ファイルをDRIVE PX2へ転送
①は割愛し②まで終わった状態が以下の画像。
gcc -E HelloWorld.c >> HelloWorld_Pre.c
gcc -S HelloWorld_Pre.c
as -o HelloWorld.o HelloWorld_Pre.s
gcc -o HelloWorld HelloWorld.o
このような操作を実行。
緑字のファイル名で表示されている実行ファイルまで作成します。
ちなみに各操作について簡単にまとめると・・・
○プリプロセス (マクロの展開、includeなどのディレクティブ処理)
gcc -E [ファイル名].c
or
gcc -E [ファイル名].c >> [プリプロセス内容が記述されたファイル名].c
※プリプロセス後の状態をファイルとして出力する必要はなく、今回は明示的に出力しています。
○コンパイル(アセンブラ変換。拡張子.sのファイルが出力される)
gcc -S [ファイル名].c
or
gcc -E [ファイル名].c >> [プリプロセス内容が記述されたファイル名].c
gcc -S [プリプロセス内容が記述されたファイル名].c
※プリプロセス手順をせずいきなりコンパイルすることも可能。
○アセンブル(バイナリで記述されているオブジェクトファイルを生成)
as -o [ファイル名].o [ファイル名].s
(ファイル名を指定しない場合はデフォルトファイル名
○リンク(実行可能ファイルを生成する)
gcc -o [ファイル名] [ファイル名].o
段階的に操作せず一気に実行可能ファイル生成まで行う操作もあります。
gcc -o [ファイル名] [ファイル名].c
いざ転送。
(赤がGPU端末、青がDRIVE PX2です)
無事に転送が完了しました。
いよいよ実行。
_人人人人人人人人人人人人人人人人人人人人人人_
>cannot execute binary file: Exec format error<
 ̄YYYYYYYYYYYYYYYYYYYYYY ̄
エラー発生。
形式違うから実行できません、だそうです。
ここで先程アセンブル時に生成したオブジェクトファイルを見てみます。
同様の操作で転送先でアセンブルして生成ファイルを比較します。
下線部、違っていますね。
転送元はx86-64ですが、転送先はARM aarch64です。
コンパイル設定も見てみます。
GPU端末(転送元)
$ file /bin/ls
/bin/ls: ELF 64-bit LSB executable,
x86-64,
version 1 (SYSV),
dynamically linked (uses shared libs),
for GNU/Linux 2.6.24,
BuildID[sha1]=8d0966ce81ec6609bbf4aa439c77138e2f48a471,
stripped
DRIVE PX2(転送先)
$ file /bin/ls
/bin/ls: ELF 64-bit LSB executable,
ARM aarch64,
version 1 (SYSV),
dynamically linked,
interpreter /lib/ld-linux-aarch64.so.1,
for GNU/Linux 3.7.0,
BuildID[sha1]=f527cc1407593140220d53f85225fe8030bee7b1,
stripped
機械語が何であるか、というアーキテクチャが違っている状態になります。
英語の説明書作ったけど相手はフランス語しか読めないので伝わってないような状況です。
なので、相手が読める言語で書いてあげる必要があります。
郷に入っては郷に従え、ですね。
コンパイル操作で使用してきたgccコマンドを対応するものに変更します。
今回は「ARM AArch64」で実行できるファイルを作成しなければならないので、
「aarch64-linux-gnu-gcc」を使います。
画像下段、別の実行ファイルが生成されていることが確認できます。
新たに生成した実行ファイルを転送し...
実行......できました!
というわけで、今回はコンパイル作業の注意についてのお話でした。