构建简单 cgo 模块的问题

Posted

技术标签:

【中文标题】构建简单 cgo 模块的问题【英文标题】:Problems building a simple cgo module 【发布时间】:2021-12-24 10:31:24 【问题描述】:

Ubuntu。 vscode 1.62.1。去1.17.3。 vscode 去扩展 v0.29.0。深入研究 v1.7.1。

我正在尝试使用 vscode 和 vscode-go 构建一个使用 Cgo 的小型应用程序。只有一个模块导入“C”。

我的项目结构的根目录包含“go.mod”和“main.go”文件,子文件夹中有子包。我还有包含 C 工件的“include”和“lib”目录。

这是我目前在 C 模块中的内容:

package voltage

// #cgo CFLAGS: -g -Wall -Iinclude
// #cgo LDFLAGS: -Llib/linux -lvibesimple -lcurl -lssl -lvibecrypto -lvibeictk -lvibeserver
// #include <stdio.h>
// #include <errno.h>
// #include "veapi.h"
import "C"

func Encrypt(datatype string, data string) (result string) 
    return


func Decrypt(datatype string, data string) (result string) 
    return

在“问题”视图中,它显示了以下两个问题:

go list 未能返回 CompiledGoFiles。这可能表示无法执行 cgo 处理;尝试在命令行构建。见https://golang.org/issue/38990。

还有:

无法导入C(cgo预处理失败)(编译)

我阅读了引用的问题,但我不确定如何处理这些信息。

我不知道如何继续前进。

【问题讨论】:

【参考方案1】:

C 编译器不在源目录中执行,而是在仅包含中间文件的临时目录中执行,例如编译为静态库 (.a) 的 go 文件。因此,LDFLAG -Llib/linux 指向一个不存在的目录。

要解决此问题,只需将该标志替换为 -L$SRCDIR/lib/linux

直接来自 cgo 文档:

解析 cgo 指令时,任何出现的字符串 $SRCDIR 都将替换为包含源文件的目录的绝对路径。这允许将预编译的静态库包含在包目录中并正确链接。

cgo 工具将始终使用包含路径中的源文件目录调用 C 编译器;即 -I$SRCDIR 总是隐含的。

【讨论】:

好的,绝对有帮助。我希望有一个“根”变量可用。就我而言,源文件位于对等目录中,因此我必须引用“$SRCDIR/../lib/inux”,但至少它可以工作。这消除了“无法导入 C”错误,但“go list failed to return CompiledGoFiles”消息仍然存在。我已阅读引用的问题,但我不了解所有含义。 嗯,我现在向前推进并尝试添加一些引用库的代码,现在“CompiledGoFiles”的东西已经消失了。

以上是关于构建简单 cgo 模块的问题的主要内容,如果未能解决你的问题,请参考以下文章

CGO内部机制

使用 cgo 构建时如何调试/转储 Go 变量?

CGO基础

CGO基础

如何构建 CGO 程序静态链接到 glibc 和动态链接到 libGL.so?

CGO 编译和链接参数