cmd/go: generating C header files for transitive dependencies is awkward

fivyi3re  于 6个月前  发布在  Go
关注(0)|答案(7)|浏览(43)

CL 208117 ( #30316 )中,cmd/go(截至Go 1.14版本)缺乏一种生成Go库C头文件的好方法,以便从C中使用它们。
go install -buildmode=c-archivego install -buildmode=c-shared 作为副作用,会为请求的包生成头文件。然而,今天的 -buildmode=c-archive-buildmode=c-shared 需要命名的包是一个 package main ,这些命令不会为命名包的(传递)Go依赖项生成头文件。
-i 标志确实为传递依赖项生成头文件,但它还有一个不想要的副作用:它为命名包的传递依赖项构建(并尝试安装)库,包括标准库中的传递依赖项。如果用户无法写入 GOROOT/pkg ,例如当一个非根用户正在使用一个作为根安装的 go 工具时,这将失败。
作为解决方法,可以运行 go tool cgo -exportheader ,但 go tool cgo 接受文件列表而不是包列表,并生成一些额外的输出(通常在 _obj 子目录中),而C调用者不需要直接使用这些输出。因此,我们仍然在不同的位置进行额外的工作。
我们应该看看如何使生成C头文件更容易,同时避免不必要的或不想要的副作用。
CC @ianlancetaylor@jayconrod

zpgglvta

zpgglvta1#

一种可能性是添加另一个 -buildmode,例如 -buildmode=c-header,它可以执行所需的任何工作(并可能将额外的产物写入 GOCACHE ),但只发出(或安装)头文件而不是整个存档。
这可以作为具有特定包参数的 go tool cgo 调用的更直接替代品。

eoxn13cs

eoxn13cs2#

另一个选项可能是让-i标志抑制标准库目标的错误,这样即使GOROOT不可写,go install -i命令也能正常工作。

u1ehiz5o

u1ehiz5o3#

https://golang.org/cl/208117提到了这个问题:misc/cgo/testcarchive: avoid writing to GOROOT in tests

laawzig2

laawzig24#

https://golang.org/cl/208119提到了这个问题:misc/cgo/testcshared: avoid writing to GOROOT in tests

bprjcwpo

bprjcwpo5#

我们可以让 go install 安装所有导入包的头文件,即使没有 -i 也可以。这将改变行为,但仅限于不是 main 但已导出函数的包,这种情况比较少见。

23c0lvtd

23c0lvtd6#

也许吧,但导入本身似乎有点牵强附会:如果C代码使用了来自包a的标识符,那么构建过程应该提到包a,而不是恰好导入了a的其他包b
另一方面,我想C库必须链接到某个(共享或归档)文件,该文件是由包main生成的,所以让go install为链接到该包的所有标识符生成所有头文件似乎并不糟糕。

qvk1mo1f

qvk1mo1f7#

在这个问题中,用户想要在不同的文件中使用类型别名 type T1 = T2,但是遇到了一些问题。以下是翻译后的文本内容:

任何进展吗?我正在尝试使用 bcmills@ 建议的解决方法,即使用 go tool cgo -exportheader,所以我的构建脚本包括:

go tool cgo -exportheader ${CGO_BUILD_ROOT}/foo.h foo.go
&& go tool cgo -exportheader ${CGO_BUILD_ROOT}/bar.h bar.go
&& go build -buildmode=c-shared -o ${LIB_FULL_PATH}
&& rm -rf _obj

其中 foo.gobar.go 都位于同一个包中。这之前运行得很好,直到我尝试使用类型别名时。
我想定义一个类型别名 type T1 = T2,并在 foo.gobar.go 中使用它。
如果我在 foo.go 中定义了这个别名,go build 可以正常工作,就像预期的那样(T1bar.go 的作用域内)。然而,导出 bar.go 的头文件失败了,而 unrecognized Go type T1 可以正常工作。
如果我在 foo.gobar.go 中定义了相同的别名,那么这两个文件的导出头文件都可以成功,但是在 go build 中会出现重复声明错误(并不奇怪)。

相关问题