使用Go构建C++封装

huangapple go评论109阅读模式
英文:

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文档中提到,对于扩展名为.swigcxx的文件,go build将使用c++选项调用Swig,但是go build抱怨在目录中没有可构建的Go源文件。

  • 平台:Darwin
  • Go版本:1.8
  • Swig版本:3.0.12
  • clang版本:8.0.0

以下是我遇到该错误的步骤:

  1. 克隆labstreaminglayer仓库。
  2. 将文件liblsl_cpp.i重命名为liblsl.swigcxx(我以为这样会告诉go build该文件应该与swig一起使用)。
  3. 进入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  # 由Swig创建
    └── liblsl.go        # 由Swig创建
英文:

I am trying to wrap C++ code (LabStreamingLayer) in Go.

Update: @dragonx explained how to use go build without swig. But I am still running into a linker issue. The build depends on LSL/liblsl/bin/liblsl.dylib. How do I tell go build to use that file? I tried go build -ldflags "-L ../liblsl/bin -l lsl" app.go with no success.

The Go documentation says that go build will invoke Swig with the c++ option for files with the .swigcxx extension, but go build complains that there are no buildable Go source files in the directory.

  • Platform: Darwin
  • Go version: 1.8
  • Swig version: 3.0.12
  • clang version: 8.0.0

Here are the steps I took to arrive at that error:

  1. Clone the labstreaminglayer repo.
  2. Rename the file liblsl_cpp.i to liblsl.swigcxx (I thought this would tell go build that the file should be used with swig).
  3. cd into LSL/liblsl-Generic and run go build. Go complains that there are no buildable Go source files in this directory.

After that failed, I tried using Swig. I ran swig -c++ -go -cgo -intgosize 64 liblsl_cpp.i, which created a .go file. I then ran go build in that directory, but it raised the error:

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

I am not familiar with C++, so I am not sure how to resolve the linker issue. I do know that this C++ code requires the file LSL/liblsl/bin/liblsl64.dylib. I assume that is the file that must be linked?

How can I wrap this C++ code in Go?

Here is the file structure:

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

得分: 2

我几个月前遇到了这个问题,花了比我想象中更长的时间来解决,但我不记得具体是怎么解决的了,但我认为解决方法大致如下:

  1. 不要手动调用swig,这实际上会使事情变得更加困难。清理由swig生成的文件。

  2. 在libsl-Generic中创建一个名为a.go的文件,内容如下:

     package libsls-Generic
    
  3. 理论上,你还有另一个文件,比如app.go,它将使用libsls-Generic。适当地编写app.go并导入libsls-Generic

  4. 使用go build app.go。这将同时构建依赖项。

最终,我找到了如何让go手动包含由swig生成的文件,但我现在忘记了具体细节。我记得当使用swig手动生成文件时,重新构建时我需要手动删除某些文件。当只使用go运行时,构建步骤要简单得多。

英文:

I ran into this a few months ago, took longer to figure out than I would have liked, but I don't remember exactly what I did to fix it, but I think it was along these lines:

  1. Don't call swig manually, it actually makes things a bit more difficult. Clean out the files generate by swig.

  2. Create a file a.go in libsl-Generic with the contents:

     package libsls-Generic
    
  3. In theory you have some other file, say app.go that will use libsls-Generic. Write app.go and import libsls-Generic appropriately.

  4. Use go build app.go. This should build the dependency as well.

I eventually figured out how to get go to incorporate the files manually generated by swig, but I forget the details now. I do remember that when generating files manually with swig, I would have to manually delete certain files when rebuilding. When running with just go, the build step was much simpler.

答案2

得分: -1

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

这样做后,liblsl.a将位于Go主目录的pkg文件夹下,并且您将能够从Go程序中导入它。

英文:
  1. Unzip liblsl release tarball and clone liblsl-Generic to a folder under Go home directory
  2. Fix liblsl_cpp.i so that it points to the correct header file path
  3. Run swig -go -c++ -cgo -intgosize 32 -package liblsl liblsl_cpp.i
  4. Add // #cgo LDFLAGS: -Wl,-rpath,/usr/local/lib -llsl64 (assuming liblsl64.dylib is at /usr/local/lib) after package liblsl on the preceding line before the next comment in your liblsl.go
  5. Run go install

That will make it, liblsl.a will be under Go home dir's pkg folder and you will be able to import it from Go programs.

huangapple
  • 本文由 发表于 2017年3月15日 02:56:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/42794318.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定