Skip to content

Commit

Permalink
Fix issue with old rubygems not detecting musl linux properly (#40)
Browse files Browse the repository at this point in the history
* Fix issue with old rubygems not detecting musl linux properly

Old versions of rubygems (for instance 3.0.3) don't properly detect
alternative libc implementations on Linux; in particular for our case,
they don't detect musl.

(For reference, Rubies older than 2.7 may have shipped with an affected
 version of rubygems).

In such cases, we fall back to use RbConfig::CONFIG['arch'] instead.

Why not use `RbConfig::CONFIG['arch']` always? Because
`Gem::Platform.local.to_s` does some normalization we want
in other situations -- for instance, it turns `x86_64-linux-gnu` to
`x86_64-linux`. So for now we only add this workaround in a specific
situation where we actually know it is wrong.

See also rubygems/rubygems#2922 and
rubygems/rubygems#4082

Fixes DataDog/dd-trace-rb#2222

* Bump libdatadog minor version in preparation for release

I'm planning to release 0.7.0.1.1 with the musl fix. This will be
automatically picked up by customers using the currently-released
version of dd-trace-rb (1.3.0).

* Fix file open permissions / directory creation

Otherwise this breaks in Linux due to the rest of the spec flow.

* Remove redundant directory creation in spec
  • Loading branch information
ivoanjo committed Aug 18, 2022
1 parent 7eed32d commit 35b4b18
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 3 deletions.
17 changes: 17 additions & 0 deletions ruby/lib/libdatadog.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,23 @@ def self.available_binaries
def self.pkgconfig_folder(pkgconfig_file_name = "ddprof_ffi_with_rpath.pc")
current_platform = Gem::Platform.local.to_s

if RbConfig::CONFIG["arch"].include?("-musl") && !current_platform.include?("-musl")
# Fix/workaround for https://github.com/DataDog/dd-trace-rb/issues/2222
#
# Old versions of rubygems (for instance 3.0.3) don't properly detect alternative libc implementations on Linux;
# in particular for our case, they don't detect musl. (For reference, Rubies older than 2.7 may have shipped with
# an affected version of rubygems).
# In such cases, we fall back to use RbConfig::CONFIG['arch'] instead.
#
# Why not use RbConfig::CONFIG['arch'] always? Because Gem::Platform.local.to_s does some normalization we want
# in other situations -- for instance, it turns `x86_64-linux-gnu` to `x86_64-linux`. So for now we only add this
# workaround in a specific situation where we actually know it is wrong.
#
# See also https://github.com/rubygems/rubygems/pull/2922 and https://github.com/rubygems/rubygems/pull/4082

current_platform = RbConfig::CONFIG["arch"]
end

return unless available_binaries.include?(current_platform)

pkgconfig_file = Dir.glob("#{vendor_directory}/#{current_platform}/**/#{pkgconfig_file_name}").first
Expand Down
2 changes: 1 addition & 1 deletion ruby/lib/libdatadog/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module Libdatadog
LIB_VERSION = "0.7.0"

GEM_MAJOR_VERSION = "1"
GEM_MINOR_VERSION = "0"
GEM_MINOR_VERSION = "1"
GEM_PRERELEASE_VERSION = "" # remember to include dot prefix, if needed!
private_constant :GEM_MAJOR_VERSION, :GEM_MINOR_VERSION, :GEM_PRERELEASE_VERSION

Expand Down
30 changes: 28 additions & 2 deletions ruby/spec/libdatadog_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,41 @@
let(:pkgconfig_folder) { "#{temporary_directory}/#{Gem::Platform.local}/some/folder/containing/the/pkgconfig/file" }

before do
FileUtils.mkdir_p(pkgconfig_folder)
File.open("#{pkgconfig_folder}/ddprof_ffi_with_rpath.pc", "w") {}
create_dummy_pkgconfig_file(pkgconfig_folder)
end

def create_dummy_pkgconfig_file(pkgconfig_folder)
begin
FileUtils.mkdir_p(pkgconfig_folder)
rescue Errno::EEXIST
# No problem, a few specs try to create the same folder
end

File.open("#{pkgconfig_folder}/ddprof_ffi_with_rpath.pc", "w+") {}
end

describe ".pkgconfig_folder" do
it "returns the folder containing the pkgconfig file" do
expect(Libdatadog.pkgconfig_folder).to eq pkgconfig_folder
end
end

context "when `RbConfig::CONFIG[\"arch\"]` indicates we're on musl libc, but `Gem::Platform.local.to_s` does not detect it" do
# Fix for https://github.com/DataDog/dd-trace-rb/issues/2222

before do
allow(RbConfig::CONFIG).to receive(:[]).with("arch").and_return("x86_64-linux-musl")
allow(Gem::Platform).to receive(:local).and_return("x86_64-linux")

["x86_64-linux", "x86_64-linux-musl"].each do |arch|
create_dummy_pkgconfig_file("#{temporary_directory}/#{arch}/some/folder/containing/the/pkgconfig/file")
end
end

it "returns the folder containing the pkgconfig file for the musl variant" do
expect(Libdatadog.pkgconfig_folder).to eq "#{temporary_directory}/x86_64-linux-musl/some/folder/containing/the/pkgconfig/file"
end
end
end

context "but not for the current platform" do
Expand Down

0 comments on commit 35b4b18

Please sign in to comment.