在 Linux 下为 windows 交叉编译一个共享库
Cross compile a shared Library under Linux for windows
我想得到一个windows-DLL,但是我想在Ubuntu-Linux下编译它。
构建可执行文件很简单:env GOOS=windows GOARCH=386 go build wrapper.go
生成一个 wrapper.exe
,其行为符合预期。
但是使用 env GOOS=windows GOARCH=386 go build -buildmode=c-shared wrapper.go
构建 DLL 会导致错误:
running gcc failed: exit status 1
gcc: error: unrecognized command line option ‘-mconsole’; did you mean ‘--compile’?
我宁愿不在windows下安装运行go
,因为我的完整工具链是运行ning在Ubuntu[=18下=]
go version go1.15.6 linux/amd64
如果您将 -x
传递给对 go build -buildmode=c-shared ...
的调用,您会注意到在该模式下,Go 工具链中的链接器调用外部 C 链接器;例如,在 GNU/Linux 上使用 Go 1.15.x,我有:
mkdir -p $WORK/b001/exe/
cd $WORK/b001/exe/
/home/username/devel/golang-1.15.6/pkg/tool/linux_amd64/link -o cshared.dll -importcfg $WORK/b001/importcfg.link -buildmode=c-shared -buildid=OJVN3iT0GI_DEAMVbLDu/o9eT_YGfUiRe07beNQAA/-xRRfDcM8nVc03rltdqz/OJVN3iT0GI_DEAMVbLDu -extld=gcc $WORK/b001/_pkg_.a
# command-line-arguments
loadinternal: cannot find runtime/cgo
/home/username/devel/golang-1.15.6/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
gcc: error: unrecognized command line option ‘-mconsole’; did you mean ‘--compile’?
请注意 pkg/tool/linux_amd64/link
是用 -extld=gcc
调用的,从 go doc cmd/link
中我们收集到
-extld linker
Set the external linker (default "clang" or "gcc").
我的猜测是,为了生成与 C 兼容的动态库,Go 工具链依赖于外部 C 链接器,并且由 cgo
machinery — at which there's actually a hint in the documentation of -buildmode=c-shared
:
执行
-buildmode=c-shared
Build the listed main package, plus all packages it imports,
into a C shared library. The only callable symbols will
be those functions exported using a cgo
//export
comment.
Requires exactly one main package to be listed.
因此我的猜测是,为了做你想做的事,你必须:
我想得到一个windows-DLL,但是我想在Ubuntu-Linux下编译它。
构建可执行文件很简单:env GOOS=windows GOARCH=386 go build wrapper.go
生成一个 wrapper.exe
,其行为符合预期。
但是使用 env GOOS=windows GOARCH=386 go build -buildmode=c-shared wrapper.go
构建 DLL 会导致错误:
running gcc failed: exit status 1
gcc: error: unrecognized command line option ‘-mconsole’; did you mean ‘--compile’?
我宁愿不在windows下安装运行go
,因为我的完整工具链是运行ning在Ubuntu[=18下=]
go version go1.15.6 linux/amd64
如果您将 -x
传递给对 go build -buildmode=c-shared ...
的调用,您会注意到在该模式下,Go 工具链中的链接器调用外部 C 链接器;例如,在 GNU/Linux 上使用 Go 1.15.x,我有:
mkdir -p $WORK/b001/exe/
cd $WORK/b001/exe/
/home/username/devel/golang-1.15.6/pkg/tool/linux_amd64/link -o cshared.dll -importcfg $WORK/b001/importcfg.link -buildmode=c-shared -buildid=OJVN3iT0GI_DEAMVbLDu/o9eT_YGfUiRe07beNQAA/-xRRfDcM8nVc03rltdqz/OJVN3iT0GI_DEAMVbLDu -extld=gcc $WORK/b001/_pkg_.a
# command-line-arguments
loadinternal: cannot find runtime/cgo
/home/username/devel/golang-1.15.6/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
gcc: error: unrecognized command line option ‘-mconsole’; did you mean ‘--compile’?
请注意 pkg/tool/linux_amd64/link
是用 -extld=gcc
调用的,从 go doc cmd/link
中我们收集到
-extld linker
Set the external linker (default "clang" or "gcc").
我的猜测是,为了生成与 C 兼容的动态库,Go 工具链依赖于外部 C 链接器,并且由 cgo
machinery — at which there's actually a hint in the documentation of -buildmode=c-shared
:
-buildmode=c-shared
Build the listed main package, plus all packages it imports,
into a C shared library. The only callable symbols will
be those functions exported using acgo
//export
comment.
Requires exactly one main package to be listed.
因此我的猜测是,为了做你想做的事,你必须: