aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/cxxstdlib.rb
blob: a7c84ac2da4dc34e122f2b10e4dd6c55bc4c1b4f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
require "compilers"

class CxxStdlib
  attr_reader :type, :compiler

  def initialize(type, compiler)
    if type && ![:libstdcxx, :libcxx].include?(type)
      raise ArgumentError, "Invalid C++ stdlib type: #{type}"
    end

    @type     = type.to_sym if 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
  end

  def check_dependencies(formula, deps)
    unless formula.skip_cxxstdlib_check?
      deps.each do |dep|
        # Software is unlikely to link against anything from its
        # buildtime deps, so it doesn't matter at all if they link
        # against different C++ stdlibs
        next if dep.build?

        dep_stdlib = Tab.for_formula(dep.to_formula).cxxstdlib
        if !compatible_with? dep_stdlib
          raise IncompatibleCxxStdlibs.new(formula, dep, dep_stdlib, self)
        end
      end
    end
  end

  def type_string
    type.to_s.gsub(/cxx$/, 'c++')
  end
end