【问题标题】:Wrapping C++ with Go build用 Go 构建包装 C++
【发布时间】:2019-05-21 02:12:11
【问题描述】:

我正在尝试在 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 documentation 表示 go build 将使用 c++ 选项调用带有 .swigcxx 扩展名的文件的 Swig,但 go build 抱怨目录中没有可构建的 Go 源文件。

  • 平台:达尔文
  • Go 版本:1.8
  • Swig 版本:3.0.12
  • clang 版本:8.0.0

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

  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

【问题讨论】:

    标签: c++ go swig


    【解决方案1】:

    几个月前我遇到了这个问题,花了比我想象的更长的时间来弄清楚,但我不记得我到底做了什么来解决它,但我认为是这样的:

    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 手动生成文件时,我必须在重建时手动删除某些文件。使用 just go 运行时,构建步骤要简单得多。

    【讨论】:

    • 谢谢,这清楚了如何在没有swig 的情况下使用go build。但是,我遇到了与使用 swig: linker command failed 时类似的错误(并且找不到许多符号)。链接器找不到LSL/liblsl/bin/liblsl.dylib。我尝试运行go build -ldflags "-L ../liblsl/bin -l lsl" app.go,但遇到了同样的链接器错误。
    • 您是否尝试过将 dylib 指定为 cgo 评论链接? stackoverflow.com/questions/16747021/…
    【解决方案2】:
    1. 解压 liblsl release tarball 并将 liblsl-Generic 克隆到 Go 主目录下的文件夹中
    2. 修复 liblsl_cpp.i 使其指向正确的头文件路径
    3. 运行swig -go -c++ -cgo -intgosize 32 -package liblsl liblsl_cpp.i
    4. 在上一行的package liblsl 之后添加// #cgo LDFLAGS: -Wl,-rpath,/usr/local/lib -llsl64(假设liblsl64.dylib 位于/usr/local/lib),然后在您的liblsl.go 中的下一条注释之前
    5. 运行go install

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

    【讨论】:

      猜你喜欢
      • 2017-05-04
      • 2013-07-31
      • 1970-01-01
      • 2022-01-13
      • 2016-01-24
      • 2018-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多