简介
到目前为止,在我们的《如何使用 Go 编程》系列中,您已经使用 go run
命令自动编译您的源代码并运行生成的可执行文件。虽然这个命令对于在命令行上测试代码很有用,但是要分发或部署应用程序,您需要将代码构建成一个可共享的二进制可执行文件,或者一个包含可以运行您的应用程序的机器字节码的单个文件。为此,您可以使用 Go 工具链来构建和安装您的程序。
在 Go 中,将源代码转换为二进制可执行文件的过程称为构建。一旦构建了这个可执行文件,它将包含不仅您的应用程序,还包括在目标平台上执行二进制文件所需的所有支持代码。这意味着 Go 二进制文件不需要系统依赖项,比如 Go 工具,就可以在新系统上运行。将这些可执行文件放在自己系统上的可执行文件路径上,就可以在系统的任何地方运行程序。这与安装程序到系统上是一样的。
在本教程中,您将使用 Go 工具链来运行、构建和安装一个示例的 Hello, World!
程序,从而能够有效地使用、分发和部署未来的应用程序。
先决条件
要按照本文中的示例,您需要:
- 通过《如何安装 Go 并设置本地编程环境》设置好的 Go 工作区。
步骤 1 —— 设置并运行 Go 二进制文件
首先,创建一个应用程序,用作演示 Go 工具链的示例。为此,您将使用《如何在 Go 中编写您的第一个程序》教程中的经典的 “Hello, World!” 程序。
在您的 src
目录中创建一个名为 greeter
的目录:
mkdir greeter
接下来,进入新创建的目录,并在您选择的文本编辑器中创建 main.go
文件:
cd greeter nano main.go
文件打开后,添加以下内容:
package main import "fmt" func main() { fmt.Println("Hello, World!") }
运行时,此程序将在控制台打印短语 Hello, World!
,然后程序将成功退出。
保存并退出文件。
要测试该程序,使用 go run
命令,就像在之前的教程中所做的那样:
go run main.go
您将收到以下输出:
Hello, World!
如前所述,go run
命令将您的源文件构建成一个可执行二进制文件,然后运行编译后的程序。但是,本教程旨在以一种可以随意共享和分发的方式构建二进制文件。为此,您将在下一步中使用 go build
命令。
步骤 2 —— 创建 Go 模块以构建 Go 二进制文件
Go 程序和库围绕着模块的核心概念构建。一个模块包含有关您的程序使用的库以及要使用的这些库的版本的信息。
为了告诉 Go 这是一个 Go 模块,您需要使用 go mod
命令创建一个 Go 模块:
go mod init greeter
这将创建名为 go.mod
的文件,其中包含模块的名称以及用于构建它的 Go 版本。
go: creating new go.mod: module greeter go: to add module requirements and sums: go mod tidy
Go 将提示您运行 go mod tidy
以更新此模块的要求,如果它们在将来发生更改。现在运行它将不会有额外的效果。
步骤 3 —— 使用 go build
构建 Go 二进制文件
使用 go build
,您可以为我们的示例 Go 应用程序生成一个可执行二进制文件,从而可以在需要的地方分发和部署程序。
尝试使用 main.go
。在您的 greeter
目录中,运行以下命令:
go build
如果不向此命令提供参数,go build
将自动编译当前目录中的 main.go
程序。该命令将包括目录中的所有 *.go
文件。它还将构建执行二进制文件所需的所有支持代码,以便能够在具有相同系统架构的任何计算机上执行二进制文件,而不管该系统是否具有 .go
源文件,甚至是否安装了 Go。
在这种情况下,您将您的 greeter
应用程序构建成一个可执行文件,该文件已添加到当前目录。通过运行 ls
命令来检查:
ls
如果您正在运行 macOS 或 Linux,您将找到一个新的可执行文件,该文件的名称与您构建程序的目录相同:
greeter main.go go.mod
默认情况下,go build
将为当前平台和架构生成可执行文件。例如,在 linux/386
系统上构建,该可执行文件将与任何其他 linux/386
系统兼容,即使没有安装 Go。Go 支持为其他平台和架构构建,您可以在我们的《为不同操作系统和架构构建 Go 应用程序》文章中了解更多信息。
现在,您已经创建了一个可执行二进制文件,运行它以确保二进制文件已正确构建。在 macOS 或 Linux 上,运行以下命令:
./greeter
在 Windows 上,运行:
greeter.exe
二进制文件的输出将与您使用 go run
运行程序时的输出相匹配:
Hello, World!
现在,您已经创建了一个包含不仅您的程序,还包括运行该二进制文件所需的所有系统代码的单个可执行二进制文件。您现在可以将此程序分发到新系统或将其部署到服务器,知道该文件将始终运行相同的程序。
在下一节中,本教程将解释二进制文件的命名方式以及您如何更改它,以便您可以更好地控制程序的构建过程。
步骤 4 —— 更改二进制文件名称
现在你已经知道如何生成可执行文件,下一步是了解 Go 如何选择二进制文件的名称,并为你的项目自定义这个名称。
当你运行 go build
时,默认情况下,Go 会自动决定生成的可执行文件的名称。它通过使用你之前创建的模块来实现这一点。当运行 go mod init greeter
命令时,它使用名称为 ‘greeter’ 创建了模块,这就是为什么生成的二进制文件也被命名为 greeter
。
让我们更仔细地看看模块方法。如果你的项目中有一个 go.mod
文件,并且其中有一个 module
声明,如下所示:
module github.com/sammy/shark
那么生成的可执行文件的默认名称将是 shark
。
在需要特定命名约定的更复杂的程序中,这些默认值并不总是命名你的二进制文件的最佳选择。在这些情况下,最好使用 -o
标志来自定义你的输出。
为了测试这一点,将上一节中创建的可执行文件的名称更改为 hello
,并将其放置在一个名为 bin
的子文件夹中。你不需要创建这个文件夹;Go 在构建过程中会自行创建它。
运行以下带有 -o
标志的 go build
命令:
go build -o bin/hello
-o
标志使得 Go 将命令的输出与你选择的任何参数匹配。在这种情况下,结果是一个名为 hello
的新可执行文件,位于名为 bin
的子文件夹中。
为了测试新的可执行文件,切换到新目录并运行二进制文件:
cd bin ./hello
你将收到以下输出:
Hello, World!
现在你可以自定义可执行文件的名称以满足项目的需求,完成了我们关于如何在 Go 中构建二进制文件的调查。但是使用 go build
,你仍然受限于只能从当前目录运行你的二进制文件。为了能够从系统的任何位置使用新构建的可执行文件,你可以使用 go install
来安装它们。
步骤 5 —— 使用 go install
安装 Go 程序
到目前为止,在本文中,我们已经讨论了如何从我们的 .go
源文件生成可执行二进制文件。这些可执行文件有助于分发、部署和测试,但目前还不能从它们的源目录之外执行。如果你想要在 shell 脚本或其他工作流中主动使用你的程序,这将是一个问题。为了使程序更易于使用,你可以将它们安装到系统中,并从任何位置访问。
为了理解这意味着什么,你将使用 go install
命令来安装你的示例应用程序。
go install
命令的行为几乎与 go build
相同,但它不会将可执行文件留在当前目录,也不会将其放置在由 -o
标志指定的目录中,而是将其放置在 $GOPATH/bin
目录中。
要找到你的 $GOPATH
目录的位置,运行以下命令:
go env GOPATH
你收到的输出将有所不同,但默认值是你的 $HOME
目录中的 go
目录:
$HOME/go
由于 go install
将生成的可执行文件放置在 $GOPATH
的名为 bin
的子目录中,因此必须将此目录添加到 $PATH
环境变量中。这在先决条件文章《如何安装 Go并设置本地编程环境》的 创建你的 Go 工作区 步骤中有所涉及。
设置好 $GOPATH/bin
目录后,返回到你的 greeter
目录:
cd ..
现在运行安装命令:
go install
这将构建你的二进制文件并将其放置在 $GOPATH/bin
中。为了测试这一点,运行以下命令:
ls $GOPATH/bin
这将列出 $GOPATH/bin
的内容:
greeter
安装了二进制文件后,测试一下程序是否可以从其源目录之外运行。返回到你的主目录:
cd $HOME
使用以下命令运行程序:
greeter
这将产生以下结果:
Hello, World!
现在你可以将你编写的程序安装到系统中,从任何地方使用它们。
结论
在本教程中,你演示了 Go 工具链如何轻松地从源代码构建可执行二进制文件。这些二进制文件可以分发到其他系统上运行,即使这些系统没有 Go 工具和环境。你还使用了 go install
自动构建并安装我们的程序作为可执行文件到系统的 $PATH
中。通过 go build
和 go install
,你现在可以随意分享和使用你的应用程序。
现在你已经了解了 go build
的基础知识,你可以探索如何使用自定义构建标签定制 Go 二进制文件的模块化源代码,或者如何为不同平台构建不同操作系统和架构的应用程序。如果你想更多地了解 Go 编程语言,可以查看整个《如何在 Go 中编码》系列文章。