Use polymorphism to simplify stdlib compatibility check
This commit is contained in:
parent
90e370d2ef
commit
142beddd7a
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
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
|
||||
def compatible_with?(other)
|
||||
(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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user