
Go 语言是一门需要编译才能运行的编程语言,也就是说代码在运行之前需要通过编译器生成二进制机器码,包含二进制机器码的文件才能在目标机器上运行,下边就展开讲解下Go语言的编译的细节。
| 附加参数 | 备 注 |
|---|---|
| -v | 编译时显示包名 |
| -p n | 开启并发编译,默认情况下该值为 CPU 逻辑核数 |
| -a | 强制重新构建 |
| -n | 打印编译时会用到的所有命令,但不真正执行 |
| -x | 打印编译时会用到的所有命令 |
| -race | 开启竞态检测 |
gc,全称Golang Compiler
go有两种不同的编译器,但是默认采用gc,这也会后边提到项目中运用了gccgo的编译错误的问题;
Go 语言编译器的源代码在 src/cmd/compile 目录中,目录下的文件共同组成了 Go 语言的编译器,学过编译原理的人可能听说过编译器的前端和后端, 编译器的前端一般承担着词法分析、语法分析、类型检查和中间代码生成几部分工作,而编译器后端主要负责目标代码的生成和优化,也就是将中间代码翻译成目标机器能够运行的二进制机器码。
Go 语言源代码的 src/cmd/compile/internal 目录中包含了很多机器码生成相关的包,不同类型的 CPU 分别使用了不同的包生成机器码,其中包括 amd64、arm、arm64、mips、mips64、ppc64、s390x、x86 和 wasm
下边列举一些常用的机器码生成的场景
SET CGO_ENABLED=0 // 禁用CGO
SET GOOS=linux // 目标平台是linux
SET GOARCH=amd64 // 目标处理器架构是amd64
SET CGO_ENABLED=0 GOOS=linux GOARCH=amd64
go build custom.go //编译原名称
go build -o customLinux custom.go //编译自定义名称
GOOS=linux GOARCH=amd64 go build
GOOS=windows GOARCH=amd64 go build
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build
SET CGO_ENABLED=0
SET GOOS=darwin
SET GOARCH=amd64
go build
上边提到go的两种编译方式:gc和gccgo,在项目过程有用到了go-sqlite3组件,并且还必须依赖cgo去编译生成;
当禁止cgo编译器时,出现这种错误:
Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work.
开启了gcc,直接go build ,还是报错:
/usr/local/go1.18/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
推荐的解决方案 讨论细节:https://github.com/golang/go/issues/44703 源头:https://github.com/golang/go/issues/43996
rm -rf ~/.cache/go-build : this contained a few build artifacts
rm -rf ${MyProject}/{bin,pkg} : for the same reason
export CXXFLAGS="-stdlib=libstdc++" CC=/usr/bin/gcc CXX=/usr/bin/g++
当代码开启了cgo,以上解决不了的,再使用如下代码执行,适用于:Linux
yum install gcc
yum install gcc-c++ libstdc++-devel
yum install glibc-static.x86_64 -y
大概率是Linux版本过低
gcflags的参数
-N: 禁止编译器优化-l: 关闭内联 (inline)-c int: 编译过程中的并发数,默认是1# 为当前模块下的所有包关闭编译优化和内联
go build -v -gcflags="all=-N -l"
or
go build -v -gcflags="all=-N -l" -o customeLinux custom.go
go build -gcflags all="-N -l" *.go
单独介绍windows中gccgo编译问题
MinGW 的全称是:Minimalist GNU on Windows 。是将经典的开源 C语言 编译器 GCC 移植到了 Windows 平台下,并且包含了 Win32API ,因此可以将源代码编译为可在 Windows 中运行的可执行程序。
没有gcc的报错:
cgo: C compiler "gcc" not found: exec: "gcc": executable file not found in %PATH%
本文为胡梦旭原创文章,转载无需和我联系,但请注明来自胡梦旭博客
最新评论