Ubuntu16.04で複数のプラットフォーム用のGo実行可能ファイルを構築する方法
序章
Goプログラミング言語には、パッケージの取得と実行可能ファイルの構築を非常に簡単にする豊富なツールチェーンが付属しています。 Goの最も強力な機能の1つは、Goがサポートする外部プラットフォーム用の実行可能ファイルをクロスビルドする機能です。 これにより、パッケージを配布するために特定のプラットフォームにアクセスする必要がないため、テストとパッケージ配布がはるかに簡単になります。
このチュートリアルでは、Goのツールを使用して、バージョン管理からパッケージを取得し、その実行可能ファイルを自動的にインストールします。 次に、実行可能ファイルを手動でビルドしてインストールし、プロセスに精通できるようにします。 次に、異なるアーキテクチャ用の実行可能ファイルをビルドし、ビルドプロセスを自動化して、複数のプラットフォーム用の実行可能ファイルを作成します。 完了すると、WindowsとmacOS、およびサポートしたい他のプラットフォーム用の実行可能ファイルを作成する方法がわかります。
前提条件
このチュートリアルに従うには、次のものが必要です。
- Ubuntu16.04初期サーバーセットアップガイドに従ってセットアップされた1つのUbuntu16.04サーバー。これには、sudo非rootユーザーとファイアウォールが含まれます。
- Ubuntu16.04にGo1.6をインストールする方法の説明に従ってインストールします。
ステップ1—バージョン管理からGoプログラムをインストールする
Goパッケージから実行可能ファイルを作成する前に、そのソースコードを取得する必要があります。 go getツールは、GitHubなどのバージョン管理システムからパッケージをフェッチできます。 内部的には、go getはパッケージを$GOPATH/src/ディレクトリのサブディレクトリに複製します。 次に、該当する場合は、実行可能ファイルをビルドして$GOPATH/binディレクトリに配置することでパッケージをインストールします。 前提条件のチュートリアルで説明されているようにGoを構成した場合、$GOPATH/binディレクトリが$PATH環境変数に含まれ、システムのどこからでもインストール済みパッケージを使用できるようになります。
go getコマンドの構文はgo get package-import-pathです。 package-import-pathは、パッケージを一意に識別する文字列です。 多くの場合、Githubなどのリモートリポジトリ内のパッケージの場所、またはマシンの$GOPATH/src/ディレクトリ内のディレクトリです。
go getを-uフラグとともに使用するのが一般的です。このフラグは、go getにパッケージとその依存関係を取得するか、それらの依存関係がすでにマシンに存在する場合はそれらを更新するように指示します。
このチュートリアルでは、Goで記述されたWebサーバーであるCaddyをインストールします。 Caddyの指示xに従って、パッケージのインポートパスにgithub.com/mholt/caddy/caddyを使用します。 go getを使用して、Caddyをフェッチしてインストールします。
go get -u github.com/mholt/caddy/caddy
コマンドの完了にはしばらく時間がかかりますが、パッケージをフェッチしてインストールしている間は進行状況は表示されません。 出力がない場合は、コマンドが正常に実行されたことを実際に示しています。
コマンドが完了すると、Caddyのソースコードが$GOPATH/src/github.com/mholt/caddyにあります。 さらに、Caddyには実行可能ファイルがあるため、自動的に作成され、$GOPATH/binディレクトリに保存されます。 whichを使用して実行可能ファイルの場所を印刷することにより、これを確認します。
which caddy
次の出力が表示されます。
Output/home/sammy/work/bin/caddy
注:go getコマンドは、Gitリポジトリのデフォルトブランチ(多くの場合、masterまたは開発中のブランチ)からパッケージをインストールします。 go getを使用する前に、通常はリポジトリのREADMEファイルにある手順を確認してください。
git checkoutなどのGitコマンドを使用して、go getコマンドを使用して取得したソースで別のブランチを選択できます。 チュートリアルGitブランチの使用方法を確認して、ブランチを切り替える方法の詳細を確認してください。
すでに取得したパッケージから実行可能ファイルを作成することから始めて、Goパッケージをインストールするプロセスをより詳細に見てみましょう。
ステップ2—実行可能ファイルを作成する
go getコマンドは、ソースをダウンロードし、Caddyの実行可能ファイルを1つのコマンドでインストールしました。 ただし、実行可能ファイルを自分で再構築するか、独自のコードから実行可能ファイルを構築することをお勧めします。 go buildコマンドは、実行可能ファイルをビルドします。
すでにCaddyをインストールしましたが、プロセスに慣れるために、手動で再度ビルドしてみましょう。 go buildを実行し、パッケージのインポートパスを指定します。
go build github.com/mholt/caddy/caddy
以前と同様に、出力がない場合は正常に動作したことを示します。 実行可能ファイルは、パッケージを含むディレクトリと同じ名前で、現在のディレクトリに生成されます。 この場合、実行可能ファイルの名前はcaddyになります。
パッケージディレクトリにいる場合は、パッケージへのパスを省略して、go buildを実行するだけです。
実行可能ファイルに別の名前または場所を指定するには、-oフラグを使用します。 caddy-serverという実行可能ファイルを作成し、現在の作業ディレクトリ内のbuildディレクトリに配置してみましょう。
go build -o build/caddy-server github.com/mholt/caddy/caddy
このコマンドは実行可能ファイルを作成し、./buildディレクトリが存在しない場合はそれも作成します。
次に、実行可能ファイルのインストールを見てみましょう。
ステップ3—実行可能ファイルのインストール
実行可能ファイルを作成すると、現在のディレクトリまたは選択したディレクトリに実行可能ファイルが作成されます。 実行可能ファイルのインストールは、実行可能ファイルを作成して$GOPATH/binに保存するプロセスです。 go installコマンドはgo buildと同じように機能しますが、go installが出力ファイルを適切な場所に配置します。
実行可能ファイルをインストールするには、go installに続けて、パッケージのインポートパスを使用します。 もう一度、Caddyを使用してこれを試してください。
go install github.com/mholt/caddy/caddy
go buildと同様に、コマンドが成功した場合、出力は表示されません。 以前と同様に、実行可能ファイルはパッケージを含むディレクトリと同じ名前で作成されます。 ただし、今回は実行可能ファイルは$GOPATH/binに格納されます。 $GOPATH/binが$PATH環境変数の一部である場合、実行可能ファイルはオペレーティングシステムのどこからでも利用できます。 whichコマンドを使用して、その場所を確認できます。
which caddy
次の出力が表示されます。
Output of which/home/sammy/work/bin/caddy
go get、go build、およびgo installがどのように機能し、それらがどのように関連しているかを理解したところで、最も人気のあるGo機能の1つである他のターゲットの実行可能ファイルの作成について見ていきましょう。プラットフォーム。
ステップ4—さまざまなアーキテクチャの実行可能ファイルを構築する
go buildコマンドを使用すると、Goがサポートするターゲットプラットフォームの実行可能ファイルをプラットフォームに作成できます。 つまり、使用するターゲットプラットフォームで実行可能ファイルをビルドしなくても、アプリケーションをテスト、リリース、および配布できます。
クロスコンパイルは、ターゲットオペレーティングシステムとアーキテクチャを指定する必要な環境変数を設定することで機能します。 ターゲットオペレーティングシステムには変数GOOSを使用し、ターゲットアーキテクチャにはGOARCHを使用します。 実行可能ファイルを作成するには、コマンドは次の形式になります。
env GOOS=target-OS GOARCH=target-architecture go build package-import-path
envコマンドは、変更された環境でプログラムを実行します。 これにより、現在のコマンド実行にのみ環境変数を使用できます。 コマンドの実行後、変数は設定解除またはリセットされます。
次の表に、使用できるGOOSとGOARCHの可能な組み合わせを示します。
GOOS-ターゲットオペレーティングシステム
|
GOARCH-ターゲットプラットフォーム
|
|---|---|
android
|
arm
|
darwin
|
386
|
darwin
|
amd64
|
darwin
|
arm
|
darwin
|
arm64
|
dragonfly
|
amd64
|
freebsd
|
386
|
freebsd
|
amd64
|
freebsd
|
arm
|
linux
|
386
|
linux
|
amd64
|
linux
|
arm
|
linux
|
arm64
|
linux
|
ppc64
|
linux
|
ppc64le
|
linux
|
mips
|
linux
|
mipsle
|
linux
|
mips64
|
linux
|
mips64le
|
netbsd
|
386
|
netbsd
|
amd64
|
netbsd
|
arm
|
openbsd
|
386
|
openbsd
|
amd64
|
openbsd
|
arm
|
plan9
|
386
|
plan9
|
amd64
|
solaris
|
amd64
|
windows
|
386
|
windows
|
amd64
|
警告: Android用の実行可能ファイルのクロスコンパイルには、 Android NDK と、このチュートリアルの範囲を超える追加のセットアップが必要です。
表の値を使用して、次のようにCaddy forWindows64ビットを構築できます。
env GOOS=windows GOARCH=amd64 go build github.com/mholt/caddy/caddy
この場合も、操作が成功したことを示す出力はありません。 実行可能ファイルは、パッケージ名を名前として使用して、現在のディレクトリに作成されます。 ただし、この実行可能ファイルをWindows用にビルドしたため、名前は接尾辞.exeで終わります。
現在のディレクトリにcaddy.exeファイルがあり、lsコマンドで確認できます。
ls caddy.exe
caddy.exeファイルが出力に表示されます。
Outputcaddy.exe
注:-oフラグを使用して、実行可能ファイルの名前を変更したり、別の場所に配置したりできます。 ただし、Windows用の実行可能ファイルを作成して別の名前を付ける場合は、実行可能ファイルの名前を設定するときに、必ず.exeサフィックスを明示的に指定してください。
複数のターゲット環境向けのソフトウェアをリリースしやすくするために、このプロセスのスクリプトを見てみましょう。
ステップ5—クロスコンパイルを自動化するスクリプトを作成する
多くのプラットフォームで実行可能ファイルを作成するプロセスは少し面倒ですが、スクリプトを作成して作業を簡単にすることができます。
スクリプトは、パッケージのインポートパスを引数として取り、オペレーティングシステムとプラットフォームのペアの事前定義されたリストを反復処理し、各ペアの実行可能ファイルを生成して、出力を現在のディレクトリに配置します。 各実行可能ファイルには、package-OS-architectureの形式で、パッケージ名に続いてターゲットプラットフォームとアーキテクチャという名前が付けられます。 これは、あらゆるプロジェクトで使用できるユニバーサルスクリプトになります。
ホームディレクトリに切り替えて、テキストエディタでgo-executable-build.bashという名前の新しいファイルを作成します。
cd ~ nano go-executable-build.bash
スクリプトはshebang行から始めます。 この行は、実行可能ファイルとして実行されたときにこのスクリプトを解析するインタープリターを定義します。 次の行を追加して、bash がこのスクリプトを実行するように指定します。
go-executable-build.bash
#!/usr/bin/env bash
パッケージのインポートパスをコマンドライン引数として使用します。 これを行うには、$n変数を使用します。ここで、nは非負の数です。 変数$0には実行したスクリプトの名前が含まれ、$1以降にはユーザー指定の引数が含まれます。 この行をスクリプトに追加します。これにより、コマンドラインから最初の引数が取得され、packageという変数に格納されます。
go-executable-build.bash
... package=$1
次に、ユーザーがこの値を指定したことを確認します。 値が指定されていない場合は、スクリプトの使用方法を説明するメッセージを表示してスクリプトを終了します。
go-executable-build.bash
... if [[ -z "$package" ]]; then echo "usage: $0 <package-name>" exit 1 fi
このifステートメントは、$package変数の値をチェックします。 設定されていない場合は、echoを使用して正しい使用法を出力し、exitを使用してスクリプトを終了します。 exitは引数として戻り値を取ります。これは、実行が成功した場合は0であり、実行が失敗した場合はゼロ以外の値である必要があります。 スクリプトが成功しなかったため、ここでは1を使用します。
注:このスクリプトを事前定義されたパッケージで機能させる場合は、package変数を変更してそのインポートパスを指すようにします。
go-executable-build.bash
... package="github.com/user/hello"
次に、パスからパッケージ名を抽出します。 パッケージのインポートパスは/文字で区切られ、パッケージ名はパスの最後にあります。 まず、/を区切り文字として使用して、パッケージのインポートパスを配列に分割します。
go-executable-build.bash
package_split=(${package//\// })
パッケージ名は、この新しい$package_split配列の最後の要素である必要があります。 Bashでは、負の配列インデックスを使用して、最初からではなく最後から配列にアクセスできます。 この行を追加して、配列からパッケージ名を取得し、package_nameという変数に格納します。
go-executable-build.bash
...
package_name=${package_split[-1]}
次に、実行可能ファイルをビルドするプラットフォームとアーキテクチャを決定する必要があります。 このチュートリアルでは、Windows 64ビット、Windows 32ビット、および64ビットmacOS用の実行可能ファイルを作成します。 これらのターゲットをOS/Platformの形式で配列に配置するため、パッケージ名の抽出に使用したのと同じ方法を使用して、各ペアをGOOS変数とGOARCH変数に分割できます。パスから。 スクリプトにプラットフォームを追加します。
go-executable-build.bash
...
platforms=("windows/amd64" "windows/386" "darwin/amd64")
次に、プラットフォームの配列を反復処理し、各プラットフォームエントリをGOOSおよびGOARCH環境変数の値に分割し、それらを使用して実行可能ファイルをビルドします。 これは、次のforループで実行できます。
go-executable-build.bash
...
for platform in "${platforms[@]}"
do
...
done
platform変数には、各反復でplatforms配列からのエントリが含まれます。 platformをGOOSとGOARCHの2つの変数に分割する必要があります。 forループに次の行を追加します。
go-executable-build.bash
for platform in "${platforms[@]}"
do
platform_split=(${platform//\// })
GOOS=${platform_split[0]}
GOARCH=${platform_split[1]}
done
次に、パッケージ名とOSおよびアーキテクチャを組み合わせて、実行可能ファイルの名前を生成します。 Windows用にビルドする場合は、ファイル名に.exeサフィックスを追加する必要もあります。 このコードをforループに追加します。
go-executable-build.bash
for platform in "${platforms[@]}"
do
platform_split=(${platform//\// })
GOOS=${platform_split[0]}
GOARCH=${platform_split[1]}
output_name=$package_name'-'$GOOS'-'$GOARCH
if [ $GOOS = "windows" ]; then
output_name+='.exe'
fi
done
変数を設定したら、go buildを使用して実行可能ファイルを作成します。 この行をforループの本体、doneキーワードのすぐ上に追加します。
go-executable-build.bash
...
if [ $GOOS = "windows" ]; then
output_name+='.exe'
fi
env GOOS=$GOOS GOARCH=$GOARCH go build -o $output_name $package
done
最後に、実行可能ファイルの構築中にエラーが発生したかどうかを確認する必要があります。 たとえば、ソースがないパッケージをビルドしようとすると、エラーが発生する可能性があります。 go buildコマンドの戻りコードでゼロ以外の値を確認できます。 変数$?には、前のコマンドの実行からの戻りコードが含まれています。 go buildが0以外を返す場合は、問題が発生しているため、スクリプトを終了します。 このコードをforループに追加し、go buildコマンドの後、doneキーワードの上に追加します。
go-executable-build.bash
...
env GOOS=$GOOS GOARCH=$GOARCH go build -o $output_name $package
if [ $? -ne 0 ]; then
echo 'An error has occurred! Aborting the script execution...'
exit 1
fi
これで、Goパッケージから複数の実行可能ファイルをビルドするスクリプトができました。 完成したスクリプトは次のとおりです。
go-executable-build.bash
#!/usr/bin/env bash
package=$1
if [[ -z "$package" ]]; then
echo "usage: $0 <package-name>"
exit 1
fi
package_split=(${package//\// })
package_name=${package_split[-1]}
platforms=("windows/amd64" "windows/386" "darwin/amd64")
for platform in "${platforms[@]}"
do
platform_split=(${platform//\// })
GOOS=${platform_split[0]}
GOARCH=${platform_split[1]}
output_name=$package_name'-'$GOOS'-'$GOARCH
if [ $GOOS = "windows" ]; then
output_name+='.exe'
fi
env GOOS=$GOOS GOARCH=$GOARCH go build -o $output_name $package
if [ $? -ne 0 ]; then
echo 'An error has occurred! Aborting the script execution...'
exit 1
fi
done
ファイルが前のコードと一致することを確認します。 次に、ファイルを保存してエディターを終了します。
スクリプトを使用する前に、chmodコマンドでスクリプトを実行可能にする必要があります。
chmod +x go-executable-build.bash
最後に、Caddyの実行可能ファイルを作成して、スクリプトをテストします。
./go-executable-build.bash github.com/mholt/caddy/caddy
すべてがうまくいけば、現在のディレクトリに実行可能ファイルがあるはずです。 スクリプトが正常に実行されたことを示す出力はありません。 lsコマンドを使用して作成された実行可能ファイルであることを確認できます。
ls caddy*
3つのバージョンすべてが表示されます。
Example ls outputcaddy-darwin-amd64 caddy-windows-386.exe caddy-windows-amd64.exe
ターゲットプラットフォームを変更するには、スクリプトのplatforms変数を変更するだけです。
結論
このチュートリアルでは、Goのツールを使用してバージョン管理システムからパッケージを取得する方法と、さまざまなプラットフォーム用の実行可能ファイルをビルドおよびクロスコンパイルする方法を学習しました。
また、多くのプラットフォーム用に単一のパッケージをクロスコンパイルするために使用できるスクリプトを作成しました。
アプリケーションが正しく機能することを確認するために、テストおよびTravis-CIやAppVeyorなどの継続的インテグレーションを確認してテストできます。 Windowsの場合。
Caddyとその使用方法に興味がある場合は、 Ubuntu16.04でCaddyを使用してWebサイトをホストする方法を参照してください。