<commit_before>= rake-compiler

rake-compiler aims to help Gem developers while dealing with Ruby C
extensions, simplifiying the code and reducing the duplication.

It follows *convention over configuration* and set an standarized 
structure to build and package C extensions in your gems.

This is the result of expriences dealing with several Gems that required 
native extensions across platforms and different user configurations 
where details like portability and clarity of code were lacking.


== An Overview

Let's summarize what rake-compiler provides:

* No custom rake tasks required. Less code duplication and errors.

* Painlessly build extensions on different platforms (Linux, OSX and Windows).

* Allow multiple extensions be compiled inside the same gem.

* Mimics RubyGems installation process, so helps as test environment.


== I'm sold! show me how to use it! (Installation)

Usage of rake-compiler is pretty much straight forward.

First, you need to install the gem:

  $ gem install rake-compiler

Since this package is in constant evolution, you could try installing it
from GitHub:

  $ gem install luislavena-rake-compiler --source http://gems.github.com

The development gem is usually in pretty good shape actually.


== Now what? (Usage)

Now that you have the gem installed, let's give your project some structure.


=== 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 it's job:

    |-- ext
    |   `-- hello_world
    |       |-- extconf.rb
    |       `-- 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.


=== Adding the code

So now it's time to introduce the code to compile our extension:

    # File: Rakefile
    
    require 'rake/extensiontask'
    
    Rake::ExtensionTask.new('hello_world')

Ok, that's it. No other line of code.


=== Compile process

Those *two* lines of code automatically added the needed rake tasks to build
the hello_world extension:

  $ rake -T
  (in /home/user/my_extesion)
  rake compile                # Compile the extension(s)
  rake compile:hello_world    # Compile just the hello_world extension

Simply calling <tt>compile</tt>:

  $ rake compile

Will do all the compile process for us, putting the result extension inside
<tt>lib</tt> directory.

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.

=== Generate native gems

A common usage scenario of rake-compiler is generate native gems that bundles
your extensions.

This got over-simplified with <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|
    end

    # feed your ExtensionTask with your spec
    Rake::ExtensionTask.new('hello_world', spec)

Now, as usual, you can build your pure-ruby gem (standard output):

  $ 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:

  # rake native gem
  (... compilation output ...)
  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
    Successfully built RubyGem
    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.

=== What about breaking the standards? (Customization)

In case you want to bend the convention established, rake-compiler let you
personalize 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.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.
    end


== Future

rake-compiler is a work in progress and we will appreciate feedback during the
development of it! (and contributions too!)

You can find more information about rake-compiler:

Blog:      http://blog.mmediasys.com
GitHub:    http://github.com/luislavena/rake-compiler


=== Some of the features already underworks

* <tt>Rake::JavaJarTask</tt> to generate <tt>jar</tt> packages and gems for JRuby.

  $ rake java gem


== Disclaimer
<commit_msg>Updated README to give examples on the cross compilation options.<commit_after>= rake-compiler

rake-compiler aims to help Gem developers while dealing with Ruby C
extensions, simplifiying the code and reducing the duplication.

It follows *convention over configuration* and set an standarized 
structure to build and package C extensions in your gems.

This is the result of expriences dealing with several Gems that required 
native extensions across platforms and different user configurations 
where details like portability and clarity of code were lacking.


== An Overview

Let's summarize what rake-compiler provides:

* No custom rake tasks required. Less code duplication and errors.

* Painlessly build extensions on different platforms (Linux, OSX and Windows).

* Allow multiple extensions be compiled inside the same gem.

* Mimics RubyGems installation process, so helps as test environment.


== I'm sold! show me how to use it! (Installation)

Usage of rake-compiler is pretty much straight forward.

First, you need to install the gem:

  $ gem install rake-compiler

Since this package is in constant evolution, you could try installing it
from GitHub:

  $ gem install luislavena-rake-compiler --source http://gems.github.com

The development gem is usually in pretty good shape actually.


== Now what? (Usage)

Now that you have the gem installed, let's give your project some structure.


=== 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 it's job:

    |-- ext
    |   `-- hello_world
    |       |-- extconf.rb
    |       `-- 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.


=== Adding the code

So now it's time to introduce the code to compile our extension:

    # File: Rakefile
    
    require 'rake/extensiontask'
    
    Rake::ExtensionTask.new('hello_world')

Ok, that's it. No other line of code.


=== Compile process

Those *two* lines of code automatically added the needed rake tasks to build
the hello_world extension:

  $ rake -T
  (in /home/user/my_extesion)
  rake compile                # Compile the extension(s)
  rake compile:hello_world    # Compile just the hello_world extension

Simply calling <tt>compile</tt>:

  $ rake compile

Will do all the compile process for us, putting the result extension inside
<tt>lib</tt> directory.

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.

=== Generate native gems

A common usage scenario of rake-compiler is generate native gems that bundles
your extensions.

This got over-simplified with <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|
    end

    # feed your ExtensionTask with your spec
    Rake::ExtensionTask.new('hello_world', spec)

Now, as usual, you can build your pure-ruby gem (standard output):

  $ 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:

  # rake native gem
  (... compilation output ...)
  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
    Successfully built RubyGem
    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.

=== What about breaking the standards? (Customization)

In case you want to bend the convention established, rake-compiler let you
personalize 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.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.
    end


== Future is now: Cross compilation

rake-compiler provides now an standarized way to generate, from Linux or OSX
both extensions and gem binaries for Windows!

It takes advantages from GCC host/target to build binaries (for target) on 
different OS (hosts).


=== How I enjoy this?

Besides having the development tool chain installed (GCC), you should install
also <tt>mingw32</tt> cross compilation package.

Dependending on your operating system distribution, a simple <tt>apt-get install mingw32</tt>
will be enough.

Please check OSX documentation about installing mingw32 from macports.


=== I have my toolchain, now what?

You need to build Ruby for Windows.

Relax, no need to freak out. rake-compiler do it 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>

If, instead, you want to build another version than the default one, please
supply a <tt>VERSION</tt>:

  rake-compiler cross-ruby VERSION=1.8.6-p114

=== Let's build some gems!

Now, you only need to use additional options in your extension defintion:

    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
      ext.cross_config_options << '--with-something'
    end

By default, cross compilation targets 'i386-mingw32' which is default GCC platform
for Ruby.

To target gems for current Ruby official distribution, please force the platform
to the one shown before.

=== Magician doing some tricks, don't blink!

Compiles keeps being simple:

  rake cross compile

And now, build your gems for Windows is just 4 more letters:

  rake cross native gem

And you're done, yeah.


== Future

rake-compiler is a work in progress and we will appreciate feedback during the
development of it! (and contributions too!)

You can find more information about rake-compiler:

Blog:      http://blog.mmediasys.com
GitHub:    http://github.com/luislavena/rake-compiler


=== Some of the features already underworks

* <tt>Rake::JavaJarTask</tt> to generate <tt>jar</tt> packages and gems for JRuby.

  $ rake java gem


== Disclaimer

{'fraction_non_alphanumeric': 0.07600641662210679, 'fraction_numerical': 0.009090214651287143, 'mean_word_length': 3.1509194673430563, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 7, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3454184', 'n_tokens_mistral': 3878, 'n_tokens_neox': 3649, 'n_words': 1556}