diff options
| author | Misty De Meo | 2013-06-28 01:38:09 -0500 | 
|---|---|---|
| committer | Misty De Meo | 2013-09-01 13:19:13 -0700 | 
| commit | 733076ec22a21bcc481afc38fc79fd0ea40700a0 (patch) | |
| tree | 11562b9fbc0afdf15358c499b002878b12a70cc3 /Library | |
| parent | 512801cd260c317a9af54a1da8bfe314ba61d6f4 (diff) | |
| download | homebrew-733076ec22a21bcc481afc38fc79fd0ea40700a0.tar.bz2 | |
Implement fails_with for non-Apple compilers
This adds support for non-Apple GCC compilers in the fails_with code.
A fails_with block for a non-Apple compiler looks like:
fails_with :gcc => '4.8.1' do
  cause 'Foo'
end
Non-Apple compilers don't have build numbers, so compiler failures are
based on version strings instead.
Internally non-Apple compilers can be distinguished because they are
passed around as strings instead of symbols.
In addition, this alters the priority list for compilers, with the
following changes:
* Apple GCC 4.2 and LLVM-GCC swap positions, with GCC now taking
  priority. (Maybe LLVM-GCC should just go away.)
* Non-Apple GCC compilers are ranked below GCC 4.2 but above LLVM-GCC
  and Apple GCC 4.0.
