Merge pull request #13608 from lukaso/debug-symbols

Support for `--debug-symbols` for macos
This commit is contained in:
Mike McQuaid 2022-08-12 10:05:32 +01:00 committed by GitHub
commit a73a1a665e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 182 additions and 63 deletions

View File

@ -21,6 +21,7 @@ Metrics/BlockLength:
# TODO: extract more of the bottling logic # TODO: extract more of the bottling logic
- "dev-cmd/bottle.rb" - "dev-cmd/bottle.rb"
- "test/**/*" - "test/**/*"
- "cmd/install.rb"
Metrics/BlockNesting: Metrics/BlockNesting:
Max: 5 Max: 5
Metrics/ClassLength: Metrics/ClassLength:

View File

@ -83,6 +83,7 @@ class Build
cc: args.cc, cc: args.cc,
build_bottle: args.build_bottle?, build_bottle: args.build_bottle?,
bottle_arch: args.bottle_arch, bottle_arch: args.bottle_arch,
debug_symbols: args.debug_symbols?,
) )
reqs.each do |req| reqs.each do |req|
req.modify_build_environment( req.modify_build_environment(
@ -96,6 +97,7 @@ class Build
cc: args.cc, cc: args.cc,
build_bottle: args.build_bottle?, build_bottle: args.build_bottle?,
bottle_arch: args.bottle_arch, bottle_arch: args.bottle_arch,
debug_symbols: args.debug_symbols?,
) )
reqs.each do |req| reqs.each do |req|
req.modify_build_environment( req.modify_build_environment(
@ -129,6 +131,7 @@ class Build
formula.brew( formula.brew(
fetch: false, fetch: false,
keep_tmp: args.keep_tmp?, keep_tmp: args.keep_tmp?,
debug_symbols: args.debug_symbols?,
interactive: args.interactive?, interactive: args.interactive?,
) do ) do
with_env( with_env(

View File

@ -87,6 +87,9 @@ module Homebrew
sig { returns(T::Boolean) } sig { returns(T::Boolean) }
def keep_tmp?; end def keep_tmp?; end
sig { returns(T::Boolean) }
def debug_symbols?; end
sig { returns(T::Boolean) } sig { returns(T::Boolean) }
def overwrite?; end def overwrite?; end

View File

@ -91,6 +91,10 @@ module Homebrew
[:switch, "--keep-tmp", { [:switch, "--keep-tmp", {
description: "Retain the temporary files created during installation.", description: "Retain the temporary files created during installation.",
}], }],
[:switch, "--debug-symbols", {
depends_on: "--build-from-source",
description: "Generate debug symbols on build. Source will be retained in a cache directory. ",
}],
[:switch, "--build-bottle", { [:switch, "--build-bottle", {
description: "Prepare the formula for eventual bottling during installation, skipping any " \ description: "Prepare the formula for eventual bottling during installation, skipping any " \
"post-install steps.", "post-install steps.",
@ -232,6 +236,7 @@ module Homebrew
git: args.git?, git: args.git?,
interactive: args.interactive?, interactive: args.interactive?,
keep_tmp: args.keep_tmp?, keep_tmp: args.keep_tmp?,
debug_symbols: args.debug_symbols?,
force: args.force?, force: args.force?,
overwrite: args.overwrite?, overwrite: args.overwrite?,
debug: args.debug?, debug: args.debug?,
@ -247,6 +252,7 @@ module Homebrew
build_from_source_formulae: args.build_from_source_formulae, build_from_source_formulae: args.build_from_source_formulae,
interactive: args.interactive?, interactive: args.interactive?,
keep_tmp: args.keep_tmp?, keep_tmp: args.keep_tmp?,
debug_symbols: args.debug_symbols?,
force: args.force?, force: args.force?,
debug: args.debug?, debug: args.debug?,
quiet: args.quiet?, quiet: args.quiet?,

View File

@ -57,6 +57,10 @@ module Homebrew
[:switch, "--keep-tmp", { [:switch, "--keep-tmp", {
description: "Retain the temporary files created during installation.", description: "Retain the temporary files created during installation.",
}], }],
[:switch, "--debug-symbols", {
depends_on: "--build-from-source",
description: "Generate debug symbols on build. Source will be retained in a cache directory. ",
}],
[:switch, "--display-times", { [:switch, "--display-times", {
env: :display_install_times, env: :display_install_times,
description: "Print install times for each formula at the end of the run.", description: "Print install times for each formula at the end of the run.",
@ -115,6 +119,7 @@ module Homebrew
build_from_source_formulae: args.build_from_source_formulae, build_from_source_formulae: args.build_from_source_formulae,
interactive: args.interactive?, interactive: args.interactive?,
keep_tmp: args.keep_tmp?, keep_tmp: args.keep_tmp?,
debug_symbols: args.debug_symbols?,
force: args.force?, force: args.force?,
debug: args.debug?, debug: args.debug?,
quiet: args.quiet?, quiet: args.quiet?,
@ -132,6 +137,7 @@ module Homebrew
build_from_source_formulae: args.build_from_source_formulae, build_from_source_formulae: args.build_from_source_formulae,
interactive: args.interactive?, interactive: args.interactive?,
keep_tmp: args.keep_tmp?, keep_tmp: args.keep_tmp?,
debug_symbols: args.debug_symbols?,
force: args.force?, force: args.force?,
debug: args.debug?, debug: args.debug?,
quiet: args.quiet?, quiet: args.quiet?,

View File

@ -68,6 +68,10 @@ module Homebrew
[:switch, "--keep-tmp", { [:switch, "--keep-tmp", {
description: "Retain the temporary files created during installation.", description: "Retain the temporary files created during installation.",
}], }],
[:switch, "--debug-symbols", {
depends_on: "--build-from-source",
description: "Generate debug symbols on build. Source will be retained in a cache directory. ",
}],
[:switch, "--display-times", { [:switch, "--display-times", {
env: :display_install_times, env: :display_install_times,
description: "Print install times for each package at the end of the run.", description: "Print install times for each package at the end of the run.",
@ -187,6 +191,7 @@ module Homebrew
build_from_source_formulae: args.build_from_source_formulae, build_from_source_formulae: args.build_from_source_formulae,
interactive: args.interactive?, interactive: args.interactive?,
keep_tmp: args.keep_tmp?, keep_tmp: args.keep_tmp?,
debug_symbols: args.debug_symbols?,
force: args.force?, force: args.force?,
debug: args.debug?, debug: args.debug?,
quiet: args.quiet?, quiet: args.quiet?,
@ -202,6 +207,7 @@ module Homebrew
build_from_source_formulae: args.build_from_source_formulae, build_from_source_formulae: args.build_from_source_formulae,
interactive: args.interactive?, interactive: args.interactive?,
keep_tmp: args.keep_tmp?, keep_tmp: args.keep_tmp?,
debug_symbols: args.debug_symbols?,
force: args.force?, force: args.force?,
debug: args.debug?, debug: args.debug?,
quiet: args.quiet?, quiet: args.quiet?,

View File

@ -37,15 +37,17 @@ module EnvActivation
cc: T.nilable(String), cc: T.nilable(String),
build_bottle: T::Boolean, build_bottle: T::Boolean,
bottle_arch: T.nilable(String), bottle_arch: T.nilable(String),
debug_symbols: T.nilable(T::Boolean),
_block: T.proc.returns(T.untyped), _block: T.proc.returns(T.untyped),
).returns(T.untyped) ).returns(T.untyped)
} }
def with_build_environment(env: nil, cc: nil, build_bottle: false, bottle_arch: nil, &_block) def with_build_environment(env: nil, cc: nil, build_bottle: false, bottle_arch: nil, debug_symbols: false, &_block)
old_env = to_hash.dup old_env = to_hash.dup
tmp_env = to_hash.dup.extend(EnvActivation) tmp_env = to_hash.dup.extend(EnvActivation)
T.cast(tmp_env, EnvActivation).activate_extensions!(env: env) T.cast(tmp_env, EnvActivation).activate_extensions!(env: env)
T.cast(tmp_env, T.any(Superenv, Stdenv)) T.cast(tmp_env, T.any(Superenv, Stdenv))
.setup_build_environment(cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch) .setup_build_environment(cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch,
debug_symbols: debug_symbols)
replace(tmp_env) replace(tmp_env)
begin begin

View File

@ -40,13 +40,16 @@ module SharedEnvExtension
build_bottle: T.nilable(T::Boolean), build_bottle: T.nilable(T::Boolean),
bottle_arch: T.nilable(String), bottle_arch: T.nilable(String),
testing_formula: T::Boolean, testing_formula: T::Boolean,
debug_symbols: T.nilable(T::Boolean),
).void ).void
} }
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false) def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false,
debug_symbols: false)
@formula = formula @formula = formula
@cc = cc @cc = cc
@build_bottle = build_bottle @build_bottle = build_bottle
@bottle_arch = bottle_arch @bottle_arch = bottle_arch
@debug_symbols = debug_symbols
reset reset
end end
private :setup_build_environment private :setup_build_environment

View File

@ -21,9 +21,11 @@ module Stdenv
build_bottle: T.nilable(T::Boolean), build_bottle: T.nilable(T::Boolean),
bottle_arch: T.nilable(String), bottle_arch: T.nilable(String),
testing_formula: T::Boolean, testing_formula: T::Boolean,
debug_symbols: T.nilable(T::Boolean),
).void ).void
} }
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false) def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false,
debug_symbols: false)
super super
self["HOMEBREW_ENV"] = "std" self["HOMEBREW_ENV"] = "std"

