From 47b3ca909b4218c87e287df04697737f2eaef755 Mon Sep 17 00:00:00 2001 From: Jarred Holman Date: Sat, 4 Apr 2015 17:17:38 +1030 Subject: [PATCH] Added support for windows platforms using mingw. --- ext/libv8/builder.rb | 22 +++++-- ext/libv8/checkout.rb | 8 ++- ext/libv8/patcher.rb | 1 + patches/mingw-generate-makefiles.sh | 97 +++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+), 6 deletions(-) create mode 100644 patches/mingw-generate-makefiles.sh diff --git a/ext/libv8/builder.rb b/ext/libv8/builder.rb index cdb6275..572cc61 100755 --- a/ext/libv8/builder.rb +++ b/ext/libv8/builder.rb @@ -16,6 +16,10 @@ module Libv8 @compiler = choose_compiler end + def make_target + "#{libv8_arch}.#{profile}" + end + def make_flags(*flags) profile = enable_config('debug') ? 'debug' : 'release' @@ -42,7 +46,7 @@ module Libv8 # with it on flags << 'werror=no' - "#{libv8_arch}.#{profile} #{flags.join ' '}" + "#{make_target} #{flags.join ' '}" end def build_libv8! @@ -53,7 +57,17 @@ module Libv8 setup_build_deps! patch! *patch_directories_for(@compiler) print_build_info - puts `env CXX=#{@compiler} LINK=#{@compiler} #{make} #{make_flags}` + + case RUBY_PLATFORM + when /mingw/ + # use a script that will fix the paths in the generated Makefiles + # don't use make_flags otherwise it will trigger a rebuild of the Makefiles + `env CXX=#{@compiler} LINK=#{@compiler} bash #{PATCH_DIRECTORY}/mingw-generate-makefiles.sh` + puts `env CXX=#{@compiler} LINK=#{@compiler} make #{make_target}` + + else + puts `env CXX=#{@compiler} LINK=#{@compiler} #{make} #{make_flags}` + end end return $?.exitstatus end @@ -96,8 +110,8 @@ module Libv8 end def python_version - if system 'which python 2>&1 > /dev/null' - `python -c 'import platform; print(platform.python_version())'`.chomp + if `which python` =~ /python/ + `python -c "import platform; print(platform.python_version())"`.chomp else "not available" end diff --git a/ext/libv8/checkout.rb b/ext/libv8/checkout.rb index 25ab62e..4ddd340 100644 --- a/ext/libv8/checkout.rb +++ b/ext/libv8/checkout.rb @@ -15,7 +15,7 @@ module Libv8 Dir.chdir(V8_Source) do `git fetch` - `git checkout #{Libv8::VERSION.gsub(/\.\d+$/,'')} -f` + `git checkout #{Libv8::VERSION.gsub(/\.\d+(\.rc\d+)?$/,'')} -f` `rm -f .applied_patches` end @@ -31,7 +31,8 @@ module Libv8 # --git-dir is needed for older versions of git and git-svn `git --git-dir=../../.git/modules/vendor/gyp/ svn init #{GYP_SVN} -Ttrunk` `git config --replace-all svn-remote.svn.fetch trunk:refs/remotes/origin/master` - `git checkout $(git --git-dir=../../.git/modules/vendor/gyp/ svn find-rev r#{rev} | tail -n 1) -f` + svn_rev = `git --git-dir=../../.git/modules/vendor/gyp/ svn find-rev r#{rev} | tail -n 1` + `git checkout #{svn_rev} -f` end end @@ -40,6 +41,9 @@ module Libv8 end def check_git_svn! + # msysgit provides git svn + return if RUBY_PLATFORM =~ /mingw/ + unless system 'git help svn 2>&1 > /dev/null' fail "git-svn not installed!\nPlease install git-svn." end diff --git a/ext/libv8/patcher.rb b/ext/libv8/patcher.rb index fee1c3e..6f555d8 100644 --- a/ext/libv8/patcher.rb +++ b/ext/libv8/patcher.rb @@ -47,6 +47,7 @@ module Libv8 (available_patches - applied_patches).each do |patch| `patch -p1 -N < #{patch}` + fail 'failed to apply patch' unless $?.success? f.puts patch end end diff --git a/patches/mingw-generate-makefiles.sh b/patches/mingw-generate-makefiles.sh new file mode 100644 index 0000000..38baa0a --- /dev/null +++ b/patches/mingw-generate-makefiles.sh @@ -0,0 +1,97 @@ +#!/bin/sh +# Copyright 2013 the V8 project authors. All rights reserved. +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Monkey-patch GYP. +cat > build/gyp/gyp.mingw << EOF +#!/usr/bin/env python + +# Copyright (c) 2009 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import sys + +# TODO(mark): sys.path manipulation is some temporary testing stuff. +try: + import gyp +except ImportError, e: + import os.path + sys.path.append(os.path.join(os.path.dirname(sys.argv[0]), 'pylib')) + import gyp + +def MonkeyBuildFileTargets(target_list, build_file): + """From a target_list, returns the subset from the specified build_file. + """ + build_file = build_file.replace('/', '\\\\') + return [p for p in target_list if gyp.common.BuildFile(p) == build_file] +gyp.common.BuildFileTargets = MonkeyBuildFileTargets + +import gyp.generator.make +import os +def Monkey_ITIP(self): + """Returns the location of the final output for an installable target.""" + sep = os.path.sep + # Xcode puts shared_library results into PRODUCT_DIR, and some gyp files + # rely on this. Emulate this behavior for mac. + if (self.type == 'shared_library' and + (self.flavor != 'mac' or self.toolset != 'target')): + # Install all shared libs into a common directory (per toolset) for + # convenient access with LD_LIBRARY_PATH. + return '\$(builddir)%slib.%s%s%s' % (sep, self.toolset, sep, self.alias) + return '\$(builddir)' + sep + self.alias +gyp.generator.make.MakefileWriter._InstallableTargetInstallPath = Monkey_ITIP + +if __name__ == '__main__': + sys.exit(gyp.main(sys.argv[1:])) +EOF + +# Delete old generated Makefiles. +find out -name '*.mk' -or -name 'Makefile*' -exec rm {} \; + +# Generate fresh Makefiles. +mv build/gyp/gyp build/gyp/gyp.original +mv build/gyp/gyp.mingw build/gyp/gyp +make out/Makefile.ia32 out/Makefile.x64 +mv build/gyp/gyp build/gyp/gyp.mingw +mv build/gyp/gyp.original build/gyp/gyp + +# Patch generated Makefiles: replace most backslashes with forward slashes, +# fix library names in linker flags. +FILES=$(find out -name '*.mk' -or -name 'Makefile*') +for F in $FILES ; do + echo "Patching $F..." + cp $F $F.orig + cat $F.orig \ + | sed -e 's|\([)a-zA-Z0-9]\)\\\([a-zA-Z]\)|\1/\2|g' \ + -e 's|\([)a-zA-Z0-9]\)\\\\\([a-zA-Z]\)|\1/\2|g' \ + -e 's|'%s/n'|'%s\\\\n'|g' \ + -e 's|-lwinmm\.lib|-lwinmm|g' \ + -e 's|-lws2_32\.lib|-lws2_32|g' \ + > $F + rm $F.orig +done