Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 17990] ファイルの概要

このコミットは、Goプロジェクトのドキュメントセクションにあるdoc/articles/wikiディレクトリ内のMakefileから、GNU Makeに特有の依存関係を削除するものです。具体的には、CLEANFILES変数の定義において、GNU Makeの即時展開代入演算子:=を、標準的な再帰展開代入演算子=に置き換えることで、よりポータブルなMakefileに修正しています。

コミット

commit 22a7b3442ee621bd8b73d5b4ccdfcfd7b62ca8b0
Author: Aram Hăvărneanu <aram@mgk.ro>
Date:   Sun Dec 15 17:51:03 2013 -0500

    doc/articles/wiki: remove GNU make dependency
    
    R=golang-dev, adg, minux.ma
    CC=golang-dev
    https://golang.org/cl/38410043

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/22a7b3442ee621bd8b73d5b4ccdfcfd7b62ca8b0

元コミット内容

doc/articles/wiki: remove GNU make dependency

R=golang-dev, adg, minux.ma
CC=golang-dev
https://golang.org/cl/38410043

変更の背景

この変更の背景には、Goプロジェクトのビルドシステムやドキュメント生成プロセスにおけるポータビリティの向上が挙げられます。Makefileは、ソフトウェアのビルドプロセスを自動化するためのツールですが、その実装にはいくつかの種類があります。最も広く使われているのはGNU Makeですが、BSD Makeやその他のMake実装も存在します。

GNU Makeには、他のMake実装にはない独自の機能や構文拡張があります。:=演算子はその一例です。この演算子を使用すると、GNU Makeがインストールされていないシステムや、他のMake実装を使用している環境では、Makefileが正しく解釈されず、ビルドエラーが発生する可能性があります。

このコミットは、doc/articles/wikiディレクトリ内のMakefileが特定のMake実装(GNU Make)に依存している状態を解消し、より多くの環境で問題なく動作するようにするために行われました。これにより、Goプロジェクトのドキュメント生成プロセスがより堅牢になり、様々な開発環境での互換性が向上します。

前提知識の解説

MakeとMakefile

Makeは、プログラムのコンパイルやドキュメントの生成など、一連のタスクを自動化するためのユーティリティです。これらのタスクの依存関係と実行手順は、Makefileというファイルに記述されます。Makefileは、ターゲット(生成したいファイルや実行したいアクション)、依存関係(ターゲットを生成するために必要なファイルや他のターゲット)、そしてコマンド(ターゲットを生成するための具体的なシェルコマンド)から構成されます。

GNU Make

GNU Makeは、Makeプログラムの最も一般的な実装です。多くのLinuxディストリビューションやmacOSに標準で含まれています。GNU Makeは、標準的なMakeの機能に加えて、多くの強力な拡張機能を提供しています。

Makefileにおける変数の代入演算子

Makefileでは、変数を定義するためにいくつかの代入演算子が使用されます。

  1. = (再帰展開代入):

    • これは最も基本的な代入演算子です。変数の値は、その変数が実際に使用されるときに展開されます。
    • 例: VAR = $(OTHER_VAR) /path
    • OTHER_VARが後で定義または変更された場合、VARの値もそれに合わせて変化します。
    • この代入は、変数の値が他の変数の値に依存している場合に便利ですが、循環参照を引き起こす可能性や、予期しない動作をする場合があります。
  2. := (即時展開代入):

    • これはGNU Makeに特有の代入演算子です。変数の値は、その変数が定義された時点で一度だけ展開されます。
    • 例: VAR := $(OTHER_VAR) /path
    • OTHER_VARがこの行より前に定義されている場合、その時点でのOTHER_VARの値がVARに代入されます。OTHER_VARが後で変更されても、VARの値は変わりません。
    • この代入は、変数の値が固定されるため、より予測可能で、パフォーマンスの向上にも寄与することがあります。しかし、GNU Make以外のMake実装ではサポートされていません。

ポータビリティ

ソフトウェア開発におけるポータビリティ(移植性)とは、ある環境で開発されたソフトウェアが、他の異なる環境でも問題なく動作する能力を指します。Makefileの文脈では、特定のMake実装に依存しない汎用的な構文を使用することで、様々なオペレーティングシステムやMakeのバージョンでビルドプロセスが成功するようにすることを意味します。

技術的詳細

このコミットの技術的詳細は、Makefileにおける変数の代入演算子の選択とその影響に集約されます。

変更前:

CLEANFILES:=get.bin final-test.bin a.out

変更後:

CLEANFILES=get.bin final-test.bin a.out

CLEANFILESという変数は、cleanターゲットが実行されたときに削除されるファイルの一覧を保持しています。

  • 変更前 (:=): CLEANFILES変数は、GNU Makeの即時展開代入演算子:=を使用して定義されていました。これは、CLEANFILESが定義された時点で、右辺のget.bin final-test.bin a.outという文字列が評価され、その結果がCLEANFILESに代入されることを意味します。この形式はGNU Makeの拡張機能であり、他のMake実装では認識されません。

  • 変更後 (=): CLEANFILES変数は、標準的な再帰展開代入演算子=を使用して定義されるようになりました。この形式では、CLEANFILESが実際に使用されるまで右辺の評価は行われません。しかし、この特定のケースでは、右辺が単なる静的な文字列であるため、:==の機能的な違いはほとんどありません。重要なのは、=がすべてのMake実装でサポートされている標準的な構文であるという点です。

この変更により、doc/articles/wiki/MakefileはGNU Makeへの明示的な依存を解消し、より広範なMake実装との互換性を確保しました。これにより、Goプロジェクトのドキュメント生成プロセスが、GNU Makeがインストールされていない環境や、他のMake実装がデフォルトで使用されている環境でも、よりスムーズに実行できるようになります。

コアとなるコードの変更箇所

--- a/doc/articles/wiki/Makefile
+++ b/doc/articles/wiki/Makefile
@@ -4,7 +4,7 @@
 
 all: index.html
 
-CLEANFILES:=get.bin final-test.bin a.out
+CLEANFILES=get.bin final-test.bin a.out
 
 clean:
 	rm -f $(CLEANFILES)

コアとなるコードの解説

上記のdiffは、doc/articles/wiki/Makefileファイルにおける唯一の変更点を示しています。

  • -CLEANFILES:=get.bin final-test.bin a.out: この行は、変更前のMakefileにおけるCLEANFILES変数の定義です。:=演算子が使用されており、これがGNU Makeに特有の構文でした。
  • +CLEANFILES=get.bin final-test.bin a.out: この行は、変更後のMakefileにおけるCLEANFILES変数の定義です。=演算子が使用されており、これはMakeの標準的な構文です。

この変更は、CLEANFILES変数の値自体を変更するものではなく、その変数がどのように評価されるかというメカニズムを変更するものです。結果としてCLEANFILESが保持する値(get.bin final-test.bin a.out)は同じですが、この変更によってMakefileのポータビリティが向上し、GNU Make以外のMake実装でもこのMakefileが正しく解釈されるようになります。

cleanターゲットは、rm -f $(CLEANFILES)というコマンドを実行して、CLEANFILES変数にリストされているファイルを削除します。このcleanターゲットの動作自体は、:=から=への変更によって影響を受けません。

関連リンク

参考にした情報源リンク