2013-03-13 02:07:01 -05:00
|
|
|
class Compiler < Struct.new(:name, :priority)
|
|
|
|
def build
|
2013-04-01 13:23:09 -05:00
|
|
|
MacOS.send("#{name}_build_version")
|
2012-03-18 13:58:13 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class CompilerFailure
|
|
|
|
attr_reader :compiler
|
|
|
|
|
|
|
|
def initialize compiler, &block
|
|
|
|
@compiler = compiler
|
|
|
|
instance_eval(&block) if block_given?
|
2013-03-11 22:54:15 -05:00
|
|
|
@build ||= 9999
|
2012-03-18 13:58:13 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def build val=nil
|
|
|
|
val.nil? ? @build.to_i : @build = val.to_i
|
|
|
|
end
|
|
|
|
|
|
|
|
def cause val=nil
|
|
|
|
val.nil? ? @cause : @cause = val
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-03-13 02:07:01 -05:00
|
|
|
class CompilerQueue
|
|
|
|
def initialize
|
|
|
|
@array = []
|
|
|
|
end
|
2012-03-18 13:58:13 -05:00
|
|
|
|
2013-03-13 02:07:01 -05:00
|
|
|
def <<(o)
|
|
|
|
@array << o
|
|
|
|
self
|
|
|
|
end
|
|
|
|
|
|
|
|
def pop
|
|
|
|
@array.delete(@array.max { |a, b| a.priority <=> b.priority })
|
|
|
|
end
|
2012-03-18 13:58:13 -05:00
|
|
|
|
2013-03-13 02:07:01 -05:00
|
|
|
def empty?
|
|
|
|
@array.empty?
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class CompilerSelector
|
2013-04-01 12:56:56 -05:00
|
|
|
def initialize(f, old_compiler)
|
2012-03-18 13:58:13 -05:00
|
|
|
@f = f
|
2013-03-13 02:07:01 -05:00
|
|
|
@old_compiler = old_compiler
|
|
|
|
@compilers = CompilerQueue.new
|
|
|
|
%w{clang llvm gcc}.map(&:to_sym).each do |cc|
|
2013-04-01 13:23:09 -05:00
|
|
|
unless MacOS.send("#{cc}_build_version").nil?
|
|
|
|
@compilers << Compiler.new(cc, priority_for(cc))
|
|
|
|
end
|
2013-03-13 02:07:01 -05:00
|
|
|
end
|
2012-03-18 13:58:13 -05:00
|
|
|
end
|
|
|
|
|
2013-05-20 19:35:07 -05:00
|
|
|
# Attempts to select an appropriate alternate compiler, but
|
|
|
|
# if none can be found raises CompilerError instead
|
2013-03-13 02:07:01 -05:00
|
|
|
def compiler
|
2013-03-13 02:07:01 -05:00
|
|
|
begin
|
|
|
|
cc = @compilers.pop
|
|
|
|
end while @f.fails_with?(cc)
|
2013-05-20 19:35:07 -05:00
|
|
|
|
|
|
|
if cc.nil?
|
|
|
|
raise CompilerSelectionError
|
|
|
|
else
|
|
|
|
cc.name
|
|
|
|
end
|
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
|
|
|
|
2013-03-13 02:07:01 -05:00
|
|
|
def priority_for(cc)
|
|
|
|
case cc
|
2013-04-01 12:33:42 -05:00
|
|
|
when :clang then MacOS.clang_build_version >= 318 ? 3 : 0.5
|
2013-03-13 02:07:01 -05:00
|
|
|
when :llvm then 2
|
|
|
|
when :gcc then 1
|
2013-04-13 01:07:46 -05:00
|
|
|
when :gcc_4_0 then 0.25
|
2012-03-18 13:58:13 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|