rake-compiler / rake-compiler-dock

Easy to use and reliable cross compiler environment for building Windows, Linux, Mac and JRuby binary gems.
MIT License
77 stars 30 forks source link

Help building GRPC gem on x64-mingw-ucrt #69

Closed johnnyshields closed 2 years ago

johnnyshields commented 2 years ago

I'm trying to build GRPC gem (master) using Rake Compiler Dock.

Docker image: larskanis/rake-compiler-dock-mri-x64-mingw-ucrt:1.2.1

It fails on this line:

linking shared-object grpc/grpc_c.so
/usr/bin/x86_64-w64-mingw32-ld: cannot find -lx64-ucrt-ruby310
collect2: error: ld returned 1 exit status
make: *** [Makefile:265: grpc_c.so] Error 1
rake aborted!

Any idea what's going wrong here or pointers on how to debug?

flavorjones commented 2 years ago

Hey @johnnyshields, I'd be happy to collaborate on getting grpc to compile for this platform. I know you've been doing some work over the last few months to get Ruby 3.1 support, etc. going for grpc, thank you for that!

Help me understand the current status of that work. Are you trying to build off the v1.46.3 tag, or a feature branch, or some other tag? How do I catch up and reproduce exactly what you're doing?

johnnyshields commented 2 years ago

@flavorjones thanks for the reply!

Please try the branch in this PR, I think it should be the most stable: https://github.com/grpc/grpc/pull/29941

Make sure to checkout all submodules in order to build, it's quite heavy.

flavorjones commented 2 years ago

Taking a look now, apologies for the delay.

flavorjones commented 2 years ago

@johnnyshields So I think the issue is with trying to statically link the ruby library. This patch results in a successful build:

commit 3e22505 (HEAD -> flavorjones-v1.46.x-backport-ruby-x64-mingw-ucrt)
Author: Mike Dalessio <mike.dalessio@gmail.com>
Date:   2022-06-23 15:29:53 -0400

    fix: do not statically link the ruby windows ucrt library

    The error being raised by the linked when trying to create the
    grpc_c.so was:

    > linking shared-object grpc/grpc_c.so
    > /usr/bin/x86_64-w64-mingw32-ld: cannot find -lx64-ucrt-ruby310
    > collect2: error: ld returned 1 exit status
    > make: *** [Makefile:265: grpc_c.so] Error 1

    as described at
    https://github.com/rake-compiler/rake-compiler-dock/issues/69

diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb
index e0ca9b7..844f817 100644
--- a/src/ruby/ext/grpc/extconf.rb
+++ b/src/ruby/ext/grpc/extconf.rb
@@ -16,6 +16,7 @@
 require 'mkmf'

 windows = RUBY_PLATFORM =~ /mingw|mswin/
+windows_ucrt = RUBY_PLATFORM =~ /(mingw|mswin).*ucrt/
 bsd = RUBY_PLATFORM =~ /bsd/
 darwin = RUBY_PLATFORM =~ /darwin/
 linux = RUBY_PLATFORM =~ /linux/
@@ -100,7 +101,7 @@

 $LDFLAGS << ' -Wl,-wrap,memcpy' if linux
 $LDFLAGS << ' -static-libgcc -static-libstdc++' if linux
-$LDFLAGS << ' -static' if windows
+$LDFLAGS << ' -static' if windows && !windows_ucrt

 $CFLAGS << ' -std=c99 '
 $CFLAGS << ' -Wall '

I can submit that as a PR to GRPC if you like.

It's not clear to me why this is different for the ucrt build environment. Poking around in the containers:

# larskanis/rake-compiler-dock-mri-x64-mingw32:1.2.1
$ file /usr/local/rake-compiler/ruby/x86_64-w64-mingw32/ruby-3.0.0/lib/lib*ruby* 
/usr/local/rake-compiler/ruby/x86_64-w64-mingw32/ruby-3.0.0/lib/libx64-msvcrt-ruby300-static.a: current ar archive
/usr/local/rake-compiler/ruby/x86_64-w64-mingw32/ruby-3.0.0/lib/libx64-msvcrt-ruby300.a:        current ar archive
# larskanis/rake-compiler-dock-mri-x64-mingw-ucrt:1.2.1
$ file /usr/local/rake-compiler/ruby/x86_64-w64-mingw32/ruby-3.1.0/lib/lib*ruby*
/usr/local/rake-compiler/ruby/x86_64-w64-mingw32/ruby-3.1.0/lib/libx64-ucrt-ruby310-static.a: current ar archive
/usr/local/rake-compiler/ruby/x86_64-w64-mingw32/ruby-3.1.0/lib/libx64-ucrt-ruby310.dll.a:    current ar archive

So maybe this is a file naming issue (note the .dll in the ucrt shared file name)? @larskanis I'm curious what you think.

flavorjones commented 2 years ago

Look like this line in Dockerfile.mri.erb needs to be updated:

RUN find /usr/local/rake-compiler/ruby -name *msvcrt-ruby*.dll.a | while read f ; do n=`echo $f | sed s/.dll//` ; mv $f $n ; done

because this misses the file named libx64-ucrt-ruby310.dll.a

flavorjones commented 2 years ago

I'll submit a PR tonight.

johnnyshields commented 2 years ago

@flavorjones awesome, much appreciated! Your diagnosis matches what I'm seeing as well.

flavorjones commented 2 years ago

PR is up at https://github.com/rake-compiler/rake-compiler-dock/pull/70