Skip to content

Commit

Permalink
delegate makefile configuration to v8
Browse files Browse the repository at this point in the history
therubyracer now delegates all lookup for its v8
compilation dependencies to the libv8 gem.

if you pass the --with-system-v8 flag to the libv8
gem on install, try to configure therubyracer upon
compile with the following options.

--with-v8-include, --with-v8-lib and --with-v8-dir

Otherwise, it will configure therubyracer to use
its own vendored version of v8.
  • Loading branch information
cowboyd committed Jan 4, 2013
1 parent d58d5e4 commit 6e2a278
Show file tree
Hide file tree
Showing 12 changed files with 209 additions and 95 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ pkg/*
tmp/*
lib/libv8/build/*
lib/libv8/VERSION
/ext/libv8/.location.yml
5 changes: 4 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ task :binary => :compile do
gemspec = get_binary_gemspec
gemspec.extensions.clear
# We don't need most things for the binary
gemspec.files = ['lib/libv8.rb', 'ext/libv8/arch.rb', 'lib/libv8/version.rb']
gemspec.files = []
gemspec.files += ['lib/libv8.rb', 'lib/libv8/version.rb']
gemspec.files += ['ext/libv8/arch.rb', 'ext/libv8/location.rb', 'ext/libv8/paths.rb']
gemspec.files += ['ext/libv8/.location.yml']
# V8
gemspec.files += Dir['vendor/v8/include/*']
gemspec.files += Dir['vendor/v8/out/**/*.a']
Expand Down
20 changes: 20 additions & 0 deletions ext/libv8/builder.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
require 'libv8/compiler'
require 'libv8/arch'
require 'libv8/make'

module Libv8
class Builder
include Libv8::Arch
include Libv8::Compiler
include Libv8::Make

def build_libv8!
profile = enable_config('debug') ? 'debug' : 'release'

Dir.chdir(File.expand_path '../../../vendor/v8', __FILE__) do
puts `env CXX=#{compiler} LINK=#{compiler} #{make} #{libv8_arch}.#{profile} GYPFLAGS="-Dhost_arch=#{libv8_arch}"`
end
return $?.exitstatus
end
end
end
15 changes: 3 additions & 12 deletions ext/libv8/extconf.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@
require 'mkmf'
create_makefile('libv8')
require File.expand_path '../arch.rb', __FILE__
require File.expand_path '../make.rb', __FILE__
require File.expand_path '../compiler.rb', __FILE__

include Libv8::Arch
include Libv8::Make
include Libv8::Compiler
require File.expand_path '../location', __FILE__
location = with_config('system-v8') ? Libv8::Location::System.new : Libv8::Location::Vendor.new

profile = enable_config('debug') ? 'debug' : 'release'

Dir.chdir(File.expand_path '../../../vendor/v8', __FILE__) do
puts `env CXX=#{compiler} LINK=#{compiler} #{make} #{libv8_arch}.#{profile} GYPFLAGS="-Dhost_arch=#{libv8_arch}"`
end
exit $?.exitstatus
exit location.install!
81 changes: 81 additions & 0 deletions ext/libv8/location.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
require 'yaml'
require 'pathname'
require File.expand_path '../paths', __FILE__

module Libv8
class Location
def install!
File.open(Pathname(__FILE__).dirname.join('.location.yml'), "w") do |f|
f.write self.to_yaml
end
return 0
end

def self.load!
File.open(Pathname(__FILE__).dirname.join('.location.yml')) do |f|
YAML.load f
end
end

class Vendor < Location
def install!
require File.expand_path '../builder', __FILE__
builder = Libv8::Builder.new
exit_status = builder.build_libv8!
super if exit_status == 0
verify_installation!
return exit_status
end
def configure(context = MkmfContext.new)
context.incflags.insert 0, Libv8::Paths.include_paths.map{|p| "-I#{p}"}.join(" ") + " "
context.ldflags.insert 0, Libv8::Paths.object_paths.join(" ") + " "
end

def verify_installation!
Libv8::Paths.object_paths.each do |p|
fail ArchiveNotFound, p unless File.exists? p
end
end

class ArchiveNotFound < StandardError
def initialize(filename)
super "libv8 did not install properly, expected binary v8 archive '#{filename}'to exist, but it was not found"
end
end
end

class System < Location
def configure(context = MkmfContext.new)
context.dir_config('v8')
context.find_header('v8.h') or fail NotFoundError
end

class NotFoundError < StandardError
def initialize(*args)
super(<<-EOS)
You have chosen to use the version of V8 found on your system
and *not* the one that is bundle with the libv8 rubygem. However,
it could not be located. please make sure you have a version of
v8 that is compatible with #{Libv8::VERSION} installed. You may
need to special --with-v8-dir options if it is in a non-standard
location
thanks,
The Mgmt
EOS
end
end
end

class MkmfContext
def incflags
$INCFLAGS
end

def ldflags
$LDFLAGS
end
end
end
end
38 changes: 38 additions & 0 deletions ext/libv8/paths.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
require 'rbconfig'
require File.expand_path '../arch', __FILE__

