Reproducible builds for native compiled binaries

This commit is contained in:
Bo Anderson 2024-03-08 21:26:25 +00:00
parent 4348e06888
commit 5582849ae7
No known key found for this signature in database
7 changed files with 35 additions and 13 deletions

View File

@ -139,12 +139,14 @@ class Build
with_env(
# For head builds, HOMEBREW_FORMULA_PREFIX should include the commit,
# which is not known until after the formula has been staged.
HOMEBREW_FORMULA_PREFIX: formula.prefix,
HOMEBREW_FORMULA_PREFIX: formula.prefix,
# https://reproducible-builds.org/docs/build-path/
HOMEBREW_FORMULA_BUILDPATH: formula.buildpath,
# https://reproducible-builds.org/docs/source-date-epoch/
SOURCE_DATE_EPOCH: formula.source_modified_time.to_i.to_s,
SOURCE_DATE_EPOCH: formula.source_modified_time.to_i.to_s,
# Avoid make getting confused about timestamps.
# https://github.com/Homebrew/homebrew-core/pull/87470
TZ: "UTC0",
TZ: "UTC0",
) do
formula.patch

View File

@ -109,6 +109,7 @@ module Superenv
# D - Generate debugging information
# f - Pass `-no_fixup_chains` to `ld` whenever it
# is invoked with `-undefined dynamic_lookup`
# o - Pass `-oso_prefix` to `ld` whenever it is invoked
#
# These flags will also be present:
# a - apply fix for apr-1-config path

View File

@ -35,6 +35,18 @@ class DevelopmentTools
:clang
end
sig { returns(Version) }
def ld64_version
@ld64_version ||= begin
json = Utils.popen_read("/usr/bin/ld", "-version_details")
if $CHILD_STATUS.success?
Version.parse(JSON.parse(json)["version"])
else
Version::NULL
end
end
end
sig { returns(T::Boolean) }
def curl_handles_most_https_certificates?
# The system Curl is too old for some modern HTTPS certificates on

View File

@ -35,15 +35,9 @@ module SharedEnvExtension
sig { returns(T::Boolean) }
def no_fixup_chains_support?
return false if MacOS.version <= :catalina
# NOTE: `-version_details` is supported in Xcode 10.2 at the earliest.
ld_version_details = JSON.parse(Utils.safe_popen_read("/usr/bin/ld", "-version_details"))
ld_version = Version.parse(ld_version_details["version"])
# This is supported starting Xcode 13, which ships ld64-711.
# https://developer.apple.com/documentation/xcode-release-notes/xcode-13-release-notes
# https://en.wikipedia.org/wiki/Xcode#Xcode_11.0_-_14.x_(since_SwiftUI_framework)_2
ld_version >= 711
DevelopmentTools.ld64_version >= 711
end
end

View File

@ -140,6 +140,9 @@ module Superenv
# See: https://github.com/python/cpython/issues/97524
# https://github.com/pybind/pybind11/pull/4301
no_fixup_chains
# Strip build prefixes from linker where supported, for deterministic builds.
append_to_cccfg "o" if DevelopmentTools.ld64_version >= 512
end
def no_weak_imports

View File

@ -50,7 +50,7 @@ module OS
when "10.14" then "10.2"
when "10.13" then "9.0"
when "10.12" then "8.0"
else "2.0"
else "7.3"
end
end
@ -373,7 +373,7 @@ module OS
when "10.14" then "10.0.0"
when "10.13" then "9.0.0"
when "10.12" then "8.0.0"
else "1.0.0"
else "7.3.0"
end
end

View File

@ -29,7 +29,7 @@ class Cmd
CXX_REGEX = /(?:c|g|clang)\+\+/.freeze
attr_reader :config, :prefix, :cellar, :opt, :cachedir, :tmpdir, :sysroot, :deps
attr_reader :archflags, :optflags, :keg_regex, :formula_prefix
attr_reader :archflags, :optflags, :keg_regex, :formula_prefix, :formula_buildpath
def initialize(arg0, args)
@arg0 = arg0
@ -45,6 +45,7 @@ class Cmd
@optflags = ENV.fetch("HOMEBREW_OPTFLAGS", "").split
@deps = Set.new(ENV.fetch("HOMEBREW_DEPENDENCIES", "").split(","))
@formula_prefix = ENV["HOMEBREW_FORMULA_PREFIX"]
@formula_buildpath = ENV["HOMEBREW_FORMULA_BUILDPATH"]
# matches opt or cellar prefix and formula name
@keg_regex = %r{(#{Regexp.escape(opt)}|#{Regexp.escape(cellar)})/([\w+-.@]+)}
end
@ -310,6 +311,9 @@ class Cmd
args += path_flags("-isystem", isystem_paths) + path_flags("-I", include_paths)
# Add -nostdinc when building against glibc@2.13 to avoid mixing system and brewed glibc headers.
args << "-nostdinc" if @deps.include?("glibc@2.13")
# Ideally this would be -ffile-prefix-map, but that requires a minimum of GCC 8, LLVM Clang 10 or Apple Clang 12
# and detecting the version dynamically based on what `HOMEBREW_CC` may have been rewritten to point to is awkward
args << "-fdebug-prefix-map=#{formula_buildpath}=." if formula_buildpath
args
end
@ -319,10 +323,12 @@ class Cmd
args << "-headerpad_max_install_names"
args << "-no_weak_imports" if no_weak_imports?
args << "-no_fixup_chains" if no_fixup_chains?
args << "-oso_prefix" << formula_buildpath if oso_prefix? && formula_buildpath
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?
args << "-Wl,-oso_prefix,#{formula_buildpath}" if oso_prefix? && formula_buildpath
end
args
end
@ -431,6 +437,10 @@ class Cmd
@args.include?("-undefineddynamic_lookup")
end
def oso_prefix?
config.include?("o")
end
def calls_ld?
return true if mode == :ld
return false unless [:ccld, :cxxld].include?(mode)