Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Keeping Ruby Running on Cygwin

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.
Avatar for fd0 fd0
April 23, 2026

Keeping Ruby Running on Cygwin

Avatar for fd0

fd0

April 23, 2026

More Decks by fd0

Other Decks in Technology

Transcript

  1. ˒ Daisuke Fujimura ˒ Maintainer of the ruby binary package

    on cygwin (Not a Ruby commi tt er) ˒ Interested in software packaging, build systems, and platform engineering About Me 2
  2. ˒ A large collection of GNU and Open Source tools

    which provide functionality similar to a Linux distribution on Windows ˒ A DLL (cygwin1.dll) which provides substantial POSIX API functionality Cygwin is... 5 h tt ps://cygwin.com/
  3. ˒ WSL has taken over many use cases ˒ But

    Cygwin still has demand ˒ Native Windows interop ˒ Legacy work fl ows Cygwin in the WSL Era 6
  4. ˒ O ff icial pre-compiled binary packages ˒ Distributed like

    rpm or deb ˒ Via the Cygwin installer; ruby.exe ready ˒ Maintained by me Ruby on Cygwin 7
  5. ˒ Works like Linux ˒ Unix-style paths (e.g. /home, not

    C:\Users) ˒ Many POSIX APIs work (e.g. Process.fork) ˒ ...and more Di ff erent from Windows Ruby 10
  6. ˒ Each package has a volunteer maintainer ˒ Step away

    → package becomes orphaned ˒ Orphaned = no active maintainer ˒ Ruby went orphaned after 2.6 ˒ Ruby commi tt ers had no Cygwin maintainer either [1] The Orphaned Package 11 [1] h tt ps://github.com/ruby/ruby/blob/master/doc/maintainers.md
  7. ˒ My interests all converge here ˒ Long-time Cygwin user

    ˒ Into language runtimes and libraries ˒ Love Linux packaging (e.g. rpm, deb,...) Motivation: Why I started maintaining Ruby on Cygwin (1) 14
  8. ˒ The outdated Ruby was a real problem ˒ Security

    risk ˒ Missing new features Motivation: Why I started maintaining Ruby on Cygwin (2) 15
  9. ˒ KaigiE ff ect ˒ First a tt ended RubyKaigi

    2018 ˒ Blew my mind; never missed one since Motivation: Why I started maintaining Ruby on Cygwin (3) 16
  10. Release History 17 Version Original Release Cygwin Package Release EOL

    2.6.4 2019-08-28 2019-09-16 2022-04-12 3.2.2 2023-03-30 2023-04-28 2026-03-31 3.4.7 2025-10-07 2025-10-17 TBD h tt ps://cygwin.com/packages/summary/ruby.html
  11. ˒ No handover docs: the repository was the only guide

    ˒ Let's look at what's in there Climbing from 2.6 to 3.2 19
  12. ˒ Cygport: Cygwin's build system ˒ Rules wri tt en

    in bash syntax in a .cygport fi le Repository Tree (1) 20 h tt ps://cygwin.com/cgit/cygwin-packages/ruby/
  13. ˒ Some parts of Ruby assume only major platforms; patches

    make them work correctly on Cygwin Repository Tree (2) 21 h tt ps://cygwin.com/cgit/cygwin-packages/ruby/
  14. ˒ Some patches are sourced from Fedora for reliability and

    license compatibility Repository Tree (3) 22 h tt ps://cygwin.com/cgit/cygwin-packages/ruby/
  15. ˒ Opt out of arch-speci fi c bindir (e.g. /usr/libexec/x86_64-linux/

    bin) Patch Example 23 h tt ps://cygwin.com/cgit/cygwin-packages/ruby/tree/3.4.2-rbinstall-archbindir.patch
  16. ruby.cygport — Metadata 25 ˒ Declared as bash variables: name,

    version, source URLs, patch locations, etc.
  17. ˒ Build steps (compile, install, etc.) are de fi ned

    by overriding bash functions ˒ Ruby uses GNU Autotools; con fi gure options are speci fi ed in src_compile() ruby.cygport — Build Functions 26
  18. Package Layout (1) 📃 ruby.cygport (3.2.2) 📦 ruby (3.2.2) 📦

    ruby-devel (3.2.2) 📦 rubygems (3.4.10) 📦 ruby-rdoc (6.5.0) $ cygport ruby.cygport package 27 X X (3.2.2) (3.2.2)
  19. Package Layout (2) 📃 rubygems.cygport (3.4.10) 📦 rubygems (3.4.10) 📦

    ruby-rdoc (6.5.0) 📃 ruby-rdoc.cygport (6.5.0) $ cygport rubygems.cygport package $ cygport ruby-rdoc.cygport package 28 📃 ruby.cygport (3.2.2) 📦 ruby (3.2.2) $ cygport ruby.cygport package
  20. Package Layout (3) 📦 ruby (3.2.2) /usr/bin/ruby.exe /usr/bin/gem /usr/bin/rdoc :

    📦 rubygems (3.4.10) /usr/bin/gem : 📦 ruby-rdoc (6.5.0) /usr/bin/rdoc : Con fl ict Con fl ict 29
  21. ABI Info Missing (1) 📦 ruby-bcrypt (3.1.20) 📦 ruby (2.6.4)

    📦 ruby (3.2.2) Wants to install Which ABI? ˒ New Ruby → ABI changes → gems must be rebuilt ˒ The installer had no way to know which Ruby ABI each gem was built for ˒ → Unable to resolve dependencies 31
  22. ˒ Hint fi les (generated per package build) → aggregated

    into setup.ini ABI Info Missing (2) 📃 ruby-bcrypt.hint 📃 setup.ini 📃 ruby-devel.hint : 📃 ruby.hint $ mksetupini 32
  23. ˒ O ff icial CI/CD takes it from here ˒

    GitHub Actions: build, upload, update setup.ini, announce ˒ Users get the latest Ruby. happy ending! Ge tt ing It Out the Door 34
  24. ˒ 3.3 never shipped: a SEGV with unknown cause blocked

    the release ˒ gdb investigation, but hard to use e ff ectively ˒ With AI's step-by-step guidance, narrowed down the cause Climbing Again: 3.2 to 3.4 — Debugging with AI 35
  25. ˒ Root cause: SEGV inside pthread, triggered by libssl 3

    ˒ 3.2 was fi ne: linked against libssl 1.1 ˒ Shipped with 3.4.7, after libssl resolved the issue ˒Lesson: sometimes the bug is outside Ruby Climbing Again: 3.2 to 3.4 — Root Cause & Resolution 36
  26. ˒ My own (uno ff icial) CI pipeline ˒ Tracks

    Ruby HEAD ˒ Fix issues upstream, reduce local patches ˒ Led to several upstream PRs ˒ #9269 (#9357), #11952, #14870 Running CI Myself — and What I Found 38
  27. ˒ test_ractor.rb, test_thread.rb → SEGV on Cygwin ˒ Grepping #if

    de fi ned(__CYGWIN__) ˒ native_thread_init_stack() was skipped ˒ Tried removing the exclusion → SEGV was gone ˒ But why? 🤔 ˒ Kept digging to fi nd the reason #9269: Use native_thread_init_stack — Problem 40
  28. ˒ Found commit in 2010 [1] ˒ Incomplete signal stack

    → exclusion was justi fi ed ˒ Cygwin fi xed signal stack in 2015 [2] ˒ Code outlived the reason #9269: Use native_thread_init_stack — Investigation 41 [1] h tt ps://github.com/ruby/ruby/commit/6957c6d9cf0b6a1e211c4b0175bc5474296f2031 [2] h tt ps://github.com/cygwin/cygwin/commit/c8432a01c8401c121940c806a9d868c4adc4cefd
  29. ˒ make test on Cygwin passing again after ~10 years

    ˒ That's win! #9357: Use ubf list 43
  30. ˒ A dangling pointer is a pointer to memory that

    is no longer valid ˒ GCC's -Wdangling-pointer caught one in dln.c ˒ But only on Cygwin #11952: Avoid dangling pointer — Problem: Warning 45
  31. ˒ dladdr(): looks up which library a given address belongs

    to ˒ Fills a Dl_info struct with the result ˒ dli_fname member holds the library fi le path ˒ libname holds dli_fname... #11952: Avoid dangling pointer — Problem: The Code 46
  32. #11952: Avoid dangling pointer — Investigation: Type Di ff erence

    47 Linux [1] Cygwin [2] [1] h tt ps://sourceware.org/git/?p=glibc.git;a=blob;f=dlfcn/dlfcn.h [2] h tt ps://github.com/cygwin/cygwin/blob/main/winsup/cygwin/include/dlfcn.h
  33. ˒ Why the type di ff erence? ˒ dladdr() standardized

    in POSIX Issue 8 (2024) ˒ Cygwin: 2017 [1] ˒ Each platform de fi ned types independently #11952: Avoid dangling pointer — Investigation: Background 48 [1] h tt ps://github.com/cygwin/cygwin/commit/c8432a01c8401c121940c806a9d868c4adc4cefd
  34. ˒ libname is only used in error messages; skipping is

    su ff icient #11952: Avoid dangling pointer — Fix 49
  35. ˒ Tried namespace (box) locally ˒ Native extension .so →

    LoadError #14870: Fix extension fi le permissions in namespace feature — Problem 51
  36. ˒ fwrite copy → dlopen #14870: Fix extension fi le

    permissions in namespace feature — Investigation: Copy 52
  37. ˒ Cygwin: copied .so permissions come from Windows ACL ˒

    The executable bit was not set on the copy #14870: Fix extension fi le permissions in namespace feature — Investigation: Permission 53 -rwxr-xr-x openssl.so -rw-r--r-- openssl.so Copy by fwrite
  38. ˒ dlopen internally calls Windows LoadLibraryW ˒ No Executable in

    ACL → ERROR_ACCESS_DENIED ˒ Not o ff icially documented, but widely known behavior #14870: Fix extension fi le permissions in namespace feature — Investigation: Implementation 54
  39. ˒ Preserve permissions after fwrite copy #14870: Fix extension fi

    le permissions in namespace feature — Fix 55
  40. ˒ My CI caught a compile failure on Cygwin ˒

    -municode (MinGW-w64-only) accidentally applied to Cygwin ˒ Fixed by #12015 Cygwin Joins the O ff icial CI Matrix (1) 57
  41. ˒ To prevent this class of breakage from landing again

    ˒ Now every commit is veri fi ed to build on Cygwin Cygwin Joins the O ff icial CI Matrix (2) 58
  42. ˒ Upgraded Ruby on Cygwin from 2.6 to 3.4 ˒

    Deepened understanding of the packaging system ˒ Encountered a new debugging experience ˒ A dependency-blocked release tackled with AI Looking Back — Packaging Journey 60
  43. ˒ Niche bugs that only surface on Cygwin ˒ Hard

    to see without downstream involvement ˒ Cygwin is now in the o ff icial CI matrix Looking Back — Upstream Contributions 61
  44. ˒ All of this contributes to Ruby's "Highly Portable" goal

    ˒ Covering underserved platforms helps grow the Ruby community Looking Forward 62