module Libv8
module Paths
module_function

def include_paths
["#{vendored_source_path}/include"]
end

def object_paths
[libv8_object(:base), libv8_object(:snapshot)]
end

def config
RbConfig::MAKEFILE_CONFIG
end

def libv8_object(name)
filename = "#{libv8_profile}/libv8_#{name}.#{config['LIBEXT']}"
unless File.exists? filename
filename = "#{libv8_profile}/obj.target/tools/gyp/libv8_#{name}.#{config['LIBEXT']}"
end
return filename
end

def libv8_profile
base = "#{vendored_source_path}/out/#{Libv8::Arch.libv8_arch}"
debug = "#{base}.debug"
File.exists?(debug) ? debug : "#{base}.release"
end

def vendored_source_path
File.expand_path "../../../vendor/v8", __FILE__
end
end
end
62 changes: 5 additions & 57 deletions lib/libv8.rb
Original file line number Diff line number Diff line change
@@ -1,61 +1,9 @@
require 'rbconfig'
require 'libv8/version'
require 'libv8/location'

require 'libv8/arch'
module Libv8

module_function

def config
Config::MAKEFILE_CONFIG
end

def libv8_object(name)
filename = "#{libv8_profile}/libv8_#{name}.#{config['LIBEXT']}"
unless File.exists? filename
filename = "#{libv8_profile}/obj.target/tools/gyp/libv8_#{name}.#{config['LIBEXT']}"
end
return filename
end

def libv8_profile
base = "#{libv8_source_path}/out/#{Libv8::Arch.libv8_arch}"
debug = "#{base}.debug"
File.exists?(debug) ? debug : "#{base}.release"
end

def libv8_base
libv8_object :base
end

def libv8_snapshot
libv8_object :snapshot
end

def libv8_nosnapshot
libv8_object :nosnapshot
end

def libv8_objects(*names)
names = [:base, :snapshot] if names.empty?
names.map do |name|
fail "no libv8 object #{name}" unless File.exists?(object = libv8_object(name))
object
end
end

def libv8_ldflags
"-L#{libv8_base} -L#{libv8_snapshot}"
end

def libv8_include_flags
"-I#{libv8_include_path}"
end

def libv8_include_path
"#{libv8_source_path}/include"
end

def libv8_source_path
File.expand_path "../../vendor/v8", __FILE__
def self.configure_makefile
location = Location.load!
location.configure
end
end
2 changes: 1 addition & 1 deletion lib/libv8/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Libv8
VERSION = "3.11.8.3"
VERSION = "3.11.8.5"
end
3 changes: 2 additions & 1 deletion libv8.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ Gem::Specification.new do |s|
s.extensions = ["ext/libv8/extconf.rb"]
s.require_paths = ["lib", "ext"]

s.add_development_dependency "rake", "~> 0.9.2"
s.add_development_dependency "rake"
s.add_development_dependency "rake-compiler"
s.add_development_dependency "rspec"
s.add_development_dependency "rspec-spies"
end
22 changes: 0 additions & 22 deletions spec/libv8_spec.rb

This file was deleted.

51 changes: 51 additions & 0 deletions spec/location_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
require 'spec_helper'

describe "libv8 locations" do
before do
@context = mock(:CompilationContext)
end
describe "the system location" do
before do
@location = Libv8::Location::System.new
@context.stub(:dir_config)
end
describe "configuring a compliation context with it" do
before do
@context.stub(:find_header) {true}
@location.configure @context
end
it "adds the include path to the front of the include flags" do
@context.should have_received(:dir_config).with 'v8'
@context.should have_received(:find_header).with 'v8.h'
end
end
describe "when the v8.h header cannot be found" do
before do
@context.stub(:find_header) {false}
end
it "raises a NotFoundError" do
expect {@location.configure @context}.to raise_error Libv8::Location::System::NotFoundError
end
end
end

describe "the vendor location" do
before do
@location = Libv8::Location::Vendor.new
@context.stub(:incflags) {@incflags ||= "-I/usr/include -I/usr/local/include"}
@context.stub(:ldflags) {@ldflags ||= "-lobjc -lpthread"}

Libv8::Paths.stub(:include_paths) {["/frp/v8/include"]}
Libv8::Paths.stub(:object_paths) {["/frp/v8/obj/libv8_base.a", "/frp/v8/obj/libv8_snapshot.a"]}
@location.configure @context
end

it "prepends its own incflags before any pre-existing ones" do
@context.incflags.should eql "-I/frp/v8/include -I/usr/include -I/usr/local/include"
end

it "prepends the locations of any libv8 objects on the the ldflags" do
@context.ldflags.should eql "/frp/v8/obj/libv8_base.a /frp/v8/obj/libv8_snapshot.a -lobjc -lpthread"
end
end
end
4 changes: 3 additions & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
$:.unshift File.expand_path '../../lib', __FILE__
require 'libv8'
require 'rspec'
require 'rspec-spies'
require 'libv8'

0 comments on commit 6e2a278

Please sign in to comment.