| 
									
										
										
										
											2015-08-29 10:56:24 +01:00
										 |  |  | # @private | 
					
						
							| 
									
										
										
										
											2014-07-02 21:57:52 -05:00
										 |  |  | module CompilerConstants | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |   GNU_GCC_VERSIONS = %w[4.3 4.4 4.5 4.6 4.7 4.8 4.9 5 6 7].freeze | 
					
						
							| 
									
										
										
										
											2016-09-13 15:03:37 -04:00
										 |  |  |   GNU_GCC_REGEXP = /^gcc-(4\.[3-9]|[5-7])$/ | 
					
						
							| 
									
										
										
										
											2015-06-19 21:38:39 -04:00
										 |  |  |   COMPILER_SYMBOL_MAP = { | 
					
						
							| 
									
										
										
										
											2016-09-24 23:56:54 -04:00
										 |  |  |     "gcc-4.0"    => :gcc_4_0, | 
					
						
							|  |  |  |     "gcc-4.2"    => :gcc, | 
					
						
							|  |  |  |     "clang"      => :clang, | 
					
						
							|  |  |  |     "llvm_clang" => :llvm_clang, | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |   }.freeze | 
					
						
							| 
									
										
										
										
											2015-06-19 21:38:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   COMPILERS = COMPILER_SYMBOL_MAP.values + | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |               GNU_GCC_VERSIONS.map { |n| "gcc-#{n}" } | 
					
						
							| 
									
										
										
										
											2014-07-02 21:57:52 -05:00
										 |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-18 13:58:13 -05:00
										 |  |  | class CompilerFailure | 
					
						
							| 
									
										
										
										
											2014-08-03 10:47:47 -05:00
										 |  |  |   attr_reader :name | 
					
						
							| 
									
										
										
										
											2016-11-03 16:48:51 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   def version(val = nil) | 
					
						
							|  |  |  |     if val | 
					
						
							|  |  |  |       @version = Version.parse(val.to_s) | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       @version | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2012-03-18 13:58:13 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-16 16:08:41 -05:00
										 |  |  |   # Allows Apple compiler `fails_with` statements to keep using `build` | 
					
						
							|  |  |  |   # even though `build` and `version` are the same internally | 
					
						
							| 
									
										
										
										
											2016-09-23 18:13:48 +02:00
										 |  |  |   alias build version | 
					
						
							| 
									
										
										
										
											2014-06-16 16:08:41 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-21 00:53:15 -05:00
										 |  |  |   # The cause is no longer used so we need not hold a reference to the string | 
					
						
							|  |  |  |   def cause(_); end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def self.for_standard(standard) | 
					
						
							| 
									
										
										
										
											2014-08-01 20:15:58 -05:00
										 |  |  |     COLLECTIONS.fetch(standard) do | 
					
						
							| 
									
										
										
										
											2014-04-04 21:16:09 -07:00
										 |  |  |       raise ArgumentError, "\"#{standard}\" is not a recognized standard" | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-01 20:15:57 -05:00
										 |  |  |   def self.create(spec, &block) | 
					
						
							| 
									
										
										
										
											2013-06-28 01:38:09 -05:00
										 |  |  |     # Non-Apple compilers are in the format fails_with compiler => version | 
					
						
							| 
									
										
										
										
											2014-08-01 20:15:57 -05:00
										 |  |  |     if spec.is_a?(Hash) | 
					
						
							| 
									
										
										
										
											2015-12-26 23:00:38 +01:00
										 |  |  |       _, major_version = spec.first | 
					
						
							| 
									
										
										
										
											2014-08-03 10:47:47 -05:00
										 |  |  |       name = "gcc-#{major_version}" | 
					
						
							| 
									
										
										
										
											2013-09-28 12:21:16 -07:00
										 |  |  |       # so fails_with :gcc => '4.8' simply marks all 4.8 releases incompatible | 
					
						
							| 
									
										
										
										
											2014-08-01 20:15:57 -05:00
										 |  |  |       version = "#{major_version}.999" | 
					
						
							| 
									
										
										
										
											2013-12-12 14:53:53 -06:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2014-08-03 10:47:47 -05:00
										 |  |  |       name = spec | 
					
						
							| 
									
										
										
										
											2014-08-01 20:15:57 -05:00
										 |  |  |       version = 9999
 | 
					
						
							| 
									
										
										
										
											2013-09-28 12:21:16 -07:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2014-08-03 11:15:39 -05:00
										 |  |  |     new(name, version, &block) | 
					
						
							| 
									
										
										
										
											2014-08-01 20:15:57 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-03 10:47:47 -05:00
										 |  |  |   def initialize(name, version, &block) | 
					
						
							| 
									
										
										
										
											2014-08-03 10:47:47 -05:00
										 |  |  |     @name = name | 
					
						
							| 
									
										
										
										
											2016-11-03 16:48:51 -07:00
										 |  |  |     @version = Version.parse(version.to_s) | 
					
						
							| 
									
										
										
										
											2014-08-01 20:15:57 -05:00
										 |  |  |     instance_eval(&block) if block_given? | 
					
						
							| 
									
										
										
										
											2012-03-18 13:58:13 -05:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2014-08-01 20:15:58 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-24 18:59:44 +02:00
										 |  |  |   def fails_with?(compiler) | 
					
						
							| 
									
										
										
										
											2014-08-03 13:12:59 -05:00
										 |  |  |     name == compiler.name && version >= compiler.version | 
					
						
							| 
									
										
										
										
											2014-08-03 10:47:47 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-03 15:28:26 -05:00
										 |  |  |   def inspect | 
					
						
							|  |  |  |     "#<#{self.class.name}: #{name} #{version}>" | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-01 20:15:58 -05:00
										 |  |  |   COLLECTIONS = { | 
					
						
							| 
									
										
										
										
											2016-09-17 15:32:44 +01:00
										 |  |  |     cxx11: [ | 
					
						
							| 
									
										
										
										
											2014-09-21 00:53:15 -05:00
										 |  |  |       create(:gcc_4_0), | 
					
						
							|  |  |  |       create(:gcc), | 
					
						
							|  |  |  |       create(:clang) { build 425 }, | 
					
						
							| 
									
										
										
										
											2016-09-17 15:32:44 +01:00
										 |  |  |       create(gcc: "4.3"), | 
					
						
							|  |  |  |       create(gcc: "4.4"), | 
					
						
							|  |  |  |       create(gcc: "4.5"), | 
					
						
							|  |  |  |       create(gcc: "4.6"), | 
					
						
							| 
									
										
										
										
											2014-08-01 20:15:58 -05:00
										 |  |  |     ], | 
					
						
							| 
									
										
										
										
											2016-09-17 15:32:44 +01:00
										 |  |  |     openmp: [ | 
					
						
							| 
									
										
										
										
											2015-04-21 17:51:55 -04:00
										 |  |  |       create(:clang), | 
					
						
							| 
									
										
										
										
											2015-12-30 21:14:01 +00:00
										 |  |  |     ], | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |   }.freeze | 
					
						
							| 
									
										
										
										
											2012-03-18 13:58:13 -05:00
										 |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-18 15:50:54 -05:00
										 |  |  | class CompilerSelector | 
					
						
							|  |  |  |   include CompilerConstants | 
					
						
							| 
									
										
										
										
											2012-03-18 13:58:13 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-18 15:50:54 -05:00
										 |  |  |   Compiler = Struct.new(:name, :version) | 
					
						
							| 
									
										
										
										
											2013-03-13 02:07:01 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-18 15:50:54 -05:00
										 |  |  |   COMPILER_PRIORITY = { | 
					
						
							| 
									
										
										
										
											2016-09-24 23:56:54 -04:00
										 |  |  |     clang: [:clang, :gcc, :gnu, :gcc_4_0, :llvm_clang], | 
					
						
							| 
									
										
										
										
											2016-09-17 15:32:44 +01:00
										 |  |  |     gcc: [:gcc, :gnu, :clang, :gcc_4_0], | 
					
						
							|  |  |  |     gcc_4_0: [:gcc_4_0, :gcc, :gnu, :clang], | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |   }.freeze | 
					
						
							| 
									
										
										
										
											2012-03-18 13:58:13 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def self.select_for(formula, compilers = self.compilers) | 
					
						
							| 
									
										
										
										
											2016-04-25 18:01:03 +01:00
										 |  |  |     new(formula, DevelopmentTools, compilers).compiler | 
					
						
							| 
									
										
										
										
											2013-03-13 02:07:01 -05:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2014-09-18 15:50:54 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-18 15:50:54 -05:00
										 |  |  |   def self.compilers | 
					
						
							| 
									
										
										
										
											2016-04-25 18:01:03 +01:00
										 |  |  |     COMPILER_PRIORITY.fetch(DevelopmentTools.default_compiler) | 
					
						
							| 
									
										
										
										
											2014-09-18 15:50:54 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-18 15:50:54 -05:00
										 |  |  |   attr_reader :formula, :failures, :versions, :compilers | 
					
						
							| 
									
										
										
										
											2014-09-18 15:50:54 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-18 15:50:54 -05:00
										 |  |  |   def initialize(formula, versions, compilers) | 
					
						
							| 
									
										
										
										
											2014-09-18 15:50:54 -05:00
										 |  |  |     @formula = formula | 
					
						
							|  |  |  |     @failures = formula.compiler_failures | 
					
						
							| 
									
										
										
										
											2014-06-11 21:05:31 -05:00
										 |  |  |     @versions = versions | 
					
						
							| 
									
										
										
										
											2014-09-18 15:50:54 -05:00
										 |  |  |     @compilers = compilers | 
					
						
							| 
									
										
										
										
											2012-03-18 13:58:13 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-13 02:07:01 -05:00
										 |  |  |   def compiler | 
					
						
							| 
									
										
										
										
											2014-09-18 15:50:54 -05:00
										 |  |  |     find_compiler { |c| return c.name unless fails_with?(c) } | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |     raise CompilerSelectionError, formula | 
					
						
							| 
									
										
										
										
											2013-03-13 02:07:01 -05:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2012-03-18 13:58:13 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-13 02:07:01 -05:00
										 |  |  |   private | 
					
						
							| 
									
										
										
										
											2012-03-18 13:58:13 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-18 15:50:54 -05:00
										 |  |  |   def find_compiler | 
					
						
							|  |  |  |     compilers.each do |compiler| | 
					
						
							|  |  |  |       case compiler | 
					
						
							|  |  |  |       when :gnu | 
					
						
							|  |  |  |         GNU_GCC_VERSIONS.reverse_each do |v| | 
					
						
							| 
									
										
										
										
											2015-05-07 01:12:24 -07:00
										 |  |  |           name = "gcc-#{v}" | 
					
						
							| 
									
										
										
										
											2015-05-17 19:18:32 -04:00
										 |  |  |           version = compiler_version(name) | 
					
						
							| 
									
										
										
										
											2016-11-08 13:25:44 -08:00
										 |  |  |           yield Compiler.new(name, version) unless version.null? | 
					
						
							| 
									
										
										
										
											2014-09-18 15:50:54 -05:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2016-05-22 09:40:08 +01:00
										 |  |  |       when :llvm | 
					
						
							| 
									
										
										
										
											2016-11-13 23:37:51 +01:00
										 |  |  |         next # no-op. DSL supported, compiler is not. | 
					
						
							| 
									
										
										
										
											2014-09-18 15:50:54 -05:00
										 |  |  |       else | 
					
						
							| 
									
										
										
										
											2015-05-17 19:18:32 -04:00
										 |  |  |         version = compiler_version(compiler) | 
					
						
							| 
									
										
										
										
											2016-11-08 13:25:44 -08:00
										 |  |  |         yield Compiler.new(compiler, version) unless version.null? | 
					
						
							| 
									
										
										
										
											2014-09-18 15:50:54 -05:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-18 15:50:54 -05:00
										 |  |  |   def fails_with?(compiler) | 
					
						
							| 
									
										
										
										
											2016-09-24 18:59:44 +02:00
										 |  |  |     failures.any? { |failure| failure.fails_with?(compiler) } | 
					
						
							| 
									
										
										
										
											2014-09-18 15:50:54 -05:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2015-05-17 19:18:32 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   def compiler_version(name) | 
					
						
							|  |  |  |     case name | 
					
						
							|  |  |  |     when GNU_GCC_REGEXP | 
					
						
							|  |  |  |       versions.non_apple_gcc_version(name) | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       versions.send("#{name}_build_version") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2012-03-18 13:58:13 -05:00
										 |  |  | end |