| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-02 21:57:52 -05:00
										 |  |  | require "compilers" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-27 00:11:45 -07:00
										 |  |  | class CxxStdlib | 
					
						
							| 
									
										
										
										
											2014-08-02 19:29:59 -05:00
										 |  |  |   include CompilerConstants | 
					
						
							| 
									
										
										
										
											2013-07-27 00:11:45 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 22:36:58 -05:00
										 |  |  |   class CompatibilityError < StandardError | 
					
						
							|  |  |  |     def initialize(formula, dep, stdlib) | 
					
						
							| 
									
										
										
										
											2017-10-15 02:28:32 +02:00
										 |  |  |       super <<~EOS | 
					
						
							| 
									
										
										
										
											2015-05-27 21:33:11 +08:00
										 |  |  |         #{formula.full_name} dependency #{dep.name} was built with a different C++ standard | 
					
						
							| 
									
										
										
										
											2014-08-22 22:36:58 -05:00
										 |  |  |         library (#{stdlib.type_string} from #{stdlib.compiler}). This may cause problems at runtime. | 
					
						
							| 
									
										
										
										
											2018-06-06 23:34:19 -04:00
										 |  |  |       EOS | 
					
						
							| 
									
										
										
										
											2014-08-22 22:36:58 -05:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-02 19:29:59 -05:00
										 |  |  |   def self.create(type, compiler) | 
					
						
							| 
									
										
										
										
											2019-02-19 13:11:32 +00:00
										 |  |  |     raise ArgumentError, "Invalid C++ stdlib type: #{type}" if type && ![:libstdcxx, :libcxx].include?(type) | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-29 18:24:52 +01:00
										 |  |  |     klass = (compiler.to_s =~ GNU_GCC_REGEXP) ? GnuStdlib : AppleStdlib | 
					
						
							| 
									
										
										
										
											2014-08-02 19:29:59 -05:00
										 |  |  |     klass.new(type, compiler) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 22:18:03 -05:00
										 |  |  |   def self.check_compatibility(formula, deps, keg, compiler) | 
					
						
							|  |  |  |     return if formula.skip_cxxstdlib_check? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     stdlib = create(keg.detect_cxx_stdlibs.first, compiler) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     begin | 
					
						
							|  |  |  |       stdlib.check_dependencies(formula, deps) | 
					
						
							| 
									
										
										
										
											2014-08-22 22:36:58 -05:00
										 |  |  |     rescue CompatibilityError => e | 
					
						
							| 
									
										
										
										
											2014-08-22 22:18:03 -05:00
										 |  |  |       opoo e.message | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-02 19:29:59 -05:00
										 |  |  |   attr_reader :type, :compiler | 
					
						
							| 
									
										
										
										
											2013-07-27 00:11:45 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-02 19:29:59 -05:00
										 |  |  |   def initialize(type, compiler) | 
					
						
							| 
									
										
										
										
											2014-08-02 19:29:58 -05:00
										 |  |  |     @type = type | 
					
						
							| 
									
										
										
										
											2013-07-27 00:11:45 -07:00
										 |  |  |     @compiler = compiler.to_sym | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  |   # If either package doesn't use C++, all is well. | 
					
						
							|  |  |  |   # libstdc++ and libc++ aren't ever intercompatible. | 
					
						
							| 
									
										
										
										
											2014-08-02 19:29:59 -05:00
										 |  |  |   # libstdc++ is compatible across Apple compilers, but | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  |   # not between Apple and GNU compilers, or between GNU compiler versions. | 
					
						
							| 
									
										
										
										
											2013-07-27 00:11:45 -07:00
										 |  |  |   def compatible_with?(other) | 
					
						
							| 
									
										
										
										
											2014-08-02 20:03:42 -05:00
										 |  |  |     return true if type.nil? || other.type.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false unless type == other.type | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-02 20:09:42 -05:00
										 |  |  |     apple_compiler? && other.apple_compiler? || | 
					
						
							|  |  |  |       !other.apple_compiler? && compiler.to_s[4..6] == other.compiler.to_s[4..6] | 
					
						
							| 
									
										
										
										
											2013-07-27 00:11:45 -07:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def check_dependencies(formula, deps) | 
					
						
							| 
									
										
										
										
											2014-08-22 22:18:03 -05:00
										 |  |  |     deps.each do |dep| | 
					
						
							|  |  |  |       # Software is unlikely to link against libraries from build-time deps, so | 
					
						
							|  |  |  |       # it doesn't matter if they link against different C++ stdlibs. | 
					
						
							|  |  |  |       next if dep.build? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       dep_stdlib = Tab.for_formula(dep.to_formula).cxxstdlib | 
					
						
							| 
									
										
										
										
											2019-02-19 13:11:32 +00:00
										 |  |  |       raise CompatibilityError.new(formula, dep, dep_stdlib) unless compatible_with? dep_stdlib | 
					
						
							| 
									
										
										
										
											2013-07-27 00:11:45 -07:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def type_string | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |     type.to_s.gsub(/cxx$/, "c++") | 
					
						
							| 
									
										
										
										
											2013-07-27 00:11:45 -07:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2014-08-02 19:29:59 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-03 15:28:26 -05:00
										 |  |  |   def inspect | 
					
						
							|  |  |  |     "#<#{self.class.name}: #{compiler} #{type}>" | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-02 19:29:59 -05:00
										 |  |  |   class AppleStdlib < CxxStdlib | 
					
						
							|  |  |  |     def apple_compiler? | 
					
						
							|  |  |  |       true | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   class GnuStdlib < CxxStdlib | 
					
						
							|  |  |  |     def apple_compiler? | 
					
						
							|  |  |  |       false | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-07-27 00:11:45 -07:00
										 |  |  | end |