View File

@ -55,9 +55,11 @@ module Superenv
build_bottle: T.nilable(T::Boolean), build_bottle: T.nilable(T::Boolean),
bottle_arch: T.nilable(String), bottle_arch: T.nilable(String),
testing_formula: T::Boolean, testing_formula: T::Boolean,
debug_symbols: T.nilable(T::Boolean),
).void ).void
} }
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false) def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false,
debug_symbols: false)
super super
send(compiler) send(compiler)
@ -87,6 +89,8 @@ module Superenv
self["HOMEBREW_DEPENDENCIES"] = determine_dependencies self["HOMEBREW_DEPENDENCIES"] = determine_dependencies
self["HOMEBREW_FORMULA_PREFIX"] = @formula.prefix unless @formula.nil? self["HOMEBREW_FORMULA_PREFIX"] = @formula.prefix unless @formula.nil?
set_debug_symbols if debug_symbols
# The HOMEBREW_CCCFG ENV variable is used by the ENV/cc tool to control # The HOMEBREW_CCCFG ENV variable is used by the ENV/cc tool to control
# compiler flag stripping. It consists of a string of characters which act # compiler flag stripping. It consists of a string of characters which act
# as flags. Some of these flags are mutually exclusive. # as flags. Some of these flags are mutually exclusive.
@ -100,6 +104,7 @@ module Superenv
# d - Don't strip -march=<target>. Use only in formulae that # d - Don't strip -march=<target>. Use only in formulae that
# 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
# #
# 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
@ -331,6 +336,11 @@ module Superenv
append_to_cccfg "g" if compiler == :clang append_to_cccfg "g" if compiler == :clang
end end
sig { void }
def set_debug_symbols
append_to_cccfg "D"
end
# @private # @private
sig { void } sig { void }
def refurbish_args def refurbish_args

