ebitengine/purego
GitHub: ebitengine/purego
purego 是一个让 Go 在不使用 Cgo 的前提下调用 C 函数的库,旨在简化交叉编译、加快编译速度并减小二进制体积。
Stars: 3738 | Forks: 118
# purego
[](https://pkg.go.dev/github.com/ebitengine/purego?GOOS=darwin)
一个无需 Cgo 即可从 Go 调用 C 函数的库。
## 动机
[Ebitengine](https://github.com/hajimehoshi/ebiten) 游戏引擎已被移植为在 Windows 上仅使用 Go。这使得只需设置 `GOOS=windows`,就能从任何其他操作系统交叉编译到 Windows。purego 项目的诞生,正是为了将这一愿景带到 Ebitengine 支持的其他平台上。
## 优势
- **简单的交叉编译**:没有 C 意味着你可以轻松地为其他平台构建,而无需 C 编译器。
- **更快的编译速度**:高效地缓存完全由 Go 编写的构建。
- **更小的二进制文件**:使用 Cgo 会为每个调用的 C 函数生成一个 C 包装函数。而 Purego 不会!
- **动态链接**:在 runtime 加载 symbol 并将其用作插件系统。
- **外部函数接口(Foreign Function Interface)**:调用编译为共享对象的其他语言。
- **Cgo 回退**:即使在 `CGO_ENABLED=1` 的情况下也能工作,因此可以实现增量移植。
这也意味着不支持的 GOARCH(freebsd/riscv64、linux/mips 等)仍然可以工作,但不支持浮点数参数和返回值。
## 支持的平台
### Tier 1
Tier 1 平台是 PureGo 官方支持的主要目标。当发布新版本的 PureGo 时,在 Tier 1 平台上发现的任何严重 bug 都会被视为发布的阻塞问题。在这些问题得到解决之前,发布将被推迟。
- **Android**:amd641, arm641
- **iOS**:amd641, arm641
- **Linux**:amd64, arm64
- **macOS**:amd64, arm64
- **Windows**:amd642, arm642
### Tier 2
- **Android**:3861,3, arm1,3
- **FreeBSD**:amd643,4, arm643,4
- **Linux**:3863, arm3, loong643, ppc64le3, riscv643, s390x3, 5
- **NetBSD**:amd643,4, arm643,4
- **Windows**:3863,6, arm3,6,7
## 示例
下面的示例仅展示了 purego 在 macOS 和 Linux 上的使用。其他平台需要特殊处理,可以在 [examples/libc](https://github.com/ebitengine/purego/tree/main/examples/libc) 的完整示例中查看,该示例支持 FreeBSD 和 Windows。
```
package main
import (
"fmt"
"runtime"
"github.com/ebitengine/purego"
)
func getSystemLibrary() string {
switch runtime.GOOS {
case "darwin":
return "/usr/lib/libSystem.B.dylib"
case "linux":
return "libc.so.6"
default:
panic(fmt.Errorf("GOOS=%s is not supported", runtime.GOOS))
}
}
func main() {
libc, err := purego.Dlopen(getSystemLibrary(), purego.RTLD_NOW|purego.RTLD_GLOBAL)
if err != nil {
panic(err)
}
var puts func(string)
purego.RegisterLibFunc(&puts, libc, "puts")
puts("Calling C from Go without Cgo!")
}
```
然后运行:`CGO_ENABLED=0 go run main.go`
## 问题
如果你对如何将 purego 整合到你的项目中有疑问,或者想讨论它的运作方式,请加入 [Discord](https://discord.gg/HzGZVD6BkY)!
### 外部代码
Purego 使用了源自 Go runtime 的代码。这些文件采用 BSD-3 许可证,可以在 [Go 源码](https://github.com/golang/go/blob/master/LICENSE)中找到。
以下是复制的文件列表:
* `abi_*.h` 来自 `runtime/cgo` 包
* `wincallback.go` 来自 `runtime` 包
* `zcallback_darwin_*.s` 来自 `runtime` 包
* `internal/fakecgo/abi_*.h` 来自 `runtime/cgo` 包
* `internal/fakecgo/asm_GOARCH.s` 来自 `runtime/cgo` 包
* `internal/fakecgo/callbacks.go` 来自 `runtime/cgo` 包
* `internal/fakecgo/iscgo.go` 来自 `runtime/cgo` 包
* `internal/fakecgo/setenv.go` 来自 `runtime/cgo` 包
* `internal/fakecgo/freebsd.go` 来自 `runtime/cgo` 包
* `internal/fakecgo/netbsd.go` 来自 `runtime/cgo` 包
* `internal/fakecgo/linux.go` 来自 `runtime/cgo` 包
`internal/fakecgo/go_GOOS.go` 文件是根据 `runtime/cgo/gcc_GOOS_GOARCH.go` 修改而来的。
`internal/fakecgo/linux.go` 文件是 `runtime/cgo/linux.go` 和 `runtime/cgo/linux_syscall.c` 的组合。
标签:安全报告生成, 日志审计