SagerNet / cronet-go

The Chromium network stack library for Go
Other
64 stars 15 forks source link

Compile from Windows (general question; looking for advice, willing to contribute) #14

Closed sleeyax closed 10 months ago

sleeyax commented 10 months ago

As a full time Linux user, I can compile and use this library in my project just fine on my machine but I also have a developer in my team who is using Windows. I spun up a VM to try and build the project and was met with a nightmare of compilation issues trying to get CGO working on Windows.

I learned that CGO doesn't really support Windows all that well and only supports MINGW for now. So I installed the native compilation toolset from https://www.msys2.org/#installation. I have the following packages installed:

Click to expand ```bash # pacman -Qe base 2022.06-1 base-devel 2022.12-2 filesystem 2023.02.07-1 lld 11.0.0-5 mingw-w64-i686-binutils 2.41-2 mingw-w64-i686-crt-git 11.0.0.r239.g037ba0184-1 mingw-w64-i686-gcc 13.2.0-2 mingw-w64-i686-gcc-ada 13.2.0-2 mingw-w64-i686-gcc-fortran 13.2.0-2 mingw-w64-i686-gcc-libgfortran 13.2.0-2 mingw-w64-i686-gcc-libs 13.2.0-2 mingw-w64-i686-gcc-objc 13.2.0-2 mingw-w64-i686-gdb 13.2-3 mingw-w64-i686-gdb-multiarch 13.2-3 mingw-w64-i686-headers-git 11.0.0.r239.g037ba0184-1 mingw-w64-i686-libgccjit 13.2.0-2 mingw-w64-i686-libmangle-git 11.0.0.r239.g037ba0184-1 mingw-w64-i686-libwinpthread-git 11.0.0.r239.g037ba0184-1 mingw-w64-i686-make 4.4-2 mingw-w64-i686-pkgconf 1~2.0.3-2 mingw-w64-i686-tools-git 11.0.0.r239.g037ba0184-1 mingw-w64-i686-winpthreads-git 11.0.0.r239.g037ba0184-1 mingw-w64-i686-winstorecompat-git 11.0.0.r239.g037ba0184-1 mingw-w64-ucrt-x86_64-gcc 13.2.0-2 mingw-w64-x86_64-binutils 2.41-2 mingw-w64-x86_64-clang 17.0.2-2 mingw-w64-x86_64-crt-git 11.0.0.r239.g037ba0184-1 mingw-w64-x86_64-gcc 13.2.0-2 mingw-w64-x86_64-gcc-ada 13.2.0-2 mingw-w64-x86_64-gcc-fortran 13.2.0-2 mingw-w64-x86_64-gcc-libgfortran 13.2.0-2 mingw-w64-x86_64-gcc-libs 13.2.0-2 mingw-w64-x86_64-gcc-objc 13.2.0-2 mingw-w64-x86_64-gdb 13.2-3 mingw-w64-x86_64-gdb-multiarch 13.2-3 mingw-w64-x86_64-headers-git 11.0.0.r239.g037ba0184-1 mingw-w64-x86_64-libgccjit 13.2.0-2 mingw-w64-x86_64-libmangle-git 11.0.0.r239.g037ba0184-1 mingw-w64-x86_64-libwinpthread-git 11.0.0.r239.g037ba0184-1 mingw-w64-x86_64-make 4.4-2 mingw-w64-x86_64-pkgconf 1~2.0.3-2 mingw-w64-x86_64-tools-git 11.0.0.r239.g037ba0184-1 mingw-w64-x86_64-winpthreads-git 11.0.0.r239.g037ba0184-1 mingw-w64-x86_64-winstorecompat-git 11.0.0.r239.g037ba0184-1 msys2-runtime 3.4.9-2 ```

And with the appropriate environment variables set:

go env -w CGO_ENABLED=1
go env -w CC=clang

I get these warnings and errors when I try to build an example with // #cgo LDFLAGS: -fuse-ld=lld -Wl,--build-id=sha1 -fPIC -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--icf=all -Wl,--color-diagnostics -Wl,-mllvm,-instcombine-lower-dbg-declare=0 -flto=thin -Wl,--thinlto-jobs=all -Wl,--thinlto-cache-dir=thinlto-cache -Wl,--thinlto-cache-policy=cache_size=10%:cache_size_bytes=40g:cache_size_files=100000 -Wl,-mllvm,-import-instr-limit=30 -fwhole-program-vtables -m64 -no-canonical-prefixes -rdynamic -Wl,-z,defs -Wl,--as-needed -Wl,--lto-O2 -pie -Wl,--disable-new-dtags -ldl -lpthread -lrt ./build/windows/amd64/cronet.dll -Wl,-rpath,$ORIGIN :

