Skip to content

Commit

Permalink
Implement proof of concept
Browse files Browse the repository at this point in the history
  • Loading branch information
lloeki committed Oct 13, 2020
0 parents commit 8b7154a
Show file tree
Hide file tree
Showing 19 changed files with 333 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/pkg
/src
/vendor
/Gemfile.lock
*.gem
/Makefile
Empty file added CHANGELOG.md
Empty file.
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source "https://rubygems.org"

# Specify your gem's dependencies in libv8.gemspec
gemspec
Empty file added LICENSE
Empty file.
Empty file added README.md
Empty file.
48 changes: 48 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
require 'bundler/setup'

Bundler::GemHelper.install_tasks

module Helpers
module_function

def binary_gemspec(platform = Gem::Platform.local)
gemspec = eval(File.read('libv8-node.gemspec'))
gemspec.platform = platform
gemspec
end

def binary_gem_name(platform = Gem::Platform.local)
File.basename(binary_gemspec(platform).cache_file)
end
end

task :compile do
#sh 'ruby ext/libv8-node/extconf.rb'
end

task :binary => :compile do
gemspec = Helpers.binary_gemspec
gemspec.extensions.clear

# We don't need most things for the binary
gemspec.files = []
gemspec.files += ['lib/libv8-node.rb', 'lib/libv8_node.rb', 'lib/libv8_node/version.rb']
gemspec.files += ['ext/libv8-node/location.rb', 'ext/libv8-node/paths.rb']
gemspec.files += ['ext/libv8-node/.location.yml']

# V8
gemspec.files += Dir['vendor/v8/include/**/*.h']
gemspec.files += Dir['vendor/v8/out.gn/**/*.a']

FileUtils.chmod(0o0644, gemspec.files)
FileUtils.mkdir_p('pkg')

package = if Gem::VERSION < '2.0.0'
Gem::Builder.new(gemspec).build
else
require 'rubygems/package'
Gem::Package.build(gemspec)
end

FileUtils.mv(package, 'pkg')
end
21 changes: 21 additions & 0 deletions build-libv8
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/sh

set -e
set -u

version="${1}"

cd "src/node-${version}"

# taken from
# ./configure
# make
# make -C out BUILDTYPE=Release V=1

python configure.py --openssl-no-asm --without-npm
make BUILDTYPE=Release out/Makefile
make -C out BUILDTYPE=Release V=1 v8
make -C out BUILDTYPE=Release V=1 v8_libbase
make -C out BUILDTYPE=Release V=1 v8_libplatform
make -C out BUILDTYPE=Release V=1 v8_libsampler

43 changes: 43 additions & 0 deletions build-monolith
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/bin/sh

set -e
set -u

version="${1}"

cd "src/node-${version}"

BASEDIR="${PWD}"
BUILDTYPE="${BUILDTYPE:-Release}"
LIBV8_MONOLITH="libv8_monolith.a"

cd "out/${BUILDTYPE}/obj.target"

platform=$(uname)

rm -vf "${LIBV8_MONOLITH}"
case "${platform}" in
"SunOS")
/usr/xpg4/bin/find . -path "**/v8*/**/*.o" | xargs ar cqs "${LIBV8_MONOLITH}"
/usr/xpg4/bin/find . -path "**/icu*/**/*.o" | xargs ar cqs "${LIBV8_MONOLITH}"
;;
"Darwin")
#/usr/bin/find . -path "**/v8*/**/*.o" | xargs ar -q "${LIBV8_MONOLITH}"
#/usr/bin/find . -path "**/icu*/**/*.o" | xargs ar -q "${LIBV8_MONOLITH}"
/usr/bin/find . -path "**/v8*/**/*.o" -or -path "**/icu*/**/*.o" | sort | uniq | xargs ar -q "${LIBV8_MONOLITH}"
;;
"Linux")
find . -path './deps/v8/gypfiles/*.a' | while read -r lib; do
ar -t "${lib}" | xargs ar -q "${LIBV8_MONOLITH}"
done
find . -path './tools/icu/*.a' | while read -r lib; do
ar -t "${lib}" | xargs ar -q "${LIBV8_MONOLITH}"
done
;;
*)
echo "Unsupported platform: ${platform}"
exit 1
;;
esac

mv -vf "${LIBV8_MONOLITH}" "${BASEDIR}/out/${BUILDTYPE}/${LIBV8_MONOLITH}"
10 changes: 10 additions & 0 deletions download-node
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh

set -e
set -u

version="${1}"

mkdir -p src

curl -L -o "src/node-${version}.tar.gz" "https://github.com/nodejs/node/archive/v${version}.tar.gz"
2 changes: 2 additions & 0 deletions ext/libv8-node/.location.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--- !ruby/object:Libv8Node::Location::Vendor {}

