diff options
| -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) |
