Merge bottle install without Xcode branch
Merge branch 'bottle_hooks'
This commit is contained in:
commit
727239e12f
@ -7,23 +7,23 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
|
|
||||||
def llvm
|
def llvm
|
||||||
@llvm ||= MacOS.llvm_build_version
|
@llvm ||= MacOS.llvm_build_version if MacOS.has_apple_developer_tools?
|
||||||
end
|
end
|
||||||
|
|
||||||
def gcc_42
|
def gcc_42
|
||||||
@gcc_42 ||= MacOS.gcc_42_build_version
|
@gcc_42 ||= MacOS.gcc_42_build_version if MacOS.has_apple_developer_tools?
|
||||||
end
|
end
|
||||||
|
|
||||||
def gcc_40
|
def gcc_40
|
||||||
@gcc_40 ||= MacOS.gcc_40_build_version
|
@gcc_40 ||= MacOS.gcc_40_build_version if MacOS.has_apple_developer_tools?
|
||||||
end
|
end
|
||||||
|
|
||||||
def clang
|
def clang
|
||||||
@clang ||= MacOS.clang_version
|
@clang ||= MacOS.clang_version if MacOS.has_apple_developer_tools?
|
||||||
end
|
end
|
||||||
|
|
||||||
def clang_build
|
def clang_build
|
||||||
@clang_build ||= MacOS.clang_build_version
|
@clang_build ||= MacOS.clang_build_version if MacOS.has_apple_developer_tools?
|
||||||
end
|
end
|
||||||
|
|
||||||
def xcode
|
def xcode
|
||||||
|
@ -258,6 +258,7 @@ class Checks
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# TODO: distill down into single method definition a la BuildToolsError
|
||||||
if MacOS.version >= "10.9"
|
if MacOS.version >= "10.9"
|
||||||
def check_for_installed_developer_tools
|
def check_for_installed_developer_tools
|
||||||
unless MacOS::Xcode.installed? || MacOS::CLT.installed? then <<-EOS.undent
|
unless MacOS::Xcode.installed? || MacOS::CLT.installed? then <<-EOS.undent
|
||||||
|
@ -38,6 +38,10 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# if the user's flags will prevent bottle only-installations when no
|
||||||
|
# developer tools are available, we need to stop them early on
|
||||||
|
FormulaInstaller.prevent_build_flags unless MacOS.has_apple_developer_tools?
|
||||||
|
|
||||||
ARGV.formulae.each do |f|
|
ARGV.formulae.each do |f|
|
||||||
# head-only without --HEAD is an error
|
# head-only without --HEAD is an error
|
||||||
if !ARGV.build_head? && f.stable.nil? && f.devel.nil?
|
if !ARGV.build_head? && f.stable.nil? && f.devel.nil?
|
||||||
@ -131,10 +135,10 @@ module Homebrew
|
|||||||
checks = Checks.new
|
checks = Checks.new
|
||||||
%w[
|
%w[
|
||||||
check_for_unsupported_osx
|
check_for_unsupported_osx
|
||||||
|
check_for_bad_install_name_tool
|
||||||
check_for_installed_developer_tools
|
check_for_installed_developer_tools
|
||||||
check_xcode_license_approved
|
check_xcode_license_approved
|
||||||
check_for_osx_gcc_installer
|
check_for_osx_gcc_installer
|
||||||
check_for_bad_install_name_tool
|
|
||||||
].each do |check|
|
].each do |check|
|
||||||
out = checks.send(check)
|
out = checks.send(check)
|
||||||
opoo out unless out.nil?
|
opoo out unless out.nil?
|
||||||
@ -161,7 +165,7 @@ module Homebrew
|
|||||||
def perform_preinstall_checks
|
def perform_preinstall_checks
|
||||||
check_ppc
|
check_ppc
|
||||||
check_writable_install_location
|
check_writable_install_location
|
||||||
check_xcode
|
check_xcode if MacOS.has_apple_developer_tools?
|
||||||
check_cellar
|
check_cellar
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@ require "formula_installer"
|
|||||||
|
|
||||||
module Homebrew
|
module Homebrew
|
||||||
def reinstall
|
def reinstall
|
||||||
|
FormulaInstaller.prevent_build_flags unless MacOS.has_apple_developer_tools?
|
||||||
|
|
||||||
ARGV.resolved_formulae.each { |f| reinstall_formula(f) }
|
ARGV.resolved_formulae.each { |f| reinstall_formula(f) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@ require "cmd/outdated"
|
|||||||
|
|
||||||
module Homebrew
|
module Homebrew
|
||||||
def upgrade
|
def upgrade
|
||||||
|
FormulaInstaller.prevent_build_flags unless MacOS.has_apple_developer_tools?
|
||||||
|
|
||||||
Homebrew.perform_preinstall_checks
|
Homebrew.perform_preinstall_checks
|
||||||
|
|
||||||
if ARGV.named.empty?
|
if ARGV.named.empty?
|
||||||
|
@ -257,6 +257,100 @@ class BuildError < RuntimeError
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# raised by FormulaInstaller.check_dependencies_bottled and
|
||||||
|
# FormulaInstaller.install if the formula or its dependencies are not bottled
|
||||||
|
# and are being installed on a system without necessary build tools
|
||||||
|
class BuildToolsError < RuntimeError
|
||||||
|
def initialize(formulae)
|
||||||
|
if formulae.length > 1
|
||||||
|
formula_text = "formulae"
|
||||||
|
package_text = "binary packages"
|
||||||
|
else
|
||||||
|
formula_text = "formula"
|
||||||
|
package_text = "a binary package"
|
||||||
|
end
|
||||||
|
|
||||||
|
if MacOS.version >= "10.10"
|
||||||
|
xcode_text = <<-EOS.undent
|
||||||
|
To continue, you must install Xcode from the App Store,
|
||||||
|
or the CLT by running:
|
||||||
|
xcode-select --install
|
||||||
|
EOS
|
||||||
|
elsif MacOS.version == "10.9"
|
||||||
|
xcode_text = <<-EOS.undent
|
||||||
|
To continue, you must install Xcode from:
|
||||||
|
https://developer.apple.com/downloads/
|
||||||
|
or the CLT by running:
|
||||||
|
xcode-select --install
|
||||||
|
EOS
|
||||||
|
elsif MacOS.version >= "10.7"
|
||||||
|
xcode_text = <<-EOS.undent
|
||||||
|
To continue, you must install Xcode or the CLT from:
|
||||||
|
https://developer.apple.com/downloads/
|
||||||
|
EOS
|
||||||
|
else
|
||||||
|
xcode_text = <<-EOS.undent
|
||||||
|
To continue, you must install Xcode from:
|
||||||
|
https://developer.apple.com/downloads/
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
|
||||||
|
super <<-EOS.undent
|
||||||
|
The following #{formula_text}:
|
||||||
|
#{formulae.join(', ')}
|
||||||
|
cannot be installed as a #{package_text} and must be built from source.
|
||||||
|
#{xcode_text}
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# raised by Homebrew.install, Homebrew.reinstall, and Homebrew.upgrade
|
||||||
|
# if the user passes any flags/environment that would case a bottle-only
|
||||||
|
# installation on a system without build tools to fail
|
||||||
|
class BuildFlagsError < RuntimeError
|
||||||
|
def initialize(flags)
|
||||||
|
if flags.length > 1
|
||||||
|
flag_text = "flags"
|
||||||
|
require_text = "require"
|
||||||
|
else
|
||||||
|
flag_text = "flag"
|
||||||
|
require_text = "requires"
|
||||||
|
end
|
||||||
|
|
||||||
|
if MacOS.version >= "10.10"
|
||||||
|
xcode_text = <<-EOS.undent
|
||||||
|
or install Xcode from the App Store, or the CLT by running:
|
||||||
|
xcode-select --install
|
||||||
|
EOS
|
||||||
|
elsif MacOS.version == "10.9"
|
||||||
|
xcode_text = <<-EOS.undent
|
||||||
|
or install Xcode from:
|
||||||
|
https://developer.apple.com/downloads/
|
||||||
|
or the CLT by running:
|
||||||
|
xcode-select --install
|
||||||
|
EOS
|
||||||
|
elsif MacOS.version >= "10.7"
|
||||||
|
xcode_text = <<-EOS.undent
|
||||||
|
or install Xcode or the CLT from:
|
||||||
|
https://developer.apple.com/downloads/
|
||||||
|
EOS
|
||||||
|
else
|
||||||
|
xcode_text = <<-EOS.undent
|
||||||
|
or install Xcode from:
|
||||||
|
https://developer.apple.com/downloads/
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
|
||||||
|
super <<-EOS.undent
|
||||||
|
The following #{flag_text}:
|
||||||
|
#{flags.join(', ')}
|
||||||
|
#{require_text} building tools, but none are installed.
|
||||||
|
Either remove the #{flag_text} to attempt bottle installation,
|
||||||
|
#{xcode_text}
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# raised by CompilerSelector if the formula fails with all of
|
# raised by CompilerSelector if the formula fails with all of
|
||||||
# the compilers available on the user's system
|
# the compilers available on the user's system
|
||||||
class CompilerSelectionError < RuntimeError
|
class CompilerSelectionError < RuntimeError
|
||||||
|
@ -207,6 +207,20 @@ module HomebrewArgvExtension
|
|||||||
value "env"
|
value "env"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# If the user passes any flags that trigger building over installing from
|
||||||
|
# a bottle, they are collected here and returned as an Array for checking.
|
||||||
|
def collect_build_flags
|
||||||
|
build_flags = []
|
||||||
|
|
||||||
|
build_flags << '--HEAD' if build_head?
|
||||||
|
build_flags << '--universal' if build_universal?
|
||||||
|
build_flags << '--32-bit' if build_32_bit?
|
||||||
|
build_flags << '--build-bottle' if build_bottle?
|
||||||
|
build_flags << '--build-from-source' if build_from_source?
|
||||||
|
|
||||||
|
build_flags
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def spec(default = :stable)
|
def spec(default = :stable)
|
||||||
|
@ -29,7 +29,7 @@ module Stdenv
|
|||||||
self["PKG_CONFIG_LIBDIR"] = determine_pkg_config_libdir
|
self["PKG_CONFIG_LIBDIR"] = determine_pkg_config_libdir
|
||||||
|
|
||||||
# make any aclocal stuff installed in Homebrew available
|
# make any aclocal stuff installed in Homebrew available
|
||||||
self["ACLOCAL_PATH"] = "#{HOMEBREW_PREFIX}/share/aclocal" if MacOS::Xcode.provides_autotools?
|
self["ACLOCAL_PATH"] = "#{HOMEBREW_PREFIX}/share/aclocal" if MacOS.has_apple_developer_tools? && MacOS::Xcode.provides_autotools?
|
||||||
|
|
||||||
self["MAKEFLAGS"] = "-j#{make_jobs}"
|
self["MAKEFLAGS"] = "-j#{make_jobs}"
|
||||||
|
|
||||||
|
@ -23,6 +23,8 @@ module Superenv
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.bin
|
def self.bin
|
||||||
|
return unless MacOS.has_apple_developer_tools?
|
||||||
|
|
||||||
bin = (HOMEBREW_REPOSITORY/"Library/ENV").subdirs.reject { |d| d.basename.to_s > MacOS::Xcode.version }.max
|
bin = (HOMEBREW_REPOSITORY/"Library/ENV").subdirs.reject { |d| d.basename.to_s > MacOS::Xcode.version }.max
|
||||||
bin.realpath unless bin.nil?
|
bin.realpath unless bin.nil?
|
||||||
end
|
end
|
||||||
|
@ -741,7 +741,11 @@ class Formula
|
|||||||
end
|
end
|
||||||
|
|
||||||
def file_modified?
|
def file_modified?
|
||||||
return false unless which("git")
|
git_dir = MacOS.locate("git").dirname.to_s
|
||||||
|
|
||||||
|
# /usr/bin/git is a popup stub when Xcode/CLT aren't installed, so bail out
|
||||||
|
return false if git_dir == "/usr/bin" && !MacOS.has_apple_developer_tools?
|
||||||
|
|
||||||
path.parent.cd do
|
path.parent.cd do
|
||||||
diff = Utils.popen_read("git", "diff", "origin/master", "--", "#{path}")
|
diff = Utils.popen_read("git", "diff", "origin/master", "--", "#{path}")
|
||||||
!diff.empty? && $?.exitstatus == 0
|
!diff.empty? && $?.exitstatus == 0
|
||||||
|
@ -13,6 +13,7 @@ require "cmd/postinstall"
|
|||||||
require "hooks/bottles"
|
require "hooks/bottles"
|
||||||
require "debrew"
|
require "debrew"
|
||||||
require "sandbox"
|
require "sandbox"
|
||||||
|
require "requirements/cctools_requirement"
|
||||||
|
|
||||||
class FormulaInstaller
|
class FormulaInstaller
|
||||||
include FormulaCellarChecks
|
include FormulaCellarChecks
|
||||||
@ -55,6 +56,15 @@ class FormulaInstaller
|
|||||||
@pour_failed = false
|
@pour_failed = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# When no build tools are available and build flags are passed through ARGV,
|
||||||
|
# it's necessary to interrupt the user before any sort of installation
|
||||||
|
# can proceed. Only invoked when the user has no developer tools.
|
||||||
|
def self.prevent_build_flags
|
||||||
|
build_flags = ARGV.collect_build_flags
|
||||||
|
|
||||||
|
raise BuildFlagsError.new(build_flags) unless build_flags.empty?
|
||||||
|
end
|
||||||
|
|
||||||
def pour_bottle?(install_bottle_options = { :warn=>false })
|
def pour_bottle?(install_bottle_options = { :warn=>false })
|
||||||
return true if Homebrew::Hooks::Bottles.formula_has_bottle?(formula)
|
return true if Homebrew::Hooks::Bottles.formula_has_bottle?(formula)
|
||||||
|
|
||||||
@ -146,7 +156,15 @@ class FormulaInstaller
|
|||||||
|
|
||||||
check_conflicts
|
check_conflicts
|
||||||
|
|
||||||
compute_and_install_dependencies unless ignore_deps?
|
if !pour_bottle? && !MacOS.has_apple_developer_tools?
|
||||||
|
raise BuildToolsError.new([formula])
|
||||||
|
end
|
||||||
|
|
||||||
|
if !ignore_deps?
|
||||||
|
deps = compute_dependencies
|
||||||
|
check_dependencies_bottled(deps) if pour_bottle?
|
||||||
|
install_dependencies(deps)
|
||||||
|
end
|
||||||
|
|
||||||
return if only_deps?
|
return if only_deps?
|
||||||
|
|
||||||
@ -166,6 +184,7 @@ class FormulaInstaller
|
|||||||
|
|
||||||
if pour_bottle?(:warn => true)
|
if pour_bottle?(:warn => true)
|
||||||
begin
|
begin
|
||||||
|
install_relocation_tools unless formula.bottle.skip_relocation?
|
||||||
pour
|
pour
|
||||||
rescue => e
|
rescue => e
|
||||||
raise if ARGV.homebrew_developer?
|
raise if ARGV.homebrew_developer?
|
||||||
@ -215,18 +234,31 @@ class FormulaInstaller
|
|||||||
raise FormulaConflictError.new(formula, conflicts) unless conflicts.empty?
|
raise FormulaConflictError.new(formula, conflicts) unless conflicts.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
def compute_and_install_dependencies
|
# Compute and collect the dependencies needed by the formula currently
|
||||||
|
# being installed.
|
||||||
|
def compute_dependencies
|
||||||
req_map, req_deps = expand_requirements
|
req_map, req_deps = expand_requirements
|
||||||
|
|
||||||
check_requirements(req_map)
|
check_requirements(req_map)
|
||||||
|
|
||||||
deps = expand_dependencies(req_deps + formula.deps)
|
deps = expand_dependencies(req_deps + formula.deps)
|
||||||
|
|
||||||
if deps.empty? && only_deps?
|
deps
|
||||||
puts "All dependencies for #{formula.full_name} are satisfied."
|
end
|
||||||
else
|
|
||||||
install_dependencies(deps)
|
# Check that each dependency in deps has a bottle available, terminating
|
||||||
|
# abnormally with a BuildToolsError if one or more don't.
|
||||||
|
# Only invoked when the user has no developer tools.
|
||||||
|
def check_dependencies_bottled(deps)
|
||||||
|
unbottled = deps.select do |dep, _|
|
||||||
|
formula = dep.to_formula
|
||||||
|
!formula.pour_bottle? && !MacOS.has_apple_developer_tools?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
raise BuildToolsError.new(unbottled) unless unbottled.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def compute_and_install_dependencies
|
||||||
|
deps = compute_dependencies
|
||||||
|
install_dependencies(deps)
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_requirements(req_map)
|
def check_requirements(req_map)
|
||||||
@ -317,15 +349,29 @@ class FormulaInstaller
|
|||||||
end
|
end
|
||||||
|
|
||||||
def install_dependencies(deps)
|
def install_dependencies(deps)
|
||||||
if deps.length > 1
|
if deps.empty? && only_deps?
|
||||||
oh1 "Installing dependencies for #{formula.full_name}: #{Tty.green}#{deps.map(&:first)*", "}#{Tty.reset}"
|
puts "All dependencies for #{formula.full_name} are satisfied."
|
||||||
|
else
|
||||||
|
oh1 "Installing dependencies for #{formula.full_name}: #{Tty.green}#{deps.map(&:first)*", "}#{Tty.reset}" unless deps.empty?
|
||||||
|
deps.each { |dep, options| install_dependency(dep, options) }
|
||||||
end
|
end
|
||||||
|
|
||||||
deps.each { |dep, options| install_dependency(dep, options) }
|
|
||||||
|
|
||||||
@show_header = true unless deps.empty?
|
@show_header = true unless deps.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Installs the relocation tools (as provided by the cctools formula) as a hard
|
||||||
|
# dependency for every formula installed from a bottle when the user has no
|
||||||
|
# developer tools. Invoked unless the formula explicitly sets
|
||||||
|
# :any_skip_relocation in its bottle DSL.
|
||||||
|
def install_relocation_tools
|
||||||
|
cctools = CctoolsRequirement.new
|
||||||
|
dependency = cctools.to_dependency
|
||||||
|
formula = dependency.to_formula
|
||||||
|
return if cctools.satisfied? || @@attempted.include?(formula)
|
||||||
|
|
||||||
|
install_dependency(dependency, inherited_options_for(cctools))
|
||||||
|
end
|
||||||
|
|
||||||
class DependencyInstaller < FormulaInstaller
|
class DependencyInstaller < FormulaInstaller
|
||||||
def initialize(*)
|
def initialize(*)
|
||||||
super
|
super
|
||||||
@ -397,7 +443,8 @@ class FormulaInstaller
|
|||||||
|
|
||||||
keg = Keg.new(formula.prefix)
|
keg = Keg.new(formula.prefix)
|
||||||
link(keg)
|
link(keg)
|
||||||
fix_install_names(keg)
|
|
||||||
|
fix_install_names(keg) unless @poured_bottle && formula.bottle.skip_relocation?
|
||||||
|
|
||||||
if formula.post_install_defined?
|
if formula.post_install_defined?
|
||||||
if build_bottle?
|
if build_bottle?
|
||||||
@ -633,8 +680,10 @@ class FormulaInstaller
|
|||||||
end
|
end
|
||||||
|
|
||||||
keg = Keg.new(formula.prefix)
|
keg = Keg.new(formula.prefix)
|
||||||
keg.relocate_install_names Keg::PREFIX_PLACEHOLDER, HOMEBREW_PREFIX.to_s,
|
unless formula.bottle.skip_relocation?
|
||||||
Keg::CELLAR_PLACEHOLDER, HOMEBREW_CELLAR.to_s, :keg_only => formula.keg_only?
|
keg.relocate_install_names Keg::PREFIX_PLACEHOLDER, HOMEBREW_PREFIX.to_s,
|
||||||
|
Keg::CELLAR_PLACEHOLDER, HOMEBREW_CELLAR.to_s, :keg_only => formula.keg_only?
|
||||||
|
end
|
||||||
|
|
||||||
Pathname.glob("#{formula.bottle_prefix}/{etc,var}/**/*") do |path|
|
Pathname.glob("#{formula.bottle_prefix}/{etc,var}/**/*") do |path|
|
||||||
path.extend(InstallRenamed)
|
path.extend(InstallRenamed)
|
||||||
|
@ -98,8 +98,8 @@ class Keg
|
|||||||
end
|
end
|
||||||
|
|
||||||
def install_name_tool(*args)
|
def install_name_tool(*args)
|
||||||
tool = MacOS.locate("install_name_tool")
|
tool = MacOS.install_name_tool
|
||||||
system(tool, *args) || raise(ErrorDuringExecution.new(tool, args))
|
system(tool, *args) or raise ErrorDuringExecution.new(tool, args)
|
||||||
end
|
end
|
||||||
|
|
||||||
# If file is a dylib or bundle itself, look for the dylib named by
|
# If file is a dylib or bundle itself, look for the dylib named by
|
||||||
|
@ -154,9 +154,9 @@ module MachO
|
|||||||
|
|
||||||
def parse_otool_L_output
|
def parse_otool_L_output
|
||||||
ENV["HOMEBREW_MACH_O_FILE"] = path.expand_path.to_s
|
ENV["HOMEBREW_MACH_O_FILE"] = path.expand_path.to_s
|
||||||
libs = `#{MacOS.locate("otool")} -L "$HOMEBREW_MACH_O_FILE"`.split("\n")
|
libs = `#{MacOS.otool} -L "$HOMEBREW_MACH_O_FILE"`.split("\n")
|
||||||
unless $?.success?
|
unless $?.success?
|
||||||
raise ErrorDuringExecution.new(MacOS.locate("otool"),
|
raise ErrorDuringExecution.new(MacOS.otool,
|
||||||
["-L", ENV["HOMEBREW_MACH_O_FILE"]])
|
["-L", ENV["HOMEBREW_MACH_O_FILE"]])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -36,6 +36,33 @@ module OS
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Locates a (working) copy of install_name_tool, guaranteed to function
|
||||||
|
# whether the user has developer tools installed or not.
|
||||||
|
def install_name_tool
|
||||||
|
if File.executable?(path = "#{HOMEBREW_PREFIX}/opt/cctools/bin/install_name_tool")
|
||||||
|
Pathname.new(path)
|
||||||
|
else
|
||||||
|
locate("install_name_tool")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Locates a (working) copy of otool, guaranteed to function whether the user
|
||||||
|
# has developer tools installed or not.
|
||||||
|
def otool
|
||||||
|
if File.executable?(path = "#{HOMEBREW_PREFIX}/opt/cctools/bin/otool")
|
||||||
|
Pathname.new(path)
|
||||||
|
else
|
||||||
|
locate("otool")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Checks if the user has any developer tools installed, either via Xcode
|
||||||
|
# or the CLT. Convenient for guarding against formula builds when building
|
||||||
|
# is impossible.
|
||||||
|
def has_apple_developer_tools?
|
||||||
|
Xcode.installed? || CLT.installed?
|
||||||
|
end
|
||||||
|
|
||||||
def active_developer_dir
|
def active_developer_dir
|
||||||
@active_developer_dir ||= Utils.popen_read("/usr/bin/xcode-select", "-print-path").strip
|
@active_developer_dir ||= Utils.popen_read("/usr/bin/xcode-select", "-print-path").strip
|
||||||
end
|
end
|
||||||
|
@ -76,6 +76,8 @@ module OS
|
|||||||
|
|
||||||
return "0" unless OS.mac?
|
return "0" unless OS.mac?
|
||||||
|
|
||||||
|
return nil if !MacOS::Xcode.installed? && !MacOS::CLT.installed?
|
||||||
|
|
||||||
%W[#{prefix}/usr/bin/xcodebuild #{which("xcodebuild")}].uniq.each do |path|
|
%W[#{prefix}/usr/bin/xcodebuild #{which("xcodebuild")}].uniq.each do |path|
|
||||||
if File.file? path
|
if File.file? path
|
||||||
Utils.popen_read(path, "-version") =~ /Xcode (\d(\.\d)*)/
|
Utils.popen_read(path, "-version") =~ /Xcode (\d(\.\d)*)/
|
||||||
|
13
Library/Homebrew/requirements/cctools_requirement.rb
Normal file
13
Library/Homebrew/requirements/cctools_requirement.rb
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Represents a general requirement for utilities normally installed by Xcode,
|
||||||
|
# the CLT, or provided by the cctools formula. In particular, this requirement
|
||||||
|
# allows Homebrew to pull in the cctools formula and use its utilities to
|
||||||
|
# perform relocation operations on systems that do not have either Xcode or the
|
||||||
|
# CLT installed (but still want to install bottled formulae).
|
||||||
|
class CctoolsRequirement < Requirement
|
||||||
|
fatal true
|
||||||
|
default_formula 'cctools'
|
||||||
|
|
||||||
|
satisfy(:build_env => false) do
|
||||||
|
MacOS::Xcode.installed? || MacOS::CLT.installed? || Formula['cctools'].installed?
|
||||||
|
end
|
||||||
|
end
|
@ -245,6 +245,11 @@ class Bottle
|
|||||||
@spec.compatible_cellar?
|
@spec.compatible_cellar?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Does the bottle need to be relocated?
|
||||||
|
def skip_relocation?
|
||||||
|
@spec.skip_relocation?
|
||||||
|
end
|
||||||
|
|
||||||
def stage
|
def stage
|
||||||
resource.downloader.stage
|
resource.downloader.stage
|
||||||
end
|
end
|
||||||
@ -281,7 +286,12 @@ class BottleSpecification
|
|||||||
end
|
end
|
||||||
|
|
||||||
def compatible_cellar?
|
def compatible_cellar?
|
||||||
cellar == :any || cellar == HOMEBREW_CELLAR.to_s
|
cellar == :any || cellar == :any_skip_relocation || cellar == HOMEBREW_CELLAR.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
# Does the Bottle this BottleSpecification belongs to need to be relocated?
|
||||||
|
def skip_relocation?
|
||||||
|
cellar == :any_skip_relocation
|
||||||
end
|
end
|
||||||
|
|
||||||
def tag?(tag)
|
def tag?(tag)
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
testball_bottle-0.1.yosemite.bottle.tar.gz
|
@ -0,0 +1 @@
|
|||||||
|
testball_bottle-0.1.yosemite.bottle.tar.gz
|
Binary file not shown.
78
Library/Homebrew/test/test_formula_installer_bottle.rb
Normal file
78
Library/Homebrew/test/test_formula_installer_bottle.rb
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
require "testing_env"
|
||||||
|
require "formula"
|
||||||
|
require "compat/formula_specialties"
|
||||||
|
require "formula_installer"
|
||||||
|
require "keg"
|
||||||
|
require "testball_bottle"
|
||||||
|
require "testball"
|
||||||
|
|
||||||
|
class InstallBottleTests < Homebrew::TestCase
|
||||||
|
def temporary_bottle_install(formula)
|
||||||
|
refute_predicate formula, :installed?
|
||||||
|
assert_predicate formula, :bottled?
|
||||||
|
assert_predicate formula, :pour_bottle?
|
||||||
|
|
||||||
|
installer = FormulaInstaller.new(formula)
|
||||||
|
|
||||||
|
shutup { installer.install }
|
||||||
|
|
||||||
|
keg = Keg.new(formula.prefix)
|
||||||
|
|
||||||
|
assert_predicate formula, :installed?
|
||||||
|
|
||||||
|
begin
|
||||||
|
yield formula
|
||||||
|
ensure
|
||||||
|
keg.unlink
|
||||||
|
keg.uninstall
|
||||||
|
formula.clear_cache
|
||||||
|
Dir["#{HOMEBREW_CACHE}/testball_bottle*"].each { |f| File.delete(f) }
|
||||||
|
# there will be log files when sandbox is enable.
|
||||||
|
formula.logs.rmtree if formula.logs.directory?
|
||||||
|
end
|
||||||
|
|
||||||
|
refute_predicate keg, :exist?
|
||||||
|
refute_predicate formula, :installed?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_a_basic_bottle_install
|
||||||
|
MacOS.stubs(:has_apple_developer_tools?).returns(false)
|
||||||
|
|
||||||
|
temporary_bottle_install(TestballBottle.new) do |f|
|
||||||
|
# Copied directly from test_formula_installer.rb as we expect
|
||||||
|
# the same behavior
|
||||||
|
|
||||||
|
# Test that things made it into the Keg
|
||||||
|
assert_predicate f.bin, :directory?
|
||||||
|
|
||||||
|
assert_predicate f.libexec, :directory?
|
||||||
|
|
||||||
|
refute_predicate f.prefix+"main.c", :exist?
|
||||||
|
|
||||||
|
# Test that things make it into the Cellar
|
||||||
|
keg = Keg.new f.prefix
|
||||||
|
keg.link
|
||||||
|
|
||||||
|
bin = HOMEBREW_PREFIX+"bin"
|
||||||
|
assert_predicate bin, :directory?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_build_tools_error
|
||||||
|
MacOS.stubs(:has_apple_developer_tools?).returns(false)
|
||||||
|
|
||||||
|
# Testball doesn't have a bottle block, so use it to test this behavior
|
||||||
|
formula = Testball.new
|
||||||
|
|
||||||
|
refute_predicate formula, :installed?
|
||||||
|
refute_predicate formula, :bottled?
|
||||||
|
|
||||||
|
installer = FormulaInstaller.new(formula)
|
||||||
|
|
||||||
|
assert_raises(BuildToolsError) do
|
||||||
|
installer.install
|
||||||
|
end
|
||||||
|
|
||||||
|
refute_predicate formula, :installed?
|
||||||
|
end
|
||||||
|
end
|
17
Library/Homebrew/test/testball_bottle.rb
Normal file
17
Library/Homebrew/test/testball_bottle.rb
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
class TestballBottle < Formula
|
||||||
|
def initialize(name = "testball_bottle", path = Pathname.new(__FILE__).expand_path, spec = :stable)
|
||||||
|
self.class.instance_eval do
|
||||||
|
stable.url "file://#{File.expand_path("..", __FILE__)}/tarballs/testball-0.1.tbz"
|
||||||
|
stable.sha256 "1dfb13ce0f6143fe675b525fc9e168adb2215c5d5965c9f57306bb993170914f"
|
||||||
|
stable.bottle do
|
||||||
|
cellar :any_skip_relocation
|
||||||
|
root_url "file://#{File.expand_path("..", __FILE__)}/bottles"
|
||||||
|
sha256 "9abc8ce779067e26556002c4ca6b9427b9874d25f0cafa7028e05b5c5c410cb4" => :yosemite
|
||||||
|
sha256 "9abc8ce779067e26556002c4ca6b9427b9874d25f0cafa7028e05b5c5c410cb4" => :mavericks
|
||||||
|
sha256 "9abc8ce779067e26556002c4ca6b9427b9874d25f0cafa7028e05b5c5c410cb4" => :mountain_lion
|
||||||
|
end
|
||||||
|
cxxstdlib_check :skip
|
||||||
|
end
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
Loading…
x
Reference in New Issue
Block a user