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

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

このコミットは、src/pkg/net/dnsclient_unix_test.go ファイルに対する変更です。具体的には、Windowsビルドにおけるコンパイルエラーを修正するために、ビルドタグの追加と、既存のOS判定によるテストスキップロジックの削除が行われています。

コミット

commit d90a81c39f06351ce6524a1ae15499d2d60253c8
Author: Dmitriy Vyukov <dvyukov@google.com>
Date:   Wed Aug 14 00:44:57 2013 +0400

    net: fix windows build
    Windows builders say:
    pkg\net\dnsclient_unix_test.go:24: undefined: dnsConfig
    pkg\net\dnsclient_unix_test.go:25: undefined: exchange
    
    R=golang-dev
    CC=golang-dev
    https://golang.org/cl/12889043

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

https://github.com/golang/go/commit/d90a81c39f06351ce6524a1ae15499d2d60253c8

元コミット内容

net: fix windows build
Windows builders say:
pkg\net\dnsclient_unix_test.go:24: undefined: dnsConfig
pkg\net\dnsclient_unix_test.go:25: undefined: exchange

変更の背景

このコミットの背景には、Go言語のnetパッケージ内のDNSクライアントのUnix固有のテストファイル(dnsclient_unix_test.go)が、Windows環境でビルドエラーを引き起こしていた問題があります。具体的には、Windowsのビルド環境でこのファイルをコンパイルしようとすると、dnsConfigexchangeというシンボルが未定義であるというエラーが発生していました。

これは、dnsclient_unix_test.goがUnix系OS(Darwin, FreeBSD, Linux, NetBSD, OpenBSDなど)に特化した機能や構造体を使用しているためです。Windows環境ではこれらのシンボルが存在しないため、コンパイルエラーが発生していました。

この問題を解決するため、コミットではGoのビルドタグ(+buildディレクティブ)を利用して、このテストファイルが特定のUnix系OSでのみコンパイルされるように変更されました。これにより、Windows環境でのビルド時にこのファイルが無視され、エラーが解消されます。

前提知識の解説

Go言語のビルドタグ(Build Tags / Build Constraints)

Go言語には、特定のファイルが特定の環境(OS、アーキテクチャ、Goのバージョンなど)でのみコンパイルされるように制御するメカニズムとして「ビルドタグ(Build Tags)」または「ビルド制約(Build Constraints)」があります。これは、ソースファイルの先頭に// +buildディレクティブを記述することで実現されます。

  • 構文: // +build tag1 tag2,tag3
    • タグはスペースで区切られ、OR条件として扱われます(tag1またはtag2,tag3のいずれかが真であればコンパイルされる)。
    • カンマで区切られたタグはAND条件として扱われます(tag2tag3の両方が真であればコンパイルされる)。
    • !tagのように!を前置するとNOT条件になります。
  • 目的:
    • プラットフォーム固有のコード: OSやアーキテクチャに依存するコードを分離し、適切な環境でのみコンパイルされるようにする。
    • テストコードの分離: 特定の環境でのみ実行されるテストや、外部リソースに依存するテストを分離する。
    • 開発環境と本番環境の分離: デバッグ用のコードや開発ツールを本番ビルドから除外する。
  • :
    • // +build linux:Linuxでのみコンパイル。
    • // +build windows,amd64:WindowsかつAMD64アーキテクチャでのみコンパイル。
    • // +build !windows:Windows以外でコンパイル。

Goのビルドシステムは、ソースファイルをスキャンし、これらのビルドタグを評価して、現在のビルド環境に合致するファイルのみをコンパイル対象とします。これにより、クロスプラットフォーム開発が容易になり、特定のOSに依存するコードが他のOSでコンパイルエラーを引き起こすのを防ぐことができます。

runtime.GOOS

runtime.GOOSは、Go言語の標準ライブラリruntimeパッケージで提供される定数で、プログラムが実行されているオペレーティングシステムの名前を表す文字列です。例えば、Linuxでは"linux"、Windowsでは"windows"、macOSでは"darwin"となります。

この定数は、実行時にOSを判別し、それに基づいて異なるロジックを実行するために使用されます。しかし、コンパイル時に特定のOS用のコードを完全に除外したい場合には、ビルドタグの方が適しています。なぜなら、runtime.GOOSによる条件分岐は、そのコードブロックがコンパイル時に含まれてしまうため、未定義シンボルエラーなどを完全に回避できない場合があるからです。

