LoginSignup
16
18

More than 5 years have passed since last update.

Windows用バイナリGemをMacでクロスコンパイルする

Last updated at Posted at 2015-11-05

昨今、Unix環境ではそれぞれのマシンでRubyをビルドし、native gemをビルドするのが一般的になっています。一方、Windowsでは未だにCコンパイラを導入している環境は少数派ですので、バイナリgemの配布が望まれています。しかし、Windows用バイナリgemを2.0.0/2.1/2.2と32bit/64bitで6バージョンビルドするのは誰にとっても負担です。

rake-compiler-dock is awesome

そんな状況を解決するスーパーライフチェンジングなgemがrake-compiler-dockです。詳しくはREADMEの通りですが、Docker Toolboxをインストールした環境でrake-compiler-dockをサポートしたgemをbundle exec rake build:windowsとすると、dockerでビルド用のLinux環境が立ち上がり、しばらく待つとローカルにpkg/-x86-mingw32.gemと-x64-mingw32.gemができあがります。便利!

以下のような変更を行えば導入できますので、是非皆さん導入しましょう。

diff --git a/Rakefile b/Rakefile
index 84443f9..dbfb045 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,4 +1,5 @@
-require "bundler/gem_tasks"
+require "bundler"
+Bundler::GemHelper.install_tasks
 require "rspec/core/rake_task"

 RSpec::Core::RakeTask.new(:spec)
@@ -9,6 +10,19 @@ require "rake/extensiontask"
 task :build => :compile
 task :spec => :compile

-Rake::ExtensionTask.new("strptime") do |ext|
-  ext.lib_dir = "lib/strptime"
+spec = eval File.read("strptime.gemspec")
+Rake::ExtensionTask.new("strptime", spec) do |ext|
+  ext.ext_dir = 'ext/strptime'
+  ext.cross_compile = true
+  ext.lib_dir = File.join(*['lib', 'strptime', ENV['FAT_DIR']].compact)
+  # cross_platform names are of MRI's platform name
+  ext.cross_platform = ['x86-mingw32', 'x64-mingw32']
+end
+
+namespace :build do
+  desc 'Build gems for Windows per rake-compiler-dock'
+  task :windows do
+    require 'rake_compiler_dock'
+    RakeCompilerDock.sh 'bundle && rake cross native gem RUBY_CC_VERSION=2.0.0:2.1.6:2.2.2'
+  end
 end
diff --git a/lib/strptime.rb b/lib/strptime.rb
index 049d0c1..c18c7e2 100644
--- a/lib/strptime.rb
+++ b/lib/strptime.rb
@@ -1,5 +1,9 @@
 require "strptime/version"
-require "strptime/strptime"
+begin
+  require "strptime/#{RUBY_VERSION[/\d+\.\d+/]}/strptime"
+rescue LoadError
+  require "strptime/strptime"
+end

 class Strptime
   # Your code goes here...
diff --git a/strptime.gemspec b/strptime.gemspec
index df30440..7b0a8e4 100644
--- a/strptime.gemspec
+++ b/strptime.gemspec
@@ -23,6 +23,6 @@ Gem::Specification.new do |spec|

   spec.add_development_dependency "bundler"
   spec.add_development_dependency "rake"
   spec.add_development_dependency "rake-compiler"
+  spec.add_development_dependency 'rake-compiler-dock'
   spec.add_development_dependency "rspec"
diff --git a/README.md b/README.md
index 29185fa..c5b8da5 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,8 @@
 # Strptime

 [![Build Status](https://travis-ci.org/nurse/strptime.png)](https://travis-ci.org/nurse/strptime)
+[![Build status](https://ci.appveyor.com/api/projects/status/9wr116l8uy1bdcxf/branch/master?svg=true)](https://ci.appveyor.com/project/nurse/strptime/branch/master)
+

 Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/strptime`. To experiment with that code, run `bin/console` for an interactive prompt.

diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000..d848da2
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,16 @@
+---
+install:
+  - SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
+  - ruby --version
+  - gem --version
+  - bundle install
+build_script:
+  - bundle exec rake -rdevkit
+environment:
+  matrix:
+    - ruby_version: "200"
+    - ruby_version: "200-x64"
+    - ruby_version: "21"
+    - ruby_version: "21-x64"
+    - ruby_version: "22"
+    - ruby_version: "22-x64"

なお、ついでにAppVeyorの設定もの設定も載せているのでご活用ください。

16
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
18