MSP-Greg / ruby-loco

Fully tested Ruby Windows Mingw, ucrt & mswin builds, built and saved on GitHub
https://github.com/MSP-Greg/ruby-loco
MIT License
17 stars 5 forks source link

[enhancement request] Add a static build #10

Open jmarrec opened 6 months ago

jmarrec commented 6 months ago

Would it be possible to add a mswin build with --disable-shared --enable-static --with-static-linked-ext --enable-load-relative options?

I've tried on a fork (and locally), can't seem to be make it work exactly, though it's close. It builds and all, but ruby -v does nothing unless I do use the manifest with the dlls provided by vcpkg (ruby_builtin_dlls).

I'm guessing there's a way to statically link those as well.


Should maybe try using pkgconf on windows instead of manually symlinking the DLLs to the ruby repo?

> C:\vcpkg\vcpkg.exe install --triplet=x64-windows pkgconf 
> $env:PKG_CONFIG_PATH="C:\vcpkg\installed\x64-windows\lib\pkgconfig"
> C:\vcpkg\installed\x64-windows\tools\pkgconf\pkgconf.exe --libs openssl --msvc-syntax
/libpath:C:/vcpkg/installed/x64-windows/lib libssl.lib libcrypto.lib

I've got a patch (for several versions, here is 3.2.2): https://github.com/jmarrec/conan-recipes/blob/main/recipes/ruby/all/patches/0005-fix-pkg-config-on-windows-3.2.2.patch and an upstream PR to support pkgconf on windows: https://github.com/ruby/ruby/pull/9815

MSP-Greg commented 6 months ago

@jmarrec

Never tried. Let me see what I can do locally. Might I ask why you'd like a build like this? Anything to do with SketchUp (since it uses Ruby)?

jmarrec commented 6 months ago

This for OpenStudio, a building energy modeling tool that has an embedded ruby interpreter (c++, we build darwin and linux x64 and armv8, windows x64 mswin). And the OpenStudio Application, and openstudio-sketchup-plugin build upon it. So yes, related to sketchup. We're upgrading ruby from 2.7.2 to 3.x (probably 3.2.2)

We have been building ruby through conan, and updated it for 3.2.2, but it's such a pain that 1) I'm exploring options, 2) having some CI test the static / static linked ext builds, especially mswin, would be very helpful so that upstream would be less likely to break it.

jmarrec commented 6 months ago

(This is kinda how I came across this repo, partly through sketchup forums and partly through setup-ruby gha action, then I noticed your su-3.2 branch)

MSP-Greg commented 6 months ago

@jmarrec

I just built a 'fully' static Ruby. This means there are no dll's needed. Or, bin/ruby_builtin_dlls is empty. Also, there are no *.so files in lib/ruby/3.2.0/x64-mswin64_140.

Is that what you want? Or, do you want the dll's static, but not the *.so files?

Re vcpkg, have you built static 'installs' with it? as in:

./vcpkg --triplet=x64-windows-static install libffi libyaml openssl readline-win32 zlib

Also, change

$script:d_vcpkg_install = "$d_vcpkg/installed/x64-windows"

to

$script:d_vcpkg_install = "$d_vcpkg/installed/x64-windows-static"

Remember the --so-name= issue...

JFYI, a long time ago SketchUp introduced me to Ruby. I've also got a rather specialized SU extension written 12+ years ago that is still in use. Since then, I've gotten involved in Ruby OSS...

jmarrec commented 6 months ago

Thanks for looking into it (and so quickly), I appreciate it!

I thought about using the triplet x64-windows-static for vcpkg and started modifying your ps1 files to do that but I stopped.

I have to admit I'm lacking full understanding when it comes to windows / MSVC, but I thought using /MT (which is what the -static part of the tripplet does IIUC) meant it was incompatible to be linked into an application that is built with /MD (or /MDd in Debug mode) which is my end product. Perhaps I misunderstood that part?

Are you able to load static exts (bigdecimal, openssl, etc) with the ruby you built?