技術的詳細

このコミットの技術的詳細は、Go言語のビルドシステムがどのようにプラットフォーム固有のコードを扱うかという点に集約されます。

元のコードでは、TestTCPLookup関数内でruntime.GOOS == "windows" || runtime.GOOS == "plan9"という条件分岐を使って、WindowsまたはPlan 9環境の場合にテストをスキップしていました。これは実行時の動作を制御するためのものであり、コンパイル時の問題を解決するものではありませんでした。

Windowsのビルド環境では、dnsclient_unix_test.goファイル全体がコンパイル対象に含まれていました。このファイルはUnix系OSのDNSクライアントテストであり、内部でdnsConfigexchangeといったUnix系OSのネットワークスタックに関連する構造体や関数を参照していました。これらのシンボルはWindowsのGo標準ライブラリには存在しないため、コンパイル時に「undefined」(未定義)エラーが発生していました。

コミットによる修正は、この問題を根本的に解決するために、ファイルレベルでコンパイル対象を制御するビルドタグを導入しました。

// +build darwin freebsd linux netbsd openbsd

この行をファイルの先頭に追加することで、Goのビルドツールは、このdnsclient_unix_test.goファイルがdarwin(macOS)、freebsdlinuxnetbsdopenbsdのいずれかのOSでビルドされる場合にのみコンパイル対象に含めるようになります。Windows環境でビルドする際には、このファイルは完全に無視されるため、dnsConfigexchangeといった未定義シンボルによるコンパイルエラーが発生しなくなります。

また、ファイル全体がWindows環境でコンパイルされなくなるため、既存のruntime.GOOSによるテストスキップロジックは不要となり、削除されました。これにより、コードの冗長性が解消され、意図がより明確になりました。

この変更は、Go言語におけるクロスプラットフォーム開発のベストプラクティスを示しています。実行時にOSを判別して動作を変えるのではなく、コンパイル時にOS固有のファイルを切り替えることで、よりクリーンでエラーの少ないビルドプロセスを実現できます。

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

--- a/src/pkg/net/dnsclient_unix_test.go
+++ b/src/pkg/net/dnsclient_unix_test.go
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// +build darwin freebsd linux netbsd openbsd
+
 package net
 
 import (
@@ -10,9 +12,6 @@ import (
 )
 
 func TestTCPLookup(t *testing.T) {
-\tif runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
-\t\tt.Skip("skipping unix dns test")
-\t}\
 \tif testing.Short() || !*testExternal {\
 \t\tt.Skip("skipping test to avoid external network")
 \t}\

コアとなるコードの解説

このコミットにおけるコアとなるコードの変更は以下の2点です。

  1. ファイルの先頭にビルドタグを追加:

    // +build darwin freebsd linux netbsd openbsd
    

    この行がsrc/pkg/net/dnsclient_unix_test.goファイルの2行目に追加されました。これはGoのビルド制約ディレクティブであり、このファイルがdarwin (macOS), freebsd, linux, netbsd, openbsd のいずれかのオペレーティングシステムでビルドされる場合にのみ、コンパイル対象に含めることをGoコンパイラに指示します。これにより、WindowsやPlan 9などの他のOSでビルドする際には、このファイルは完全に無視され、ファイル内の未定義シンボルによるコンパイルエラーが回避されます。

  2. TestTCPLookup関数内のOS判定ロジックを削除:

    -	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
    -		t.Skip("skipping unix dns test")
    -	}
    

    TestTCPLookup関数内に存在した、runtime.GOOSを使ってWindowsまたはPlan 9の場合にテストをスキップする条件分岐が削除されました。これは、上記1.のビルドタグの追加により、このファイル自体がWindowsやPlan 9環境ではコンパイルされなくなったため、この実行時チェックが不要になったためです。ファイルがコンパイル対象から除外されることで、より根本的な解決が図られています。

これらの変更により、dnsclient_unix_test.goはUnix系OS専用のテストファイルとして明確に位置づけられ、クロスプラットフォームビルドにおけるコンパイルエラーが解消されました。

関連リンク

参考にした情報源リンク

