用 Go 构建包装 C++

Wrapping C++ with Go build

我正在尝试在 Go 中包装 C++ 代码 (LabStreamingLayer)。

更新:@dragonx 解释了如何在没有 swig 的情况下使用 go build。但我仍然 运行 陷入链接器问题。构建取决于 LSL/liblsl/bin/liblsl.dylib。我如何告诉 go build 使用该文件?我尝试了 go build -ldflags "-L ../liblsl/bin -l lsl" app.go 但没有成功。

Go documentationgo build 将使用 c++ 选项为扩展名为 .swigcxx 的文件调用 Swig,但是 go build 抱怨有目录中没有可构建的 Go 源文件。

以下是我为解决该错误所采取的步骤:

  1. 克隆 labstreaminglayer 存储库。
  2. 将文件 liblsl_cpp.i 重命名为 liblsl.swigcxx(我认为这会告诉 go build 该文件应该与 swig 一起使用)。
  3. cd 变成 LSL/liblsl-Generic 和 运行 go build。 Go 抱怨此目录中没有可构建的 Go 源文件。

失败后,我尝试使用Swig。我 运行 swig -c++ -go -cgo -intgosize 64 liblsl_cpp.i,它创建了一个 .go 文件。然后我在该目录中 运行 go build,但它引发了错误:

ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1

我不熟悉C++,所以我不确定如何解决链接器问题。我知道此 C++ 代码需要文件 LSL/liblsl/bin/liblsl64.dylib。我假设这是必须链接的文件?

如何在 Go 中包装此 C++ 代码?

文件结构如下:

LSL
├── liblsl
│   ├── bin
│   ├── distros
│   ├── examples
│   ├── external
│   ├── include
│   ├── project
│   ├── src
│   └── testing
└── liblsl-Generic
    ├── AUTOGENERATE\ HOWTO.txt
    ├── examples
    ├── liblsl.swigcxx
    ├── liblsl_c.i
    ├── liblsl_cpp.i
    ├── liblsl_wrap.cxx  # created by Swig
    └── liblsl.go        # created by Swig

我 运行 几个月前就进入了这个,花了比我想要的更长的时间来弄清楚,但我不记得我做了什么来修复它,但我认为它是沿着这些行:

  1. 不要手动调用 swig,它实际上会使事情变得更加困难。清除swig生成的文件。
  2. 在 libsl-Generic 中创建一个文件 a.go,内容如下:

    package libsls-Generic
    
  3. 理论上你有一些其他文件,比如 app.go 将使用 libsls-Generic。适当地写app.goimport libsls-Generic
  4. 使用go build app.go。这也应该建立依赖关系。

我最终想出了如何让 go 合并 swig 手动生成的文件,但我现在忘记了细节。我记得当用 swig 手动生成文件时,我必须在重建时手动删除某些文件。 运行刚开始的时候,构建步骤就简单多了。

  1. 解压 liblsl release tarball 并克隆 liblsl-Generic 到 Go home 目录下的文件夹
  2. 修复liblsl_cpp.i使其指向正确的头文件路径
  3. 运行 swig -go -c++ -cgo -intgosize 32 -package liblsl liblsl_cpp.i
  4. 在 liblsl.go[=25 中的下一条评论之前的前一行 package liblsl 之后添加 // #cgo LDFLAGS: -Wl,-rpath,/usr/local/lib -llsl64(假设 liblsl64.dylib 位于 /usr/local/lib) =]
  5. 运行 go install

这样就可以了,liblsl.a 将在 Go home 目录的 pkg 文件夹下,您将能够从 Go 程序中导入它。