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

So ruby in the primary bin directory couldn't load libyaml in the prefix bin
directory, since the latter was not in the PATH.

This was not 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
reinstated 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 bb43c90 commit 755467e
Showing 1 changed file with 4 additions and 0 deletions.
4 changes: 4 additions & 0 deletions configs/components/runtime-pdk.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
pkg.install_file "#{settings[:tools_root]}/bin/libgdbm_compat-4.dll", "#{settings[:ruby_bindir]}/libgdbm_compat-4.dll"
pkg.install_file "#{settings[:tools_root]}/bin/libiconv-2.dll", "#{settings[:ruby_bindir]}/libiconv-2.dll"

# Ruby 3 depends on libyaml & libffi, install the libraries we built earlier
pkg.install_file "#{settings[:bindir]}/libffi-8.dll", "#{settings[:ruby_bindir]}/libffi-8.dll"
pkg.install_file "#{settings[:bindir]}/libyaml-0-2.dll", "#{settings[:ruby_bindir]}/libyaml-0-2.dll"

# Ruby 3 depends on strong stack protection
pkg.install_file "#{settings[:bindir]}/libssp-0.dll", "#{settings[:ruby_bindir]}/libssp-0.dll"

Expand Down

0 comments on commit 755467e

Please sign in to comment.