View File

@ -2,11 +2,10 @@
# frozen_string_literal: true # frozen_string_literal: true
module Stdenv module Stdenv
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false) def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false,
generic_setup_build_environment( debug_symbols: false)
formula: formula, cc: cc, build_bottle: build_bottle, generic_setup_build_environment(formula: formula, cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch,
bottle_arch: bottle_arch, testing_formula: testing_formula testing_formula: testing_formula, debug_symbols: debug_symbols)
)
prepend_path "CPATH", HOMEBREW_PREFIX/"include" prepend_path "CPATH", HOMEBREW_PREFIX/"include"
prepend_path "LIBRARY_PATH", HOMEBREW_PREFIX/"lib" prepend_path "LIBRARY_PATH", HOMEBREW_PREFIX/"lib"

View File

@ -15,11 +15,10 @@ module Superenv
end end
# @private # @private
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false) def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false,
generic_setup_build_environment( debug_symbols: false)
formula: formula, cc: cc, build_bottle: build_bottle, generic_setup_build_environment(formula: formula, cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch,
bottle_arch: bottle_arch, testing_formula: testing_formula testing_formula: testing_formula, debug_symbols: debug_symbols)
)
self["HOMEBREW_OPTIMIZATION_LEVEL"] = "O2" self["HOMEBREW_OPTIMIZATION_LEVEL"] = "O2"
self["HOMEBREW_DYNAMIC_LINKER"] = determine_dynamic_linker_path self["HOMEBREW_DYNAMIC_LINKER"] = determine_dynamic_linker_path
self["HOMEBREW_RPATH_PATHS"] = determine_rpath_paths(@formula) self["HOMEBREW_RPATH_PATHS"] = determine_rpath_paths(@formula)

