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.
 | 
			
		||||
    # w - Pass -no_weak_imports to the linker
 | 
			
		||||
    # 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:
 | 
			
		||||
    # a - apply fix for apr-1-config path
 | 
			
		||||
 | 
			
		||||
@ -23,4 +23,12 @@ module SharedEnvExtension
 | 
			
		||||
 | 
			
		||||
    true
 | 
			
		||||
  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
 | 
			
		||||
 | 
			
		||||
@ -101,4 +101,8 @@ module Stdenv
 | 
			
		||||
  def no_weak_imports
 | 
			
		||||
    append "LDFLAGS", "-Wl,-no_weak_imports" if no_weak_imports_support?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def no_fixup_chains
 | 
			
		||||
    append "LDFLAGS", "-Wl,-no_fixup_chains" if no_fixup_chains_support?
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@ -136,4 +136,11 @@ module Superenv
 | 
			
		||||
  def no_weak_imports
 | 
			
		||||
    append_to_cccfg "w" if no_weak_imports_support?
 | 
			
		||||
  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
 | 
			
		||||
 | 
			
		||||
@ -318,9 +318,11 @@ class Cmd
 | 
			
		||||
    when :ld
 | 
			
		||||
      args << "-headerpad_max_install_names"
 | 
			
		||||
      args << "-no_weak_imports" if no_weak_imports?
 | 
			
		||||
      args << "-no_fixup_chains" if no_fixup_chains?
 | 
			
		||||
    when :ccld, :cxxld
 | 
			
		||||
      args << "-Wl,-headerpad_max_install_names"
 | 
			
		||||
      args << "-Wl,-no_weak_imports" if no_weak_imports?
 | 
			
		||||
      args << "-Wl,-no_fixup_chains" if no_fixup_chains?
 | 
			
		||||
    end
 | 
			
		||||
    args
 | 
			
		||||
  end
 | 
			
		||||
@ -416,6 +418,18 @@ class Cmd
 | 
			
		||||
    config.include?("D")
 | 
			
		||||
  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)
 | 
			
		||||
    path = Pathname.new(path)
 | 
			
		||||
    path = path.realpath if path.exist?
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user