aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/cxxstdlib.rb
diff options
context:
space:
mode:
authorMisty De Meo2013-07-27 00:11:45 -0700
committerMisty De Meo2013-09-01 13:19:13 -0700
commitb71682bdc79e49e43bfc4f9652f613a2ed398ed2 (patch)
tree86a7bc3c082f081f7f67037f21368fd5bb774de8 /Library/Homebrew/cxxstdlib.rb
parent3ac74331a86d031179c3e25fe46bcb9f292dacc1 (diff)
downloadbrew-b71682bdc79e49e43bfc4f9652f613a2ed398ed2.tar.bz2
Tab: track C++ stdlib in use
There are subtle incompatibilities between Apple's libstdc++ and the libstdc++ used by the various GNU GCC formulae. In addition, we'll likely also be supporting libc++ in the future, and that's also incompatible with the other stdlibs. Tracking it in the tab lets us make sure that dependencies are all built against the same stdlib to avoid subtle breakage.
Diffstat (limited to 'Library/Homebrew/cxxstdlib.rb')
-rw-r--r--Library/Homebrew/cxxstdlib.rb44
1 files changed, 44 insertions, 0 deletions
diff --git a/Library/Homebrew/cxxstdlib.rb b/Library/Homebrew/cxxstdlib.rb
new file mode 100644
index 000000000..4e3bed22e
--- /dev/null
+++ b/Library/Homebrew/cxxstdlib.rb
@@ -0,0 +1,44 @@
+class CxxStdlib
+ attr_accessor :type, :compiler
+
+ def initialize(type, compiler)
+ if ![:libstdcxx, :libcxx].include? type
+ raise ArgumentError, "Invalid C++ stdlib type: #{type}"
+ end
+
+ @type = type.to_sym
+ @compiler = compiler.to_sym
+ end
+
+ def apple_compiler?
+ not compiler.to_s =~ SharedEnvExtension::GNU_GCC_REGEXP
+ end
+
+ def compatible_with?(other)
+ # 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 =~ SharedEnvExtension::GNU_GCC_REGEXP
+ return false unless other.compiler.to_s =~ SharedEnvExtension::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)
+ deps.each do |dep|
+ 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
+
+ def type_string
+ type.to_s.gsub(/cxx$/, 'c++')
+ end
+end