From 7c3d6ea81c23d4c2c9daf4c9d97e75e6ac6320a5 Mon Sep 17 00:00:00 2001 From: Misty De Meo Date: Sat, 27 Jul 2013 02:07:29 -0700 Subject: [PATCH] Check dependencies for a compatible C++ stdlib There are now a few possible C++ standard libraries a given build could be using, with subtle incompatibilities and possibility of breakage when mixed. This makes sure that the dependency chain was compiled in a compatible manner. Fortunately all of the Apple compilers use the same libstdc++, and we don't yet support building with libc++, so this will primarily only nag users trying to use GNU gcc who already have software installed with Apple compilers. Future TODOs: * Add general support for building with libc++ (compatibility checking already handled here) * Possibly track formulae which actually build C++ bindings, so that users aren't bothered by spurious nagging re: interpreted languages, pure-C software, etc. --- Library/Homebrew/build.rb | 11 ++++++++++- Library/Homebrew/exceptions.rb | 15 +++++++++++++++ Library/Homebrew/formula_installer.rb | 12 ++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/build.rb b/Library/Homebrew/build.rb index 9d25c9a865..69ef1a6def 100755 --- a/Library/Homebrew/build.rb +++ b/Library/Homebrew/build.rb @@ -13,6 +13,7 @@ at_exit do end require 'global' +require 'cxxstdlib' require 'debrew' if ARGV.debug? def main @@ -148,6 +149,14 @@ class Build end end + # We only support libstdc++ right now + stdlib_in_use = CxxStdlib.new(:libstdcxx, ENV.compiler) + + # This is a bad place for this check, but we don't have access to + # compiler selection within the formula installer, only inside the + # build instance. + stdlib_in_use.check_dependencies(f, deps) + f.brew do if ARGV.flag? '--git' system "git init" @@ -170,7 +179,7 @@ class Build begin f.install - Tab.create(f, ENV.compiler, + Tab.create(f, :libstdcxx, ENV.compiler, Options.coerce(ARGV.options_only)).write rescue Exception => e if ARGV.debug? diff --git a/Library/Homebrew/exceptions.rb b/Library/Homebrew/exceptions.rb index 29da3ab085..5865eb98e5 100644 --- a/Library/Homebrew/exceptions.rb +++ b/Library/Homebrew/exceptions.rb @@ -112,6 +112,21 @@ class UnsatisfiedRequirements < Homebrew::InstallationError end end +class IncompatibleCxxStdlibs < Homebrew::InstallationError + def initialize(f, dep, wrong, right) + super f, <<-EOS.undent + #{f} dependency #{dep} was built with the following + C++ standard library: #{wrong.type_string} (from #{wrong.compiler}) + + This is incompatible with the standard library being used + to build #{f}: #{right.type_string} (from #{right.compiler}) + + Please reinstall #{dep} using a compatible compiler. + hint: Check https://github.com/mxcl/homebrew/wiki/C++-Standard-Libraries + EOS + end +end + class FormulaConflictError < Homebrew::InstallationError attr_reader :f, :conflicts diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index aff8d29fc0..328334b836 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -1,5 +1,6 @@ # encoding: UTF-8 +require 'cxxstdlib' require 'exceptions' require 'formula' require 'keg' @@ -94,6 +95,17 @@ class FormulaInstaller raise "Unrecognized architecture for --bottle-arch: #{arch}" end + if pour_bottle? true + # TODO We currently only support building with libstdc++ as + # the default case, and all Apple libstdc++s are compatible, so + # this default is sensible. + # In the future we need to actually provide a way to read this from + # the bottle, or update the default should that change + # at some other point. + stdlib_in_use = CxxStdlib.new(:libstdcxx, :clang) + stdlib_in_use.check_dependencies(f, f.deps) + end + oh1 "Installing #{Tty.green}#{f}#{Tty.reset}" if show_header @@attempted << f