!!! 全体を繋げよう 個々のモジュールが完成したら,全体をリンクしてみましょう. * ソースプログラムと単体テストだけでは見つからなかったミスを発見できます. * 未完成な部品でも,リンクだけはできるようにプログラミングしてください. * インタフェースの思い違いが出てくるかもしれません. リンクできるようになったらテストランしてみましょう. * 全体を通して実行できるようにしましょう. * 部品を完成させるのが難しい場合,取り合えず版でも良いのでまずは組み込んでみましょう. * あるいは,総合テストを作ってみましょう. !!! リンク時のエラー例 関数や変数の未定義,多重定義などのエラーの例が[repos:devel/ld-errors|https://svn.cis.iwate-u.ac.jp/svn/csd/devel/ld-errors/]にあります. 8< cd 適切なディレクトリ svn export https://svn.cis.iwate-u.ac.jp/svn/csd/devel/ld-errors cd ld-errors make >8 リンク時にエラーが起こりますので,確認してみましょう. !! リンクとは? * コンパイルが通ったオブジェクトプログラムを集め, * 必要なライブラリ中の関数を集めて, * 実行可能なプログラムにする '''オブジェクトファイル( .o ファイル)中の基本情報''' * 変数 ** 名前,サイズ,初期値 * 関数 ** 名前,サイズ,関数の中身 ((color green '''型やパラメータの個数チェックはコンパイル時に行われ,リンク時には行われない'''))ので注意. * コンパイル時は,.h と .c に書かれていることに従い,その整合性を検査する * コンパイル時は,.c 間の整合性は検査できない * リンク時は,.o 間の変数と関数の参照定義を行う. ** 複数あるとか, ** 定義されていないとか, ** 大きさが違うとか,(異なる .h をつかってオブジェクトを作った場合など) !! サンプルプログラム * [common.h|https://svn.cis.iwate-u.ac.jp/svn/csd/devel/ld-errors/common.h] - 外部変数 xの宣言,関数 foo, goo の API を記述 8< extern int x; int foo(int); int goo(int); >8 * [main.c|https://svn.cis.iwate-u.ac.jp/svn/csd/devel/ld-errors/main.c] - 変数 x の定義 8< # include # include # include "common.h" int x=0; int main() { foo(1); goo(1); return 1; } >8 * [foo.c|https://svn.cis.iwate-u.ac.jp/svn/csd/devel/ld-errors/foo.c], [goo.c|https://svn.cis.iwate-u.ac.jp/svn/csd/devel/ld-errors/goo.c] - foo, goo の定義 8< # include "common.h" int foo(int y) { return 1; } >8 8< # include "common.h" int goo(int y) { return x; } >8 * [Makefile|https://svn.cis.iwate-u.ac.jp/svn/csd/devel/ld-errors/Makefile] - Makefile !! サンプルプログラムでのエラーメッセージ normal-link: 正常な場合 8< % make normal-link cc -o exe main.o foo.o goo.o >8 undef-x-link: [main.c で変数 x の定義をしなかった場合|https://svn.cis.iwate-u.ac.jp/svn/csd/devel/ld-errors/main-nox.c] 8< % make undef-x-link cc -o exe main-nox.o foo.o goo.o goo.o(.text+0x4): In function `goo': : undefined reference to `x' collect2: ld はステータス 1 で終了しました make: *** [undef-x-link] エラー 1 >8 undef-foo-link: foo.o をリンクしなかった場合 8< % make undef-foo-link cc -o exe main.o goo.o main.o(.text+0x16): In function `main': : undefined reference to `foo' collect2: ld はステータス 1 で終了しました make: *** [undef-foo-link] エラー 1 >8 multi-x-link: 変数 x の多重定義(main.c, [foo-x.c|https://svn.cis.iwate-u.ac.jp/svn/csd/devel/ld-errors/foo-x.c] で x の初期値を定義) 8< % make multi-x-link cc -o exe main.o foo-x.o goo.o foo-x.o(.data+0x0): multiple definition of `x' main.o(.bss+0x0): first defined here collect2: ld はステータス 1 で終了しました make: *** [multi-x-link] エラー 1 >8 multi-foo-link: [関数 foo の多重定義|https://svn.cis.iwate-u.ac.jp/svn/csd/devel/ld-errors/goo-foo.c] 8< % make multi-foo-link cc -o exe main.o foo.o goo-foo.o goo-foo.o(.text+0xa): In function `foo': : multiple definition of `foo' foo.o(.text+0x0): first defined here collect2: ld はステータス 1 で終了しました make: *** [multi-foo-link] エラー 1 >8