View File

@ -4,11 +4,11 @@
module SharedEnvExtension module SharedEnvExtension
extend T::Sig extend T::Sig
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false) def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false,
generic_shared_setup_build_environment( debug_symbols: false)
formula: formula, cc: cc, build_bottle: build_bottle, generic_shared_setup_build_environment(formula: formula, cc: cc, build_bottle: build_bottle,
bottle_arch: bottle_arch, testing_formula: testing_formula bottle_arch: bottle_arch, testing_formula: testing_formula,
) debug_symbols: debug_symbols)
# Normalise the system Perl version used, where multiple may be available # Normalise the system Perl version used, where multiple may be available
self["VERSIONER_PERL_VERSION"] = MacOS.preferred_perl_version self["VERSIONER_PERL_VERSION"] = MacOS.preferred_perl_version

View File

@ -10,11 +10,10 @@ module Stdenv
["#{HOMEBREW_LIBRARY}/Homebrew/os/mac/pkgconfig/#{MacOS.version}"] ["#{HOMEBREW_LIBRARY}/Homebrew/os/mac/pkgconfig/#{MacOS.version}"]
end end
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false) def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false,
generic_setup_build_environment( debug_symbols: false)
formula: formula, cc: cc, build_bottle: build_bottle, generic_setup_build_environment(formula: formula, cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch,
bottle_arch: bottle_arch, testing_formula: testing_formula testing_formula: testing_formula, debug_symbols: debug_symbols)
)
append "LDFLAGS", "-Wl,-headerpad_max_install_names" append "LDFLAGS", "-Wl,-headerpad_max_install_names"

View File

@ -85,7 +85,8 @@ module Superenv
end end
# @private # @private
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false) def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false,
debug_symbols: false)
sdk = formula ? MacOS.sdk_for_formula(formula) : MacOS.sdk sdk = formula ? MacOS.sdk_for_formula(formula) : MacOS.sdk
is_xcode_sdk = sdk&.source == :xcode is_xcode_sdk = sdk&.source == :xcode
@ -100,10 +101,8 @@ module Superenv
MacOS::CLT::PKG_PATH MacOS::CLT::PKG_PATH
end end
generic_setup_build_environment( generic_setup_build_environment(formula: formula, cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch,
formula: formula, cc: cc, build_bottle: build_bottle, testing_formula: testing_formula, debug_symbols: debug_symbols)
bottle_arch: bottle_arch, testing_formula: testing_formula
)
# Filter out symbols known not to be defined since GNU Autotools can't # Filter out symbols known not to be defined since GNU Autotools can't
# reliably figure this out with Xcode 8 and above. # reliably figure this out with Xcode 8 and above.

View File

