[前][次][番号順一覧][スレッド一覧]

ruby-changes:72811

From: Yuta <ko1@a...>
Date: Thu, 4 Aug 2022 16:29:38 +0900 (JST)
Subject: [ruby-changes:72811] 50d81bfbc1 (master): Link ext bundles with bundle loader option for newer ld64

https://git.ruby-lang.org/ruby.git/commit/?id=50d81bfbc1

From 50d81bfbc19d9b2e3d4be511c26c3dff317e2f8e Mon Sep 17 00:00:00 2001
From: Yuta Saito <kateinoigakukun@g...>
Date: Thu, 28 Jul 2022 17:19:28 +0900
Subject: Link ext bundles with bundle loader option for newer ld64

ld64 shipped with Xcode 14 emits a warning when using `-undefined
dynamic_lookup`.

```
ld: warning: -undefined dynamic_lookup may not work with chained fixups
```

Actually, `-undefined dynamic_lookup` doesn't work when:

1. Link a *shared library* with the option
2. Link it with a program that uses the chained-fixup introduced from
   macOS 12 and iOS 15
because `-undefined dynamic_lookup` uses lazy-bindings and they won't be
bound while dyld fixes-up by traversing chained-fixup info.

However, we build exts as *bundles* and they are loaded only through
`dlopen`, so it's safe to use `-undefined dynamic_lookup` in theory.
So the warning produced by ld64 is false-positive, and it results
failure of option checking in configuration. Therefore, it would be an
option to ignore the warning during our configuration.

On the other hand, `-undefined dynamic_lookup` is already deprecated on
all darwin platforms except for macOS, so it's good time to get rid of
the option. ld64 also provides `-bundle_loader <executable>` option,
which allows to resolve symbols defined in the executable symtab while
linking. It behaves almost the same with `-undefined dynamic_lookup`,
but it makes the following changes:

1. Require that unresolved symbols among input objects must be defined
   in the executable.
2. Lazy symbol binding will lookup only the symtab of the bundle loader
   executable. (`-undefined dynamic_lookup` lookups all symtab as flat
   namespace)

This patch adds `-bundle_loader $(RUBY)` when non-EXTSTATIC
configuration by assuming ruby executable can be linked before building
exts.

See "New Features" subsection under "Linking" section for chained fixup
https://developer.apple.com/documentation/xcode-release-notes/xcode-13-release-notes
---
 configure.ac    | 10 ++++++++--
 enc/Makefile.in |  2 ++
 ext/extmk.rb    |  5 ++++-
 lib/mkmf.rb     |  1 +
 4 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/configure.ac b/configure.ac
index 864a9a4e8b..4da115ce4c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3011,6 +3011,12 @@ STATIC= https://github.com/ruby/ruby/blob/trunk/configure.ac#L3011
 			: ${LDFLAGS=""}
 			: ${LIBPATHENV=DYLD_FALLBACK_LIBRARY_PATH}
 			: ${PRELOADENV=DYLD_INSERT_LIBRARIES}
