【Golang】使用Zig跨平台编译带有CGO依赖的Go项目

文章目录

    • 背景
    • 运行环境
    • 下载源代码
    • 1. 为Linux amd64目标编译
    • 2. 为Linux arm64目标编译
    • 3. 为Windows amd64目标编译
    • 4. 为macOS amd64目标编译
    • 5. 为macOS arm64目标编译
    • 参考内容

背景

使用Go进行跨平台编译通常是直接的:设置GOOS和GOARCH环境变量,然后执行go build命令。

不幸的是,对于使用CGO依赖的项目来说,事情可能会更复杂。根据目标架构的不同,可能需要安装C编译器,如gcc、clang或x86_64-w64-mingw64-gcc,并配置额外的环境变量,如CC,以及启用CGO_ENABLED=1。

在这篇文章中,我们将看到如何使用Zig来跨编译Paw项目,针对Linux、macOS和Windows,无需安装额外的编译器。

Paw是一个用于安全地管理密码和身份的跨平台应用程序,它是用Go编写的,并使用Fyne工具包作为GUI,以及golang.design/x/clipboard库作为CLI,这些都有CGO依赖。

Zig是一个通用编程语言和工具链,它提供了一个零依赖的C/C++编译器,并且支持开箱即用的跨平台编译。

运行环境

  • debian/ubuntu based distro
  • go v1.18.0
  • zig v0.9.1

下载源代码

git clone https://github.com/lucor/paw.git

1. 为Linux amd64目标编译

# install the GUI and CLI dependencies
apt-get update
apt-get install -y -q --no-install-recommends \
    libgl-dev \
    libx11-dev \
    libxrandr-dev \
    libxxf86vm-dev \
    libxi-dev \
    libxcursor-dev \
    libxinerama-dev

# create dist dir
mkdir -p dist/linux-amd64

# build
CGO_ENABLED=1 \
GOOS=linux \
GOARCH=amd64 \
CC="zig cc -target x86_64-linux-gnu -isystem /usr/include -L/usr/lib/x86_64-linux-gnu" \
CXX="zig c++ -target x86_64-linux-gnu -isystem /usr/include -L/usr/lib/x86_64-linux-gnu" \
go build -trimpath -o dist/linux-amd64 ./cmd/...

2. 为Linux arm64目标编译

# install the GUI and CLI dependencies
dpkg --add-architecture arm64
apt-get update
apt-get install -y -q --no-install-recommends \
    libgl-dev:arm64 \
    libx11-dev:arm64 \
    libxrandr-dev:arm64 \
    libxxf86vm-dev:arm64 \
    libxi-dev:arm64 \
    libxcursor-dev:arm64 \
    libxinerama-dev:arm64

# create dist dir
mkdir -p dist/linux-arm64

# build
CGO_ENABLED=1 \
GOOS=linux \
GOARCH=arm64 \
PKG_CONFIG_LIBDIR=/usr/lib/aarch64-linux-gnu/pkgconfig \
CC="zig cc -target aarch64-linux-gnu -isystem /usr/include -L/usr/lib/aarch64-linux-gnu" \
CXX="zig c++ -target aarch64-linux-gnu -isystem /usr/include -L/usr/lib/aarch64-linux-gnu" \
go build -trimpath -o dist/linux-arm64 ./cmd/...

3. 为Windows amd64目标编译

# create dist dir
mkdir -p dist/windows-amd64

# build
CGO_ENABLED=1 \
GOOS=windows \
GOARCH=amd64 \
CC="zig cc -target x86_64-windows-gnu" \
CXX="zig c++ -target x86_64-windows-gnu" \
go build -trimpath -ldflags='-H=windowsgui' -o dist/windows-amd64 ./cmd/...

4. 为macOS amd64目标编译

export MACOS_MIN_VER=10.14
export MACOS_SDK_PATH="/path/to/macOS/sdk"

# create dist dir
mkdir -p dist/darwin-amd64

# build
CGO_ENABLED=1 \
GOOS=darwin \
GOARCH=amd64 \
CGO_LDFLAGS="-mmacosx-version-min=${MACOS_MIN_VER} --sysroot ${MACOS_SDK_PATH} -F/System/Library/Frameworks -L/usr/lib" \
CC="zig cc -mmacosx-version-min=${MACOS_MIN_VER} -target x86_64-macos-gnu -isysroot ${MACOS_SDK_PATH} -iwithsysroot /usr/include -iframeworkwithsysroot /System/Library/Frameworks" \
CXX="zig c++ -mmacosx-version-min=${MACOS_MIN_VER} -target x86_64-macos-gnu -isysroot ${MACOS_SDK_PATH} -iwithsysroot /usr/include -iframeworkwithsysroot /System/Library/Frameworks" \
go build -trimpath -buildmode=pie -o dist/darwin-amd64  ./cmd/...

5. 为macOS arm64目标编译

export MACOS_MIN_VER=11.1
export MACOS_SDK_PATH="/path/to/macOS/sdk"

# create dist dir
mkdir -p dist/darwin-arm64

# build
CGO_ENABLED=1 \
GOOS=darwin \
GOARCH=arm64 \
CGO_LDFLAGS="-mmacosx-version-min=${MACOS_MIN_VER} --sysroot ${MACOS_SDK_PATH} -F/System/Library/Frameworks -L/usr/lib" \
CC="zig cc -mmacosx-version-min=${MACOS_MIN_VER} -target aarch64-macos-gnu -isysroot ${MACOS_SDK_PATH} -iwithsysroot /usr/include -iframeworkwithsysroot /System/Library/Frameworks" \
CXX="zig c++ -mmacosx-version-min=${MACOS_MIN_VER} -target aarch64-macos-gnu -isysroot ${MACOS_SDK_PATH} -iwithsysroot /usr/include -iframeworkwithsysroot /System/Library/Frameworks" \
go build -ldflags "-s -w" -buildmode=pie -trimpath -o dist/darwin-arm64 ./cmd/...

参考内容

  • https://dev.to/kristoff/zig-makes-go-cross-compilation-just-work-29ho
  • https://github.com/ziglang/zig/issues/9050#issuecomment-859939664

你可能感兴趣的:(Golang,golang,开发语言)