@ -62,4 +62,19 @@ class Keg
#{result.stderr} #{result.stderr}
EOS EOS
end end
def prepare_debug_symbols
binary_executable_or_library_files.each do |file|
odebug "Extracting symbols #{file}"
result = system_command("dsymutil", args: [file], print_stderr: false)
next if result.success?
# If it fails again, error out
ofail <<~EOS
Failed to extract symbols from #{file}:
#{result.stderr}
EOS
end
end
end end

View File

@ -1270,11 +1270,11 @@ class Formula
# Yields |self,staging| with current working directory set to the uncompressed tarball # Yields |self,staging| with current working directory set to the uncompressed tarball
# where staging is a {Mktemp} staging context. # where staging is a {Mktemp} staging context.
# @private # @private
def brew(fetch: true, keep_tmp: false, interactive: false) def brew(fetch: true, keep_tmp: false, debug_symbols: false, interactive: false)
@prefix_returns_versioned_prefix = true @prefix_returns_versioned_prefix = true
active_spec.fetch if fetch active_spec.fetch if fetch
stage(interactive: interactive) do |staging| stage(interactive: interactive, debug_symbols: debug_symbols) do |staging|
staging.retain! if keep_tmp staging.retain! if keep_tmp || debug_symbols
prepare_patches prepare_patches
fetch_patches if fetch fetch_patches if fetch
@ -2529,8 +2529,8 @@ class Formula
} }
end end
def stage(interactive: false) def stage(interactive: false, debug_symbols: false)
active_spec.stage do |staging| active_spec.stage(debug_symbols: debug_symbols) do |staging|
@source_modified_time = active_spec.source_modified_time @source_modified_time = active_spec.source_modified_time
@buildpath = Pathname.pwd @buildpath = Pathname.pwd
env_home = buildpath/".brew_home" env_home = buildpath/".brew_home"

View File

