Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
859 views
in Technique[技术] by (71.8m points)

go - Cross compile a shared Library under Linux for windows

I want to get a windows-DLL, but I want to compile it under Ubuntu-Linux.

Building an Executable was simple: env GOOS=windows GOARCH=386 go build wrapper.go generates a wrapper.exe, that behaves as expected.

but building a DLL with env GOOS=windows GOARCH=386 go build -buildmode=c-shared wrapper.go results in error:

running gcc failed: exit status 1
gcc: error: unrecognized command line option ‘-mconsole’; did you mean ‘--compile’?

I would prefer not to install and run go under windows, because my complete tool chain is running under Ubuntu

go version go1.15.6 linux/amd64

question from:https://stackoverflow.com/questions/65843413/cross-compile-a-shared-library-under-linux-for-windows

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you would pass -x to the call to go build -buildmode=c-shared ..., you'd notice that in that mode the linker from the Go toolchain calls out to the external C linker; for instance, here on GNU/Linux with Go 1.15.x, I have:

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’?

Note that pkg/tool/linux_amd64/link is called with -extld=gcc, and from go doc cmd/link, we gather that

-extld linker
Set the external linker (default "clang" or "gcc").

My guess is that in order to produce a C-compatible dynamic library, the Go toolchain relies on an external C linker, and that is carried out by 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.

Hence my guess is that in order to do what you want you have to:

  • Install a cross-compiler supporting Windows/i386 — you can start with this.
  • Set up the environment before calling go build as explained in the cgo docs so that the Go toolchain calls the Windows-specific linker.
  • Verify it works by running go build with the -x command-line option.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...