C++のMakefile入門|複数ファイルを分割・リンクしてビルドする方法
はじめに
この記事では、C++におけるMakefileの基本とその活用方法について解説します。
規模の大きなプログラムを1つのファイルにすべて記述するのは非効率的です。そこで一般的に行われるのが、プログラム全体を複数の.cppファイルと.h(ヘッダー)ファイルに分割し、クラスや機能ごとに整理したうえで、Makefileを使ってこれらをコンパイル・リンクして1つの実行ファイルにまとめるという手法です。
今回作成するファイル構成
- main.cpp … プログラムのエントリーポイント(main関数)
- print.cpp … 文字列を出力するprint()関数
- factorial.cpp … 階乗を計算するfactorial()関数
- multiply.cpp … 掛け算を行うmultiply()関数
- function.h … 各関数のプロトタイプ宣言をまとめたヘッダーファイル
ソースコード例
main.cpp
#include <bits/stdc++.h>
#include "function.h"
using namespace std;
// メイン実行プログラム
int main(){
int num1 = 1;
int num2 = 2;
cout << multiply(num1, num2) << endl;
int num3 = 5;
cout << factorial(num3) << endl;
print();
}
print.cpp
#include <bits/stdc++.h>
#include "function.h"
using namespace std;
// 文字列を出力する関数
void print()
{
cout << "makefile" << endl;
}
factorial.cpp
#include <bits/stdc++.h>
#include "function.h"
using namespace std;
// 階乗を計算する関数
int factorial(int n){
if (n == 1)
return 1;
return n * factorial(n - 1);
}
multiply.cpp
#include <bits/stdc++.h>
#include "function.h"
using namespace std;
// 掛け算を行う関数
int multiply(int a, int b){
return a * b;
}
function.h
#ifndef FUNCTION_H #define FUNCTION_H void print(); int factorial(int); int multiply(int, int); #endif
Makefileの作成
続いて、上記のファイル群をコンパイルし、リンクして実行ファイルを生成するためのMakefileを作成します。
main: main.o print.o factorial.o multiply.o g++ main.o print.o factorial.o multiply.o -o main main.o: main.cpp function.h g++ -c main.cpp print.o: print.cpp function.h g++ -c print.cpp factorial.o: factorial.cpp function.h g++ -c factorial.cpp multiply.o: multiply.cpp function.h g++ -c multiply.cpp clean: rm -f *.o main
注意: コマンド行の先頭は必ずタブ文字(Tab)でインデントしてください。半角スペースでは正しく動作しません。
ビルドと実行の手順
ターミナルで以下のコマンドを実行します。
make ./main
makeコマンドを実行すると、Makefileの依存関係に従って必要なファイルだけがコンパイルされ、最終的な実行ファイル「main」が生成されます。
出力結果
2 120 makefile
まとめ
Makefileを活用することで、変更があったソースファイルだけを効率よく再コンパイルでき、ビルドにかかる時間を大幅に短縮できます。また、ビルド手順を自動化・共有できるため、個人開発からチーム開発まで幅広く利用されている重要なツールです。まずは小さなプロジェクトでMakefileの書き方に慣れておきましょう。
-
C++で円と長方形の重なりを判定するアルゴリズム
問題の概要円を (radius, xc, yc) という形式で表します。ここで (xc, yc) は円の中心座標です。同様に、軸に平行な長方形(軸平行境界ボックス)を (x1, y1, x2, y2) という形式で表し、(x1, y1) が左下隅の座標、(x2, y2) が右上隅の座標とします。このとき、円と長方形が互いに重なっているかどうかを判定する必要があります。たとえば、次のような入力が与えられた場合を考えてみましょう。この場合、出力は true(重なりあり)となります。解決のアプローチこの問題を解く鍵は、「長方形の中で円の中心に最も近い点」を見つけることです。その点と円の中心との距離が
-
C++で解くドミノとトロミノを使ったタイル敷き詰め問題(2×Nボード)
問題の概要本記事では、「ドミノ」と「トロミノ」という2種類の形状を使ったタイル敷き詰め(タイリング)問題をC++で解く方法を解説します。これらのピースは、以下のように回転させて使用することができます。タイリングでは、盤面上のすべてのマスを必ずタイルで覆わなければなりません。また、2つのタイリング方法は、盤上の4方向に隣接する2つのセルにおいて、片方のタイリングだけがその両方のマスを同じタイルで占有している場合に限り「異なる」とみなされます。入力と出力の例整数Nが与えられたとき、2×Nのボードを敷き詰める方法が何通りあるかを求めます。例えば、入力が3の場合、出力は5となります。敷き詰め方は以下の