As far as I can tell, when you build static-linked-ext you end up with a bunch of ext/**/*.lib and enc/**/*.lib which are never installed nor linked into the final librubyxxxx-static.lib. And on Unix at least, the ext/extinit.c and enc/encinit.c that are generated dynamically during the build are not linked to it either: early in the build it uses dmyext.c / dmyenc.c with a no-op Init_ext / Init_enc definition so it can build miniruby. (cf this patch for Unix that adds a dumb target I can call in the end to replace the dmyext.o with the extinit.o: https://github.com/jmarrec/conan-recipes/blob/main/recipes/ruby/all/patches/0009-fixup-libruby-static-3.2.2.patch)

jmarrec commented 6 months ago

for context, the original idea, and the way it's been for the past 10+ years, is that the OpenStudio CLI is a self contained, relocatable executable. OpenStudio.exe libs to static ruby and ext libs, and we also embed .rb (core + gems) as binary representations in the CLI, patch the rubygems code so we can load them. And we also export our C++ code to ruby via SWIG, and the embedded ruby interpreter also has access to that.

It changed a bit lately after we've essentially done the same thing with python. Now we have an executable that runs C++, where you can also executable abritrary ruby or python files to modify some internal C++ object as part of a workflow. It's kinda crazy, but it works.

MSP-Greg commented 6 months ago

See https://github.com/MSP-Greg/sketchup-ext-gem/releases/download/v1.0.0/Ruby-3.2.3-su-static.zip

The Ruby dll is named x64-ucrt-ruby320.dll, and it's built with the current vcpkg OpenSSL, which is 3.2.1.

Let me know if that works for you...

MSP-Greg commented 6 months ago

Now, as to how/what I changed to build the above, I could add a branch for it. Or, I could add an argument to 1_0_build_install_mswin.ps1, which would be easier.

As to building it here as part of it's CI, the 'setup-ruby' system has a companion repo that builds the shared vcpkg items required to build Ruby and then saves them as an archive file. That would have to be updated to add an archive for static packages. I've been building Ruby for quite a while, I don't recall if I've done a static build.

Not sure what would happen if one installed a new version of ruby/openssl and tried to use it. The main reason I started this was to encourage other repos to run CI on Windows master builds. The builds are also used by the repos containing Ruby std-lib extensions (e.g. https://github.com/ruby/openssl).

jmarrec commented 6 months ago

Is this what you need for building the mswin static vcpkg? I added a matrix job to do both regular and static https://github.com/ruby/setup-msys2-gcc/commit/763266281e78a594ec4611af5a069e3758d78c54

It didn't upload anything but that's another story (this usage of a single release/tag to continuously store new assets is new to me. There's likely a precondition like the table in the post that I didn't have).

I can make a PR tomorrow if that's of interest (even if you don't end up merging, might be a good idea to review/discuss in context)

MSP-Greg commented 6 months ago

@jmarrec

Thanks for the work you've done. I need to have a block of time to think about some of the changes here and in setup-msys2-gcc.

The main purpose of this repo is to allow using Windows Ruby 'master/head' builds in GitHub Actions (GHA). As you know, it builds MSYS2 ucrt and mingw builds, and also an mswin build. Since build tools and packages are pre-installed on Ubuntu & macOS Actions images, setup-msys2-gcc was created as a means to quicky install the proper build tools and packages on Windows images. Doing so means that repo maintainers don't need to be familiar with Windows, and most Actions CI scripts need nothing 'Windows' specific in them.

For instance, in the sqlite3-ruby workflow run, the mswin build comes from this repo, and all the 'build tools' and 'mswin vcpkg packages' archives are from setup-msys2-gcc. You probably already know this.

Another issue with this repo is the testing that happens after the build scripts. If the tests fail, the build isn't uploaded. It's a long story as to why, but this repo runs the tests from the 'install folder'. Hence, there are patches, as the normal Ruby tests run from the 'build folder'. Bottom line is that the tests may not pass when building an older Ruby.

So, there are a few issues with using this 'as is' for building older Rubies.

I've already got https://github.com/MSP-Greg/ruby-mswin, but I haven't done much with it. Maybe that would be a better repo, having a focus on building Ruby releases...

MSP-Greg commented 6 months ago

@jmarrec

I tried a few things. I tried gem install openssl on the static build, and it failed. It does install when using the mswin build (non-static build from this repo).

So, maybe there needs to be changes to the extconf.rb file, or possibly mkmf.rb, not sure. Regardless, the static build is causing issues with extension gem installation.

jmarrec commented 6 months ago

I'm not that surprised that it didn't work.

We've been building static openssl (and a few others), using a siteconf.rb and using the "static" target.

https://github.com/NREL/openstudio-gems/blob/04a6a4cb36a11374487bc609adf1eee156454377/lib/rubygems_plugin.rb#L74-L122 and the ruby3 version with CI added on my fork here: https://github.com/jmarrec/openstudio-gems/blob/a3c46e8fa93bc261508defbe8e2f0d8c2642c56a/lib/rubygems_plugin.rb#L26-L149