英文:
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.i
toliblsl.swigcxx
(I thought this would tellgo build
that the file should be used with swig). cd
intoLSL/liblsl-Generic
and 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.go
that will uselibsls-Generic
. Writeapp.go
andimport libsls-Generic
appropriately. -
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 liblsl
on 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论