8 changes: 8 additions & 0 deletions ext/libv8-node/extconf.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
require 'mkmf'
create_makefile('libv8-node')

#require File.expand_path('../location', __FILE__)
#location = Libv8Node::Location::Vendor.new

#exit location.install!
exit 0
89 changes: 89 additions & 0 deletions ext/libv8-node/location.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
require 'yaml'
require 'pathname'
require File.expand_path '../paths', __FILE__

module Libv8Node
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 = Libv8Node::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, Libv8Node::Paths.include_paths.map{ |p| "-I#{p}" }.join(" ") + " "
context.ldflags.insert 0, Libv8Node::Paths.object_paths.join(" ") + " "
end

def verify_installation!
include_paths = Libv8Node::Paths.include_paths
unless include_paths.detect { |p| Pathname(p).join('v8.h').exist? }
fail HeaderNotFound, "Unable to locate 'v8.h' in the libv8 header paths: #{include_paths.inspect}"
end
Libv8Node::Paths.object_paths.each do |p|
fail ArchiveNotFound, p unless File.exist? p
end
end

class HeaderNotFound < StandardError; 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.send(:dir_config, 'v8')
context.send(:find_header, 'v8.h') or fail NotFoundError
context.send(:find_header, 'libplatform/libplatform.h') or fail NotFoundError
context.send(:have_library, 'v8') or fail NotFoundError
end

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

class MkmfContext
def incflags
$INCFLAGS
end

def ldflags
$LDFLAGS
end
end
end
end
28 changes: 28 additions & 0 deletions ext/libv8-node/paths.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
require 'rbconfig'
require 'shellwords'

module Libv8Node
module Paths
module_function

def include_paths
[Shellwords.escape(File.join(vendored_source_path, 'include'))]
end

def object_paths
[Shellwords.escape(File.join(vendored_source_path,
'out.gn',
'libv8',
'obj',
"libv8_monolith.#{config['LIBEXT']}"))]
end

def config
RbConfig::MAKEFILE_CONFIG
end

def vendored_source_path
File.expand_path "../../../vendor/v8", __FILE__
end
end
end
8 changes: 8 additions & 0 deletions extract-node
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh

set -e
set -u

version="${1}"

tar -C src -xz -f "src/node-${version}.tar.gz"
29 changes: 29 additions & 0 deletions inject-libv8
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/sh

set -e
set -u

version="${1}"
top="${PWD}"

cd "src/node-${version}"

BASEDIR="${PWD}"
BUILDTYPE="${BUILDTYPE:-Release}"

cd "${BASEDIR}/deps/v8/include"

find . -name '*.h' | while read -r header; do
dir="${top}/vendor/v8/include/$(dirname "${header}")"
mkdir -p "${dir}"
cp "${header}" "${dir}"
done

cd "${BASEDIR}/out/${BUILDTYPE}"

for lib in libv8_libbase.a libv8_libplatform.a libv8_monolith.a; do
dir="${top}/vendor/v8/out.gn/libv8/obj/$(dirname "${lib}")"
mkdir -p "${dir}"
rm -fv "${dir}/${lib}"
strip -S -x -o "${dir}/${lib}" "${lib}"
done
1 change: 1 addition & 0 deletions lib/libv8-node.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require 'libv8_node'
10 changes: 10 additions & 0 deletions lib/libv8_node.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require 'libv8_node/version'
require 'libv8-node/location'

module Libv8Node
def self.configure_makefile
location = Location.load!
location.configure
end
end

5 changes: 5 additions & 0 deletions lib/libv8_node/version.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module Libv8Node
VERSION = "12.18.4.0.beta1"
NODE_VERSION = "12.18.4"
LIBV8_VERSION = "7.8.279.23" # v8/include/v8-version.h
end
21 changes: 21 additions & 0 deletions libv8-node.gemspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
require 'libv8_node/version'

Gem::Specification.new do |s|
s.name = 'libv8-node'
s.version = Libv8Node::VERSION
s.platform = Gem::Platform::RUBY
s.authors = ['']
s.email = ['']
s.homepage = 'https://github.com/sqreen/libv8-node'
s.summary = "Node.JS's V8 JavaScript engine"
s.description = "Node.JS's V8 JavaScript engine for multiplatform goodness"
s.license = 'MIT'

s.files = `git ls-files`.split("\n")

s.extensions = ['ext/libv8-node/extconf.rb']
s.require_paths = ['lib', 'ext']

s.add_development_dependency 'rake', '~> 12'
end

0 comments on commit 8b7154a

Please sign in to comment.