#!/usr/bin/env ruby
require 'tempfile'
root = File.expand_path File.dirname(__FILE__)
require File.join(root, "kernel", "delta", "options")
class Configure
def initialize(root)
@config = File.join(root, "config.rb")
@llvm = :no
@llvm_path = nil
@llvm_configure = nil
@prefix = nil
@defines = []
@llvm_svn_dir = File.join(root, "vm", "external_libs", "llvm")
o = Rubinius::Options.new "Usage: configure [options]", 40
o.on "-h", "--help", "Display this help" do
puts o
exit 1
end
o.on("--enable-llvm", "[MODE]",
"Build with LLVM") do |which|
@llvm = (which || "auto").to_sym
end
o.on "--llvm-path", "PATH", "Where to find LLVM" do |dir|
@llvm_path = dir
end
o.on "--prefix", "PATH", "Where to install Rubinius" do |dir|
@prefix = dir
end
o.on "--update-prebuilt", "Update prebuilt packages from the internet" do
update_prebuilt
end
@options = o
end
def parse(ary)
@options.parse ary
end
def update_prebuilt
file = "llvm-#{arch}.tar.bz2"
full_path = "vm/external_libs/prebuilt/#{file}"
url = "http://asset.rubini.us/prebuilt/#{file}"
unless File.exists?(full_path)
dir = File.dirname(full_path)
Dir.mkdir dir unless File.directory?(dir)
puts "Fetching #{url}..."
system "curl -# -f -o \"#{full_path}\" #{url}"
if $?.exitstatus == 22
puts "ERROR. No #{file} available on server."
end
end
puts "Prebuilt packages updated."
end
LLVM_SVN_DIR = %w!vm external_libs llvm!
LLVM_SVN_URL = "http://llvm.org/svn/llvm-project/llvm/branches/release_26/"
def setup_svn
unless File.directory?(@llvm_svn_dir)
print " Checking out LLVM from svn: #{LLVM_SVN_URL}"
system "svn co -q #{LLVM_SVN_URL} #{@llvm_svn_dir}"
end
if File.exists?(File.join(@llvm_svn_dir, "include"))
puts " Code appears to be proper svn tree."
else
puts " Code in #{@llvm_svn_dir} doesn't appear to be proper LLVM tree!"
exit 1
end
end
def setup_prebuilt
file = "vm/external_libs/prebuilt/llvm-#{arch}.tar.bz2"
update_prebuilt unless File.exists?(file)
if File.exists?(file)
print " Unpacking prebuilt LLVM for #{arch}: "
system "cd vm/external_libs; mkdir llvm; cd llvm; tar xjf ../prebuilt/llvm-#{arch}.tar.bz2"
puts "done!"
@llvm = :prebuilt
return true
end
return false
end
def setup_path
print "Validating '#{@llvm_path}': "
if File.directory? @llvm_path
["Release", "Debug"].each do |which|
sub = File.join(@llvm_path, which, "bin")
if File.directory? sub
puts "Ok! Using #{which}"
@llvm_configure = File.join(@llvm_path, which, "bin", "llvm-config")
@llvm = :config
return true
end
end
puts "ERROR. Doesn't appear to be built already!"
end
puts "ERROR. Path doesn't exist."
return false
end
def setup_auto
print " Checking for existing LLVM tree: "
if File.directory?(@llvm_svn_dir)
puts "found!"
if File.exists?(File.join(@llvm_svn_dir, "Makefile.common"))
@llvm = :svn
else
@llvm = :prebuilt
end
return
else
puts "not found."
end
if @llvm_path
unless setup_path
puts "ABORT: Path '#{@llvm_path}' not a proper LLVM path"
exit 1
end
return
end
return if setup_prebuilt
return if setup_config
@llvm = :svn
setup_svn
end
def setup_config
print " Checking for 'llvm-config': "
which = ENV['PATH'].split(":").find do |path|
File.exists? File.join(path, "llvm-config")
end
if which
config = File.join(which, "llvm-config")
version = `#{config} --version`.strip
parts = version.sub(/svn$/, "").split(".").map { |i| i.to_i }
if parts[0] < 2 or parts[1] < 6
puts "too old of a version"
else
puts "found! (version #{version})"
@llvm_configure = which
@llvm = :config
return true
end
else
puts "not found"
end
false
end
def has_function(name, includes=[])
print "Checking for function '#{name}': "
tf = Tempfile.new("rbx-test")
includes.each do |i|
tf.puts "#include <#{i}>"
end
tf.puts "int main() { void* ptr = &#{name}; }"
tf.close
`#{compiler} -o /dev/null -x c #{tf.path} 2>&1`
status = ($?.exitstatus == 0)
tf.unlink
if status
puts "found!"
else
puts "not found."
end
return status
end
def detect_features
if has_function("backtrace", "execinfo.h")
@defines << "HAS_EXECINFO"
end
end
def process
print "Using LLVM: "
case @llvm
when :svn
puts "svn"
setup_svn
when :auto
puts "auto"
setup_auto
when :config
puts "config"
exit 1 unless setup_config
when :prebuilt
unless setup_prebuilt
puts "No prebuilt LLVM available for #{arch}"
exit 1
end
when :path
puts "existing build"
exit 1 unless setup_path
when :no
puts "no"
else
puts "unknown value '#{@llvm}'"
end
detect_features
end
def arch
@arch ||= `./rakelib/config.guess`.strip
end
def compiler
ENV['CC'] || "gcc"
end
def write_config
File.open @config, "w" do |f|
f.puts "module Rubinius"
f.puts "BUILD_CONFIG = {"
f.puts " :llvm => :#{@llvm},"
f.puts " :llvm_configure => '#{@llvm_configure}',"
f.puts " :arch => '#{arch()}',"
f.puts " :prefix => #{@prefix.inspect},"
f.puts " :compiler => '#{compiler}',"
if @defines.empty?
f.puts " :defines => []"
else
f.puts " :defines => ['#{@defines.join(', ')}']"
end
f.puts "}"
f.puts "end"
end
end
end
STDOUT.sync = true
c = Configure.new(root)
c.parse ARGV
c.process
c.write_config