一篇文章搞懂 Go 开发跨平台应用要点

Go 是一门对跨平台开发特别友好的语言,天生支持跨平台的编译,能够通过构建约束等方式对不同操作系统、架构采取不同的实现。本文试从开发中常用到的一些代码片段、功能讲起,在编写代码时就有意识地针对跨平台进行适配,而非先在开发平台上实现,在调试时再针对其他平台进行适配,影响开发效率。

在开发前,最好是看一下一些开源的包是如何进行跨平台适配的,例如 fsnotify。另,由于篇幅有限,本文仅考虑 Linux、macOS 及 Windows 这几个在生产中常见的操作系统,Go 实际上支持的系统要更多,一般来说日常开发针对这三个系统足矣。

交叉编译

Go 语言天生支持跨平台编译,只需要在命令行中指定目标平台的操作系统和处理器架构即可。

bash 复制代码
GOOS=windows GOARCH=amd64 go build

一般来说,打包构建以下平台即可:

GOOS GOARCH
windows amd64
linux amd64
linux arm64
darwin amd64
darwin arm64

全部列表,见链接。darwin 一般而言等价于 macOS,但两者有区别,感兴趣可以看文后链接。

第三方库支持

使用第三方库时,需要确保它们支持目标平台。可以查看库的文档或者 issue 了解支持情况。有些库可能只支持特定平台,需要根据情况选择替代品。

路径

在 Windows 平台上,路径分隔符使用反斜杠 \ (backslashes),而 Linux 和 macOS 使用斜杠 / (slashes)。

解决方案非常简单,一直使用 filepath 包即可。

go 复制代码
outPath := src + "/" + out // ❌容易拼错
parent := path.Dir(path) // ❌会按照斜杠处理
outPath := path.Join(src, "out") // ❌同上,但比直接操作字符串可读性更好

parent := filepath.Dir(path) // ✅根据操作系统选择斜杠或反斜杠
outPath := filepath.Join(src, "out") // ✅同上

目录

一般而言,有一些目录是约定俗成的,例如 home 目录、配置目录、缓存目录等,可以通过 os 包获得。

go 复制代码
homeDir, _ := os.UserHomeDir()
configDir, _ := os.UserConfigDir()
cacheDir, _ := os.UserCacheDir()

在一些情况下,如果我们希望把文件保存在某一个绝对路径,则需要对不同系统作适配。具体做法是针对操作系统使用不一样的文件,在末尾加上操作系统的名称,加上编译标记。如下:

dir.go

go 复制代码
//go:build !windows
var specialDir = "/tmp/this/is/a/dir"

dir_windows.go

go 复制代码
//go:build windows
var specialDir = "C:\\some\other\dir"

这样,在编译目标为 Windows 时,变量的值将会是 WIndows 的文件路径。

关于 go 的构建约束更多信息,可以参考文后的链接。

系统调用

Go 的 syscall 包提供了一些常用的系统调用函数。不同操作系统的系统调用可能有所不同,如果需要使用底层系统调用,需要区分目标平台。一个比较简单的解决方案是使用 Go 提供的更高级别的标准库函数,如 osnet 等,它们内部通过调用系统调用来实现功能。

Ref

GitHub - fsnotify/fsnotify: Cross-platform file system notifications for Go.

Build constraints and vendoring | GoLand Documentation

build package - go/build - Go Packages

Why is macOS often referred to as 'Darwin'? - Ask Different

相关推荐
木卫二号Coding6 分钟前
在 Ubuntu 上安装 noVNC
linux·运维·ubuntu
爱吃苹果的梨叔13 分钟前
NTP 网络时间服务器硬件驯服技术说明(投标技术响应说明)
linux·运维·服务器·网络·嵌入式硬件·tcp/ip
有时.不昰沉默34 分钟前
ubuntu 20.04 启动直接进入 tty1,而非 图形界面
linux·运维·ubuntu·tty1
济61738 分钟前
linux 系统移植(第七期)----U-Boot 图形化配置--添加自定义菜单-- Ubuntu20.04
linux·运维·服务器
松涛和鸣41 分钟前
DAY56 ARM Cortex-A Bare Metal
linux·服务器·c语言·开发语言·arm开发·数据库
星陨7744 分钟前
OpenStack私有云平台API接口练习
linux·运维·网络·openstack
别再下雨辽1 小时前
开发板通过 VSCode Remote-SSH 反向转发复用 PC 代理排障总结
linux·ide·笔记·vscode·ssh
Kratzdisteln1 小时前
【Linux】Docker容器中快速部署VNC远程桌面环境
linux·运维·docker
轻蓝雨1 小时前
树莓派4B安装ubuntu server后再访问GPIO
linux·运维·ubuntu
宇宙帅猴1 小时前
Ubuntu网络问题解决方案
linux·网络·ubuntu