From 35b2704fc79aca22488251b1910d3b8e6be6f83e Mon Sep 17 00:00:00 2001 From: Lars Kanis Date: Sat, 30 Aug 2025 15:34:03 +0200 Subject: [PATCH 1/4] Add tests for rpath or other build related paths --- spec/pg_spec.rb | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/spec/pg_spec.rb b/spec/pg_spec.rb index b24d3c1bf..c83bff57f 100644 --- a/spec/pg_spec.rb +++ b/spec/pg_spec.rb @@ -67,4 +67,30 @@ [PG.library_version, PG.version_string, PG.threadsafe?, PG::VERSION, PG::POSTGRESQL_LIB_PATH] ) end + + it "native gem's C-ext file shouldn't contain any rpath or other build-related paths" do + skip "applies to native binary gems only" unless PG::IS_BINARY_GEM + cext_fname = $LOADED_FEATURES.grep(/pg_ext/).first + expect(cext_fname).not_to be_nil + cext_text = File.binread(cext_fname) + expect(cext_text).to match(/Init_pg_ext/) # C-ext shoud contain the init function + expect(cext_text).not_to match(/usr\/local/) # there should be no rpath to /usr/local/rake-compiler/ruby/x86_64-unknown-linux-musl/ruby-3.4.5/lib or so + expect(cext_text).not_to match(/home\//) # there should be no path to /home/ or so + end + + it "native gem's libpq file shouldn't contain any rpath or other build-related paths" do + skip "applies to native binary gems only" unless PG::IS_BINARY_GEM + + libpq_fname = case RUBY_PLATFORM + when /mingw|mswin/ then "libpq.dll" + when /linux/ then "libpq-ruby-pg.so.1" + when /darwin/ then "libpq-ruby-pg.1.dylib" + end + + path = File.join(PG::POSTGRESQL_LIB_PATH, libpq_fname) + text = File.binread(path) + expect(text).to match(/PQconnectdb/) # libpq shoud contain the connect function + expect(text).not_to match(/usr\/local/) # there should be no rpath to build dirs + expect(text).not_to match(/home\//) # there should be no path to /home/.../ports/ or so + end end From 70551b94eab64bcfd879d91382b216224d2394b5 Mon Sep 17 00:00:00 2001 From: Lars Kanis Date: Sat, 30 Aug 2025 18:08:31 +0200 Subject: [PATCH 2/4] Add spec/pg_spec.rb to tests .. which wasn't tested in CI. We could use `rake test` instead, but it starts a separate `rspec` process, which doesn't respect our early load `-rpg`. Instead it uses the git checkout for lib files and not the files installed from the native binary gem. This in turn doesn't set POSTGRESQL_LIB_PATH correctly. --- .github/workflows/binary-gems.yml | 4 ++-- .github/workflows/source-gem.yml | 2 +- spec/env/Dockerfile.alpine | 2 +- spec/env/Dockerfile.centos | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/binary-gems.yml b/.github/workflows/binary-gems.yml index 86ebb3fca..363a74e64 100644 --- a/.github/workflows/binary-gems.yml +++ b/.github/workflows/binary-gems.yml @@ -142,12 +142,12 @@ jobs: - run: echo $env:PATH - name: Run specs if: ${{ matrix.os != 'windows-latest' }} - run: ruby -rpg -S rspec -fd spec/**/*_spec.rb + run: ruby -rpg -S rspec -fd spec/*_spec.rb spec/**/*_spec.rb - name: Run specs if: ${{ matrix.os == 'windows-latest' }} run: | ridk enable - ruby -rpg -S rspec -fd spec/**/*_spec.rb + ruby -rpg -S rspec -fd spec/*_spec.rb spec/**/*_spec.rb - name: Print logs if job failed if: ${{ failure() && matrix.os == 'windows-latest' }} diff --git a/.github/workflows/source-gem.yml b/.github/workflows/source-gem.yml index 7b56eee9d..961902a07 100644 --- a/.github/workflows/source-gem.yml +++ b/.github/workflows/source-gem.yml @@ -147,7 +147,7 @@ jobs: PG_DEBUG: 0 # Temprary fix only for Truffleruby-24.0.0: TRUFFLERUBYOPT: --experimental-options --keep-handles-alive - run: ruby -rpg -S rspec spec/**/*_spec.rb -cfdoc + run: ruby -rpg -S rspec spec/*_spec.rb spec/**/*_spec.rb -cfdoc - name: Print db logs if job failed if: ${{ failure() && matrix.os == 'windows' }} diff --git a/spec/env/Dockerfile.alpine b/spec/env/Dockerfile.alpine index ff83b0c93..340fee53b 100644 --- a/spec/env/Dockerfile.alpine +++ b/spec/env/Dockerfile.alpine @@ -25,4 +25,4 @@ CMD ruby -v && \ bundle config set --local without 'development' && \ bundle install && \ sudo -u postgres ruby -rpg -e "p RUBY_DESCRIPTION, PG::VERSION, PG::POSTGRESQL_LIB_PATH, PG::IS_BINARY_GEM, PG::BUNDLED_LIBPQ_WITH_UNIXSOCKET; puts PG.connect.exec('SELECT version()').values; p PG.connect.host" && \ - sudo -u postgres ruby -rpg -S rspec -fd spec/**/*_spec.rb + sudo -u postgres ruby -rpg -S rspec -fd spec/*_spec.rb spec/**/*_spec.rb diff --git a/spec/env/Dockerfile.centos b/spec/env/Dockerfile.centos index bd09a2abb..06afc1fef 100644 --- a/spec/env/Dockerfile.centos +++ b/spec/env/Dockerfile.centos @@ -24,4 +24,4 @@ CMD ruby -v && \ bundle config set --local without 'development' && \ bundle install && \ sudo -u postgres ruby -rpg -e "p RUBY_DESCRIPTION, PG::VERSION, PG::POSTGRESQL_LIB_PATH, PG::IS_BINARY_GEM, PG::BUNDLED_LIBPQ_WITH_UNIXSOCKET; puts PG.connect.exec('SELECT version()').values; p PG.connect.host" && \ - sudo -u postgres ruby -rpg -S rspec -fd spec/**/*_spec.rb + sudo -u postgres ruby -rpg -S rspec -fd spec/*_spec.rb spec/**/*_spec.rb From 5e2ac6e14589f8698f127be080e94e93151552fc Mon Sep 17 00:00:00 2001 From: Lars Kanis Date: Sat, 30 Aug 2025 22:41:44 +0200 Subject: [PATCH 3/4] Temporary enable head version of rake-compiler-dock ... to fix C-ext rpath test case. --- .github/workflows/binary-gems.yml | 2 ++ Gemfile | 2 +- Rakefile | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/binary-gems.yml b/.github/workflows/binary-gems.yml index 363a74e64..e70c02686 100644 --- a/.github/workflows/binary-gems.yml +++ b/.github/workflows/binary-gems.yml @@ -20,6 +20,8 @@ jobs: rcd_build: name: Build runs-on: ubuntu-latest + env: + RCD_IMAGE_VERSION: snapshot strategy: fail-fast: false matrix: diff --git a/Gemfile b/Gemfile index d0237dd8b..ae91a95d1 100644 --- a/Gemfile +++ b/Gemfile @@ -13,7 +13,7 @@ end group :test do gem "bundler", ">= 1.16", "< 3.0" gem "rake-compiler", "~> 1.0" - gem "rake-compiler-dock", "~> 1.9.1" + gem "rake-compiler-dock", "~> 1.9.1", git: "https://github.com/rake-compiler/rake-compiler-dock" gem "rspec", "~> 3.5" # "bigdecimal" is a gem on ruby-3.4+ and it's optional for ruby-pg. # Specs should succeed without it, but 4 examples are then excluded. diff --git a/Rakefile b/Rakefile index 28e8f67f1..3b9955c54 100644 --- a/Rakefile +++ b/Rakefile @@ -74,7 +74,7 @@ Rake::ExtensionTask.new do |ext| # Activate current cross compiled platform only. # This is to work around the issue that `linux` platform is selected in `linux-musl` image. ext.cross_platform = CrossLibraries.map(&:platform).select do |pl| - m = ENV["RCD_IMAGE"]&.match(/:(?[\d\.]+)-mri-(?[-\w]+)$/) + m = ENV["RCD_IMAGE"]&.match(/:(?[\w\.]+)-mri-(?[-\w]+)$/) m && m[:platform] == pl end @@ -106,7 +106,7 @@ task 'gem:native:prepare' do # Copy gem signing key and certs to be accessible from the docker container mkdir_p 'build/gem' sh "cp ~/.gem/gem-*.pem build/gem/ || true" - sh "bundle package" + sh "bundle package --all" begin OpenSSL::PKey.read(File.read(File.expand_path("~/.gem/gem-private_key.pem")), ENV["GEM_PRIVATE_KEY_PASSPHRASE"] || "") rescue OpenSSL::PKey::PKeyError From 19a35473b0ef7b4bf0d9caf7b62fb7fbbf7e168b Mon Sep 17 00:00:00 2001 From: Lars Kanis Date: Sun, 31 Aug 2025 18:50:39 +0200 Subject: [PATCH 4/4] Strip darwin C-ext to remove paths to C files ... which are only valid in the build environment. --- ext/extconf.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/ext/extconf.rb b/ext/extconf.rb index ecfc885a0..c55133dcd 100644 --- a/ext/extconf.rb +++ b/ext/extconf.rb @@ -330,3 +330,20 @@ module PG create_header() create_makefile( "pg_ext" ) +if gem_platform + # exercise the strip command on native binary gems + # This approach borrowed from + # https://github.com/rake-compiler/rake-compiler-dock/blob/38066d479050f4fdb3956469255b35a05e5949ef/test/rcd_test/ext/mri/extconf.rb#L97C1-L110C42 + strip_tool = RbConfig::CONFIG['STRIP'] + strip_tool += ' -x' if RUBY_PLATFORM =~ /darwin/ + File.open('Makefile.new', 'w') do |o| + o.puts 'hijack: all strip' + o.puts + o.write(File.read('Makefile')) + o.puts + o.puts 'strip: $(DLLIB)' + o.puts "\t$(ECHO) Stripping $(DLLIB)" + o.puts "\t$(Q) #{strip_tool} $(DLLIB)" + end + File.rename('Makefile.new', 'Makefile') +end