2013年2月24日日曜日

[C]静的ライブラリのリンク

大前提
  • あるオブジェクトが静的ライブラリ内の関数を呼び出す時には、呼び出される側のライブラリは後でリンクする必要がある。
静的ライブラリのヘッダファイル
Example: libtest.h
/* libtest.h */
int lib_function(char *str);
静的ライブラリの中身
Example: libtest.c
/* libtest.c */
#include <stdio.h>
#include "libtest.h"

int lib_function(char *str)
{
  printf("Hello, %s\n", str);

  return 0;
}
静的ライブラリの関数を使用するプログラム
Example: test.c
#include <stdio.h>
#include "libtest.h"

int main(void)
{
  lib_function("Hogehoge");

  return 0;
}

コンパイル
  1. 静的ライブラリの作成
    $ gcc -c libtest.c -o libtest.o
    $ ar rcs libtest.a libtest.o
    
    1. -c オプションでコンパイルのみを行い libtest.o オブジェクトを生成する。
    2. ライブラリ・アーカイブ (library archive) を作成する ar コマンドでライブラリ libtest.a を作成する。
  2. 静的ライブラリをリンク(この場合は失敗する)
    $ gcc -L. -ltest test.c
    /tmp/cccBpkWx.o(.text+0x19): In function `main':
    : undefined reference to `lib_function'
    collect2: ld はステータス 1 で終了しました
    
    リンクファイルの指定順が間違っている(リンクされる libtest を指定する -ltest が参照元の test.c より前に指定されているためリンクに失敗する)。
  3. 静的ライブラリをリンク
    $ gcc test.c -L. -ltest
    
    リンクされる libtest (-ltest) が参照元の test.c より後ろに指定されているためリンカが lib_function を正しく見つけることができている。
  4. 完成したプログラムを実行
    $ ./a.out
    Hello, Hogehoge
    

コンパイルオプション
-llibrary link させるライブラリを指定する。記述順により link が変わるので注意。
例) foo.o -lz bar.o
bar.o が z ライブラリ内の関数を参照していた場合ロードすることができなくなる。すなわち参照先ライブラリは参照元より後に記述すること。
ライブラリは libhoge.a というファイル名で search directory に配置しておき -l オプションでは -lhoge と指定する
-Ldirlinker が search する directory を追加する。
-clinker を動作させることなく、object の生成のみを行う。

ar オプション
rarchive に object ファイルを追加する
carchive を作成する
sarchive に object ファイルのインデックスを書き込む。すでに archive が存在する場合はインデックスを更新する

0 件のコメント:

コメントを投稿