Pass -no_fixup_chains to linker when required
Invoking `ld` with `-undefined dynamic_lookup` emits a warning starting
Xcode 14:
ld: warning: -undefined dynamic_lookup may not work with chained fixups
Chained fixups is a linker optimisation that results in faster binary
load times, and is enabled by default starting Xcode 13 when the target
is macOS 12 or newer.
However, this interacts poorly with `-undefined dynamic_lookup`, and
Xcode will disable chained fixups when it is invoked with this flag
starting Xcode 14.3. Until then, we may be shipping binaries that are
broken in subtle ways, so let's disable chained fixups when necessary
instead.
I patterned the changes here after the handling of `-no_weak_imports`.
The only difference is that we need to check the flags that were passed
to the linker first to see if we do need to disable chained fixups.
For additional context, see:
https://developer.apple.com/documentation/xcode-release-notes/xcode-13-release-notes
https://www.wwdcnotes.com/notes/wwdc22/110362/
https://www.emergetools.com/blog/posts/iOS15LaunchTime
https://github.com/python/cpython/issues/97524
https://github.com/pybind/pybind11/pull/4301
This commit is contained in:
parent
41d0265543
commit
1b12d74945
@ -105,6 +105,8 @@ module Superenv
|
|||||||
# have runtime detection of CPU features.
|
# have runtime detection of CPU features.
|
||||||
# w - Pass -no_weak_imports to the linker
|
# w - Pass -no_weak_imports to the linker
|
||||||
# D - Generate debugging information
|
# D - Generate debugging information
|
||||||
|
# f - Pass `-no_fixup_chains` to `ld` whenever it
|
||||||
|
# is invoked with `-undefined dynamic_lookup`
|
||||||
#
|
#
|
||||||
# These flags will also be present:
|
# These flags will also be present:
|
||||||
# a - apply fix for apr-1-config path
|
# a - apply fix for apr-1-config path
|
||||||
|
|||||||
@ -23,4 +23,12 @@ module SharedEnvExtension
|
|||||||
|
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(T::Boolean) }
|
||||||
|
def no_fixup_chains_support?
|
||||||
|
return false if !MacOS::CLT.version.null? && MacOS::CLT.version < "13.0"
|
||||||
|
return false if !MacOS::Xcode.version.null? && MacOS::Xcode.version < "13.0"
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -101,4 +101,8 @@ module Stdenv
|
|||||||
def no_weak_imports
|
def no_weak_imports
|
||||||
append "LDFLAGS", "-Wl,-no_weak_imports" if no_weak_imports_support?
|
append "LDFLAGS", "-Wl,-no_weak_imports" if no_weak_imports_support?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def no_fixup_chains
|
||||||
|
append "LDFLAGS", "-Wl,-no_fixup_chains" if no_fixup_chains_support?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -136,4 +136,11 @@ module Superenv
|
|||||||
def no_weak_imports
|
def no_weak_imports
|
||||||
append_to_cccfg "w" if no_weak_imports_support?
|
append_to_cccfg "w" if no_weak_imports_support?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def no_fixup_chains
|
||||||
|
# Pass `-no_fixup_chains` whenever the linker is invoked with `-undefined dynamic_lookup`.
|
||||||
|
# See: https://github.com/python/cpython/issues/97524
|
||||||
|
# https://github.com/pybind/pybind11/pull/4301
|
||||||
|
append_to_cccfg "f" if no_fixup_chains_support?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -318,9 +318,11 @@ class Cmd
|
|||||||
when :ld
|
when :ld
|
||||||
args << "-headerpad_max_install_names"
|
args << "-headerpad_max_install_names"
|
||||||
args << "-no_weak_imports" if no_weak_imports?
|
args << "-no_weak_imports" if no_weak_imports?
|
||||||
|
args << "-no_fixup_chains" if no_fixup_chains?
|
||||||
when :ccld, :cxxld
|
when :ccld, :cxxld
|
||||||
args << "-Wl,-headerpad_max_install_names"
|
args << "-Wl,-headerpad_max_install_names"
|
||||||
args << "-Wl,-no_weak_imports" if no_weak_imports?
|
args << "-Wl,-no_weak_imports" if no_weak_imports?
|
||||||
|
args << "-Wl,-no_fixup_chains" if no_fixup_chains?
|
||||||
end
|
end
|
||||||
args
|
args
|
||||||
end
|
end
|
||||||
@ -416,6 +418,18 @@ class Cmd
|
|||||||
config.include?("D")
|
config.include?("D")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def no_fixup_chains?
|
||||||
|
return false unless config.include?("f")
|
||||||
|
return true if @args.include?("-Wl,-undefined,dynamic_lookup")
|
||||||
|
|
||||||
|
args_consecutive_pairs = @args.each_cons(2)
|
||||||
|
return true if args_consecutive_pairs.include?(["-undefined", "dynamic_lookup"])
|
||||||
|
return true if args_consecutive_pairs.include?(["-Wl,-undefined", "-Wl,dynamic_lookup"])
|
||||||
|
|
||||||
|
# The next flag would produce an error, but we fix it in `refurbish_arg`.
|
||||||
|
@args.include?("-undefineddynamic_lookup")
|
||||||
|
end
|
||||||
|
|
||||||
def canonical_path(path)
|
def canonical_path(path)
|
||||||
path = Pathname.new(path)
|
path = Pathname.new(path)
|
||||||
path = path.realpath if path.exist?
|
path = path.realpath if path.exist?
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user