紹介
Go言語において、ビルドタグやビルド制約として、コードに追加される識別子があり、ビルドプロセス中にどのような时机にファイルがパッケージに含まれるべきか決定します。これにより、同じソースコードからあなたのGoアプリケーションの異なるバージョンを構築することができ、迅速で組織化された方法でそれらを切り替えることができます。多くの開発者がビルドタグを使用して、クロスプラットフォーム互換性のあるアプリケーションの構築 workflow を改善するために、例えば、異なる操作系统間の変化に応じてコード変更を必要とするプログラムなどのアプリケーションに対してはまとめて使用します。ビルドタグはまた、統合テストのために使用されます。これにより、統合コードとモックサービスやスタブのコードを迅速に切り替えることができます。また、アプリケーション内で異なる機能セットのレベルを切り替えることもできます。
客户の特徴集が異なる問題を見ています。例えば、某些应用程序可能需要控制二进制中应包含哪些功能,例如提供免费、专业版和企业版的应用程序。随着客户增加他们的订阅级别,更多功能解锁并可用。为了解决这个问题,您可以保持不同的项目,并通过使用import
语句来尝试同步它们。虽然这种方法可行,但随着时间的推移,它将变得乏味且容易出现错误。另一种方法是使用构建标记。在本文中,您将使用Go中的构建标记生成具有Free、Pro和企业版功能的示例应用程序的不同可执行文件。每个都将具有不同的一组可用功能,其中Free版本是默认的。
要遵循本教程中的示例,您需要:
先决条件
要遵循本教程中的示例,您需要:
- 已经按照如何安装Go并设置本地编程环境设置好Go工作区。
### 1. 准备
#### 1.1. 安装依赖项
为了编译我们的应用程序,我们需要确保我们拥有必要的工具和库。首先,让我们使用`go get`命令来安装所需的包:
“`bash
go get -u github.com/golang-tools/cmd/gofmt
“`这个命令会下载并安装`gofmt`包,这是一个用于格式化Go源代码的工具。接下来,我们将创建一个新目录来存储我们的项目文件。假设你想要将项目命名为`example-app`,你可以使用以下命令:
“`bash
mkdir example-app && cd example-app
“`现在,你已经处于项目的根目录中了。接下来,我们将创建一个`main.go`文件,这是Go应用程序的主入口点。
無料バージョンの構築
まず、アプリケーションの無料バージョンを構築しましょう。これは、go build
コマンドを実行する際にビルドタグを指定しない場合のデフォルトです。後で、ビルドタグを使用してプログラムに他の部分を選択的に追加します。
src
ディレクトリに、アプリケーションの名前と同じフォルダーを作成します。このチュートリアルではapp
を使用します:
このフォルダーに移動します:
次に、テキストエディタで新しいテキストファイルを作成し、名前をmain.go
にします:
今、無料バージョンのアプリケーションを定義しましょう。main.go
に以下の内容を追加します:
このファイルでは、features
という名前のスライスを作成し、無料アプリケーションの機能を表す2つの文字列を保持しています。main()
関数は、features
スライスをfor
ループでrange
して、すべての利用可能な機能を画面に表示します。
ファイルを保存して終了しましょう。このファイルを保存したので、この記事の残りの部分ではそれを編集する必要はありません。代わりに、ビルドタグを使用して、それからビルドするバイナリの機能を変更することができます。
プログラムをビルドして実行します:
以下の出力が得られます:
Output> Free Feature #1
> Free Feature #2
プログラムは、アプリの無料バージョンを完成させるために、2つの無料機能を出力しました。
これまで、非常に基本的な機能セットを持つアプリケーションを作成しました。次に、ビルド時にアプリケーションにさらに機能を追加する方法を構築します。
プロ機能を追加するための go build
main.go
に変更を加えることを避けてきました。これは、メインコードを変更せず、おそらく壊さずにコードを追加する必要がある一般的な生成環境をシミュレートしています。 main.go
ファイルを編集することができないため、ビルドタグを使用して features
スライスにさらに機能を注入する別のメカニズムを使用する必要があります。
新しいファイルを pro.go
という名前で作成し、init()
関数を使用して features
スライスにさらに機能を追加します:
エディタがファイルを開いたら、以下の行を追加しましょう:
このコードでは、アプリケーションのmain()
関数の前に実行するコードにinit()
を使用し、その後features
スライスにPro機能を追加するためにappend()
を使用しました。ファイルを保存して終了しましょう。
アプリケーションをコンパイルして実行するためにgo build
を使用します:
現在のディレクトリには2つのファイルがあります(pro.go
とmain.go
),go build
はこれらの両方からバイナリを作成します。このバイナリを実行してください:
これにより、以下の機能セットが得られます:
Output> Free Feature #1
> Free Feature #2
> Pro Feature #1
> Pro Feature #2
アプリケーションには今やProおよびFreeの機能が含まれています。しかし、これは望ましくありません。バージョン間の区別がないため、FreeバージョンにはProバージョンでのみ利用可能な機能が含まれています。これを修正するためには、アプリケーションの異なるティアを管理するためのさらなるコードを追加するか、Goツールチェーンにどの.go
ファイルをビルドし、どのファイルを無視するかを伝えるためにビルドタグを使用することができます。次のステップでビルドタグを追加しましょう。
ビルドタグの追加
今やビルドタグを使用して、アプリケーションのProバージョンとFreeバージョンを区別することができます。
まず、ビルドタグがどのように見えるかを確認しましょう:
このコード行をパッケージの最初の行として配置し、tag_name
をあなたの構築タグの名前に置き換えることで、このパッケージを最後のバイナリに選択的に含めることができるコードとしてタグを付けます。これを动作させるために、pro.go
ファイルに構築タグを追加し、go build
コマンドによってタグが指定されない限り無視するようにしましょう。テキストエディタでファイルを開いてください:
次に、以下の強調表示された行を追加してください:
// +build pro
package main
func init() {
features = append(features,
"Pro Feature #1",
"Pro Feature #2",
)
}
pro.go
ファイルの最上部に、// +build pro
を付けて空の改行を追加します。この末尾の改行は必須であり、否则、Goはこれをコメントとして解釈します。構築タグ宣言は.go
ファイルの最上部に必ずある必要があります。コメントよりも上に何かがあっても構いません。
+build
宣言は、go build
コマンドにこれはコメントではなく、代わりに構築タグであることを伝えます。2番目の部分はpro
タグです。このタグをpro.go
ファイルの最上部に追加することで、go build
コマンドはこれらのタグが存在する限りのpro.go
ファイルのみを含めます。
アプリケーションを再编译して実行します:
以下の出力が表示されます:
Output> Free Feature #1
> Free Feature #2
なぜなら、pro.go
ファイルはpro
タグが存在することを要求しているからです。ファイルは無視され、タグが存在しない限りアプリケーションはこれを含んでいません。
go build
コマンドを実行する際、-tags
フラグを使用して、構築時にコードをコンパイルソースに条件付きに含めることができます。タグ自体を引数として追加しましょう。これをpro
タグに対して行いましょう。
これは以下のように翻訳されます。
Output> Free Feature #1
> Free Feature #2
> Pro Feature #1
> Pro Feature #2
今、私たちはpro
ビルドタグを使用してアプリケーションを構築する時にのみ追加機能を得ることができます。
これは2つのバージョンだけであれば大丈夫ですが、タグを追加すると複雑になります。次の手順で私たちのアプリのEnterpriseバージョンを追加するために、布尔逻辑を使用して複数のビルドタグを結合することにします。
ビルドタグ布尔逻辑
Goパッケージに複数のビルドタグがある場合、タグは布尔逻辑を使用して互いに影響を与えます。これを示すために、私たちはpro
タグとenterprise
タグを使用して Enterpriseレベルのアプリケーションを追加します。
Enterpriseバイナリを構築するためには、デフォルトの機能、Proレベルの機能、そしてEnterprise用の新しい機能セットを全て含める必要があります。まず、エディタを開き、新しいファイルenterprise.go
を作成し、新しいEnterprise機能を追加するようにすることにします。
enterprise.go
の内容はpro.go
とほぼ同じであるが、新しい機能が含まれます。以下の行をファイルに追加します。
ファイルを保存し、終了します。
現在、enterprise.go
ファイルにはビルドタグがありません。そして、pro.go
を追加した際に学んだように、これは go.build
実行時にこれらの機能がフリーバージョンに追加されることを意味します。pro.go
には、// +build pro
と改行をファイルの先頭に追加して、go build
に -tags pro
が使用された場合にのみ含まれるべきだと指示しました。この場合、目標を達成するためには1つのビルドタグだけで十分です。しかし、新しいエンタープライズ機能を追加する際には、まずプロ機能をお持ちしている必要があります。
まず、enterprise.go
に pro
ビルドタグのサポートを追加しましょう。テキストエディタでファイルを開きます:
次に、package main
宣言の前にビルドタグを追加し、ビルドタグの後に改行を含めるようにします:
// +build pro
package main
func init() {
features = append(features,
"Enterprise Feature #1",
"Enterprise Feature #2",
)
}
ファイルを保存して終了します。
タグなしでアプリケーションをコンパイルして実行します:
以下の出力が得られます:
Output> Free Feature #1
> Free Feature #2
エンタープライズ機能はもはやフリーバージョンに表示されません。今度は pro
ビルドタグを追加して、再度アプリケーションをビルドして実行します:
以下の出力が得られます:
Output> Free Feature #1
> Free Feature #2
> Enterprise Feature #1
> Enterprise Feature #2
> Pro Feature #1
> Pro Feature #2
これはまだ私たちが必要としているものとはまったく异なります。エンタープライズ機能がプロバージョン構築時に表示されるようになっています。これを解決するためには、別のビルドタグを使用する必要があります。pro
タグとは異なり、今度は pro
と enterprise
の両方の機能が利用可能であることを確認する必要があります。
Goのビルドシステムは、ビルドタグシステムに基本的なブール論理を使用することで、この状況に対応しています。
enterprise.go
を再度開きましょう:
もう一つのビルドタグenterprise
をpro
タグの同一行に追加します:
// +build pro enterprise
package main
func init() {
features = append(features,
"Enterprise Feature #1",
"Enterprise Feature #2",
)
}
ファイルを保存し閉じます。
今、新しいenterprise
ビルドタグでアプリケーションをビルドして実行しましょう。
これにより以下のようになります:
Output> Free Feature #1
> Free Feature #2
> Enterprise Feature #1
> Enterprise Feature #2
これでPro機能が失われてしまいました。これは、.go
ファイルの同一行に複数のビルドタグを置くと、go build
がそれらをOR
論理で解釈するからです。// +build pro enterprise
を追加したことにより、enterprise.go
ファイルはどちらか一つのビルドタグが存在する場合にビルドされるようになりました。正しくビルドタグを設定することで、両方を必要とし、AND
論理を使用することができます。
同一行に両方のタグを置く代わりに、別の行にそれぞれのタグを置くことができます。そうすると、go build
はそれらのタグをAND
論理で解釈します。
再度enterprise.go
を開き、ビルドタグを別の行に分けてみましょう。
// +build pro
// +build enterprise
package main
func init() {
features = append(features,
"Enterprise Feature #1",
"Enterprise Feature #2",
)
}
これで新しいenterprise
ビルドタグでアプリケーションをビルドして実行しましょう。
以下の出力が受信されます:
Output> Free Feature #1
> Free Feature #2
まだ正しくありません:AND
ステートメントは両方の要素がtrue
として考慮される必要がありますので、pro
およびenterprise
の両方のビルドタグを使用する必要があります。
もう一度試してみましょう。
Output> Free Feature #1
> Free Feature #2
> Enterprise Feature #1
> Enterprise Feature #2
> Pro Feature #1
> Pro Feature #2
今のアプリケーションは、同一のソースツリーから、複数の方法で構築でき、アプリケーションの機能をそれぞれの方法でアンロックする。
この例では、新しい// +build
タグを使用して、AND
論理を示すことができましたが、ビルドタグを使用して論理式を表すための替代手段があります。以下の表は、ビルドタグの他の構文整形例を含んでおり、それぞれの論理的な等価を示しています:
Build Tag Syntax | Build Tag Sample | Boolean Statement |
---|---|---|
Space-separated elements | // +build pro enterprise |
pro OR enterprise |
Comma-separated elements | // +build pro,enterprise |
pro AND enterprise |
Exclamation point elements | // +build !pro |
NOT pro |
結論
このチュートリアルでは、ビルドタグを使用して、アプリケーションのコードの中で何をコンパイルして binary に含めるかを制御することができました。まず、ビルドタグを宣言してgo build
と共に使用し、2つ以上のタグを論理的に結合しました。その後、Free、Pro、Enterprise バージョンの異なる機能セットを表すプログラムを構築し、ビルドタグがプロジェクト上で与える強力なコントロールレベルを示しました。
ビルドタグについてもっと学びたい場合は、Golang 文档に基づいて探査したり、Go 言語でコードする方法のシリーズを続けて学ぶことができます。
Source:
https://www.digitalocean.com/community/tutorials/customizing-go-binaries-with-build-tags