前回はリンクの手前で止める-cオプションでした。今回はリンクするのだけれど、普段あまり使わない「スタティック・リンク」の -static オプションです。普段のベアメタルな組み込み開発なら「スタティック・リンク」ですが、わざわざオプション付けたりしないしな~。使う局面は極めて限定的かと。知らんけど。
※「オプション沼」投稿順 index はこちら
※動作確認に Windows11 WSL2上のUbuntu 20.04 LTS を使用しています。
今回の実験につかうソース
以下の別シリーズ記事で作成したものです。
ソフトな忘却力(27) MPFR、the Multiple Precision Floating-Point Reliable Library
定番のライブラリMPFRを使って2の平方根の値を「ちょいと桁数多めに」計算してみるだけのもの。強力なMPFRとGMPにかかればそんな多倍長精度の計算など朝飯前だと。短いものなのでソース、再掲しておきます。
#include <stdio.h> #include <gmp.h> #include <mpfr.h> int main(void) { mpfr_t r2, arg2; mpfr_init2(arg2, 4096); mpfr_set_d(arg2, 2.0, MPFR_RNDD); mpfr_init2(r2, 4096); mpfr_sqrt(r2, arg2, MPFR_RNDD); printf("sqrt(2.0)=")/ mpfr_out_str(stdout, 10, 0, r2, MPFR_RNDD); putchar ('\n'); mpfr_clear(arg2); mpfr_clear(r2); mpfr_free_cache(); return 0; }
さて、上記の回で作成した実行ファイル test が残っていました。lddコマンドでtestの共有ライブラリへの依存関係を調べれば以下のようです。
利用させてもらっている MPFRライブラリの実体 libmpfr.so.6 やら、GMPライブラリのlibgmp.so.10に依存しておるのがわかります。そしてC言語で書いているのでlibc.co.6にも依存しておりますな。そして、linux-vdso.so.1と/lib64/ld-linux-x86-64.so.2はそれら共有ライブラリを使うときにはお約束のキホンのキの字のライブラリみたいっす。知らんけど。
普通、LinuxのようなOSプラットフォームが共有ライブラリをサポートしているのなら -static する必要性などないですよね、普通は。また、先ほど述べたとおりベアメタルな組み込みであれば、そもそも共有ライブラリなどという仕組みは無く、オブジェクトファイルはすべてスタティックにリンクされる筈。-static使うのは、OSプラットフォームがあるけれども、実行環境にライブラリが用意されてないかもしれない、といったレア・ケース(個人的には)じゃないかと想像します。まあ、ライブラリの種類によっちゃあ、インストールしてないよ、てこと?それに共有ライブラリのバージョン不整合とかでエラーになる危険性は排除できるか。こっちの方があるあるか?
-staticオプションつけてビルド
心の準備も何もなく、-staticオプションをつけさえすれば、リンカにスタティック・リンクにするよう命令を下すことができます。今回のコマンドラインはこんな感じ。
$ gcc -static -o testStatic root2.c $(pkg-config --cflags --libs mpfr)
上のキャプチャの右側には長い数字の列が続いておるのでありますが、メンドイので省略しました。ともかくMPFRライブラリが動作して多倍長演算されているみたい。ここまで共有ライブラリ(ダイナミック・リンク)つかっていた以前の test 実行ファイルと同じ挙動です。
しかし、lddコマンドにスタティック・リンクのtestStaticファイルを渡してみると赤丸です(VScodeのターミナル画面では、コマンドの戻り値に色をつけてくれるという「サービス」があります。)
そうでした、lddコマンドは共有ライブラリへの依存関係を調べるものなので、そんな依存関係ないtestStaticはおよびじゃないんであります。
共有ライブラリを呼び出さないとファイルサイズ2桁も増えているのね。カイデー。