英文:
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
以下是我遇到该错误的步骤:
- 克隆labstreaminglayer仓库。
- 将文件
liblsl_cpp.i重命名为liblsl.swigcxx(我以为这样会告诉go build该文件应该与swig一起使用)。 - 进入
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:
- Clone the labstreaminglayer repo.
- Rename the file
liblsl_cpp.itoliblsl.swigcxx(I thought this would tellgo buildthat the file should be used with swig). cdintoLSL/liblsl-Genericand rungo 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
我几个月前遇到了这个问题,花了比我想象中更长的时间来解决,但我不记得具体是怎么解决的了,但我认为解决方法大致如下:
-
不要手动调用swig,这实际上会使事情变得更加困难。清理由swig生成的文件。
-
在libsl-Generic中创建一个名为a.go的文件,内容如下:
package libsls-Generic -
理论上,你还有另一个文件,比如
app.go,它将使用libsls-Generic。适当地编写app.go并导入libsls-Generic。 -
使用
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:
-
Don't call swig manually, it actually makes things a bit more difficult. Clean out the files generate by swig.
-
Create a file a.go in libsl-Generic with the contents:
package libsls-Generic -
In theory you have some other file, say
app.gothat will uselibsls-Generic. Writeapp.goandimport libsls-Genericappropriately. -
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
- 解压liblsl发布tarball并将liblsl-Generic克隆到Go主目录下的一个文件夹中。
- 修复liblsl_cpp.i,使其指向正确的头文件路径。
- 运行
swig -go -c++ -cgo -intgosize 32 -package liblsl liblsl_cpp.i。 - 在liblsl.go文件中,在下一个注释之前,在
package liblsl的前一行添加// #cgo LDFLAGS: -Wl,-rpath,/usr/local/lib -llsl64(假设liblsl64.dylib位于/usr/local/lib)。 - 运行
go install。
这样做后,liblsl.a将位于Go主目录的pkg文件夹下,并且您将能够从Go程序中导入它。
英文:
- Unzip liblsl release tarball and clone liblsl-Generic to a folder under Go home directory
- Fix liblsl_cpp.i so that it points to the correct header file path
- Run
swig -go -c++ -cgo -intgosize 32 -package liblsl liblsl_cpp.i - Add
// #cgo LDFLAGS: -Wl,-rpath,/usr/local/lib -llsl64(assuming liblsl64.dylib is at/usr/local/lib) afterpackage liblslon the preceding line before the next comment in your liblsl.go - 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论