@ -39,6 +39,7 @@ class FormulaInstaller
attr_predicate :installed_as_dependency?, :installed_on_request? attr_predicate :installed_as_dependency?, :installed_on_request?
attr_predicate :show_summary_heading?, :show_header? attr_predicate :show_summary_heading?, :show_header?
attr_predicate :force_bottle?, :ignore_deps?, :only_deps?, :interactive?, :git?, :force?, :overwrite?, :keep_tmp? attr_predicate :force_bottle?, :ignore_deps?, :only_deps?, :interactive?, :git?, :force?, :overwrite?, :keep_tmp?
attr_predicate :debug_symbols?
attr_predicate :verbose?, :debug?, :quiet? attr_predicate :verbose?, :debug?, :quiet?
def initialize( def initialize(
@ -58,6 +59,7 @@ class FormulaInstaller
git: false, git: false,
interactive: false, interactive: false,
keep_tmp: false, keep_tmp: false,
debug_symbols: false,
cc: nil, cc: nil,
options: Options.new, options: Options.new,
force: false, force: false,
@ -71,6 +73,7 @@ class FormulaInstaller
@force = force @force = force
@overwrite = overwrite @overwrite = overwrite
@keep_tmp = keep_tmp @keep_tmp = keep_tmp
@debug_symbols = debug_symbols
@link_keg = !formula.keg_only? || link_keg @link_keg = !formula.keg_only? || link_keg
@show_header = show_header @show_header = show_header
@ignore_deps = ignore_deps @ignore_deps = ignore_deps
@ -688,6 +691,7 @@ class FormulaInstaller
include_test_formulae: @include_test_formulae, include_test_formulae: @include_test_formulae,
build_from_source_formulae: @build_from_source_formulae, build_from_source_formulae: @build_from_source_formulae,
keep_tmp: keep_tmp?, keep_tmp: keep_tmp?,
debug_symbols: debug_symbols?,
force: force?, force: force?,
debug: debug?, debug: debug?,
quiet: quiet?, quiet: quiet?,
@ -741,6 +745,7 @@ class FormulaInstaller
include_test_formulae: @include_test_formulae, include_test_formulae: @include_test_formulae,
build_from_source_formulae: @build_from_source_formulae, build_from_source_formulae: @build_from_source_formulae,
keep_tmp: keep_tmp?, keep_tmp: keep_tmp?,
debug_symbols: debug_symbols?,
force: force?, force: force?,
debug: debug?, debug: debug?,
quiet: quiet?, quiet: quiet?,
@ -802,6 +807,8 @@ class FormulaInstaller
post_install post_install
end end
keg.prepare_debug_symbols if debug_symbols?
# Updates the cache for a particular formula after doing an install # Updates the cache for a particular formula after doing an install
CacheStoreDatabase.use(:linkage) do |db| CacheStoreDatabase.use(:linkage) do |db|
break unless db.created? break unless db.created?
@ -873,6 +880,11 @@ class FormulaInstaller
args << "--cc=#{@cc}" if @cc args << "--cc=#{@cc}" if @cc
args << "--keep-tmp" if keep_tmp? args << "--keep-tmp" if keep_tmp?
if debug_symbols?
args << "--debug-symbols"
args << "--build-from-source"
end
if @env.present? if @env.present?
args << "--env=#{@env}" args << "--env=#{@env}"
elsif formula.env.std? || formula.deps.select(&:build?).any? { |d| d.name == "scons" } elsif formula.env.std? || formula.deps.select(&:build?).any? { |d| d.name == "scons" }

View File

@ -269,6 +269,7 @@ module Homebrew
git: false, git: false,
interactive: false, interactive: false,
keep_tmp: false, keep_tmp: false,
debug_symbols: false,
force: false, force: false,
overwrite: false, overwrite: false,
debug: false, debug: false,
@ -293,6 +294,7 @@ module Homebrew
git: git, git: git,
interactive: interactive, interactive: interactive,
keep_tmp: keep_tmp, keep_tmp: keep_tmp,
debug_symbols: debug_symbols,
force: force, force: force,
overwrite: overwrite, overwrite: overwrite,
debug: debug, debug: debug,

View File

@ -483,6 +483,8 @@ class Keg
ObserverPathnameExtension.n ObserverPathnameExtension.n
end end
def prepare_debug_symbols; end
def remove_oldname_opt_record def remove_oldname_opt_record
return unless oldname_opt_record return unless oldname_opt_record
return if oldname_opt_record.resolved_path != path return if oldname_opt_record.resolved_path != path

View File

@ -13,7 +13,8 @@ class Mktemp
def initialize(prefix, opts = {}) def initialize(prefix, opts = {})
@prefix = prefix @prefix = prefix
@retain = opts[:retain] @retain_in_cache = opts[:retain_in_cache]
@retain = opts[:retain] || @retain_in_cache
@quiet = false @quiet = false
end end
@ -28,6 +29,11 @@ class Mktemp
@retain @retain
end end
# True if the source files should be retained.
def retain_in_cache?
@retain_in_cache
end
# Instructs this Mktemp to not emit messages when retention is triggered. # Instructs this Mktemp to not emit messages when retention is triggered.
sig { void } sig { void }
def quiet! def quiet!
@ -40,7 +46,15 @@ class Mktemp
end end
def run def run
@tmpdir = Pathname.new(Dir.mktmpdir("#{@prefix.tr "@", "AT"}-", HOMEBREW_TEMP)) prefix_name = @prefix.tr "@", "AT"
@tmpdir = if retain_in_cache?
tmp_dir = HOMEBREW_CACHE/"Sources/#{prefix_name}"
chmod_rm_rf(tmpdir) # clear out previous staging directory
tmp_dir.mkpath
tmp_dir
else
Pathname.new(Dir.mktmpdir("#{prefix_name}-", HOMEBREW_TEMP))
end
# Make sure files inside the temporary directory have the same group as the # Make sure files inside the temporary directory have the same group as the
# brew instance. # brew instance.
@ -54,18 +68,21 @@ class Mktemp
Process.gid Process.gid
end end
begin begin
chown(nil, group_id, tmpdir) chown(nil, group_id, @tmpdir)
rescue Errno::EPERM rescue Errno::EPERM
opoo "Failed setting group \"#{Etc.getgrgid(group_id).name}\" on #{tmpdir}" opoo "Failed setting group \"#{Etc.getgrgid(group_id).name}\" on #{@tmpdir}"
end end
begin begin
Dir.chdir(tmpdir) { yield self } Dir.chdir(tmpdir) { yield self }
ensure ensure
ignore_interrupts { chmod_rm_rf(tmpdir) } unless retain? ignore_interrupts { chmod_rm_rf(@tmpdir) } unless retain?
end end
ensure ensure
ohai "Temporary files retained at:", @tmpdir.to_s if retain? && !@tmpdir.nil? && !@quiet if retain? && @tmpdir.present? && !@quiet
message = retain_in_cache? ? "Source files for debugging available at:" : "Temporary files retained at:"
ohai message, @tmpdir.to_s
end
end end
private private

View File

@ -16,6 +16,7 @@ module Homebrew
build_from_source_formulae: [], build_from_source_formulae: [],
interactive: false, interactive: false,
keep_tmp: false, keep_tmp: false,
debug_symbols: false,
force: false, force: false,
debug: false, debug: false,
quiet: false, quiet: false,
@ -48,6 +49,7 @@ module Homebrew
git: git, git: git,
interactive: interactive, interactive: interactive,
keep_tmp: keep_tmp, keep_tmp: keep_tmp,
debug_symbols: debug_symbols,
force: force, force: force,
debug: debug, debug: debug,
quiet: quiet, quiet: quiet,

View File

@ -89,14 +89,14 @@ class Resource
# dir using {Mktemp} so that works with all subtypes. # dir using {Mktemp} so that works with all subtypes.
# #
# @api public # @api public
def stage(target = nil, &block) def stage(target = nil, debug_symbols: false, &block)
raise ArgumentError, "target directory or block is required" if !target && block.blank? raise ArgumentError, "target directory or block is required" if !target && block.blank?
prepare_patches prepare_patches
fetch_patches(skip_downloaded: true) fetch_patches(skip_downloaded: true)
fetch unless downloaded? fetch unless downloaded?
unpack(target, &block) unpack(target, debug_symbols: debug_symbols, &block)
end end
def prepare_patches def prepare_patches
@ -120,9 +120,9 @@ class Resource
# If block is given, yield to that block with `|stage|`, where stage # If block is given, yield to that block with `|stage|`, where stage
# is a {ResourceStageContext}. # is a {ResourceStageContext}.
# A target or a block must be given, but not both. # A target or a block must be given, but not both.
def unpack(target = nil) def unpack(target = nil, debug_symbols: false)
current_working_directory = Pathname.pwd current_working_directory = Pathname.pwd
mktemp(download_name) do |staging| stage_resource(download_name, debug_symbols: debug_symbols) do |staging|
downloader.stage do downloader.stage do
@source_modified_time = downloader.source_modified_time @source_modified_time = downloader.source_modified_time
apply_patches apply_patches
@ -235,8 +235,8 @@ class Resource
protected protected
def mktemp(prefix, &block) def stage_resource(prefix, debug_symbols: false, &block)
Mktemp.new(prefix).run(&block) Mktemp.new(prefix, retain_in_cache: debug_symbols).run(&block)
end end
private private

View File

@ -292,6 +292,7 @@ class Cmd
args.concat(optflags) unless runtime_cpu_detection? args.concat(optflags) unless runtime_cpu_detection?
args.concat(archflags) args.concat(archflags)
args << "-std=#{@arg0}" if /c[89]9/.match?(@arg0) args << "-std=#{@arg0}" if /c[89]9/.match?(@arg0)
args << "-g" if debug_symbols?
args args
end end
@ -410,6 +411,10 @@ class Cmd
config.include?("w") config.include?("w")
end end
def debug_symbols?
config.include?("D")
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?

View File

@ -205,5 +205,12 @@ describe "ENV" do
expect(env["HOMEBREW_CCCFG"]).to include("g") expect(env["HOMEBREW_CCCFG"]).to include("g")
end end
end end
describe "#set_debug_symbols" do
it "sets the debug symbols flag" do
env.set_debug_symbols
expect(env["HOMEBREW_CCCFG"]).to include("D")
end
end
end end
end end

View File

@ -72,4 +72,16 @@ describe "brew install" do
.and be_a_success .and be_a_success
expect(HOMEBREW_CELLAR/"testball1/HEAD-d5eb689/foo/test").not_to be_a_file expect(HOMEBREW_CELLAR/"testball1/HEAD-d5eb689/foo/test").not_to be_a_file
end end
it "installs formulae with debug symbols", :integration_test do
setup_test_formula "testball1"
expect { brew "install", "testball1", "--debug-symbols", "--build-from-source" }
.to output(%r{#{HOMEBREW_CELLAR}/testball1/0\.1}o).to_stdout
.and not_to_output.to_stderr
.and be_a_success
expect(HOMEBREW_CELLAR/"testball1/0.1/bin/test").to be_a_file
expect(HOMEBREW_CELLAR/"testball1/0.1/bin/test.dSYM/Contents/Resources/DWARF/test").to be_a_file if OS.mac?
expect(HOMEBREW_CACHE/"Sources/testball1").to be_a_directory
end
end end

View File

@ -24,6 +24,7 @@ module Homebrew
build_from_source_formulae: [], build_from_source_formulae: [],
interactive: false, interactive: false,
keep_tmp: false, keep_tmp: false,
debug_symbols: false,
force: false, force: false,
debug: false, debug: false,
quiet: false, quiet: false,
@ -61,6 +62,7 @@ module Homebrew
build_from_source_formulae: build_from_source_formulae, build_from_source_formulae: build_from_source_formulae,
interactive: interactive, interactive: interactive,
keep_tmp: keep_tmp, keep_tmp: keep_tmp,
debug_symbols: debug_symbols,
force: force, force: force,
debug: debug, debug: debug,
quiet: quiet, quiet: quiet,
@ -128,6 +130,7 @@ module Homebrew
build_from_source_formulae: [], build_from_source_formulae: [],
interactive: false, interactive: false,
keep_tmp: false, keep_tmp: false,
debug_symbols: false,
force: false, force: false,
debug: false, debug: false,
quiet: false, quiet: false,
@ -161,6 +164,7 @@ module Homebrew
build_from_source_formulae: build_from_source_formulae, build_from_source_formulae: build_from_source_formulae,
interactive: interactive, interactive: interactive,
keep_tmp: keep_tmp, keep_tmp: keep_tmp,
debug_symbols: debug_symbols,
force: force, force: force,
debug: debug, debug: debug,
quiet: quiet, quiet: quiet,
@ -254,6 +258,7 @@ module Homebrew
build_from_source_formulae: [], build_from_source_formulae: [],
interactive: false, interactive: false,
keep_tmp: false, keep_tmp: false,
debug_symbols: false,
force: false, force: false,
debug: false, debug: false,
quiet: false, quiet: false,
@ -339,6 +344,7 @@ module Homebrew
build_from_source_formulae: build_from_source_formulae, build_from_source_formulae: build_from_source_formulae,
interactive: interactive, interactive: interactive,
keep_tmp: keep_tmp, keep_tmp: keep_tmp,
debug_symbols: debug_symbols,
force: force, force: force,
debug: debug, debug: debug,
quiet: quiet, quiet: quiet,
@ -407,6 +413,7 @@ module Homebrew
build_from_source_formulae: build_from_source_formulae + [formula.full_name], build_from_source_formulae: build_from_source_formulae + [formula.full_name],
interactive: interactive, interactive: interactive,
keep_tmp: keep_tmp, keep_tmp: keep_tmp,
debug_symbols: debug_symbols,
force: force, force: force,
debug: debug, debug: debug,
quiet: quiet, quiet: quiet,