Linuxコマンドをコンパイルしてみる(クロスコンパイルの練習)
Linuxコマンドをコンパイルしてみる(クロスコンパイルの練習)
クロスコンパイルの練習例として、MIPS CPUのLinux上で動作するプログラムをUbuntu上で作成してみます。
ハンズオン等だと、いつもなら使えるLinuxコマンドが組み込み機器では無いことが多く、困ってしまう場合もあります。
今回は、そのような場合を想定した例になります。
ご注意 :
1)この手順での動作保証は一切しません、ご了承ください。
実行する組み込み用ハードウェア、それぞれに適した環境が必要になるため。
2)こちらの記事で紹介した環境を利用しますので、記事を見て環境を用意ください。
Mac上で動作するVirtualBoxのUbuntu上でGccクロスコンパイル環境をDockerで構築
Dcckerの起動
$ sudo docker start gcc-ubuntu
$ sudo docker exec -it gcc-ubuntu /bin/bash
Linuxコマンドのソースコード
今回はsleepenhコマンドを例とします。
探しやすかったので、Debianから持ってきます。これで良いのかはわかりません!
参考:コマンドが含まるパッケージを探す方法(Ubuntuでの例)
コマンドが【有る】マシンで実行してください。
root@af48c1a975a2:~# which bash # コマンドの場所を確認
/bin/bash
root@af48c1a975a2:~# dpkg --search /bin/bash # dpkgで調べられる
bash: /bin/bash
「bash」パッケージに/bin/bashコマンドが含まれることがわかります。
ソースコードを入手する
パッケージをソースコードで入手
root@af48c1a975a2:~/dev# mkdir sleepenh # 作業ディレクトリを作成
<docker環境でのファイルの取得や転送方法は、各自環境に合わせて実施ください 省略>
sleepenh-master.zip を手に入れた
root@af48c1a975a2:~/dev/sleepenh# unzip sleepenh-master.zip
root@af48c1a975a2:~/dev/sleepenh# cd sleepenh-master
コンパイルする
Makefaileのままコンパイルするとクロスコンパイルにならないので、Makefileを修正します。
root@af48c1a975a2:~/dev/sleepenh/sleepenh-master# vi Makefile
修正箇所は 「CC =」の場所、gcc を mips-linux-gnu-gcc に変更します。
これで、PCでMIPS用のsleepenhをコンパイルできます。(クロスコンパイル)
Q ?= @
ifneq ($(Q),@)
Q :=
endif
CC = mips-linux-gnu-gcc
CFLAGS = -std=gnu11 -Wall -Wextra -O2 $(EXTRA_CFLAGS)
<< 以下省略 >>
makeします
root@af48c1a975a2:~/dev/sleepenh/sleepenh-master# make
/bin/sh: 1: git: not found
mips-linux-gnu-gcc -std=gnu11 -Wall -Wextra -O2 -DVCSVERSION='' sleepenh.c -o sleepenh
gzip -9 < sleepenh.1 > sleepenh.1.gz
root@af48c1a975a2:~/dev/sleepenh/sleepenh-master# ls
Makefile Makefile.org changelog debian sleepenh sleepenh.1 sleepenh.1.gz sleepenh.c
sleepenh がコンパイルできました。
ダイナミックリンク と スタティックリンク
プログラムを簡単に書くためには、用意されているライブラリを活用することが大事です。
コマンド等でも多く使われています。
このとき、PCやサーバであれば、ライブラリの不具合があればライブラリだけ更新されるのが便利です。
そのため、プログラムからは、動的にライブラリを参照する(ダイナミック リンク)ようにコンパイルするのが普通です。
ただ、組み込み環境などでは、ライブラリが無い、バージョンが揃っていないなど様々な環境でも動作すると便利です。
そのため、参照するライブラリを固定してしまうために、実行バイナリにライブラリを組み込んだ形(スタティック リンク)でコンパイルし、外部環境に左右されないようにすることがあります。
gcc に -static オプションを付加してコンパイルすると「スタティック リンク」、付加しないと「ダイナミック リンク」になります。
作成できたファイルの情報を確認
実際に作成できたsleepenhコマンドを確認してみます。
root@af48c1a975a2:~/dev/sleepenh/sleepenh-master# file sleepenh
sleepenh: ELF 32-bit MSB executable, MIPS, MIPS-I version 1 (SYSV), dynamically linked, interpreter /lib/ld., for GNU/Linux 3.2.0, with debug_info, not stripped
MIPS用( MIPS, MIPS-I version 1 (SYSV) )で、ダイナミック リンク( dynamically linked )の実行ファイルができたことがわかります。
ダイナミック リンクですから、動作環境に依存してしまいます。
場合によっては参照するライブラリが無い可能性もあります。
スタティック リンクでコンパイルする
そこで、スタティック リンクでコンパイルしてみます。
後で比較できるように、ディレクトリごとコピーして、準備します。
root@af48c1a975a2:~/dev/sleepenh# cd ~/dev/sleepenh/
root@af48c1a975a2:~/dev/sleepenh# cp -r sleepenh-static sleepenh-static
root@af48c1a975a2:~/dev/sleepenh# cd sleepenh-static
root@af48c1a975a2:~/dev/sleepenh/sleepenh-static# make clean #掃除
スタティック リンクでコンパイルするため、Makefileを修正します。
root@af48c1a975a2:~/dev/sleepenh/sleepenh-static# vi Makefile
修正箇所は 「CFLAGS =」の場所に「 -static 」を追加します。
これで、PCでMIPS用のsleepenhをスタティック リンクでコンパイルできます。(クロスコンパイル)
CFLAGS = -std=gnu11 -Wall -Wextra -O2 $(EXTRA_CFLAGS)
CFLAGS = -std=gnu11 -Wall -static -Wextra -O2 $(EXTRA_CFLAGS)
Q ?= @
ifneq ($(Q),@)
Q :=
endif
CC = mips-linux-gnu-gcc
CFLAGS = -std=gnu11 -Wall -static -Wextra -O2 $(EXTRA_CFLAGS)
<< 以下省略 >>
makeします
root@af48c1a975a2:~/dev/sleepenh/sleepenh-static# make
/bin/sh: 1: git: not found
mips-linux-gnu-gcc -std=gnu11 -Wall -static -Wextra -O2 -DVCSVERSION='' sleepenh.c -o sleepenh
gzip -9 < sleepenh.1 > sleepenh.1.gz
root@af48c1a975a2:~/dev/sleepenh/sleepenh-master# ls
Makefile Makefile.org changelog debian sleepenh sleepenh.1 sleepenh.1.gz sleepenh.c
sleepenh がコンパイルできました。
作成できたファイルの情報を確認(スタティック リンクになったかどうか)
実際に作成できたsleepenhコマンドを確認してみます。
sleepenh: ELF 32-bit MSB executable, MIPS, MIPS-I version 1 (SYSV), statically linked, for GNU/Linux 3.2.0, with debug_info, not stripped
MIPS用( MIPS, MIPS-I version 1 (SYSV) )で、スタティック リンク( statically linked )の実行ファイルができたことがわかります。
スタティック リンクであれば、動作環境に依存せず動作します。
場合によっては参照するライブラリが無い可能性もありますが、問題ありません。
このスタティック リンクでコンパイルした方を、MIPS Linuxの装置に持っていき、動作試験をしてみてください。
Author And Source
この問題について(Linuxコマンドをコンパイルしてみる(クロスコンパイルの練習)), 我々は、より多くの情報をここで見つけました https://qiita.com/tagucchan/items/c3e2990e82c87e1dc7d5著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .