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

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

このコミットでは、Goプロジェクトのビルドシステムに関連する複数のMakefileが変更されています。具体的には、src/Make.ccmdsrc/Make.clibsrc/Make.ctoolsrc/Make.incsrc/cmd/5c/Makefilesrc/cmd/5g/Makefilesrc/cmd/5l/Makefilesrc/cmd/6c/Makefilesrc/cmd/6g/Makefilesrc/cmd/6l/Makefilesrc/cmd/8c/Makefilesrc/cmd/8g/Makefilesrc/cmd/8l/Makefilesrc/lib9/Makefileの計14ファイルが修正されています。

コミット

  • コミットハッシュ: 6273d6e7135a7019a4ac73e37d014007a920f574
  • 作者: Anthony Martin ality@pbrane.org
  • コミット日時: 2012年1月31日 火曜日 19:31:30 -0800
  • コミットメッセージ: build: move the "-c" flag into HOST_CFLAGS

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

https://github.com/golang/go/commit/6273d6e7135a7019a4ac73e37d014007a920f574

元コミット内容

build: move the "-c" flag into HOST_CFLAGS

On Plan 9 this flag is used to discover
constant expressions in "if" statements.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5601060

変更の背景

このコミットの主な目的は、Goのビルドシステムにおいて、Cコンパイラに渡す-cフラグの扱いを改善することです。特に、Plan 9オペレーティングシステム上でのビルドプロセスにおける特殊な要件に対応するために行われました。

通常のC/C++コンパイラ(GCCなど)において、-cフラグは「コンパイルのみを行い、リンクは行わない」ことを指示するもので、ソースファイルをオブジェクトファイルに変換する際に使用されます。しかし、Plan 9のCコンパイラ(8c, 6c, 5cなど)では、この-cフラグが異なる意味を持つことがあります。コミットメッセージによると、Plan 9では「if文内の定数式を検出する」ためにこのフラグが使用されると述べられています。

これまでのビルド設定では、-cフラグが個々のコンパイルコマンドラインで明示的に指定されていました。このアプローチは、Plan 9のような特定の環境で-cフラグが標準的なコンパイル動作以外の特殊な意味を持つ場合に、予期せぬ挙動を引き起こす可能性がありました。

この変更により、-cフラグをHOST_CFLAGSという共通のコンパイラフラグ変数に移動することで、以下の利点が得られます。

  1. 一貫性の向上: -cフラグの指定が一箇所に集約され、ビルドスクリプト全体での一貫性が向上します。
  2. 環境依存の対応: Plan 9のような特定の環境で-cフラグが特殊な意味を持つ場合でも、HOST_CFLAGSの定義を調整するだけで、その環境に合わせた適切なコンパイル動作を保証できます。これにより、クロスコンパイルや異なるOS環境でのビルドの堅牢性が高まります。
  3. 冗長性の排除: 各コンパイルコマンドから冗長な-cフラグの記述が削除され、Makefileの可読性と保守性が向上します。

前提知識の解説

Makefileとビルドシステム

Makefileは、プログラムのコンパイルやビルドプロセスを自動化するためのスクリプトファイルです。makeコマンドによって解釈され、ソースコードから実行可能ファイルやライブラリを生成する手順を定義します。Makefileは、ターゲット(生成したいファイル)、依存関係(ターゲットを生成するために必要なファイル)、レシピ(ターゲットを生成するためのコマンド)から構成されます。

Goプロジェクトのビルドシステムでは、Go言語で書かれた部分だけでなく、C言語で書かれたランタイムやツールチェインの一部もコンパイルする必要があります。そのため、Makefileが広く利用されています。

HOST_CFLAGSHOST_CC

  • HOST_CC: ホストシステム(ビルドを実行する環境)のCコンパイラを指す変数です。例えば、Linux上であればgccclang、Plan 9上であれば8c6c5cなどが設定されます。
  • HOST_CFLAGS: ホストシステムのCコンパイラに渡すコンパイルフラグ(オプション)を定義する変数です。最適化レベル、インクルードパス、警告設定など、コンパイル時の挙動を制御する様々なフラグが含まれます。

