Golang交叉编译
Golang交叉编译
1. 编译环境
宿主开发平台为:
Linux wanhy-ubuntu 5.3.0-62-generic
#56~18.04.1-Ubuntu SMP Wed Jun 24 16:17:03 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
目标执行平台为:
Linux pilotx-du 4.14.98+gebeb3d5
#1 SMP PREEMPT Wed Aug 21 10:17:13 UTC 2019 aarch64 GNU/Linux
2. 常规编译
2.1 Go Build使用
2.1.1 GOOS变量
The operating system for which to compile code.
Examples are linux, darwin, windows, netbsd.
2.1.2 GOARCH变量
The architecture, or processor, for which to compile code.
Examples are amd64, 386, arm, ppc64.
2.2.3 GOARM变量
For GOARCH=arm, the ARM architecture for which to compile.
Valid values are 5, 6, 7.
2.2 编译设置
2.2.1 建立Makefile
文件,内容如下:
NAME=agent
OS=linux
#OS=windows
# ARCH=amd64
# ARCH=arm
ARCH=arm64
ARM=7
build:
GOOS=$(OS) GOARCH=$(ARCH) GOARM=$(ARM) go build -o $(NAME)_$(OS)_$(ARCH)_$(ARM) ./max_client.go
2.2.2 编译指令:
make build
2.2.3 特别注意:
默认按照这种方式,在linux下可以正常输出linux,window,mac的可执行程序,但输出的arm不能在arm车机上运行,需要使用下面的交叉编译设置。
2. 交叉编译
本例使用docker环境来进行交叉编译环境的搭建。
2.1 获取阿里云的软件源
镜像网址为:https://developer.aliyun.com/mirror/
点击进入:系统->Ubuntu目录
网址为:https://developer.aliyun.com/mirror/ubuntu?spm=a2c6h.13651102.0.0.3e221b111qDsJK
复制ubuntu 18.04(bionic) 配置如下
内容到/etc/apt/sources.list
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
2.2 获取Golang安装文件
获取网址为:https://gomirrors.org/
使用最新的Go1.14.4版本 : https://gomirrors.org/dl/go/go1.14.4.linux-amd64.tar.gz
2.3 Dockerfile
Dockerfile文件内容为:
FROM ubuntu:18.04
VOLUME /opt/go_docker/
WORKDIR /go_workspace
COPY ./src ./
COPY ./entry.sh ./
COPY sources.list /etc/apt/sources.list
ENTRYPOINT [ "sh", "./entry.sh" ]
2.3 entry.sh
echo "bash"
# 更新软件源ls
apt-get update
# 安装交叉编译库
apt install g++-aarch64-linux-gnu -y
apt install gcc-aarch64-linux-gnu -y
# 添加此选项可以避免一个go run时的一个错误,错误描述为:
# X509
apt install ssh -y
# 解压并安装golang
tar -xvf go1.14.4.linux-amd64.tar.gz -C /usr/local
export PATH=$PATH:/usr/local/go/bin
echo $PATH
# 设置golang为国内代理
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.io,direct
bash
2.4 src文件夹内容
.
├── build.sh
├── go1.14.4.linux-amd64.tar.gz #golang安装文件
├── go.mod # 使用 go mod init utils 生成
├── go.sum # go run max_client.go 自动创建
└── hello.go # 源代码文件
2.5 hello.go
package main
import (
"log"
"github.com/gorilla/websocket"
)
func main() {
go recv_message("ws://127.0.0.1:2303/maxcount")
for {
}
}
func recv_message(ws_url string) {
log.Println("Dial To:", ws_url)
conn, _, err := websocket.DefaultDialer.Dial(ws_url, nil)
if err != nil {
log.Fatal("Dial Error:", err)
}
defer conn.Close()
for {
message_type, message_data, err := conn.ReadMessage()
if err != nil {
log.Println("ReadMessage Error:", err)
break
}
log.Printf("Recv [%v] : [%s]", message_type, message_data)
break
}
}
2.6 build.sh
export CGO_ENABLED=1
export GOOS=linux
export GOARCH=arm64
export GOARM=7
export BINARY_NAME=agent
# export CC=/usr/bin/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc
# export CXX=/usr/bin/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-g++
export CC=/usr/bin/aarch64-linux-gnu-gcc
export CXX=/usr/bin/aarch64-linux-gnu-g++
go build -o ./bin/${BINARY_NAME}_${GOOS}_${GOARCH}_${GOARM} ./hello.go
2.6 运行指令
#进入docker环境后,执行
sh build.sh
#会在bin目录下创建 agent_linux_arm64_7文件
3 测试运行
为了测试编译的arm执行文件是否可以正确运行,需要搭建arm的docker运行环境,步骤如下:
3.1 在宿主机安装 qemu
sudo apt install qemu-user-static -y
3.2 建立Dockerfile
FROM arm64v8/ubuntu
VOLUME /opt/go_docker/
WORKDIR /go_workspace
COPY ./src ./
ENTRYPOINT [ "bash" ]
3.2 运行docker
sudo docker run -it --name service_test -v /usr/bin/qemu-aarch64-static:/usr/bin/qemu-aarch64-static service_test:v1.0
3.3 运行结果
2020/07/08 13:30:24 Dial To: ws://127.0.0.1:2303/maxcount
2020/07/08 13:30:24 Recv [1] : [1594186224]
4. 存在问题
其实里面还存在一个问题,但我仅仅在程序内
package main
import (
"fmt"
)
func main() {
fmt.Println("Hello Golang")
}
编译出的程序是不能运行的,原因是编译出的程序为statically linked
,暂时还不能解决此问题。
(base) wanhy@wanhy-ubuntu:~/Project/backer777_github/go_workspace/test_docker_golang/test_build2/src$ file agent_linux_arm64_7
agent_linux_arm64_7: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, not stripped
(base) wanhy@wanhy-ubuntu:~/Project/backer777_github/go_workspace/test_docker_golang/test_build2/src$ file agent_linux_arm64_7_cc
agent_linux_arm64_7_cc: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, not stripped
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人