このコミットは、src/pkg/net/dnsclient_unix_test.go ファイルに対する変更です。具体的には、Windowsビルドにおけるコンパイルエラーを修正するために、ビルドタグの追加と、既存のOS判定によるテストスキップロジックの削除が行われています。

コミット

commit d90a81c39f06351ce6524a1ae15499d2d60253c8
Author: Dmitriy Vyukov <dvyukov@google.com>
Date:   Wed Aug 14 00:44:57 2013 +0400

    net: fix windows build
    Windows builders say:
    pkg\net\dnsclient_unix_test.go:24: undefined: dnsConfig
    pkg\net\dnsclient_unix_test.go:25: undefined: exchange
    
    R=golang-dev
    CC=golang-dev
    https://golang.org/cl/12889043

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

https://github.com/golang/go/commit/d90a81c39f06351ce6524a1ae15499d2d60253c8

元コミット内容

net: fix windows build
Windows builders say:
pkg\net\dnsclient_unix_test.go:24: undefined: dnsConfig
pkg\net\dnsclient_unix_test.go:25: undefined: exchange

変更の背景

このコミットの背景には、Go言語のnetパッケージ内のDNSクライアントのUnix固有のテストファイル(dnsclient_unix_test.go)が、Windows環境でビルドエラーを引き起こしていた問題があります。具体的には、Windowsのビルド環境でこのファイルをコンパイルしようとすると、dnsConfigexchangeというシンボルが未定義であるというエラーが発生していました。

これは、dnsclient_unix_test.goがUnix系OS(Darwin, FreeBSD, Linux, NetBSD, OpenBSDなど)に特化した機能や構造体を使用しているためです。Windows環境ではこれらのシンボルが存在しないため、コンパイルエラーが発生していました。

この問題を解決するため、コミットではGoのビルドタグ(+buildディレクティブ)を利用して、このテストファイルが特定のUnix系OSでのみコンパイルされるように変更されました。これにより、Windows環境でのビルド時にこのファイルが無視され、エラーが解消されます。

前提知識の解説

Go言語のビルドタグ(Build Tags / Build Constraints)

Go言語には、特定のファイルが特定の環境(OS、アーキテクチャ、Goのバージョンなど)でのみコンパイルされるように制御するメカニズムとして「ビルドタグ(Build Tags)」または「ビルド制約(Build Constraints)」があります。これは、ソースファイルの先頭に// +buildディレクティブを記述することで実現されます。

  • 構文: // +build tag1 tag2,tag3
    • タグはスペースで区切られ、OR条件として扱われます(tag1またはtag2,tag3のいずれかが真であればコンパイルされる)。
    • カンマで区切られたタグはAND条件として扱われます(tag2tag3の両方が真であればコンパイルされる)。
    • !tagのように!を前置するとNOT条件になります。
  • 目的:
    • プラットフォーム固有のコード: OSやアーキテクチャに依存するコードを分離し、適切な環境でのみコンパイルされるようにする。
    • テストコードの分離: 特定の環境でのみ実行されるテストや、外部リソースに依存するテストを分離する。
    • 開発環境と本番環境の分離: デバッグ用のコードや開発ツールを本番ビルドから除外する。
  • :
    • // +build linux:Linuxでのみコンパイル。
    • // +build windows,amd64:WindowsかつAMD64アーキテクチャでのみコンパイル。
    • // +build !windows:Windows以外でコンパイル。

Goのビルドシステムは、ソースファイルをスキャンし、これらのビルドタグを評価して、現在のビルド環境に合致するファイルのみをコンパイル対象とします。これにより、クロスプラットフォーム開発が容易になり、特定のOSに依存するコードが他のOSでコンパイルエラーを引き起こすのを防ぐことができます。

runtime.GOOS

runtime.GOOSは、Go言語の標準ライブラリruntimeパッケージで提供される定数で、プログラムが実行されているオペレーティングシステムの名前を表す文字列です。例えば、Linuxでは"linux"、Windowsでは"windows"、macOSでは"darwin"となります。

この定数は、実行時にOSを判別し、それに基づいて異なるロジックを実行するために使用されます。しかし、コンパイル時に特定のOS用のコードを完全に除外したい場合には、ビルドタグの方が適しています。なぜなら、runtime.GOOSによる条件分岐は、そのコードブロックがコンパイル時に含まれてしまうため、未定義シンボルエラーなどを完全に回避できない場合があるからです。