これらの変数は、クロスコンパイル環境において特に重要です。例えば、ARMアーキテクチャ向けのGoバイナリをx86_64のホストでビルドする場合、HOST_CCはx86_64上で動作するクロスコンパイラを指し、HOST_CFLAGSはそのクロスコンパイラに渡すフラグを定義します。

Cコンパイラの-cフラグ

一般的なC/C++コンパイラ(GCC, Clangなど)において、-cフラグは「コンパイルのみを行い、リンクは行わない」ことを指示します。これにより、ソースファイル(.c.cpp)はオブジェクトファイル(.o)に変換されますが、実行可能ファイルやライブラリは生成されません。これは、複数のソースファイルを個別にコンパイルし、後でまとめてリンクする際に非常に便利です。

例: gcc -c main.c -> main.o を生成 gcc -c func.c -> func.o を生成 gcc main.o func.o -o myprogram -> myprogram をリンクして生成

Plan 9オペレーティングシステム

Plan 9 from Bell Labsは、ベル研究所で開発された分散オペレーティングシステムです。Unixの設計思想をさらに推し進め、すべてのリソースをファイルとして表現し、ネットワーク透過性を重視しています。Go言語の開発者の一部はPlan 9の設計に深く関わっており、Goの設計思想にもPlan 9の影響が見られます。

Plan 9のCコンパイラ(例: 8c for ARM, 6c for AMD64, 5c for x86)は、一般的なUnix系システムのコンパイラとは異なる挙動や独自の拡張を持つことがあります。コミットメッセージで言及されているように、Plan 9のコンパイラにおける-cフラグの特殊な意味合いは、このような背景から来ています。具体的に「if文内の定数式を検出する」という挙動は、コンパイラがコードの静的解析を行う際に利用される可能性があります。

技術的詳細

このコミットの技術的な核心は、Cコンパイラの-cフラグの指定方法を、個々のコンパイルコマンドラインからHOST_CFLAGS変数へと集約した点にあります。

変更前は、多くのMakefileルールにおいて、Cソースファイルをオブジェクトファイルにコンパイルする際に、以下のようなコマンドが使われていました。

$(HOST_CC) $(HOST_CFLAGS) -c "$(PWD)/$*.c"

ここで、-cフラグはHOST_CFLAGSとは別に明示的に指定されています。

変更後、src/Make.incファイル内でHOST_CFLAGSの定義に-cフラグが追加されました。

--- a/src/Make.inc
+++ b/src/Make.inc
@@ -122,7 +122,7 @@ HOST_EXTRA_LDFLAGS?=
 # The -fno-common here is not necessary, but some compilers
 # on OS X seem to set it by default.  Setting it here keeps the build
 # working in that non-standard context.
-HOST_CFLAGS=-fno-common -I"$(GOROOT)/include" $(HOST_EXTRA_CFLAGS)
+HOST_CFLAGS=-c -fno-common -I"$(GOROOT)/include" $(HOST_EXTRA_CFLAGS)
 HOST_LDFLAGS=$(HOST_EXTRA_LDFLAGS)
 PWD=$(shell pwd)

これにより、HOST_CFLAGSには常に-cフラグが含まれるようになります。その結果、個々のコンパイルコマンドラインからは-cフラグが削除されました。

$(HOST_CC) $(HOST_CFLAGS) "$(PWD)/$*.c"

