From 887c920f702bcd7ebe5eaff816fe4ba766675a31 Mon Sep 17 00:00:00 2001 From: Josh Cooper Date: Thu, 16 Nov 2023 23:22:54 -0800 Subject: [PATCH] Install libyaml & libffi in ruby-specific bin dir 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 ba4c95513 and reverted in 811a384b2, 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 --- configs/components/_base-ruby.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/components/_base-ruby.rb b/configs/components/_base-ruby.rb index 5006040ba..0265a792d 100644 --- a/configs/components/_base-ruby.rb +++ b/configs/components/_base-ruby.rb @@ -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