Skip to content

Commit

Permalink
work around Ruby 3.2 linking conventions on Darwin
Browse files Browse the repository at this point in the history
See #87
  • Loading branch information
flavorjones committed Dec 28, 2022
1 parent 9abd7cb commit 3d0c471
Showing 1 changed file with 67 additions and 0 deletions.
67 changes: 67 additions & 0 deletions test/rcd_test/ext/mri/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,73 @@
# https://github.com/rake-compiler/rake-compiler-dock/issues/69
puts "Linking with '-static' flag"
$LDFLAGS << ' -static'
else
if RbConfig::CONFIG["target_os"].include?("darwin")
## In ruby 3.2, symbol resolution changed on Darwin, to introduce the `-bundle_loader` flag.
##
## See https://github.com/rake-compiler/rake-compiler-dock/issues/87 for a lot of context, but
## I'll try to summarize here.
##
## > -bundle_loader executable
## > This specifies the executable that will be loading the bundle output file being linked.
## > Undefined symbols from the bundle are checked against the specified executable like it
## > was one of the dynamic libraries the bundle was linked with.
##
## There are good reasons to do this, including faster initialiation/loading as the Darwin
## toolchain gets improved over time.
##
## Unfortunately, this flag prevents us from building a shared object that works with both a
## Ruby compiled with `--enable-shared` and one compiled with `--disabled-shared`. The result
## is usually an "Symbol not found" error about `_rb_cObject`, or a "dyld: missing symbol
## called" error.
##
## There are two workarounds that I know of (there may be others I don't know of), and
## they are ...

## ----------------------------------------
## SOLUTION 1, the `-flat_namespace` flag
##
## > Two-level namespace
## > By default all references resolved to a dynamic library record the library to which
## > they were resolved. At runtime, dyld uses that information to directly resolve symbols.
## > The alternative is to use the -flat_namespace option. With flat namespace, the library
## > is not recorded. At runtime, dyld will search each dynamic library in load order when
## > resolving symbols. This is slower, but more like how other operating systems resolve
## > symbols. Two-level namespace By default all references resolved to a dynamic library
## > record the library to which they were resolved. At runtime, dyld uses that information
## > to directly resolve symbols. The alternative is to use the -flat_namespace option.
## > With flat namespace, the library is not recorded. At runtime, dyld will search each
## > dynamic library in load order when resolving symbols. This is slower, but more like how
## > other operating systems resolve symbols.
##
#
# puts "Adding '-flat_namespace'"
# $LDFLAGS << ' -flat_namespace'
#
## This solution unfortunately introduces new behavior that any symbols statically linked into
## the shared object (e.g., libxml2 in nokogiri.bundle) may not be resolved locally from the
## shared object, but instead resolved from a shared object loaded in the main process.
##
## This solution might be good for you if:
## - you don't statically link things into your bundle,
## - or you don't export those symbols,
## - or you can avoid exporting those symbols (e.g., by using `-load_hidden`, or
## `-exported_symbols_list` or some other mechanism)
##

## ----------------------------------------
## BUT ... if that is a problem, try SOLUTION 2, remove the `-bundle-loader` flag
##
## This returns us to the symbol resolution we had in previous Rubies. It feels gross but may
## be a workaround for gem maintainers until we all figure out a better way to deal with this.
extdldflags = RbConfig::MAKEFILE_CONFIG["EXTDLDFLAGS"].split
if found = extdldflags.index("-bundle_loader")
removed_1 = extdldflags.delete_at(found) # flag
removed_2 = extdldflags.delete_at(found) # and its argument
puts "Removing '#{removed_1} #{removed_2}' from EXTDLDFLAGS"
end
RbConfig::MAKEFILE_CONFIG["EXTDLDFLAGS"] = extdldflags.join(" ")
end
end

create_makefile("rcd_test/rcd_test_ext")
Expand Down

0 comments on commit 3d0c471

Please sign in to comment.