バイナリ単体で動作するGNU nanoを作ります。
GNU nano とは
軽量なスクリーンエディタです。
vimやemacsのように高機能ではありませんが、小さな編集のみ行う場合には十分な機能を有しています。
操作にクセが少ないので、初めてスクリーンエディタを使う方でも扱いやすいかと思います。
ref. nano - ArchWiki
静的リンクされたnano
パッケージマネージャなどで手に入るnanoは大抵、依存するライブラリをdynamic linkして動作するものであり、nanoのバイナリファイルだけをどこかに持っていったとしても高い確率で動作しません。
かといって、プロダクション環境のサーバに依存ライブラリと一緒にゴチャッとインストールするのも気が引けるものです。
そこで、すべての依存ライブラリを静的リンクしてしまい、単一ファイルで動作する可搬性の高いnanoバイナリが作りたい!というモチベーションがあります。
ビルド手順
ビルド環境の立ち上げ
Dockerで立ち上げたコンテナ上で作業します。イメージはalpine:edge
です1。
Alpine Linuxは軽量なコンテナイメージとして有名ですが、デフォルトで採用されているmusl libcは静的リンクに最適化された軽量なlibcであり、今回の目的にもマッチしています。
docker run -it --name builder alpine:edge
以降はコンテナ内での作業になります。
必要なパッケージのインストール
以下のパッケージが必要ですので、インストールします。
apk add gcc make groff linux-headers musl-dev ncurses-dev ncurses-static zlib-dev zlib-static
ncursesとzlibはそれぞれ、nanoが依存するライブラリであり、静的リンク用のファイルを提供するパッケージが用意されています。
(末尾が-static
のもの。)
libmagic.a
のビルド
libmagicは、nanoがファイルの種別判定に用いるライブラリです。
このlibmagicは、file-devパッケージに含まれていますが、静的リンク用のバイナリは提供されていません!
ということで、自前でビルドする必要があります。libmagicのソースコードは、ファイルの種類を判定するコマンドfile(1)
のソースコードに含まれているので、これをビルドします。
cd /
wget ftp://ftp.astron.com/pub/file/file-5.37.tar.gz -O - | tar zxvf -
cd file-5.37
./configure CFLAGS="-Ofast" --prefix=/usr --enable-static
make -j8
make install
./configure
時に--enable-static
オブションをつけることで、静的リンク用のバイナリlibmagic.aが生成されるようになります。
nano
のビルド
これで材料が揃ったので、nanoをビルドできます。
LDFLAGS
に-static
を指定して静的リンクします。
cd /
wget https://www.nano-editor.org/dist/v4/nano-4.5.tar.gz -O - | tar zxvf -
cd nano-4.5
./configure CFLAGS="-Ofast" LDFLAGS="-static -no-pie -s" LIBS="-lz" --prefix=/usr
make -j8
make install
確認してみます。
# file /usr/bin/nano
/usr/bin/nano: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, with debug_info, not stripped
# ldd /usr/bin/nano
/lib/ld-musl-x86_64.so.1: /usr/bin/nano: Not a valid dynamic program
# ls -lha /usr/bin/nano
-rwxr-xr-x 1 root root 793.8K Oct 7 17:05 /usr/bin/nano
できてる!
当たり前ですが、全部入りなので若干バイナリサイズが大きいですね。
後処理
コンテナから抜けて……
exit
ビルドしたnanoをホストマシンに持ってきます。ビルドに使ったコンテは不要なので、削除。
exit
docker cp builder:/usr/bin/nano .
docker rm builder
ホストマシンでもちゃんと動作しています。
$ ./nano --version
GNU nano, version 4.5
(C) 1999-2011, 2013-2019 Free Software Foundation, Inc.
(C) 2014-2019 the contributors to nano
Email: nano@nano-editor.org Web: https://nano-editor.org/
Compiled options: --disable-nls --enable-utf8
完成
今回ビルドしたnanoを以下においておきました。自己責任でご利用ください。
https://www.dropbox.com/s/a0xmtaqy4jvb6nb/nano?dl=0
便利な機能を使おうとすると他に必要なファイルがあったりする(例えば今回無効になっているNative Language SupportやSyntax Highlightingなど)のですが、基本的な機能は一通り利用できるバイナリが生成できました。
-
edgeバージョンを用いるのは、後ほどインストールする
zlib-static
が現行の最新バージョンv3.10では提供されていないからです。 ↩