Skip to content

Commit

Permalink
Install libyaml & libffi in ruby-specific bin dir
Browse files Browse the repository at this point in the history
Previously, the pdk-vanagon's gem prune command[1] failed on Windows with Ruby
3.2:

    $ GEM_PATH="C:/ProgramFiles64Folder/PuppetLabs/DevelopmentKit/private/puppet/ruby/3.2.0;C:/ProgramFiles64Folder/PuppetLabs/DevelopmentKit/share/cache/ruby/3.2.0"  \
    RUBYOPT="-Irubygems-prune" C:/ProgramFiles64Folder/PuppetLabs/DevelopmentKit/private/ruby/3.2.2/bin/gem.bat prune
    ...
    The specified module could not be found.   - C:/ProgramFiles64Folder/PuppetLabs/DevelopmentKit/private/ruby/3.2.2/lib/ruby/3.2.0/x64-mingw32/psych.so (LoadError)

The error is misleading, because it found psych.so, but couldn't load its
dependency libyaml-0.2.dll.

The reason this occurred was because the pdk-runtime installed libyaml into its
prefix bin directory, which is different than its primary ruby bin directory:

    prefix   C:/ProgramFiles64Folder/PuppetLabs/DevelopmentKit/bin/
    ruby_dir C:/ProgramFiles64Folder/PuppetLabs/DevelopmentKit/private/ruby/3.2.2/bin

However, the prefix bin directory is not in the PATH, so it couldn't load libyaml.

This wasn't an issue for non-pdk runtimes, because the prefix and ruby_dir are
the same. And on Windows the default Dll search path includes "The folder from
which the application loaded."[2]

This is not an issue for pdk runtimes on *nix, because we embed
/opt/puppetlabs/pdk/lib into the RPATH:

    # objdump -p /opt/puppetlabs/pdk/private/ruby/3.2.2/lib/ruby/3.2.0/x86_64-linux/psych.so | grep -i path
      RUNPATH              /opt/puppetlabs/pdk/lib:/opt/puppetlabs/pdk/private/ruby/3.2.2/lib

So psych.so can load libyaml:

    # ldd /opt/puppetlabs/pdk/private/ruby/3.2.2/lib/ruby/3.2.0/x86_64-linux/psych.so | grep libyaml
           libyaml-0.so.2 => /opt/puppetlabs/pdk/lib/libyaml-0.so.2

This is not an issue when running the pdk on Windows, because the wrapper adds
the directory to the PATH[3]

The same issue existed when the ffi_c.so native extension tried to load libffi.

Since libyaml and libffi may be depended on by more than just ruby 3.2, install
the libraries in to the prefix directory and copy them into the ruby 3.2 bin
directory.

This was partially addressed in ba4c955 and reverted in 811a384, but is
implemented differently here.

[1] https://github.com/puppetlabs/pdk-vanagon/blob/c7d35b03fa014f95570cee9c84fcfd2bbfc7df32/configs/components/gem-prune.rb#L37
[2] https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order
[3] https://github.com/puppetlabs/pdk-vanagon/blob/c7d35b03fa014f95570cee9c84fcfd2bbfc7df32/resources/files/windows/pdk.bat#L7
  • Loading branch information
joshcooper committed Nov 17, 2023
1 parent a2e5bea commit 887c920
Showing 1 changed file with 2 additions and 0 deletions.
2 changes: 2 additions & 0 deletions configs/components/_base-ruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@
pkg.install do
[
"cp #{settings[:gcc_bindir]}/libssp-0.dll #{ruby_bindir}",
"cp #{settings[:bindir]}/libffi-8.dll #{ruby_bindir}",
"cp #{settings[:bindir]}/libyaml-0-2.dll #{ruby_bindir}"
]
end
end
Expand Down

0 comments on commit 887c920

Please sign in to comment.