他の静的ライブラリに依存する静的ライブラリの使い方

この記事は約5分で読めます。

やりたかったこと

他の静的ライブラリに依存した静的ライブラリを使用してプログラムをビルドしたいと考えました。結論から言うと静的ライブラリのリンク順に気を付ければよいだけだったのですが、少し嵌ったので記事として残しておきます。

実際にやろうとしたことはもう少し複雑だったのですが、この記事では問題を簡単化して以下のような構成とします。

パス内容
main.cppプログラムのソースコード
add10/add10.cppadd10関数を実装したソースコード
add10/add10.hppadd10関数のプロトタイプ宣言を含んだヘッダファイル
add10/libadd10.aadd10.cppから作成した静的ライブラリ
add20/add20.cppadd20関数を実装したソースコード
add10.hppをインクルードし、add10関数を使用
add10/add20.hppadd20関数のプロトタイプ宣言を含んだヘッダファイル
add20/libadd20.aadd20.cppから作成した静的ライブラリ

main.cppをlibadd10.aとlibadd20.aを利用してビルドすることが最終的な目標です。

ソースコードはそれぞれ以下のようなコードです。

// add10.hpp
int add10(int x);
// add10.cpp
#include "add10.hpp"

int add10(int x) {
  return x + 10;
}
// add20.hpp
int add20(int x);
// add20.cpp
#include "add20.hpp"
#include "../add10/add10.hpp"

int add20(int x) {
  return add10(add10(x));
}
// main.cpp
#include <iostream>
#include "add20/add20.hpp"

extern int add20(int x);

int main(int argc, char *argv[]) {
  auto x = 10;
  x = add20(x);
  std::cout << "add20(10)=" << x << std::endl;
  
  return 0;
}

add20.cppで実装されているadd20関数はadd10関数に依存しています。つまり、libadd20.aはlibadd10.aに依存している状態です。

静的ライブラリの生成

add10.cppからlibadd10.aを作成するには以下の手順を踏みます。

  1. add10.cppからadd10.oを生成
  2. add10.oからlibadd10.aを生成

1.のadd10.cppからadd10.oを生成するのは次のようにg++ -cを使うだけです。

$ g++ -c add10.cpp

2.のadd10.oからlibadd10.aを生成するのには次のようにarコマンドを使います。

$ ar r libadd10.a add10.o

このように2つのコマンドでadd10.cppからlibadd10.aを作ることが出来ます。

libadd20.aも同様の手順で作成することができます。libadd20.aの生成時にlibadd10.aは必要ありません。

libadd20.aとlibadd10.aを利用したプログラムのビルド

libadd20.aとlibadd10.aが生成できたので、これらを利用してmain.cppをビルドします。libadd10.aとlibadd20.aをリンクするので、-ladd10と-ladd20を付加することになりますが、以下のように先に-ladd20を指定することがポイントです。

$ g++ main.cpp -Ladd20 -ladd20 -Ladd10 -ladd10

-ladd10を先に指定するとundefined reference to `add10(int)'となってしまいビルドに失敗します。

まとめ

この記事のまとめは以下のようになります。

  • 静的ライブラリの作成にはg++ -cとar rを使用
  • 静的ライブラリは依存先を後に指定

コメント

タイトルとURLをコピーしました