介绍
该 Go 编程语言配备了丰富的工具链,使获取包和构建可执行功能非常容易。 Go 最强大的功能之一是能够为任何 Go 支持的外部平台交叉构建可执行功能。这使得测试和包分发变得更容易,因为您不需要访问特定平台才能为其分发您的包。
在本教程中,您将使用Go的工具从版本控制中获取一个包,并自动安装其可执行的程序,然后您将手动构建和安装可执行的程序,以便您熟悉该过程。
前提条件
要遵循本教程,您将需要:
- 一个 Ubuntu 16.04 服务器设置为 Ubuntu 16.04 初始服务器设置指南,包括一个 sudo 非根用户和防火墙。
步骤 1 — 从版本控制中安装Go程序
在从Go软件包中创建可执行文件之前,我们必须获得其源代码. " go get " 工具可以从GitHub等版本控制系统获取软件包。 在罩下,去'克隆包被装入
$GOPATH/src/'目录的子目录。 然后,如果适用,它通过建造其可执行文件并将其放入$GOPATH/bin'目录来安装该软件包。 如果您配置了先决条件教程中描述的去,
$GOPATH/ bin 目录将包含在您的
$PATH` 环境变量中, 它将确保您可以从系统中的任何地方使用安装的软件包 .
go get
命令的语法是go get package-import-path
。 package-import-path
是一个单独识别包的字符串,通常是包在 Github 等远程存储库中的位置,或者在您的机器上的$GOPATH/src/
目录中的目录。
通常使用go get
与-u
旗帜,指示go get
获取包和其依赖,或更新这些依赖,如果它们已经存在于机器上。
在本教程中,我們將安裝 Caddy,一個網頁伺服器寫在 Go. 在 Caddy的指示x,我們將使用 github.com/mholt/caddy/caddy
為包輸入路徑. 使用 go get
來收集和安裝 Caddy:
1go get -u github.com/mholt/caddy/caddy
该命令需要一段时间才能完成,但您不会看到任何进展,因为它接收包并安装它. 没有输出实际上表明该命令成功执行。
当命令完成时,你会发现Caddy的源代码在$GOPATH/src/github.com/mholt/caddy
上可用。此外,由于Caddy有一个可执行的代码,它被自动创建并存储在$GOPATH/bin
目录中。
1which caddy
您将看到以下输出:
1[secondary_label Output]
2/home/sammy/work/bin/caddy
美元(注)
注意 :‘go get’命令将从 Git 存储库的默认分支中安装包,这在许多情况下是‘master’或在开发中的分支。
您可以使用Git命令,如) 了解有关如何切换分支的更多信息。
美元
让我们更详细地看看安装Go包的过程,从我们已经获得的包创建可执行程序开始。
步骤 2 — 构建一个可执行的
Go Get
命令下载了源,并在一个命令中为我们安装了Caddy的可执行程序,但您可能希望自己重建可执行程序,或者从自己的代码中构建可执行程序。
虽然我们已经安装了Caddy,但让我们手动重建它,以便我们可以舒适地使用该过程。
1go build github.com/mholt/caddy/caddy
如前所述,没有输出表示成功操作. 可执行的将生成在当前目录中,与包含包的目录相同的名称。
如果您位于包目录中,您可以跳过通往包的路径,然后简单地运行去构建
。
要指定可执行的不同的名称或位置,请使用-o
旗帜. 让我们构建一个名为caddy-server
的可执行,并将其放置在当前工作目录中的构建
目录中:
1go build -o build/caddy-server github.com/mholt/caddy/caddy
此命令会创建可执行的文件,并在不存在的情况下创建 `./build’ 目录。
现在让我们来看看安装 executables。
步骤 3 — 安装一个可执行的
构建可执行程序会创建当前目录或您选择的目录中的可执行程序。 安装可执行程序是创建可执行程序并将其存储在$GOPATH/bin
中。
要安装一个可执行的,请使用去安装
,然后使用包导入路径。
1go install github.com/mholt/caddy/caddy
就像「Go build」一樣,如果命令成功的話,你將不會看到任何輸出。 和以前一樣,執行程式的名稱與包含包的目錄相同,但這次執行程式儲存在「$GOPATH/bin」。 如果「$GOPATH/bin」是您的「$PATH」環境變量的一部分,執行程式將可在您的作業系統上任何地方使用。 您可以使用「哪個」命令來驗證其位置:
1which caddy
您将看到以下输出:
1[secondary_label Output of which]
2/home/sammy/work/bin/caddy
现在,你已经了解了go get
,go build
和go install
是如何工作的,以及它们是如何相关的,让我们探索最流行的Go功能之一:为其他目标平台创建可执行的功能。
步骤4 - 构建不同架构的执行程序
Go build
命令允许您在您的平台上为任何 Go 支持的目标平台构建可执行文件,这意味着您可以测试,发布和分发您的应用程序,而不会在您想要使用的目标平台上构建这些可执行文件。
通过设置指定目标操作系统和架构的所需环境变量来进行交叉编译,我们使用目标操作系统的变量GOOS
,目标架构的变量GOARCH
。
1env 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 '
自由 '
386 ' 免费 '
amd64 '
自由'
武装'
linux ' 386 ' | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Linux ' arm '
linux '
arm64 ' `
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
linux '
mips64 ' |
Linux ' mips64le '
|
网易 '
386 ' |
网点 '
amd64 '
netbsd '
arm ' ``````
开放 '
386 ' 开放 '
amd64 '
开放 '
武装 ' 计划9 '
386 '
计划9 '
amd64 ' 索拉里斯 '
amd64 '
窗口 '
386 ' 窗口 ' `amd64 ' 号
金钱(警告)
警告: 跨编译的执行程序 Android 需要 Android NDK,和一些额外的设置,这是超出本教程的范围。
美元
使用表中的值,我们可以这样构建 64 位 Windows 的 Caddy:
1env GOOS=windows GOARCH=amd64 go build github.com/mholt/caddy/caddy
再一次,没有输出表明操作是成功的。执行将创建在当前目录中,使用包名称作为其名称。
您应该在当前目录中有caddy.exe
文件,您可以使用ls
命令验证。
1ls caddy.exe
您将看到输出中列出的caddy.exe
文件:
1[secondary_label Output]
2caddy.exe
<$>[注] 注 :您可以使用 -o
标志重新命名可执行的文件,或将其放置在不同的位置,但是,在为 Windows 构建可执行的文件并提供不同的名称时,请确保在设置可执行的名称时明确指定 .exe
suffix。
让我们来看看这个过程的脚本,以便更容易为多个目标环境发布软件。
步骤5 — 创建一个自动交叉编译的脚本
为许多平台创建可执行程序的过程可能有点无聊,但我们可以创建一个脚本来使事情变得更容易。
该脚本将采用包导入路径作为一个参数,通过预定义的操作系统和平台对列表迭代,并为每个对生成一个可执行的,将输出放置到当前目录中。
切换到您的主目录,并在文本编辑器中创建一个名为go-executable-build.bash
的新文件:
1cd ~
2nano go-executable-build.bash
我们将以 shebang 行开始我们的脚本. 该行定义了哪个解释器在作为可执行程序运行时将该脚本解析。
1[label go-executable-build.bash]
2#!/usr/bin/env bash
要做到这一点,我们将使用$n
变量,其中n
是一个非负数。$0
变量包含你执行的脚本的名称,而$1
和更大将包含用户提供的参数。
1[label go-executable-build.bash]
2...
3package=$1
接下来,请确保用户提供此值. 如果没有提供该值,请离开脚本,并发出说明如何使用脚本的消息:
1[label go-executable-build.bash]
2...
3
4if [[ -z "$package" ]]; then
5 echo "usage: $0 <package-name>"
6 exit 1
7fi
此如果
语句检查了$package
变量的值。如果没有设置,我们会使用echo
来打印正确的使用,然后使用exit
终止脚本。
美元(注)
注意 :如果您想让此脚本与预定义的包一起工作,请更改包
变量以指向该导入路径:
1[label go-executable-build.bash]
2...
3package="github.com/user/hello"
美元
接下来,我们要从路径中提取包的名称。包的导入路径由 /
字符划分,而包的名称位于路径的尽头。
1[label go-executable-build.bash]
2package_split=(${package//\// })
该包名称应该是这个新的$package_split
数组的最后一个元素。在Bash中,您可以使用负数组索引从末端访问一个数组,而不是从开始。
1[label go-executable-build.bash]
2...
3package_name=${package_split[-1]}
在本教程中,我们将构建 64 位 Windows、32 位 Windows 和 64 位 macOS 的执行程序. 我们将将这些目标放置在一个组合中,格式为OS/Platform
,因此我们可以将每个对分为GOOS
和GOARCH
变量,使用我们从路径中提取包名称的相同方法。
1[label go-executable-build.bash]
2...
3platforms=("windows/amd64" "windows/386" "darwin/amd64")
接下来,我们将重复通过平台的数组,将每个平台输入分为GOOS
和GOARCH
环境变量的值,并使用这些来构建可执行的。
1[label go-executable-build.bash]
2...
3for platform in "${platforms[@]}"
4do
5 ...
6done
平台
变量将包含每个迭代中的平台
数组的输入,我们需要将平台
分为两个变量 - GOOS
和GOARCH
。
1[label go-executable-build.bash]
2for platform in "${platforms[@]}"
3do
4 platform_split=(${platform//\// })
5 GOOS=${platform_split[0]}
6 GOARCH=${platform_split[1]}
7
8done
接下来,我们将通过将包名称与操作系统和架构相结合来生成可执行的名称. 当我们为 Windows 构建时,我们还需要在文件名中添加.exe
字符串。
1[label go-executable-build.bash]
2for platform in "${platforms[@]}"
3do
4 platform_split=(${platform//\// })
5 GOOS=${platform_split[0]}
6 GOARCH=${platform_split[1]}
7
8 output_name=$package_name'-'$GOOS'-'$GOARCH
9
10 if [ $GOOS = "windows" ]; then
11 output_name+='.exe'
12 fi
13done
随着变量设置,我们使用go build
来创建可执行的行. 将此行添加到for
循环的体内,直接在完成
关键字上方:
1[label go-executable-build.bash]
2...
3 if [ $GOOS = "windows" ]; then
4 output_name+='.exe'
5 fi
6
7 env GOOS=$GOOS GOARCH=$GOARCH go build -o $output_name $package
8
9done
最后,我们应检查一下是否存在可执行文件编制错误。 例如,如果我们试图构建一个我们没有来源的软件包,我们可能会遇到错误. 我们可以检查去建立
命令的返回代码是否为非零值。 变数"$"? 包含来自先前命令执行的返回代码。 如果去建设'返回除
0'以外的任何东西,就有一个问题,我们想退出剧本。 在去建立 ' 命令后,在
去建立 ' 关键词上方,将这个代码添加到 " for " 循环中.
1[label go-executable-build.bash]
2
3...
4
5 env GOOS=$GOOS GOARCH=$GOARCH go build -o $output_name $package
6
7 if [ $? -ne 0 ]; then
8 echo 'An error has occurred! Aborting the script execution...'
9 exit 1
10 fi
有了这一点,我们现在有一个脚本,将从我们的Go包中构建多个执行程序。
1[label go-executable-build.bash]
2
3#!/usr/bin/env bash
4
5package=$1
6if [[ -z "$package" ]]; then
7 echo "usage: $0 <package-name>"
8 exit 1
9fi
10package_split=(${package//\// })
11package_name=${package_split[-1]}
12
13platforms=("windows/amd64" "windows/386" "darwin/amd64")
14
15for platform in "${platforms[@]}"
16do
17 platform_split=(${platform//\// })
18 GOOS=${platform_split[0]}
19 GOARCH=${platform_split[1]}
20 output_name=$package_name'-'$GOOS'-'$GOARCH
21 if [ $GOOS = "windows" ]; then
22 output_name+='.exe'
23 fi
24
25 env GOOS=$GOOS GOARCH=$GOARCH go build -o $output_name $package
26 if [ $? -ne 0 ]; then
27 echo 'An error has occurred! Aborting the script execution...'
28 exit 1
29 fi
30done
检查您的文件是否匹配前面的代码,然后保存文件并退出编辑器。
在我们可以使用脚本之前,我们必须用chmod
命令使其可执行:
1chmod +x go-executable-build.bash
最后,通过构建Caddy的执行程序来测试脚本:
1./go-executable-build.bash github.com/mholt/caddy/caddy
如果一切顺利,你应该在当前的目录中有可执行的内容. 没有输出显示了成功的脚本执行情况. 你可以通过使用ls
命令来验证是否有可执行的内容:
1ls caddy*
你应该看到这三个版本:
1[secondary_label Example ls output]
2caddy-darwin-amd64 caddy-windows-386.exe caddy-windows-amd64.exe
要更改目标平台,只需在脚本中更改平台
变量。
结论
在本教程中,您已经学会了如何使用Go的工具来从版本控制系统中获取包,以及为不同的平台构建和交叉编译执行程序。
您还创建了一个脚本,您可以使用它来对多个平台进行单个包的交叉编译。
要确保您的应用程序正常工作,您可以查看 测试 和** 连续集成** 如 Travis-CI和 AppVeyor在 Windows 上进行测试。
如果您对 Caddy 和如何使用它感兴趣,请参阅 如何在 Ubuntu 16.04 上使用 Caddy 托管网站。