Click to expand ```bash # CGO_LDFLAGS_ALLOW=.* go build ./cmd/example/main.go # github.com/sagernet/cronet-go In file included from _cgo_export.c:4: cgo-gcc-export-header-prolog:49:35: warning: redeclaration of 'cronetBidirectionalStreamOnStreamReady' should not add 'dllexport' attribute [-Wdll-attribute-on-redeclaration] bidirectional_stream_impl.go:7:14: note: previous declaration is here cgo-gcc-export-header-prolog:50:35: warning: redeclaration of 'cronetBidirectionalStreamOnResponseHeadersReceived' should not add 'dllexport' attribute [-Wdll-attribute-on-redeclaration] bidirectional_stream_impl.go:8:14: note: previous declaration is here cgo-gcc-export-header-prolog:51:35: warning: redeclaration of 'cronetBidirectionalStreamOnReadCompleted' should not add 'dllexport' attribute [-Wdll-attribute-on-redeclaration] bidirectional_stream_impl.go:9:14: note: previous declaration is here cgo-gcc-export-header-prolog:52:35: warning: redeclaration of 'cronetBidirectionalStreamOnWriteCompleted' should not add 'dllexport' attribute [-Wdll-attribute-on-redeclaration] bidirectional_stream_impl.go:10:14: note: previous declaration is here cgo-gcc-export-header-prolog:53:35: warning: redeclaration of 'cronetBidirectionalStreamOnResponseTrailersReceived' should not add 'dllexport' attribute [-Wdll-attribute-on-redeclaration] bidirectional_stream_impl.go:11:14: note: previous declaration is here cgo-gcc-export-header-prolog:54:35: warning: redeclaration of 'cronetBidirectionalStreamOnSucceed' should not add 'dllexport' attribute [-Wdll-attribute-on-redeclaration] bidirectional_stream_impl.go:12:14: note: previous declaration is here cgo-gcc-export-header-prolog:55:35: warning: redeclaration of 'cronetBidirectionalStreamOnFailed' should not add 'dllexport' attribute [-Wdll-attribute-on-redeclaration] bidirectional_stream_impl.go:13:14: note: previous declaration is here cgo-gcc-export-header-prolog:56:35: warning: redeclaration of 'cronetBidirectionalStreamOnCanceled' should not add 'dllexport' attribute [-Wdll-attribute-on-redeclaration] bidirectional_stream_impl.go:14:14: note: previous declaration is here cgo-gcc-export-header-prolog:57:35: warning: redeclaration of 'cronetBufferCallbackOnDestroy' should not add 'dllexport' attribute [-Wdll-attribute-on-redeclaration] buffer_callback_impl.go:6:14: note: previous declaration is here cgo-gcc-export-header-prolog:58:35: warning: redeclaration of 'cronetExecutorExecute' should not add 'dllexport' attribute [-Wdll-attribute-on-redeclaration] executor_impl.go:6:14: note: previous declaration is here cgo-gcc-export-header-prolog:59:38: warning: redeclaration of 'cronetUploadDataProviderGetLength' should not add 'dllexport' attribute [-Wdll-attribute-on-redeclaration] upload_data_provider_impl.go:6:17: note: previous declaration is here cgo-gcc-export-header-prolog:60:35: warning: redeclaration of 'cronetUploadDataProviderRead' should not add 'dllexport' attribute [-Wdll-attribute-on-redeclaration] upload_data_provider_impl.go:7:14: note: previous declaration is here cgo-gcc-export-header-prolog:61:35: warning: redeclaration of 'cronetUploadDataProviderRewind' should not add 'dllexport' attribute [-Wdll-attribute-on-redeclaration] upload_data_provider_impl.go:8:14: note: previous declaration is here cgo-gcc-export-header-prolog:62:35: warning: redeclaration of 'cronetUploadDataProviderClose' should not add 'dllexport' attribute [-Wdll-attribute-on-redeclaration] upload_data_provider_impl.go:9:14: note: previous declaration is here cgo-gcc-export-header-prolog:63:35: warning: redeclaration of 'cronetURLRequestCallbackOnRedirectReceived' should not add 'dllexport' attribute [-Wdll-attribute-on-redeclaration] url_request_callback_impl.go:6:14: note: previous declaration is here cgo-gcc-export-header-prolog:64:35: warning: redeclaration of 'cronetURLRequestCallbackOnResponseStarted' should not add 'dllexport' attribute [-Wdll-attribute-on-redeclaration] url_request_callback_impl.go:7:14: note: previous declaration is here cgo-gcc-export-header-prolog:65:35: warning: redeclaration of 'cronetURLRequestCallbackOnReadCompleted' should not add 'dllexport' attribute [-Wdll-attribute-on-redeclaration] url_request_callback_impl.go:8:14: note: previous declaration is here cgo-gcc-export-header-prolog:66:35: warning: redeclaration of 'cronetURLRequestCallbackOnSucceeded' should not add 'dllexport' attribute [-Wdll-attribute-on-redeclaration] url_request_callback_impl.go:9:14: note: previous declaration is here cgo-gcc-export-header-prolog:67:35: warning: redeclaration of 'cronetURLRequestCallbackOnFailed' should not add 'dllexport' attribute [-Wdll-attribute-on-redeclaration] url_request_callback_impl.go:10:14: note: previous declaration is here cgo-gcc-export-header-prolog:68:35: warning: redeclaration of 'cronetURLRequestCallbackOnCanceled' should not add 'dllexport' attribute [-Wdll-attribute-on-redeclaration] url_request_callback_impl.go:11:14: note: previous declaration is here cgo-gcc-export-header-prolog:69:35: warning: redeclaration of 'cronetURLRequestFinishedInfoListenerOnRequestFinished' should not add 'dllexport' attribute [-Wdll-attribute-on-redeclaration] url_request_finished_info_impl.go:6:14: note: previous declaration is here cgo-gcc-export-header-prolog:70:35: warning: redeclaration of 'cronetURLRequestStatusListenerOnStatus' should not add 'dllexport' attribute [-Wdll-attribute-on-redeclaration] url_request_status_listener_impl.go:6:14: note: previous declaration is here # command-line-arguments C:\Program Files\Go\pkg\tool\windows_amd64\link.exe: running clang failed: exit status 1 clang: warning: argument unused during compilation: '-rdynamic' [-Wunused-command-line-argument] clang: warning: argument unused during compilation: '-pie' [-Wunused-command-line-argument] clang: warning: argument unused during compilation: '-rdynamic' [-Wunused-command-line-argument] clang: warning: argument unused during compilation: '-pie' [-Wunused-command-line-argument] lld: error: unknown argument: --build-id=sha1 lld: error: unknown argument: -z lld: error: unknown argument: -z lld: error: unknown argument: -z lld: error: unknown argument: --color-diagnostics lld: error: unknown argument: --thinlto-jobs=all lld: error: unknown argument: --thinlto-cache-policy=cache_size=10%:cache_size_bytes=40g:cache_size_files=100000 lld: error: unknown argument: -z lld: error: unknown argument: --as-needed lld: error: unknown argument: --lto-O2 lld: error: unknown argument: --disable-new-dtags lld: error: unknown argument: -rpath lld: error: unknown argument: --build-id=sha1 lld: error: unknown argument: -z lld: error: unknown argument: -z lld: error: unknown argument: -z lld: error: unknown argument: --color-diagnostics lld: error: unknown argument: --thinlto-jobs=all lld: error: unknown argument: --thinlto-cache-policy=cache_size=10%:cache_size_bytes=40g:cache_size_files=100000 lld: error: unknown argument: -z lld: error: too many errors emitted, stopping now clang: error: linker command failed with exit code 1 (use -v to see invocation) ```

I hope I didn't forget to mention anything because I tried a lot of things. Let me know and I'll dig for it.

Do you have an idea how one could get this setup working?

Another approach I haven't tried yet is cross-compilation from a Linux machine to Windows, but the problem is that then my colleague would have to switch to Linux which he probably doesn't want (yet?) :sweat_smile: And if WSL works too then I'm not sure how/if debugging would work in that case.

Thanks a lot for your help!

klzgrad commented 10 months ago

https://github.com/klzgrad/naiveproxy/issues/282#issuecomment-1132520635

https://github.com/klzgrad/naiveproxy/blob/v106.0.5249.91-3/src/make-cronet-cgo-sdk.sh https://github.com/klzgrad/naiveproxy/blob/v106.0.5249.91-3/src/components/cronet/native/go-build.sh

These were tested in here https://github.com/klzgrad/naiveproxy/blob/v106.0.5249.91-3/.github/workflows/build.yml#L330

sleeyax commented 10 months ago

Thanks a lot for pointing me in the right direction, I somehow missed that. I'll try and puzzle the pieces together to get it working and report back here.

sleeyax commented 10 months ago

I'm closing this issue as a solution has been provided. I'm still trying to figure out how to best incorporate this into a developer workflow but that's on me. Thanks!