+			AS_IF([test "x$EXTSTATIC" = x], [
+                          # When building ext bundles, a mach-o bundle needs to know its loader
+                          # program to bind symbols from the ruby executable
+                          EXTDLDFLAGS='-bundle_loader $(BUILTRUBY)'
+                          PREP="$PREP"' $(PROGRAM)'
+			])
 			rb_cv_dlopen=yes],
         [aix*], [	: ${LDSHARED='$(CC)'}
 			AS_IF([test "$GCC" = yes], [
@@ -3334,7 +3340,7 @@ AS_IF([test x"$cross_compiling" = xyes], [ https://github.com/ruby/ruby/blob/trunk/configure.ac#L3340
   AC_SUBST(XRUBY_LIBDIR)
   AC_SUBST(XRUBY_RUBYLIBDIR)
   AC_SUBST(XRUBY_RUBYHDRDIR)
-  PREP='$(arch)-fake.rb'
+  PREP="$PREP "'$(arch)-fake.rb'
   RUNRUBY_COMMAND='$(MINIRUBY) -I`cd $(srcdir)/lib; pwd`'
   RUNRUBY='$(RUNRUBY_COMMAND)'
   XRUBY='$(MINIRUBY)'
@@ -3344,7 +3350,7 @@ AS_IF([test x"$cross_compiling" = xyes], [ https://github.com/ruby/ruby/blob/trunk/configure.ac#L3350
 ], [
   MINIRUBY='./miniruby$(EXEEXT) -I$(srcdir)/lib -I.'
   MINIRUBY="$MINIRUBY"' -I$(EXTOUT)/common'
-  PREP='miniruby$(EXEEXT)'
+  PREP="$PREP "'miniruby$(EXEEXT)'
   RUNRUBY_COMMAND='$(MINIRUBY) $(tooldir)/runruby.rb --extout=$(EXTOUT) $(RUNRUBYOPT)'
   RUNRUBY='$(RUNRUBY_COMMAND) --'
   XRUBY='$(RUNRUBY)'
diff --git a/enc/Makefile.in b/enc/Makefile.in
index 5e5d39cd76..0e1a27a667 100644
--- a/enc/Makefile.in
+++ b/enc/Makefile.in
@@ -22,6 +22,7 @@ TRANSSODIR = $(ENCSODIR)/trans https://github.com/ruby/ruby/blob/trunk/enc/Makefile.in#L22
 DLEXT = @DLEXT@
 OBJEXT = @OBJEXT@
 LIBEXT = @LIBEXT@
+EXEEXT = @EXEEXT@
 TIMESTAMPDIR  = $(EXTOUT)/.timestamp
 ENC_TRANS_D   = $(TIMESTAMPDIR)/.enc-trans.time
 ENC_TRANS_SO_D = $(TIMESTAMPDIR)/.enc-trans.so.time
@@ -35,6 +36,7 @@ RUBY_SO_NAME = @RUBY_SO_NAME@ https://github.com/ruby/ruby/blob/trunk/enc/Makefile.in#L36
 LIBRUBY = @LIBRUBY@
 LIBRUBYARG_SHARED = @LIBRUBYARG_SHARED@
 LIBRUBYARG_STATIC = $(LIBRUBYARG_SHARED)
+BUILTRUBY = $(topdir)/ruby$(EXEEXT)
 
 empty =
 AR = @AR@
diff --git a/ext/extmk.rb b/ext/extmk.rb
index b5ff735cc4..70067d28b8 100755
--- a/ext/extmk.rb
+++ b/ext/extmk.rb
@@ -412,9 +412,12 @@ if CROSS_COMPILING https://github.com/ruby/ruby/blob/trunk/ext/extmk.rb#L412
   $ruby = $mflags.defined?("MINIRUBY") || CONFIG['MINIRUBY']
 elsif sep = config_string('BUILD_FILE_SEPARATOR')
   $ruby = "$(topdir:/=#{sep})#{sep}miniruby" + EXEEXT
-else
+elsif CONFIG['EXTSTATIC']
   $ruby = '$(topdir)/miniruby' + EXEEXT
+else
+  $ruby = '$(topdir)/ruby' + EXEEXT
 end
+$mflags << "BUILTRUBY=#$ruby"
 $ruby = [$ruby]
 $ruby << "-I'$(topdir)'"
 unless CROSS_COMPILING
diff --git a/lib/mkmf.rb b/lib/mkmf.rb
index a6ec9bae5d..79bb96ba75 100644
--- a/lib/mkmf.rb
+++ b/lib/mkmf.rb
@@ -2076,6 +2076,7 @@ sitearch = #{CONFIG['sitearch']} https://github.com/ruby/ruby/blob/trunk/lib/mkmf.rb#L2076
 ruby_version = #{RbConfig::CONFIG['ruby_version']}
 ruby = #{$ruby.sub(%r[\A#{Regexp.quote(RbConfig::CONFIG['bindir'])}(?=/|\z)]) {'$(bindir)'}}
 RUBY = $(ruby#{sep})
+BUILTRUBY = $(RUBY)
 ruby_headers = #{headers.join(' ')}
 
 RM = #{config_string('RM', &possible_command) || '$(RUBY) -run -e rm -- -f'}
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]