複数ファイルのコンパイルとリンク方法

ここまでで、簡単なプログラムをビルドできたわけですが、いかがですか? ちゃんとビルドできましたか?

うまく行ってない時はあせらずに、復習しておいてくださいね。

さて、今回はもう一歩先へ進みましょう。

前回までは test.cpp というひとつのファイルにコードを記述していましたが、 ここでは複数のファイルにコードを記述する方法を考えます。

分割コンパイルというやつです。

準備 ~ 複数ファイルへの分割

おさらいになりますが、元の test.cpp は次のようなファイルでした。

#include <windows.h>
#include <lmcons.h>
#include <tchar.h>
#include <stdio.h>

int main(int argc, LPTSTR argv[]) {

     TCHAR szUserName[UNLEN + 1];
     DWORD dwUNLen = UNLEN;

     if( !GetUserName( (LPTSTR) szUserName, &dwUNLen ) ) {
          printf("Error: %u", GetLastError() );
          return 1;
     }

     _tprintf( TEXT("%s\n"), szUserName );

     return 0;
}

これを次のように分割します。

まず「ユーザー名をコンソールに出力する」という機能を username.cpp というファイルにまとめましょう。

#include <windows.h>
#include <lmcons.h>
#include <tchar.h>
#include <stdio.h>

BOOL PrintUserName() {

     TCHAR szUserName[UNLEN + 1];
     DWORD dwUNLen = UNLEN;

     if( !GetUserName( (LPTSTR) szUserName, &dwUNLen ) ) {
          printf("Error: %u", GetLastError() );
          return FALSE;
     }

     _tprintf( TEXT("%s\n"), szUserName );

     return TRUE;
}

ヘッダファイルは username.h とします。

#pragma once

#include <windows.h>

BOOL PrintUserName();

このように機能別にソースコードを分割しておくと、使い回しができますし、コンパイルの単位も小さくできますので便利です。

すると、test.cpp は以下のように単純化できます。

#include <windows.h>
#include <tchar.h>
#include "username.h"

int main(int argc, LPTSTR argv[]) {

     PrintUserName();

     return 0;
     
}

以上、もとの test.cpp は test.cpp, username.cpp, userneme.h に分割されました。

新しく出来た3つのファイルからひとつの実行可能ファイル test.exe を作成するにはどうしたらよいでしょうか

ちなみに、基本的な C 言語では見かけない様々なキーワードが出てきていると思いますが、 ここでは気にしないでください。ビルドできるかどうかだけに着目してください。

各種キーワードは後ほど説明します。

分割コンパイルとリンク

コンパイル

コンパイルは、次のように必要となるソースファイルを並べてコンパイルすれば良いです。


> cl /c test.cpp username.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

test.cpp
username.cpp
Generating Code...

この結果 test.obj と username.obj が生成されます。

簡単ですね。ソースファイル名を並べてコンパイルすればよいだけです。

尚、この方法だと毎回、変更の無いファイルも含めて全てのファイルがコンパイル、ビルドされることになります。

しかし本来変更の無いソースファイルはコンパイルしなおす必要がありません。 必要なソースコードをコンパイルしてオブジェクトファイルを生成すればよいのですが、ファイル数が多くなると 変更のあったファイル、変更の無かったファイルを判断するのも面倒です。

変更の無いファイルをコンパイルしなおすような無駄をなくし、効率よくビルドするためには makefile を使うと良いです。 makefile を使う方法は他の節で解説します。

リンク

さて、リンクする場合は、必要となるライブラリとオブジェクトファイルを並べれば OK です。

実行可能ファイル (EXE) のファイル名は、 ひとつのファイルだけの場合は、デフォルトの オブジェクトファイル名.exe でしたが、 複数ファイルあるとわかりにくいので、明示的に実行可能ファイル名をつけると良いでしょう。

実行可能ファイル名は /OUT リンカオプションで指定します。以下の例では test.exe という名前の EXE ファイルを出力しています。


> link advapi32.lib test.obj username.obj /OUT:test.exe
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation.  All rights reserved.

以上で EXE ファイル test.exe が作成されたはずです。

複数のファイルに分割してコードを書いてコンパイルするという方法は、極めて普通のことです。

しっかり、出来るようになってくださいね。

« 前の記事 次の記事 »
コンパイルとリンク方法 よく使うコンパイル・リンカオプション

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Web/DB プログラミング徹底解説