README.rdoc in rake-compiler-0.7.5 vs README.rdoc in rake-compiler-0.7.6

- old
+ new

@@ -1,140 +1,158 @@ -= rake-compiler += What is rake-compiler? -rake-compiler aims to help Gem developers deal with Ruby extensions, simplifying -code and reducing duplication. +rake-compiler is first and foremost a productivity tool for Ruby developers. +It's goal is to make the busy developer's life easier by simplifying the building +and packaging of Ruby extensions by simplifying code and reducing duplication. -It followss *convention over configuration* and sets a standardized structure to -build and package both C and Java extensions in your gems. +It follows *convention over configuration* by advocating a standardized build and +package structure for both C and Java based RubyGems. -This is the result of experiences dealing with several Gems that required native -extensions across platforms and different user configurations where details like -portability and clarity of code were lacking. +rake-compiler is the result of many hard-won experiences dealing with several +diverse RubyGems that provided native extensions for different platforms and +different user configurations in different ways. Details such as differences in +code portability, differences in code clarity, and differences in project directory +structure often made it very difficult for newcomers to those RubyGems. -== An Overview +From these challenges, rake-compiler was born with the single-minded goal of +making the busy RubyGem developer's life much less difficult. -Let's summarize what rake-compiler provides: +== Feature Overview +Some of the benefits rake-compiler provides include: + * No custom rake tasks required. Less code duplication and errors. * Painlessly build extensions on different platforms (Linux, OSX and Windows). * Painlessly build extensions for different Ruby implementations (JRuby, Rubinius and MRI). -* Allow multiple extensions be compiled inside the same gem. +* Allow multiple extensions to be compiled inside the same gem. -* Mimics RubyGems installation process, so helps as a test environment. +* Painlessly build "fat" native gems for Windows users (from Linux or OSX). -* Simplify cross platform compilation of extensions (target Windows from Linux). +* Mimics RubyGems standard installation process, helping as a test environment. -== I'm sold! show me how to use it! (Installation) +* Simplifies cross platform extension compilation (targeting Windows from Linux). -Usage of rake-compiler is pretty much straight forward. +== OK, I'm sold! Show me how to install it! -First, you need to install the gem: +Simple: $ gem install rake-compiler -== Now what? (Usage) +== That's easy. How do I use it? -Now that you have the gem installed, let's give your project some structure. +Now that you have installed rake-compiler, it's time to give your project a +standardized structure. -=== Structure +=== Using a standardized project structure -Let's say we want to compile an extension called 'hello_world', so we should -organize the code and folders that will help rake-compiler do its job: +Let's say you want to compile an extension called 'hello_world'. Organizing +your project's code tree in the following way will help rake-compiler do +its job: |-- ext | `-- hello_world | |-- extconf.rb | |-- HelloWorldService.java | `-- hello_world.c |-- lib `-- Rakefile -TIP: Having a consistent folder structure will help developers and newcomers -to find code and also contribute back to your project more easily. +TIP: Having a consistent project directory structure will help developers and +newcomers find and understand your code, making it easier for them to +contribute back to your project. -=== Adding the code +=== Adding the code to enable rake-compiler -So now it's time to introduce the code to compile our extension: +Now the fun part. It's time to introduce the code to your projects Rakefile +to tell it to use rake-compiler to build your extension: # File: Rakefile require 'rake/extensiontask' Rake::ExtensionTask.new('hello_world') -Ok, that's it. No other line of code. +That's it? Yes, that's it! No other lines of code are needed for +rake-compiler to work its magic. -If we wanted to do the same for a JRuby extension (written in Java): +If you want to do the same for a JRuby extension written in Java, it's just +as easy: # File: Rakefile require 'rake/javaextensiontask' Rake::JavaExtensionTask.new('hello_world') -=== Compile process +=== The simple process -Those *two* lines of code automatically added the needed rake tasks to build -the hello_world extension. Running Rake on 1.8.x/1.9 (MRI): +Those *two* simple lines of code automatically added the Rake tasks needed to +build your 'hello_world' extension. For example, checking the Rake tasks on +MRI Ruby 1.8.x/1.9 returns something similar to: $ rake -T (in /home/user/my_extension) rake compile # Compile the extension(s) rake compile:hello_world # Compile just the hello_world extension -Simply calling <tt>compile</tt>: +Simply calling <tt>compile</tt> like $ rake compile -Will do all the compile process for us, putting the result extension inside -<tt>lib</tt> directory. +performs the entire compile and build process for you and places the resulting +extension inside the <tt>lib</tt> directory of your project. NOTE: Please be aware that building C extensions requires the proper -development environment for your Platform, which includes libraries, headers -and build tools. Check your distro / vendor documentation on how to install it. +development environment for your Platform, including libraries, headers +and build tools. Check your distro / vendor documentation on how to install +these development resources. NOTE: Building Java extensions requires the <tt>javac</tt>, part of the Java Development Kit (JDK). This should be included by default on Mac OS X, and downloadable from http://java.sun.com for other operating systems. -=== Generate native gems +=== Generating native RubyGems -A common usage scenario of rake-compiler is generate native gems that bundles -your extensions. +A common usage scenario for rake-compiler is generating native gems that +bundle your extensions. As mentioned above, if you have your development +environment configured correctly, the following examples work even when +building native gems on Windows systems. -This got over-simplified with <tt>Rake::ExtensionTask</tt>: +Creating native gems is really easy with rake-compiler's <tt>Rake::ExtensionTask</tt>: # somewhere in your Rakefile, define your gem spec spec = Gem::Specification.new do |s| s.name = "my_gem" s.platform = Gem::Platform::RUBY s.extensions = FileList["ext/**/extconf.rb"] end # add your default gem packing task - Rake::GemPackageTask.new(spec) do |pkg| + Gem::PackageTask.new(spec) do |pkg| end - # feed your ExtensionTask with your spec + # feed the ExtensionTask with your spec Rake::ExtensionTask.new('hello_world', spec) -Now, as usual, you can build your pure-ruby gem (standard output): +As expected, you can still build your pure-ruby gem in the usual way +(standard output) by running: $ rake gem (in /projects/oss/my_gem.git) mkdir -p pkg Successfully built RubyGem Name: my_gem Version: 0.1.0 File: my_gem-0.1.0.gem mv my_gem-0.1.0.gem pkg/my_gem-0.1.0.gem -Plus, you have the functionality to build native versions of the gem: +Plus, rake-compiler tasks give you the extra functionality needed to build +native gems by running: # rake native gem (... compilation output ...) mkdir -p pkg Successfully built RubyGem @@ -146,13 +164,14 @@ Name: my_gem Version: 0.1.0 File: my_gem-0.1.0-x86-mingw32.gem mv my_gem-0.1.0-x86-mingw32.gem pkg/my_gem-0.1.0-x86-mingw32.gem -You get two gems for the price of one. +Did you notice that you get two gems for the price of one? How's that for a +time saver? -And the same for JRuby extensions: +Similarly, it's just as easy to do the same thing for JRuby extensions: # rake java gem (... compilation output ...) mkdir -p pkg Successfully built RubyGem @@ -165,76 +184,89 @@ Version: 0.1.0 File: my_gem-0.1.0-java.gem mv my_gem-0.1.0-java.gem pkg/my_gem-0.1.0-java.gem -=== What about breaking the standards? (Customization) +=== Great, but can I use a non-standard project structure? -In case you want to bend the convention established, rake-compiler let you -personalize several settings for <tt>Rake::ExtensionTask</tt>: +Yes you can! While the conventional project structure is recommended, you may +want, or need, to tweak those conventions. Rake-compiler allows you to customize +several settings for <tt>Rake::ExtensionTask</tt>: Rake::ExtensionTask.new do |ext| ext.name = 'hello_world' # indicate the name of the extension. ext.ext_dir = 'ext/weird_world' # search for 'hello_world' inside it. ext.lib_dir = 'lib/my_lib' # put binaries into this folder. - ext.config_script = 'custom_extconf.rb' # use instead of 'extconf.rb' default + ext.config_script = 'custom_extconf.rb' # use instead of the default 'extconf.rb'. ext.tmp_dir = 'tmp' # temporary folder used during compilation. ext.source_pattern = "*.{c,cpp}" # monitor file changes to allow simple rebuild. - ext.config_options << '--with-foo' # supply additional configure options to config script. - ext.gem_spec = spec # optional indicate which gem specification - # will be used to based on. + ext.config_options << '--with-foo' # supply additional options to configure script. + ext.gem_spec = spec # optionally indicate which gem specification + # will be used. end -== Future is now: Cross compilation +== Cross compilation - the future is now. -rake-compiler provides now an standardized way to generate, from Linux or OSX -both extensions and gem binaries for Windows! +Rake-compiler also provides a standardized way to generate, from either Linux +or OSX, extensions and gem binaries for your Windows users! -It takes advantages from GCC host/target to build binaries (for target) on -different OS (hosts). +How can this be you say? Simple, rake-compiler's cross compilation features +take advantage of GCC's host/target capabilities to build 'target' binaries on +different 'host' OS's. -=== How I enjoy this? +=== How I do this from Linux or OSX? -Besides having the development tool chain installed (GCC), you should install -also <tt>mingw32</tt> cross compilation package. +In addition to having the development tool chain installed (GCC), you also need to +install your platform's <tt>mingw32</tt> cross compilation package. -Installation depends will depend on your operating system/distribution. On -Ubuntu and Debian machines, a simple <tt>apt-get install mingw32</tt> will be -enough. +Installation depends upon your operating system/distribution. On Ubuntu and Debian +host machines, a simple <tt>apt-get install mingw32</tt> will be enough. -On OSX, mingw32 is available via MacPorts: <tt>port install i386-mingw32-gcc</tt> -(ensure you update your ports tree before hand as <tt>mingw32</tt> has been -been broken). +On Arch, <tt>mingw32</tt> is installed by running <tt>pacman -S mingw32-gcc</tt> -=== I have my tool-chain, now what? +On OSX, <tt>mingw32</tt> is available via MacPorts via <tt>port install i386-mingw32-gcc</tt> +(ensure your ports tree is updated as <tt>mingw32</tt> has been broken in the past). -You need to build Ruby for Windows. +=== I've got my tool-chain installed, now what? -Relax, no need to freak out! Let rake-compiler do it for you: +First, you need to build Ruby for Windows on your Linux or OSX system. +Relax, no need to freak out! Let rake-compiler do all the heavy lifting for you: + rake-compiler cross-ruby -And you're done. It will automatically download, configure and compile latest -stable version of Ruby for Windows, and place it into <tt>~/.rake-compiler</tt> +And you're done. It will automatically download, configure and compile the latest +stable version of Ruby for Windows, and place it into your <tt>~/.rake-compiler</tt> +directory. -If, instead, you want to build another version than the default one, please +This will create <tt>~/.rake-compiler/config.yml</tt> file so that rake-compiler +knows where to find the <tt>rbconfig.rb</tt> file that matches the Ruby version +on the Windows host system you're cross-compiling for. An example: + + # File: ~/.rake-compiler/config.yml + + rbconfig-1.8.6: /path/to/ruby-1.8.6/rbconfig.rb + rbconfig-1.8.7: /path/to/ruby-1.8.7/rbconfig.rb + rbconfig-1.9.2: /path/to/ruby-1.9.2/rbconfig.rb + +If, instead, you want to build a different Ruby version than the default one, please supply a <tt>VERSION</tt>: rake-compiler cross-ruby VERSION=1.8.6-p114 -If you, like me, have multiple versions of MinGW packages, you can specify the -HOST that will be used to cross compile ruby: +If you, like me, have multiple versions of MinGW packages installed, you can +specify the HOST that will be used to cross compile Ruby: rake-compiler cross-ruby HOST=i386-mingw32 # (OSX mingw32 port) The host will vary depending on provider (mingw32 versus mingw-w64 projects). -Consult the documentation and website of the MinGW package provider before -reporting any issue. +Please consult the documentation and website of the MinGW package provider before +reporting any issues. -=== Let's build some gems! +=== OK, let's cross compile some gems! -Now, you only need to use additional options in your extension definition: +Now, you only need specify a few additional options in your extension definition: Rake::ExtensionTask.new('my_extension', gem_spec) do |ext| ext.cross_compile = true # enable cross compilation (requires cross compile toolchain) ext.cross_platform = 'i386-mswin32' # forces the Windows platform instead of the default one # configure options only for cross compile @@ -244,64 +276,76 @@ ext.cross_compiling do |gem_spec| gem_spec.post_install_message = "You installed the binary version of this gem!" end end -By default, cross compilation targets 'i386-mingw32' which is default GCC platform -for Ruby. +By default, cross compilation targets 'i386-mingw32' which is the default GCC +platform for Ruby. -To target gems for current Ruby official distribution, please force the platform -to the one shown before. +To target gems for MRI Ruby's current official distribution, please force the +platform to the one (i386-mswin32) previously shown. -=== Magician doing some tricks, don't blink! +=== Warning, magician about to do some tricks, don't blink! -Compiles keeps being simple: +Cross compiling is still very simple: rake cross compile -And now, build your gems for Windows is just 5 more letters: +And now, building gems for your Windows users is just 5 more letters: rake cross native gem And you're done, yeah. -=== Take it even further +=== But wait, there's more -You can specify against with version of Ruby you want to build the extension: +You can specify which version of Ruby to build the extension against: rake cross compile RUBY_CC_VERSION=1.8.6 -If you installed <tt>1.9.1</tt>, you can do: +For example, if you installed <tt>1.9.2</tt>, you can do: - rake cross compile RUBY_CC_VERSION=1.9.1 + rake cross compile RUBY_CC_VERSION=1.9.2 -Even more, you can target multiple versions (ie. 1.8.6 and 1.9.1): +Even better, you can target multiple versions (ie. 1.8.6 and 1.9.2) in +the same gem via: - rake cross compile RUBY_CC_VERSION=1.8.6:1.9.1 + rake cross compile RUBY_CC_VERSION=1.8.6:1.9.2 -And more exiting, bundle both binaries in one "fat" Gem: +And better yet, you can bundle both binary extensions into one so-called "fat" +gem via: - rake cross native gem RUBY_CC_VERSION=1.8.6:1.9.1 + rake cross native gem RUBY_CC_VERSION=1.8.6:1.9.2 -That will place binaries for 1.8 and 1.9 versions of ruby inside <tt>lib_dir</tt> +That will place binaries for both the 1.8 and 1.9 versions of your Ruby +extensions inside your project's <tt>lib_dir</tt> directory: lib/1.8/my_extension.so lib/1.9/my_extension.so -Now is up to you to make your gem load the proper one ;-) +NOTE: building "fat" gems is currently only supported by rake-compiler when +cross compiling from a Linux or OSX host. Patches are welcome if building +"fat" gems from Windows hosts is desired, or natively for your platform :-) +Now is up to you to make your gem load the proper binary at runtime. Here's a hint ;-) + + RUBY_VERSION =~ /(\d+.\d+)/ + require "#{$1}/my_extension" + === What are you talking about? (Give me examples) -I know all the above sounds like a complete foreign language (it does even for me!). So, what if I show you some examples? +I know all the above sounds like a complete foreign language (it does even for me!). +So, what if I show you some examples? -Check our wiki with links to the proper rake files used by many developers and projects and how they use rake-compiler. +Check our wiki with links to the proper rake files used by many developers and +projects and how they use rake-compiler. http://github.com/luislavena/rake-compiler/wiki/projects-using-rake-compiler == Future -rake-compiler is a work in progress and we will appreciate feedback during the -development of it! (and contributions too!) +rake-compiler is a work in progress and we appreciate any and all feedback +during the development of it! (and contributions too!) You can find more information about rake-compiler: * GitHub: https://github.com/luislavena/rake-compiler * Issues: https://github.com/luislavena/rake-compiler/issues