Switch compilers when no build is specified

Given the current state of OS X compilers, the original fails_with
behavior is becoming less useful, mostly resulting in build failures
each time the compiler is updated. So make the following changes:

When a build is specified, we retain the old behavior: switch compilers
if the available compiler is <= the build, don't switch if it is > the
build.

When no build is specified, unconditionally switch compilers, and don't
output the advice message. This allows us to mark formulae as
perpetually failing, avoiding the need to update formulae each time a
new compiler build is made available.

As a bonus, this makes the logic much easier to reason about.

Closes Homebrew/homebrew#18175.
This commit is contained in:
Jack Nagel 2013-03-11 22:54:15 -05:00
parent c2e642f9c1
commit cc08d08d74
4 changed files with 9 additions and 48 deletions

View File

@ -114,11 +114,7 @@ def install f
end end
end end
if f.fails_with? ENV.compiler CompilerSelector.new(f).select_compiler if f.fails_with? ENV.compiler
cs = CompilerSelector.new f
cs.select_compiler
cs.advise
end
f.brew do f.brew do
if ARGV.flag? '--git' if ARGV.flag? '--git'

View File

@ -68,6 +68,7 @@ class CompilerFailure
def initialize compiler, &block def initialize compiler, &block
@compiler = compiler @compiler = compiler
instance_eval(&block) if block_given? instance_eval(&block) if block_given?
@build ||= 9999
end end
def build val=nil def build val=nil
@ -100,8 +101,7 @@ class CompilerSelector
# the failing build is >= the currently installed version of foo. # the failing build is >= the currently installed version of foo.
@compilers = @compilers.reject do |cc| @compilers = @compilers.reject do |cc|
failure = @f.fails_with? cc failure = @f.fails_with? cc
next unless failure failure && failure.build >= cc.build
failure.build >= cc.build or not ARGV.homebrew_developer?
end end
return if @compilers.empty? or @compilers.include? ENV.compiler return if @compilers.empty? or @compilers.include? ENV.compiler
@ -126,37 +126,4 @@ class CompilerSelector
end end
end end
end end
def advise
failure = @f.fails_with? @old_compiler
return unless failure
# If we're still using the original ENV.compiler, then the formula did not
# declare a specific failing build, so we continue and print some advice.
# Otherwise, tell the user that we're switching compilers.
if @old_compiler == ENV.compiler
cc = Compiler.new(ENV.compiler)
subject = "#{@f.name}-#{@f.version}: builds with #{NAMES[cc.name]}-#{cc.build}-#{MACOS_VERSION}"
warning = "Using #{NAMES[cc.name]}, but this formula is reported to fail with #{NAMES[cc.name]}."
warning += "\n\n#{failure.cause.strip}\n" unless failure.cause.nil?
warning += <<-EOS.undent
We are continuing anyway so if the build succeeds, please open a ticket with
the subject
#{subject}
so that we can update the formula accordingly. Thanks!
EOS
viable = @compilers.reject { |c| @f.fails_with? c }
unless viable.empty?
warning += "\nIf it fails you can use "
options = viable.map { |c| "--use-#{c.name}" }
warning += "#{options*' or '} to try a different compiler."
end
opoo warning
end
end
end end

View File

@ -200,10 +200,8 @@ class Formula
def fails_with? cc def fails_with? cc
return false if self.class.cc_failures.nil? return false if self.class.cc_failures.nil?
cc = Compiler.new(cc) unless cc.is_a? Compiler cc = Compiler.new(cc) unless cc.is_a? Compiler
return self.class.cc_failures.find do |failure| self.class.cc_failures.find do |failure|
next unless failure.compiler == cc.name failure.compiler == cc.name && failure.build >= cc.build
failure.build.zero? or \
(failure.build >= cc.build or not ARGV.homebrew_developer?)
end end
end end

View File

@ -94,9 +94,9 @@ class CompilerTests < Test::Unit::TestCase
cs.select_compiler cs.select_compiler
assert_equal case MacOS.clang_build_version assert_equal case MacOS.gcc_42_build_version
when 0..210 then :gcc when nil then :llvm
else :clang else :gcc
end, ENV.compiler end, ENV.compiler
end end
@ -110,6 +110,6 @@ class CompilerTests < Test::Unit::TestCase
cs.select_compiler cs.select_compiler
assert_equal MacOS.default_compiler, ENV.compiler assert_not_equal :clang, ENV.compiler
end end
end end