Go 语言强大之处在于其能够快速编译为机器能识别的可执行文件,Go 语言有完整的开发体系,使其能够简单的获取包及编译。go语言编译的软件全平台通用,没必要再去给专门的平台开发相关的软件。
本文将教你从Git平台下载caddy所需的依赖环境,并让你熟悉Go语言的编译过程,然后,学会如何快速编译Windows和macOS的执行文件。
教程开始前,你需要做一些准备
在编译安装caddy之前,我们需要下载其源码包。这里我们使用go get
命令获取caddy在Github的源码。如果执行顺利,你会在系统目录 $GOPATH/src/
的子目录下查看到相关的源码。源码构建后将会在$GOPATH/bin
查看到已经构建的软件,同时,GO语言也会自动配置到系统$PATH
中,这时你就可以在系统任意位置使用软件的命令了。
go get
语法是go get package-import-path
,其中package-import-path
是go语言包的地址。大部分情况下这里的软件包来自github,还有可能是系统$GOPATH/src/
配置的目录。
go get
命令常和-u
命令连用,它的意思的是使用go get
命令获取该软件包所需要的依赖或更新系统已经存在的依赖。
这里我以编译安装Go语言编写的web服务器 Caddy为例,我们将使用go get
命令获取在Github上面的Caddy软件包。
go get -u github.com/mholt/caddy/caddy
当然,执行命令需要一定时间,如果你发现输入命令后没反应,那就证明安装成功啦!
命令执行成功后,你应该会在$GOPATH/src/github.com/mholt/caddy
目录下看到Caddy的源码,此外,由于Caddy里面有Go语言的执行文件,它在$GOPATH/bin
目录下。所以你可以使用which命令查看。
which caddy
您将看到以下输出:
/home/sammy/work/bin/caddy
注意:
go get
命令主要是从master
分支拉取安装包,在使用go get
命令之前,请先查看目录下的README
文件说明。你可以使用
git checkout
命令获取其他分支,获取后在使用go get
命令进行安装。
下面,我们更深入了解下如何编译相关环境。
go get
命令已经为我们下载并安装好了caddy,但是我还是想构建新的执行文件怎么办呢?使用go build
命令编译新的可执行文件。
虽然在这个系统上我已经安装了Caddy,但是我还是想创建编译环境,执行go build
命令并指定相关路径。
go build github.com/mholt/caddy/caddy
和上面一样,没有输出则表明执行成功,可执行文件将在当前目录下创建。可执行文件名字为caddy
如果你在当前目录下,可以直接执行go build
直接执行。
如果想要你的可执行文件放在其他位置,可以加-o
命令,我们构建一个名字为caddy-server
的文件吧,放在当前的目录下。
go build -o build/caddy-server github.com/mholt/caddy/caddy
此命令会创建新的可执行文件,如果./build
命令不存在,则会自动创建。
接下来我们看看如何让安装可执行文件。
编译好的执行文件可能会在当前目录创建,安装可执行文件会将编译好的可执行文件储存在$GOPATH/bin
中, go install
命令和go build
接近,但是go install
只负责将文件存储到正确的位置。
要安装可执行文件,我们进到相关的目录,以caddy为例:
go install github.com/mholt/caddy/caddy
和之前一样,你应该看不到输出。同时,可执行文件创建的包与复制到新的包的名称相同,但这次,可执行文件是
复制到$GOPATH/bin
中,如果$GOPATH/bin
是环境变量的一部分,那么你就可任意在系统目录下使用这个命令。
which caddy
您将看到以下输出:
/home/sammy/work/bin/caddy
那么。你现在应该明白go get
,go build
, go install
命令如何使用了吧,那么接下来,我们试试go语言的
新功能,为其他平台编译创建可执行文件。
go build
命令允许您在本平台构建其他平台的可执文件,这意味着你可以在本平台测试发布你想要的应用程序,
无需考虑其他平台。
交叉编译需要你提前了解其他系统的类型和cpu架构,可以使用GOOS
命令指定操作系统,使用GOARCH
命令指定
CPU架构。命令如下:
env GOOS=target-OS GOARCH=target-architecture go build package-import-path
env
命令可以修改系统的环境变量,执行该命令后,将取消或重置当前变量。
下表列出了你可能会用到的GOOS
和GOARCH
组合。
|
|
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
注意:安卓编译环境需要Android NDK编译环境以及超出本文教程范围的部分设置。
假如我们需要编译Windows64位的caddy,则可以使用下面的命令:
env GOOS=windows GOARCH=amd64 go build github.com/mholt/caddy/caddy
没有任何输出,则表明编译成功,由于我们设置了以Windows构建此文件,所以你将看到exe可执行文件,该文件
以.exe结尾。
您可以使用ls
命令验证并查看该文件。
ls caddy.exe
您将看到caddy.exe
输出中列出的文件:
caddy.exe
注意:你可以使用
-o
命令重命名可执行文件,但是为Windows构建可执行文件的时候,需要增加.exe
结尾。
接下来,我们看看如何快速创建自动化脚本,方便操作。
给多平台创建可执行文件过程是在是太麻烦了,我们能不能写一个全自动执行脚本呢?
我是这样想的,这个脚本可以自动编译各个系统的软件包,并自动输出到当前目录。文件名为系统名称和架构,命
名方式package-OS-architecture
首先,切换到主目录并在文本编辑器中创建一个名字为go-executable-build.bash
新文件:
cd ~
nano go-executable-build.bash
我们创建一个bash文件,第一行内容如下,主要是解释我们用哪个解释器来解析这个脚本
#!/usr/bin/env bash
为了更方便运行代码,我们将创建几个变量。创建变量$n
,要求变量n
不能为负数。创建变量$0
为脚本的名称,
创建变量$1
为用户创建的参数。下面代码中,将吧$1
储存在package中。
...
package=$1
为了获取到这个值,我们需要给用户展现出来。
...
if [[ -z "$package" ]]; then
echo "usage: $0 <package-name>"
exit 1
fi
这里if
语句是检查$package
变量的值。如果未设置,我们将使用echo
打印正确的用法,然后使用终止脚本
exit
。exit
将返回值作为参数,该参数为0
的情况下,则执行成功,否则不成功。这里我们输出的为1
执
行不成功。
接下来,我们要从路径中提取包名称。导入路径由/
字符分隔,所以,我们需要使用/
作为分隔符分割数组。
package_split=(${package//\// })
软件包的名称应该为新的package_split
数组最后一个元素,在bash
中,你可以引入负数数组来整理新的变量,
新的变量将存储在package_name
...
package_name=${package_split[-1]}
接下来,我们需要确定其构建可执行文件的平台和CPU架构。我这里将以Windows 64位,Windows 32位和64位
的macOS构建可执行文件。 我将这些目标放在一个格式为OS / Platform
的数组中,因此我可以使用我们用从路
径中提取包名称的相同方法将每个对分成GOOS
和GOARCH
变量。 将平台添加到脚本:
...
platforms=("windows/amd64" "windows/386" "darwin/amd64")
接下来,我们将遍历平台数组,将每个平台条目拆分为GOOS
和GOARCH
环境变量的值,并使用它们构建可执行文件。 我们可以通过以下for 循环来做到这一点:
...
for platform in "${platforms[@]}"
do
...
done
平台变量将在每次迭代中包含来自platforms
数组的条目。 我们需要将平台分成两个变量GOOS
和GOARCH
。 将以下行添加到for循环:
for platform in "${platforms[@]}"
do
platform_split=(${platform//\// })
GOOS=${platform_split[0]}
GOARCH=${platform_split[1]}
done
接下来,我们将通过将包名称与OS和体系结构相结合来生成可执行文件的名称。 当为Windows构建时,我们还需
要在文件名中添加.exe
后缀。 将此代码添加到for
循环:
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
来创建可执行文件。
...
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循环中。
...
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语言软件包了!
#!/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*
您应该看到所有三个版本:
caddy-darwin-amd64 caddy-windows-386.exe caddy-windows-amd64.exe
要更改目标平台,只需更改platforms
脚本中的变量即可。
在本文中,您已经学习了如何使用Go语言从Git获取相关安装包,以为不同平台构建和交叉编译可执行文件。 感谢您的阅读!你学会了嘛?购买一台服务器试试吧:https://cloud.tencent.com/product/cvm
参考文献:《How To Build Go Executables for Multiple Platforms on Ubuntu 16.04》
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。