一个计算机技术爱好者与学习者

0%

好好学Golang:Golang中的编译

1. 前言

编译是将高级语言编写的源代码转换成机器能够执行的指令的过程。
编译可以分为几个阶段,这包括词法分析、语法分析、语义分析、中间代码生成、优化和目标代码生成。
对于Go语言(Golang)来说,编译不仅仅是构建程序的一部分,而且是其设计哲学的核心,确保了速度、安全性和跨平台的灵活性。

参考文档:

2. Go编译器的特点

  • 快速编译:Go编译器以其极快的编译速度而闻名。这得益于Go的简洁语法、依赖管理系统和编译器的设计。快速的编译对提高开发效率和迭代速度至关重要。
  • 静态链接:Go编程语言创建的二进制文件是静态链接的,这意味着所有依赖库都被包含在最终的可执行文件中。因此,我们可以在没有Go环境的系统上运行它们,无需担心依赖问题。
  • 跨平台编译:使用Go,我们可以轻松地为不同的操作系统和架构编译程序。通过设置GOOS和GOARCH环境变量,Go编译器可以产生针对几乎任何平台的编译输出。
  • 内存安全:Go的编译器会在编译时进行内存安全的检查,例如自动内存管理(GC)。这一机制有效防止了像野指针或内存泄漏这样的问题。
  • 报错和警告:Go编译器非常严格,对于一些可能在运行时引起问题的代码段,如未使用的变量或导入的包,将无法通过编译,直到这些问题被修复。

3. 编译命令

3.1. 标准编译命令

编译Go代码非常简单,使用go build命令即可。在大多数情况下,这一命令无需任何参数,它会自动处理所有文件依赖和包引用。

1
go build

此命令将编译当前目录中的Go源文件。如果当前目录是包含Go代码的单个包的目录,它将产生一个可执行文件。

go build 需要的是一个路径,让编译器可以找到哪些需要编译的go文件。当省略所有参数时,就意味着使用当前目录进行编译。
下面的几条命令是等价的:

1
2
3
go build
go build .
go build main.go

3.2. 自定义输出

使用-o标志,我们可以为生成的二进制文件指定一个名字及路径。

1
go build -o myapp

3.3. 交叉编译

Go语言(Golang)支持交叉编译,即在一个平台上编译生成另一个平台可执行的程序。
这意味着我们可以在Mac上为Linux系统编译二进制文件,也可以在Windows上为ARM处理器编译程序,等等。
Go语言交叉编译非常容易实现,因此被广泛应用于生成各种不同系统和架构的可执行程序,使得开发者可以轻松为多个平台构建应用。

要构建特定平台的应用程序,我们可以设置GOOSGOARCH环境变量,分别表示操作系统和处理器架构。
常见的GOOS值有:

  • darwin(Apple MacOS)
  • linux
  • windows
  • freebsd

常见的GOARCH值有:

  • amd64(64位x86架构)
  • 386 (32位x86架构)
  • arm (ARM架构)
  • arm64(64位ARM架构)

例如,我们可以为Windows 64位系统生成可执行文件,即便我们正在使用Linux或macOS。

1
GOOS=windows GOARCH=amd64 go build

这将在我们的非Windows系统上生成一个Windows可执行程序。

交叉编译注意事项:
1、安装golang依赖
确保在进行交叉编译之前所有项目依赖都已经正确安装,运行go mod tidy 可以帮助我们清理和同步项目依赖。此外,我们的项目代码也应该没有平台相关的依赖,否则可能需要根据目标平台进行适配。

2、安装目标平台的库和工具链
交叉编译时,可能需要注意目标平台的特定库或工具链支持。
例如,当我们在64位系统上编译32位程序时,相应32位的库应该是可用的。还有,某些依赖C语言库(如CGO程序)的Go程序可能需要额外配置或安装相应的跨平台C语言库和工具链。

3、目标平台测试
建议在目标平台上测试编译结果,以确保程序的正常运行。

4. 简单编译示例

4.1. 编译Linux二进制文件

1
GOOS=linux GOARCH=amd64 go build -o myapp myapp.go

生成一个Linux下可运行的可执行文件myapp

注意:如果是在Windows中执行编译,需要使用set命令配置环境变量:

1
2
C:\> set GOOS=linux
C:\> set GOARCH=amd64

4.2. 编译Windows二进制文件

1
GOOS=windows GOARCH=amd64 go build -o myapp.exe myapp.go

生成一个名为myapp.exe的Windows可执行文件。

4.3. 编译Mac二进制文件

1
GOOS=darwin GOARCH=amd64 go build -o myapp myapp.go

生成一个Mac系统可运行的二进制文件myapp

4.4. 编译ARM二进制文件

1
GOOS=linux GOARCH=arm GOARM=7 go build -o myapp myapp.go

这个命令指定了GOARM环境变量,它用于定义ARM的具体版本。
比如,GOARM=7通常用于诸如Raspberry Pi 2/3这样的较新ARM设备上。

5. 复杂编译示例

1
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -installsuffix cgo -ldflags="-w -s" -o /go/bin/pod-data-retorer

编译命令释义:

1、 CGO_ENABLED=0

  • CGO_ENABLED 环境变量控制是否启用CGo。CGo允许Go代码调用C代码。
  • 设置为0表示禁用CGo,这有助于确保生成的可执行文件能在没有C库(特别是在别的平台上没有C环境的情况下)的环境中运行。

2、 GOOS=linuxGOARCH=amd64

  • 这两个变量定义了目标编译平台的操作系统和处理器架构。
  • GOOS=linux 指定目标操作系统是Linux。
  • GOARCH=amd64 指定目标处理器架构是64位x86架构。

3、go build -a -installsuffix cgo

  • go build 是Go语言的标准编译命令。
  • -a 选项告诉Go编译器重建所有涉及到的东西,包括所有的包(即使它们没有变化)。
  • -installsuffix cgo 是用来给输出的文件名添加一个后缀,以区分不同编译配置下的编译结果。由于我们设置了 CGO_ENABLED=0,所以这里使用的后缀是 cgo

4、-ldflags="-w -s"

  • ldflags 表示链接器(linker)标志。
  • -w-s 是链接选项,分别用于减小生成的二进制文件大小:
         - -w 告诉编译器忽略DWARF调试信息,从而减小了生成文件的大小。
         - -s 用于去除符号表和调试信息,进一步减小二进制文件的大小。

5、-o /go/bin/pod-data-retorer

  • -o 选项用来指定输出的二进制文件名。
  • /go/bin/pod-data-retorer 是输出的二进制文件的完整路径和名称。这里指定了文件会被放在/go/bin/目录下,并且命名为pod-data-retorer

综上所述,这条命令会生成一个静态链接的、没有C库依赖、文件尺寸优化的Linux 64位平台的可执行文件pod-data-retorer,并且会放在/go/bin目录下。轻量化和去除C库依赖的特点使得生成的可执行文件特别适合在容器化环境(如Docker)中运行,因为它能够减少容器镜像的大小,并且降低对环境的依赖。

  • 本文作者: 好好学习的郝
  • 原文链接: https://www.voidking.com/dev-golang-compile/
  • 版权声明: 本文采用 BY-NC-SA 许可协议,转载请注明出处!源站会即时更新知识点并修正错误,欢迎访问~
  • 微信公众号同步更新,欢迎关注~