Page 21 分割コンパイル

extern

複数のソースファイルから1つのプログラムを作成する方法をここで紹介しますが、その前にプログラムを分けたときに発生する問題などを考えてみます。とりあえず、2つのソースファイルを用意してみます。

/* ソースファイル1 */
int main(int argc, char* argv[]){

        prog2();

        return 0;
}
/* ソースファイル2 */
#include <stdio.h>

void prog2(){
        puts("TEST");
}

ソースファイル1のmain関数内でprog2関数を呼び出していますが、prog2はソースファイル1に存在しないので、このままではエラーとなってしまいます。それを解決するために、externを使用します。

/* ソースファイル1 */
extern void prog2();

int main(int argc, char* argv[]){

        prog2();

        return 0;
}
/* ソースファイル2 */
#include <stdio.h>

void prog2(){
        puts("TEST");
}

1行目の「extern void prog2()」でprog2を使用可能にしています。externはプログラムのどこかに存在する(同一ソース上に存在しなくてもOK)ということを意味します。ソースファイル1にprog2関数は存在しないため、externなしの「void prog2()」のプロトタイプ宣言ではエラーとなってしまいます。

関数以外でも、ソースファイル外の変数を参照する場合も、externを使用します。

/* ソースファイル1 */
int i;
extern void prog2();

int main(int argc, char* argv[]){

        i = 1;
        prog2();

        return 0;
}
/* ソースファイル2 */
#include <stdio.h>

extern int i;

void prog2(){
        printf("&d\n",i);
}

iはソースファイル2にないので、externでソースファイル1のiをとってきています。

分割コンパイル

ソースファイルは下の2つを用意したとします(このページの最初の2つのソースファイルです)。

/* ソースファイル1 (src1.cとする) */
extern void prog2();

int main(int argc, char* argv[]){

        prog2();

        return 0;
}
/* ソースファイル2 (src2.cとする) */
#include <stdio.h>

void prog2(){
        puts("TEST");
}

まず、ソースファイル1をコンパイルします。コンパイルオプション「-c」をつけます。

$ gcc src1.c -c

すると、ファイル「src1.o」ができあがります。同様にしてソースファイル2をコンパイルし、「src2.o」を作ります。

(実際、コンパイルする順番はどちらが先でも構いません。なお、「gcc src1.c src2.c -c」とすれば、src1.o、src2.oが同時にできあがります。)

そしてこの2つのファイルからプログラムを作ります。コンパイルオプション「-o」をつけます

$ gcc src1.o src2.o -o program

これで、ソースファイル1とソースファイル2から「program」ができました。

戻る