この変更の技術的な影響は以下の通りです。

  1. コンパイラフラグの正規化: -cフラグがHOST_CFLAGSの一部となることで、Goのビルドシステムが使用するCコンパイラは、常に「コンパイルのみ」モードで動作することが保証されます。これは、Goのビルドプロセスにおいて、Cソースファイルが中間オブジェクトファイルとして生成され、後でGoのリンカによってリンクされるという一般的なワークフローに合致しています。
  2. Plan 9特有の挙動の吸収: コミットメッセージにあるように、Plan 9のコンパイラでは-cフラグが「if文内の定数式を検出する」という特殊な意味を持つ場合があります。このフラグをHOST_CFLAGSに含めることで、Plan 9環境でのビルド時にこの特殊な挙動が常に有効になり、ビルドの安定性や正確性が向上します。もし-cフラグが個別に指定され、かつPlan 9のコンパイラがそのフラグを別の意味で解釈するような状況があった場合、ビルドエラーや予期せぬ動作につながる可能性がありました。HOST_CFLAGSに含めることで、この環境依存の差異をビルドシステムが吸収し、透過的に処理できるようになります。
  3. ビルドスクリプトの簡素化: 各Makefileルールから-cフラグが削除されたことで、コマンドラインが短くなり、Makefileの記述がより簡潔になりました。これは、大規模なプロジェクトにおけるビルドスクリプトの保守性を高める上で重要です。

この変更は、Goのビルドシステムが多様なプラットフォーム(特にPlan 9のようなニッチな環境)で堅牢に動作するための、細かながらも重要な改善と言えます。

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

このコミットにおけるコアとなる変更は、主にsrc/Make.incと、Cソースファイルをコンパイルするルールが定義されている各種Makefileファイルにあります。

src/Make.inc の変更

--- a/src/Make.inc
+++ b/src/Make.inc
@@ -122,7 +122,7 @@ HOST_EXTRA_LDFLAGS?=
 # The -fno-common here is not necessary, but some compilers
 # on OS X seem to set it by default.  Setting it here keeps the build
 # working in that non-standard context.
-HOST_CFLAGS=-fno-common -I"$(GOROOT)/include" $(HOST_EXTRA_CFLAGS)
+HOST_CFLAGS=-c -fno-common -I"$(GOROOT)/include" $(HOST_EXTRA_CFLAGS)
 HOST_LDFLAGS=$(HOST_EXTRA_LDFLAGS)
 PWD=$(shell pwd)

src/Make.ccmd (および類似の Make.clib, Make.ctool) の変更

--- a/src/Make.ccmd
+++ b/src/Make.ccmd
@@ -38,7 +38,7 @@ all: $(TARG)
  
  # Use $(PWD)/$*.c so that gdb shows full path in stack traces.
  %.$(HOST_O): %.c
--	$(HOST_CC) $(HOST_CFLAGS) -c "$(PWD)/$*.c"
-+	$(HOST_CC) $(HOST_CFLAGS) "$(PWD)/$*.c"
+	$(HOST_CC) $(HOST_CFLAGS) "$(PWD)/$*.c"
  
  # These are used by enough different Makefiles to be
  # worth writing down in one place, even if they don\'t