Diffstat (limited to 'Library')
| -rw-r--r-- | Library/Homebrew/compilers.rb | 32 | ||||
| -rw-r--r-- | Library/Homebrew/extend/ENV/std.rb | 10 | ||||
| -rw-r--r-- | Library/Homebrew/extend/ENV/super.rb | 7 | ||||
| -rw-r--r-- | Library/Homebrew/formula.rb | 7 | ||||
| -rw-r--r-- | Library/Homebrew/macos.rb | 10 | ||||
| -rw-r--r-- | Library/Homebrew/test/test_compiler_selector.rb | 40 | ||||
| -rw-r--r-- | Library/Homebrew/test/test_fails_with.rb | 11 | 
7 files changed, 103 insertions, 14 deletions
| diff --git a/Library/Homebrew/compilers.rb b/Library/Homebrew/compilers.rb index 3aaaecbc8..8eb6d56fb 100644 --- a/Library/Homebrew/compilers.rb +++ b/Library/Homebrew/compilers.rb @@ -2,16 +2,28 @@ class Compiler < Struct.new(:name, :priority)    def build      MacOS.send("#{name}_build_version")    end + +  def version +    MacOS.non_apple_gcc_version(name) if name.is_a? String +  end  end  class CompilerFailure -  attr_reader :compiler +  attr_reader :compiler, :version    attr_rw :build, :cause    def initialize compiler, &block -    @compiler = compiler +    # 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] +    else +      @compiler = compiler +    end +      instance_eval(&block) if block_given? -    @build = (@build || 9999).to_i +    @build = (@build || 9999).to_i unless compiler.is_a? Hash    end  end @@ -43,6 +55,14 @@ class CompilerSelector          @compilers << Compiler.new(cc, priority_for(cc))        end      end + +    # non-Apple GCC 4.x +    SharedEnvExtension::GNU_GCC_VERSIONS.each do |v| +      unless MacOS.non_apple_gcc_version("gcc-4.#{v}").nil? +        # priority is based on version, with newest preferred first +        @compilers << Compiler.new("gcc-4.#{v}", 1.0 + v/10.0) +      end +    end    end    # Attempts to select an appropriate alternate compiler, but @@ -64,9 +84,11 @@ class CompilerSelector    def priority_for(cc)      case cc      when :clang then MacOS.clang_build_version >= 318 ? 3 : 0.5 -    when :llvm  then 2 -    when :gcc   then 1 +    when :gcc   then 2 +    when :llvm  then 1      when :gcc_4_0 then 0.25 +    # non-Apple gcc compilers +    else 1.5      end    end  end diff --git a/Library/Homebrew/extend/ENV/std.rb b/Library/Homebrew/extend/ENV/std.rb index 67ab85952..e931b33ba 100644 --- a/Library/Homebrew/extend/ENV/std.rb +++ b/Library/Homebrew/extend/ENV/std.rb @@ -167,6 +167,16 @@ module Stdenv    end    alias_method :gcc_4_2, :gcc +  GNU_GCC_VERSIONS.each do |n| +    define_method(:"gcc-4.#{n}") do +      gcc = "gcc-4.#{n}" +      self.cc = self['OBJC'] = gcc +      self.cxx = self['OBJCXX'] = gcc.gsub('c', '+') +      set_cpu_cflags +      @compiler = gcc +    end +  end +    def llvm      self.cc  = MacOS.locate("llvm-gcc")      self.cxx = MacOS.locate("llvm-g++") diff --git a/Library/Homebrew/extend/ENV/super.rb b/Library/Homebrew/extend/ENV/super.rb index 2b3957209..9ca88750c 100644 --- a/Library/Homebrew/extend/ENV/super.rb +++ b/Library/Homebrew/extend/ENV/super.rb @@ -266,6 +266,13 @@ module Superenv      self.cc  = self['HOMEBREW_CC'] = "clang"      self.cxx = "clang++"    end +  GNU_GCC_VERSIONS.each do |n| +    define_method(:"gcc-4.#{n}") do +      gcc = "gcc-4.#{n}" +      self.cc = self['HOMEBREW_CC'] = gcc +      self.cxx = gcc.gsub('c', '+') +    end +  end    def make_jobs      self['MAKEFLAGS'] =~ /-\w*j(\d)+/      [$1.to_i, 1].max diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index bbcb1dab2..29e87af06 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -212,7 +212,12 @@ class Formula    def fails_with? cc      cc = Compiler.new(cc) unless cc.is_a? Compiler      (self.class.cc_failures || []).any? do |failure| -      failure.compiler == cc.name && failure.build >= cc.build +      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      end    end diff --git a/Library/Homebrew/macos.rb b/Library/Homebrew/macos.rb index 8e379ad2a..de109ade3 100644 --- a/Library/Homebrew/macos.rb +++ b/Library/Homebrew/macos.rb @@ -151,6 +151,16 @@ module MacOS extend self        end    end +  def non_apple_gcc_version(cc) +    return unless path = locate(cc) + +    ivar = "@#{cc.gsub(/(-|\.)/, '')}_version" +    return instance_variable_get(ivar) if instance_variable_defined?(ivar) + +    `#{path} --version` =~ /gcc-\d.\d \(GCC\) (\d\.\d\.\d)/ +    instance_variable_set(ivar, $1) +  end +    # See these issues for some history:    # http://github.com/mxcl/homebrew/issues/#issue/13    # http://github.com/mxcl/homebrew/issues/#issue/41 diff --git a/Library/Homebrew/test/test_compiler_selector.rb b/Library/Homebrew/test/test_compiler_selector.rb index 17c3b0449..5374a5452 100644 --- a/Library/Homebrew/test/test_compiler_selector.rb +++ b/Library/Homebrew/test/test_compiler_selector.rb @@ -22,16 +22,29 @@ class CompilerSelectorTests < Test::Unit::TestCase      MacOS.stubs(:gcc_build_version).returns(5666)      MacOS.stubs(:llvm_build_version).returns(2336)      MacOS.stubs(:clang_build_version).returns(425) +    # Yes, this is ugly - we only want one GCC version to be available. +    MacOS.send(:alias_method, :old_non_apple_gcc_version, :non_apple_gcc_version) +    MacOS.send(:define_method, :non_apple_gcc_version) do |name| +      if name == 'gcc-4.8' +        '4.8.1' +      else +        nil +      end +    end      @f  = Double.new      @cc = :clang    end +  def teardown +    MacOS.send(:alias_method, :non_apple_gcc_version, :old_non_apple_gcc_version) +  end +    def actual_cc      CompilerSelector.new(@f).compiler    end    def test_all_compiler_failures -    @f << :clang << :llvm << :gcc +    @f << :clang << :llvm << :gcc << 'gcc-4.8'      assert_raise(CompilerSelectionError) { actual_cc }    end @@ -41,7 +54,7 @@ class CompilerSelectorTests < Test::Unit::TestCase    def test_fails_with_clang      @f << :clang -    assert_equal :llvm, actual_cc +    assert_equal :gcc, actual_cc    end    def test_fails_with_llvm @@ -54,13 +67,18 @@ class CompilerSelectorTests < Test::Unit::TestCase      assert_equal :clang, actual_cc    end +  def test_fails_with_non_apple_gcc +    @f << "gcc-4.8" +    assert_equal :clang, actual_cc +  end +    def test_mixed_failures_1      @f << :clang << :llvm      assert_equal :gcc, actual_cc    end    def test_mixed_failures_2 -    @f << :gcc << :clang +    @f << :gcc << :clang << 'gcc-4.8'      assert_equal :llvm, actual_cc    end @@ -69,22 +87,32 @@ class CompilerSelectorTests < Test::Unit::TestCase      assert_equal :clang, actual_cc    end +  def test_mixed_failures_4 +    @f << :clang << "gcc-4.8" +    assert_equal :gcc, actual_cc +  end +    def test_older_clang_precedence      MacOS.stubs(:clang_build_version).returns(211) -    @f << :gcc +    @f << :gcc << 'gcc-4.8'      assert_equal :llvm, actual_cc    end +  def test_non_apple_gcc_precedence +    @f << :clang << :gcc +    assert_equal 'gcc-4.8', actual_cc +  end +    def test_missing_gcc      MacOS.stubs(:gcc_build_version).returns(nil) -    @f << :clang << :llvm +    @f << :clang << :llvm << 'gcc-4.8'      assert_raise(CompilerSelectionError) { actual_cc }    end    def test_missing_llvm_and_gcc      MacOS.stubs(:gcc_build_version).returns(nil)      MacOS.stubs(:llvm_build_version).returns(nil) -    @f << :clang +    @f << :clang << 'gcc-4.8'      assert_raise(CompilerSelectionError) { actual_cc }    end  end diff --git a/Library/Homebrew/test/test_fails_with.rb b/Library/Homebrew/test/test_fails_with.rb index 2b344cc3d..31f318a4c 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 +    attr_accessor :name, :build, :version    end    def assert_fails_with(cc) @@ -18,10 +18,11 @@ class FailsWithTests < Test::Unit::TestCase      @f.send(:fails_with, *args, &block)    end -  def build_cc(sym, build) +  def build_cc(sym, build, version=nil)      cc = Double.new      cc.name = sym      cc.build = build +    cc.version = version      cc    end @@ -47,6 +48,12 @@ class FailsWithTests < Test::Unit::TestCase      assert_fails_with cc    end +  def test_non_apple_gcc_version +    fails_with(:gcc => '4.8.2') +    cc = build_cc("gcc-4.8", nil, "4.8.1") +    assert_fails_with cc +  end +    def test_multiple_failures      fails_with(:llvm)      fails_with(:clang) | 
