Last active
July 3, 2025 15:03
-
-
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…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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