diff options
| -rw-r--r-- | Library/Homebrew/build.rb | 2 | ||||
| -rw-r--r-- | Library/Homebrew/cxxstdlib.rb | 56 | ||||
| -rw-r--r-- | Library/Homebrew/formula_installer.rb | 2 | ||||
| -rw-r--r-- | Library/Homebrew/tab.rb | 2 | ||||
| -rw-r--r-- | Library/Homebrew/test/test_stdlib.rb | 16 |
5 files changed, 46 insertions, 32 deletions
diff --git a/Library/Homebrew/build.rb b/Library/Homebrew/build.rb index 70c943d21..ef7c2c45d 100644 --- a/Library/Homebrew/build.rb +++ b/Library/Homebrew/build.rb @@ -172,7 +172,7 @@ class Build # This currently only tracks a single C++ stdlib per dep, # though it's possible for different libs/executables in # a given formula to link to different ones. - stdlib_in_use = CxxStdlib.new(stdlibs.first, ENV.compiler) + stdlib_in_use = CxxStdlib.create(stdlibs.first, ENV.compiler) begin stdlib_in_use.check_dependencies(f, deps) rescue IncompatibleCxxStdlibs => e diff --git a/Library/Homebrew/cxxstdlib.rb b/Library/Homebrew/cxxstdlib.rb index 27c03b625..4fcb4bf75 100644 --- a/Library/Homebrew/cxxstdlib.rb +++ b/Library/Homebrew/cxxstdlib.rb @@ -1,37 +1,29 @@ require "compilers" class CxxStdlib - attr_reader :type, :compiler + include CompilerConstants - def initialize(type, compiler) + def self.create(type, compiler) if type && ![:libstdcxx, :libcxx].include?(type) raise ArgumentError, "Invalid C++ stdlib type: #{type}" end + klass = GNU_GCC_REGEXP === compiler.to_s ? GnuStdlib : AppleStdlib + klass.new(type, compiler) + end + + attr_reader :type, :compiler + def initialize(type, compiler) @type = type @compiler = compiler.to_sym end - def apple_compiler? - not compiler.to_s =~ CompilerConstants::GNU_GCC_REGEXP - end - + # If either package doesn't use C++, all is well + # libstdc++ and libc++ aren't ever intercompatible + # libstdc++ is compatible across Apple compilers, but + # not between Apple and GNU compilers, or between GNU compiler versions def compatible_with?(other) - # If either package doesn't use C++, all is well - return true if type.nil? || other.type.nil? - - # libstdc++ and libc++ aren't ever intercompatible - return false unless type == other.type - - # libstdc++ is compatible across Apple compilers, but - # not between Apple and GNU compilers, or between GNU compiler versions - return false if apple_compiler? && !other.apple_compiler? - if compiler.to_s =~ CompilerConstants::GNU_GCC_REGEXP - return false unless other.compiler.to_s =~ CompilerConstants::GNU_GCC_REGEXP - return false unless compiler.to_s[4..6] == other.compiler.to_s[4..6] - end - - true + (type.nil? || other.type.nil?) || type == other.type end def check_dependencies(formula, deps) @@ -53,4 +45,26 @@ class CxxStdlib def type_string type.to_s.gsub(/cxx$/, 'c++') end + + class AppleStdlib < CxxStdlib + def apple_compiler? + true + end + + def compatible_with?(other) + super && other.apple_compiler? + end + end + + class GnuStdlib < CxxStdlib + def apple_compiler? + false + end + + def compatible_with?(other) + super && + !other.apple_compiler? && + compiler.to_s[4..6] == other.compiler.to_s[4..6] + end + end end diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index b10846a0c..74b1097a8 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -159,7 +159,7 @@ class FormulaInstaller @poured_bottle = true stdlibs = Keg.new(f.prefix).detect_cxx_stdlibs - stdlib_in_use = CxxStdlib.new(stdlibs.first, MacOS.default_compiler) + stdlib_in_use = CxxStdlib.create(stdlibs.first, MacOS.default_compiler) begin stdlib_in_use.check_dependencies(f, f.recursive_dependencies) rescue IncompatibleCxxStdlibs => e diff --git a/Library/Homebrew/tab.rb b/Library/Homebrew/tab.rb index 0b1605ab1..436af0062 100644 --- a/Library/Homebrew/tab.rb +++ b/Library/Homebrew/tab.rb @@ -119,7 +119,7 @@ class Tab < OpenStruct # Older tabs won't have these values, so provide sensible defaults lib = stdlib.to_sym if stdlib cc = compiler || MacOS.default_compiler - CxxStdlib.new(lib, cc.to_sym) + CxxStdlib.create(lib, cc.to_sym) end def to_json diff --git a/Library/Homebrew/test/test_stdlib.rb b/Library/Homebrew/test/test_stdlib.rb index 60b5885ce..55b10641c 100644 --- a/Library/Homebrew/test/test_stdlib.rb +++ b/Library/Homebrew/test/test_stdlib.rb @@ -5,14 +5,14 @@ require 'cxxstdlib' class CxxStdlibTests < Homebrew::TestCase def setup - @clang = CxxStdlib.new(:libstdcxx, :clang) - @gcc = CxxStdlib.new(:libstdcxx, :gcc) - @llvm = CxxStdlib.new(:libstdcxx, :llvm) - @gcc4 = CxxStdlib.new(:libstdcxx, :gcc_4_0) - @gcc48 = CxxStdlib.new(:libstdcxx, 'gcc-4.8') - @gcc49 = CxxStdlib.new(:libstdcxx, 'gcc-4.9') - @lcxx = CxxStdlib.new(:libcxx, :clang) - @purec = CxxStdlib.new(nil, :clang) + @clang = CxxStdlib.create(:libstdcxx, :clang) + @gcc = CxxStdlib.create(:libstdcxx, :gcc) + @llvm = CxxStdlib.create(:libstdcxx, :llvm) + @gcc4 = CxxStdlib.create(:libstdcxx, :gcc_4_0) + @gcc48 = CxxStdlib.create(:libstdcxx, 'gcc-4.8') + @gcc49 = CxxStdlib.create(:libstdcxx, 'gcc-4.9') + @lcxx = CxxStdlib.create(:libcxx, :clang) + @purec = CxxStdlib.create(nil, :clang) end def test_apple_libstdcxx_intercompatibility |
