Makeのビルドを高速化する3つの方法:「-w」オプション、タスクランナー、Makefile改良


「-w」オプションの主な機能

  • 特定のジョブサーバースタイルの使用:-wオプションと引数を組み合わせることで、特定のジョブサーバースタイルの使用を指示できます。これは、互換性やパフォーマンス上の理由で必要となる場合があります。
  • ジョブワーカー数の指定:-wオプションと数値を組み合わせることで、ジョブサーバーが実行できるジョブワーカーの最大数 (並行実行できるジョブ数) を指定できます。
  • ジョブサーバーの起動:Makeはデフォルトでジョブサーバーを起動しませんが、-wオプションを指定すると、明示的にジョブサーバーを起動するように指示できます。

「-w」オプションの利点

  • 複雑なMakefileのサポート: 複雑なMakefileを扱う場合、-wオプションは、依存関係を効率的に処理し、ビルドプロセスを円滑化することができます。
  • 効率化: ジョブサーバーは、並行実行できるジョブを賢く選択することで、CPUと入出力リソースをより効率的に活用することができます。
  • 高速化: 複数のCPUコアやマルチコアプロセッサを持つシステムでは、-wオプションを使用することで、Makeのビルド処理を大幅に高速化することができます。

「-w」オプションの使用例

以下の例は、-wオプションを使用してジョブワーカーの最大数を4に設定し、特定のジョブサーバースタイルを使用するものです。

make -w 4 --jobserver-style=swarm
  • ジョブサーバーを使用する場合は、システム負荷に注意する必要があります。ジョブワーカーが多すぎると、システム全体のパフォーマンスが低下する可能性があります。
  • -sオプション (サイレントモード) や --no-print-directoryオプションと一緒に使用すると、-wオプションは自動的に無効化されます。
  • -wオプションは、古いバージョンのGNU Makeや、ジョブサーバースタイルに特化した他のツールを使用している場合にのみ役立ちます。


# ビルド対象を指定
TARGETS = program1 program2

# 依存関係を指定
program1: main.c utils.h utils.c
program2: main2.c utils.h utils.c

# GNU Makeのバージョンが古い場合の互換性設定
ifeq ($(shell make --version | grep -E 'GNU Make [0-9]\.[0-9]+' | wc -l),1)
# GNU Make 3.81より古いバージョン
NO_MINUS_C_FLAG = 1
else
# GNU Make 3.81以降
endif


# ジョブサーバーの設定
JOBS := 4
JOBSTYLE := swarm

# ビルドルール
all: $(TARGETS)

.PHONY: clean

clean:
	-rm $(TARGETS) *.o

このMakefileの説明

  1. TARGETS変数に、ビルド対象となるプログラムの名前を指定します。
  2. 各プログラムの依存関係を、:記号で区切って指定します。
  3. ifeq条件式を使用して、GNU Makeのバージョンに応じて互換性設定を行います。古いバージョンのMakeでは、-Cフラグが必要となる場合があります。
  4. JOBS変数に、ジョブワーカーの最大数を設定します。
  5. JOBSTYLE変数に、使用するジョブサーバースタイルを設定します。
  6. allルールは、TARGETS変数に指定されたすべてのプログラムをビルドします。
  7. cleanルールは、すべてのターゲットファイルとオブジェクトファイルを削除します。

このMakefileの実行方法

以下のコマンドを実行して、Makefileを使用してプログラムをビルドできます。

make

このコマンドを実行すると、Makeはジョブサーバーを起動し、4つのジョブワーカーを並行して実行して、プログラムをビルドします。

  • ジョブワーカーの数は、システムのハードウェア構成に合わせて調整する必要があります。
  • このMakefileはあくまでも例であり、実際のプロジェクトで使用するには、必要に応じて修正する必要があります。


タスクランナーの使用

Makeは主にビルド自動化に使用されますが、近年では、より汎用的なタスクランナーを使用するケースが増えています。

  • 注意点:
    • Makeほど汎用性が高くない場合がある
    • 独自の構文を覚える必要がある
  • :
    • Apache Ant
    • Maven
    • Gradle
    • Grunt
    • Gulp
  • 利点:
    • Makeよりも記述が簡潔で分かりやすいことが多い
    • 依存関係の管理が容易
    • プラグインによる機能拡張性が高い

シェルスクリプトの使用

シンプルなビルドタスクであれば、シェルスクリプトを使用して代替することもできます。

  • 注意点:
    • 複雑なビルドタスクには向かない
    • 依存関係の管理が煩雑になる場合がある
  • :
    #!/bin/bash
    
    # ビルド対象を指定
    TARGETS="program1 program2"
    
    # 各プログラムのビルドコマンド
    build_program() {
        program=$1
    
        # ビルド処理
        gcc -o $program $program.c utils.h utils.c
    }
    
    # ビルドルール
    for program in $TARGETS; do
        build_program $program
    done
    
  • 利点:
    • 柔軟性が高い
    • Makeよりも軽量

Makefileの改良

-wオプションを使用せずに、Makefileを改良することで、並行処理を可能にすることもできます。

  • 注意点:
    • Makefileの記述が複雑になる場合がある
    • GNU Makeの高度な機能を理解する必要がある
  • 利点:
    • Makeの機能を最大限に活用できる
    • プロジェクトの可読性と保守性を向上できる
  • 方法:
    • 明示的な依存関係の指定
    • 並行実行可能なジョブのグループ化
    • GNU Makeの並行実行機能 (Makefileのmake関数) の利用

最適な代替方法の選択

-wオプションの代替方法は、プロジェクトのニーズや環境によって異なります。

  • Makeの機能を最大限に活用したい: Makefileの改良が適している
  • シンプルなビルドタスク: シェルスクリプトが適している
  • 複雑なビルドシステム: タスクランナーが適している

上記の情報に加え、以下の点にも注意する必要があります。

  • コミュニティ: 問題が発生した場合に、サポートを提供してくれるコミュニティがあるかどうかを確認する必要があります。
  • 学習曲線: 新しいツールを導入する場合は、学習曲線とドキュメントの可用性を考慮する必要があります。
  • 互換性: 選んだ代替方法が、既存のツールやワークフローと互換性があることを確認する必要があります。