Skip to content

Instantly share code, notes, and snippets.

@Jamlee
Last active July 3, 2025 15:03
Show Gist options
  • Save Jamlee/32275e038a67bbc8f5f27a67e0791597 to your computer and use it in GitHub Desktop.
Save Jamlee/32275e038a67bbc8f5f27a67e0791597 to your computer and use it in GitHub Desktop.
This script manually compiles a Go program with CGO (Go-C interoperability) by replicating the internal steps of the Go toolchain. It handles CGO preprocessing, compiles generated C files with Clang, links C objects, generates import stubs for Go-C bindings, compiles Go code, and finally links all components into an executable. Designed for debu…
#!/bin/bash
# @author: jamlee
# date: 20250703
# platform: mac pro m3
# 设置工作目录(模拟原始流程中的$WORK/b001)
rm -fr tmp
mkdir tmp
WORK_DIR=$(pwd)/tmp
printf "WORK_DIR: $WORK_DIR\n"
export CGO_LDFLAGS=''
# 步骤1: 使用cgo工具预处理Go文件(必须指定objdir)
go tool cgo -objdir $WORK_DIR -srcdir . ./main.go
# 步骤2: 编译cgo生成的C文件(保持原始参数)
clang -I $WORK_DIR -fPIC -arch arm64 -pthread \
-fno-caret-diagnostics -Qunused-arguments \
-fmessage-length=0 -gno-record-gcc-switches \
-fno-common -O2 -g -c \
$WORK_DIR/_cgo_export.c -o $WORK_DIR/_x001.o
clang -I $WORK_DIR -fPIC -arch arm64 -pthread \
-fno-caret-diagnostics -Qunused-arguments \
-fmessage-length=0 -gno-record-gcc-switches \
-fno-common -O2 -g -c \
$WORK_DIR/main.cgo2.c -o $WORK_DIR/_x002.o
clang -I $WORK_DIR -fPIC -arch arm64 -pthread \
-fno-caret-diagnostics -Qunused-arguments \
-fmessage-length=0 -gno-record-gcc-switches \
-fno-common -O2 -g -c \
$WORK_DIR/_cgo_main.c -o $WORK_DIR/_cgo_main.o
# 步骤3: 链接检查(原始流程的关键步骤)
clang -I $WORK_DIR -fPIC -arch arm64 -pthread \
-fno-caret-diagnostics -Qunused-arguments \
-fmessage-length=0 -gno-record-gcc-switches \
-fno-common -O2 -g \
-o $WORK_DIR/_cgo_.o \
$WORK_DIR/_cgo_main.o $WORK_DIR/_x001.o $WORK_DIR/_x002.o
# 步骤4: 生成导入文件
go tool cgo -dynpackage main \
-dynimport $WORK_DIR/_cgo_.o \
-dynout $WORK_DIR/_cgo_import.go
# 关键修复:确保所有生成文件被正确包含
# 添加 _cgo_export.h 包含路径
export CGO_CFLAGS="-I$WORK_DIR"
# 步骤5: 编译Go部分(包含所有生成文件)
go tool compile -p main -o $WORK_DIR/main.a -pack \
$WORK_DIR/_cgo_gotypes.go \
$WORK_DIR/main.cgo1.go \
$WORK_DIR/_cgo_import.go
# 步骤6: 将C对象打包进归档文件
go tool pack r $WORK_DIR/main.a \
$WORK_DIR/_x001.o \
$WORK_DIR/_x002.o
# 步骤7: 链接可执行文件(指定PIE构建模式)
go tool link -o main \
-buildmode=pie \
-extld=clang \
$WORK_DIR/main.a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment