这是一个积累的记录,比较杂乱,但是看完了应该可以跑通这个目标,放在这里做参考
ini
$env:CGO_ENABLED="1" # PowerShell
csharp
# 如果还没装 scoop
Set-ExecutionPolicy RemoteSigned -scope CurrentUser
irm get.scoop.sh | iex
# 装 gcc
scoop install gcc
csharp
# 1. 添加 extras 仓库(仅需一次)
scoop bucket add extras
# 2. 搜索确认名字
scoop search gcc-arm64
# 3. 安装(名称要带 -gcc)
scoop install gcc-arm64-linux-gnu-gcc
sql
PS C:\gitcodes\log-processor> scoop search gcc Results from local buckets...
Name Version Source Binaries ---- ------- ------ --------
avr-gcc 15.2.0 main gcc 13.2.0 main
xtensa-esp32-elf 11_2_0-esp-2022r1 main
xtensa-esp32-elf-gcc.exe | xtensa-esp32-elf-gcc-ar.exe | xtensa-esp32-elf-gcc-nm.exe | xtensa-esp32-elf-gcc-ranlib.exe
gcc-aarch64-none-elf 14.3.rel1 extras
gcc-aarch64-none-linux-gnu 14.3.rel1 extras
gcc-arm-none-eabi 14.3.rel1 extras
gcc-arm-none-linux-gnueabihf 14.3.rel1 extras
extras
里并没有叫 gcc-arm64-linux-gnu
的 manifest,
但 "gcc-aarch64-none-linux-gnu" 就是我们要的交叉工具链 (命名惯例不同,功能一样)。
安装它即可:
css
scoop install gcc-aarch64-none-linux-gnu
装完后 scoop 会自动把 bin
目录加进 PATH。
重新打开 PowerShell,验证:
css
aarch64-none-linux-gnu-gcc -v
能输出版本号就说明 OK。
接下来按之前步骤设置环境变量即可交叉编译:
ruby
$env:CGO_ENABLED='1'
$env:GOOS='linux'
$env:GOARCH='arm64'
$env:CC='aarch64-none-linux-gnu-gcc'
go build -ldflags '-linkmode external -extldflags "-static"' -o myapp-linux-arm64 .
静态链接 vs 动态链接(默认)
场景 | 静态链接 | 动态链接(默认) |
---|---|---|
生成的可执行文件体积 | 大(把 libc 等全拷进去) | 小(只留符号表) |
目标板依赖 | 零依赖,只要内核架构对就能跑 | 需要对应版本 的 .so 存在(如 /lib/aarch64-linux-gnu/libc.so.6 ) |
启动速度 | 稍快(不用动态重定位) | 稍慢 |
升级/安全补丁 | 要重新编译整个程序 | 只换系统 .so 即可 |
Go 默认行为 | 不开 -static 就是动态 ;交叉时如果工具链里能找到 .so ,Go 会优先动态链接 |
一句话总结
- 静态链接 = 把 libc 等全部打包进一个文件,目标板不需要额外库,体积大但部署简单。
- 默认的动态链接 = 可执行文件小,运行时依赖目标板的共享库 ;版本不一致就会报
no version information available
或not found
。 - 嵌入式、容器、未知系统环境,建议静态 ;桌面发行版、可控环境,可以动态。
既然我都要跨平台编译了,我当然选静态,一劳永逸不折腾