技術的詳細

このコミットの技術的詳細は、Go言語のビルドシステムがどのようにプラットフォーム固有のコードを扱うかという点に集約されます。

元のコードでは、TestTCPLookup関数内でruntime.GOOS == "windows" || runtime.GOOS == "plan9"という条件分岐を使って、WindowsまたはPlan 9環境の場合にテストをスキップしていました。これは実行時の動作を制御するためのものであり、コンパイル時の問題を解決するものではありませんでした。

Windowsのビルド環境では、dnsclient_unix_test.goファイル全体がコンパイル対象に含まれていました。このファイルはUnix系OSのDNSクライアントテストであり、内部でdnsConfigexchangeといったUnix系OSのネットワークスタックに関連する構造体や関数を参照していました。これらのシンボルはWindowsのGo標準ライブラリには存在しないため、コンパイル時に「undefined」(未定義)エラーが発生していました。

コミットによる修正は、この問題を根本的に解決するために、ファイルレベルでコンパイル対象を制御するビルドタグを導入しました。

// +build darwin freebsd linux netbsd openbsd

この行をファイルの先頭に追加することで、Goのビルドツールは、このdnsclient_unix_test.goファイルがdarwin(macOS)、freebsdlinuxnetbsdopenbsdのいずれかのOSでビルドされる場合にのみコンパイル対象に含めるようになります。Windows環境でビルドする際には、このファイルは完全に無視されるため、dnsConfigexchangeといった未定義シンボルによるコンパイルエラーが発生しなくなります。

また、ファイル全体がWindows環境でコンパイルされなくなるため、既存のruntime.GOOSによるテストスキップロジックは不要となり、削除されました。これにより、コードの冗長性が解消され、意図がより明確になりました。

この変更は、Go言語におけるクロスプラットフォーム開発のベストプラクティスを示しています。実行時にOSを判別して動作を変えるのではなく、コンパイル時にOS固有のファイルを切り替えることで、よりクリーンでエラーの少ないビルドプロセスを実現できます。

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

--- a/src/pkg/net/dnsclient_unix_test.go
+++ b/src/pkg/net/dnsclient_unix_test.go
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// +build darwin freebsd linux netbsd openbsd
+
 package net
 
 import (
@@ -10,9 +12,6 @@ import (
 )
 
 func TestTCPLookup(t *testing.T) {
-\tif runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
-\t\tt.Skip("skipping unix dns test")
-\t}\
 \tif testing.Short() || !*testExternal {\
 \t\tt.Skip("skipping test to avoid external network")
 \t}\

コアとなるコードの解説

このコミットにおけるコアとなるコードの変更は以下の2点です。

  1. ファイルの先頭にビルドタグを追加:

    // +build darwin freebsd linux netbsd openbsd
    

    この行がsrc/pkg/net/dnsclient_unix_test.goファイルの2行目に追加されました。これはGoのビルド制約ディレクティブであり、このファイルがdarwin (macOS), freebsd, linux, netbsd, openbsd のいずれかのオペレーティングシステムでビルドされる場合にのみ、コンパイル対象に含めることをGoコンパイラに指示します。これにより、WindowsやPlan 9などの他のOSでビルドする際には、このファイルは完全に無視され、ファイル内の未定義シンボルによるコンパイルエラーが回避されます。

  2. TestTCPLookup関数内のOS判定ロジックを削除:

    -	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
    -		t.Skip("skipping unix dns test")
    -	}
    

    TestTCPLookup関数内に存在した、runtime.GOOSを使ってWindowsまたはPlan 9の場合にテストをスキップする条件分岐が削除されました。これは、上記1.のビルドタグの追加により、このファイル自体がWindowsやPlan 9環境ではコンパイルされなくなったため、この実行時チェックが不要になったためです。ファイルがコンパイル対象から除外されることで、より根本的な解決が図られています。

これらの変更により、dnsclient_unix_test.goはUnix系OS専用のテストファイルとして明確に位置づけられ、クロスプラットフォームビルドにおけるコンパイルエラーが解消されました。

関連リンク

参考にした情報源リンク