src/cmd/5c/Makefile (および類似の src/cmd/*c/Makefile, src/cmd/*g/Makefile, src/cmd/*l/Makefile) の変更

--- a/src/cmd/5c/Makefile
+++ b/src/cmd/5c/Makefile
@@ -31,4 +31,4 @@ LIB=\
  include ../../Make.ctool
  
  %.$O: ../cc/%.c
--	$(HOST_CC) $(HOST_CFLAGS) -c -I. -o $@ ../cc/$*.c
-+	$(HOST_CC) $(HOST_CFLAGS) -I. -o $@ ../cc/$*.c
+	$(HOST_CC) $(HOST_CFLAGS) -I. -o $@ ../cc/$*.c

src/lib9/Makefile の変更

--- a/src/lib9/Makefile
+++ b/src/lib9/Makefile
@@ -111,12 +111,12 @@ include ../Make.clib
  GOROOT_FINAL?=$(GOROOT)
  
  %.$O: fmt/%.c
--	$(HOST_CC) -c $(HOST_CFLAGS) -DPLAN9PORT -Ifmt $<\
-+	$(HOST_CC) $(HOST_CFLAGS) -DPLAN9PORT -Ifmt $<\
+	$(HOST_CC) $(HOST_CFLAGS) -DPLAN9PORT -Ifmt $<\
  
  %.$O: utf/%.c
--	$(HOST_CC) -c $(HOST_CFLAGS) $<\
-+	$(HOST_CC) $(HOST_CFLAGS) $<\
+	$(HOST_CC) $(HOST_CFLAGS) $<\
  
  goos.$O: goos.c
   	GOVERSION=`../version.bash` && \
--	\t$(HOST_CC) -c $(HOST_CFLAGS) -DGOOS='\"$(GOOS)\"' -DGOARCH='\"$(GOARCH)\"' -DGOROOT='\"$(GOROOT_FINAL)\"' -DGOVERSION='\"'\"$$GOVERSION\"'\"' $<\
-+	\t$(HOST_CC) $(HOST_CFLAGS) -DGOOS='\"$(GOOS)\"' -DGOARCH='\"$(GOARCH)\"' -DGOROOT='\"$(GOROOT_FINAL)\"' -DGOVERSION='\"'\"$$GOVERSION\"'\"' $<\
+	\t$(HOST_CC) $(HOST_CFLAGS) -DGOOS='\"$(GOOS)\"' -DGOARCH='\"$(GOARCH)\"' -DGOROOT='\"$(GOROOT_FINAL)\"' -DGOVERSION='\"'\"$$GOVERSION\"'\"' $<\
  

コアとなるコードの解説

src/Make.inc の変更解説

このファイルは、Goのビルドシステム全体で共通して使用される変数やルールを定義するインクルードファイルです。 変更前は、HOST_CFLAGS変数には-fno-commonやインクルードパス(-I"$(GOROOT)/include")などが含まれていましたが、-cフラグは含まれていませんでした。 変更後、HOST_CFLAGSの定義の先頭に-cが追加されました。これにより、HOST_CFLAGSを使用するすべてのコンパイルコマンドにおいて、自動的に-cフラグが渡されるようになります。これは、Cソースファイルをオブジェクトファイルにコンパイルする際の標準的な動作を強制し、かつPlan 9環境での特殊な挙動にも対応するための中心的な変更です。

その他の Makefile ファイルの変更解説

src/Make.ccmdsrc/Make.clibsrc/Make.ctool、およびsrc/cmd/以下の各ツール(5c, 5g, 5l, 6c, 6g, 6l, 8c, 8g, 8l)のMakefile、さらにsrc/lib9/Makefileでは、Cソースファイルをコンパイルする際のレシピ(コマンド)から明示的な-cフラグが削除されています。

例えば、src/Make.ccmdの以下のルールを見てみましょう。

%.$(HOST_O): %.c
	$(HOST_CC) $(HOST_CFLAGS) -c "$(PWD)/$*.c"  # 変更前
	$(HOST_CC) $(HOST_CFLAGS) "$(PWD)/$*.c"   # 変更後

変更前は、$(HOST_CFLAGS)の後に-cが個別に指定されていました。変更後は、src/Make.incHOST_CFLAGS-cが含まれるようになったため、この個別の-cは不要となり削除されました。

これは、ビルドスクリプトの冗長性を排除し、-cフラグの管理を一元化するためのクリーンアップ作業です。これにより、ビルド設定の変更がより容易になり、将来的なメンテナンス性が向上します。また、Plan 9のような特定の環境での-cフラグの特殊な意味合いが、HOST_CFLAGSの定義を通じて適切に処理されるようになります。

関連リンク

参考にした情報源リンク

  • Goのコミットメッセージと差分情報 (提供されたファイルより)
  • 一般的なMakefileの構文とCコンパイラのフラグに関する知識
  • Plan 9オペレーティングシステムに関する一般的な情報 (Web検索)
  • Go言語のビルドプロセスに関する一般的な知識
  • GCCの-cフラグに関するドキュメント (例: https://gcc.gnu.org/onlinedocs/gcc/Option-Summary.html)
  • Plan 9のCコンパイラに関する情報 (Web検索、ただし具体的な-cフラグの挙動に関する公式ドキュメントは見つけられませんでした。コミットメッセージの記述を基にしています。)