diff options
Diffstat (limited to 'Library')
| -rw-r--r-- | Library/Homebrew/compilers.rb | 43 | ||||
| -rw-r--r-- | Library/Homebrew/formula.rb | 37 | ||||
| -rw-r--r-- | Library/Homebrew/test/test_fails_with.rb | 7 | 
3 files changed, 68 insertions, 19 deletions
diff --git a/Library/Homebrew/compilers.rb b/Library/Homebrew/compilers.rb index 9561fc0fb..cb7d74334 100644 --- a/Library/Homebrew/compilers.rb +++ b/Library/Homebrew/compilers.rb @@ -1,30 +1,55 @@  class Compiler < Struct.new(:name, :priority) -  def build -    MacOS.send("#{name}_build_version") +  # The full version of the compiler for comparison purposes. +  def version +    if name.is_a? String +      MacOS.non_apple_gcc_version(name) +    else +      MacOS.send("#{name}_build_version") +    end    end -  def version -    MacOS.non_apple_gcc_version(name) if name.is_a? String +  # This is exposed under the `build` name for compatibility, since +  # `fails_with` continues to use `build` in the public API. +  # `build` indicates the build number of an Apple compiler. +  # This is preferred over version numbers since there are often +  # significant differences within the same version, +  # e.g. GCC 4.2 build 5553 vs 5666. +  # Non-Apple compilers don't have build numbers. +  alias_method :build, :version + +  # The major version for non-Apple compilers. Used to indicate a compiler +  # series; for instance, if the version is 4.8.2, it would return "4.8". +  def major_version +    version.match(/(\d\.\d)/)[0] if name.is_a? String    end  end  class CompilerFailure -  attr_reader :compiler, :version -  attr_rw :build, :cause +  attr_reader :compiler, :major_version +  attr_rw :cause, :version    def initialize compiler, &block      # Non-Apple compilers are in the format fails_with compiler => version      if compiler.is_a? Hash        # currently the only compiler for this case is GCC -      _, @version = compiler.shift -      @compiler = 'gcc-' + @version.match(/(\d\.\d)/)[0] +      _, @major_version = compiler.shift +      @compiler = 'gcc-' + @major_version      else        @compiler = compiler      end      instance_eval(&block) if block_given? -    @build = (@build || 9999).to_i unless compiler.is_a? Hash +    if !compiler.is_a? Hash +      @version = (@version || 9999).to_i +    else +      # so fails_with :gcc => '4.8' simply marks all 4.8 releases incompatible +      @version ||= @major_version + '.999' if compiler.is_a? Hash +    end    end + +  # Allows Apple compiler `fails_with` statements to keep using `build` +  # even though `build` and `value` are the same internally +  alias_method :build, :version  end  class CompilerQueue diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 672d21056..f9de49adb 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -241,12 +241,10 @@ class Formula    def fails_with? cc      cc = Compiler.new(cc) unless cc.is_a? Compiler      (self.class.cc_failures || []).any? do |failure| -      if cc.version -        # non-Apple GCCs don't have builds, just version numbers -        failure.compiler == cc.name && failure.version >= cc.version -      else -        failure.compiler == cc.name && failure.build >= cc.build -      end +      # Major version check distinguishes between, e.g., +      # GCC 4.7.1 and GCC 4.8.2, where a comparison is meaningless +      failure.compiler == cc.name && failure.major_version == cc.major_version && \ +        failure.version >= cc.version      end    end @@ -785,6 +783,33 @@ class Formula        @keg_only_reason = KegOnlyReason.new(reason, explanation.to_s.chomp)      end +    # For Apple compilers, this should be in the format: +    # fails_with compiler do +    #   cause "An explanation for why the build doesn't work." +    #   build "The Apple build number for the newest incompatible release." +    # end +    # +    # The block may be omitted, and if present the build may be omitted; +    # if so, then the compiler will be blacklisted for *all* versions. +    # +    # For GNU GCC compilers, this should be in the format: +    # fails_with compiler => major_version do +    #   cause +    #   version "The official release number for the latest incompatible +    #            version, for instance 4.8.1" +    # end +    #  +    # `major_version` should be the major release number only, for instance +    # '4.8' for the GCC 4.8 series (4.8.0, 4.8.1, etc.). +    # If `version` or the block is omitted, then the compiler will be +    # blacklisted for all compilers in that series. +    # +    # For example, if a bug is only triggered on GCC 4.8.1 but is not +    # encountered on 4.8.2: +    #  +    # fails_with :gcc => '4.8' do +    #   version '4.8.1' +    # end      def fails_with compiler, &block        @cc_failures ||= Set.new        @cc_failures << CompilerFailure.new(compiler, &block) diff --git a/Library/Homebrew/test/test_fails_with.rb b/Library/Homebrew/test/test_fails_with.rb index 31f318a4c..642d9c060 100644 --- a/Library/Homebrew/test/test_fails_with.rb +++ b/Library/Homebrew/test/test_fails_with.rb @@ -3,7 +3,7 @@ require 'test/testball'  class FailsWithTests < Test::Unit::TestCase    class Double < Compiler -    attr_accessor :name, :build, :version +    attr_accessor :name, :version    end    def assert_fails_with(cc) @@ -21,8 +21,7 @@ class FailsWithTests < Test::Unit::TestCase    def build_cc(sym, build, version=nil)      cc = Double.new      cc.name = sym -    cc.build = build -    cc.version = version +    cc.version = version || build      cc    end @@ -49,7 +48,7 @@ class FailsWithTests < Test::Unit::TestCase    end    def test_non_apple_gcc_version -    fails_with(:gcc => '4.8.2') +    fails_with(:gcc => '4.8')      cc = build_cc("gcc-4.8", nil, "4.8.1")      assert_fails_with cc    end  | 
