public
Description: Use rbgccxml and rice to automatically generate C++ Ruby extensions.
Homepage: http://rbplusplus.rubyforge.org/rbplusplus
Clone URL: git://github.com/jameskilton/rbplusplus.git
name age message
file .gitignore Loading commit data...
file ANNOUNCE
file MIT_LICENCE
file README
file Rakefile
file TODO
directory lib/
directory samples/ Fri May 02 14:32:22 -0700 2008 My first sample [jameskilton]
directory test/
directory website/
README
== What is rb++?

Rb++ makes it almost trivially easy to create Ruby extensions for any C
or C++ library / code. In the simplest of cases, there is no need to ever
touch C, everything is done in a very simple and clean Ruby API.

Note: For those familiary with py++, the similarities are minimal. 
Outside of the purpose of both libraries, rb++ was built from scratch to 
provide a Ruby-esque query and wrapping API instead of being a port. However, 
many thanks to Roman for his work, the major inspiration for this library.

== Requirements

* rbgccxml
* rice (http://rice.rubyforge.org)

== Installation

Rice builds and installs on any *nix system, including Mac OS X and Cygwin. Rice,
and therefor rb++ will not work on Windows outside of Cygwin.

Everything is installed with a simple line:

  gem install rbplusplus

== The Project

For bug reports, patch submissions, project annoucements and downloads, visit rb++'s rubyforge
project page at:

http://www.rubyforge.org/projects/rbplusplus

Feel free to post help request, hints, or general ideas on the forums.

Rb++'s source is in a git repository hosted on github:

Project page: 

http://github.com/jameskilton/rbgplusplus/tree/master

Clone with: 

git clone git://github.com/jameskilton/rbplusplus.git

== Getting Started

All rb++ projects start off with the Extension class:

  require 'rbplusplus'
  include RbPlusPlus

  Extension.new "extension_name"

The one requirement on the C++ code for rb++ to easily handle it, is that the code that's
to be wrapped is in its own namespace. If the code to be wrapped is in the global namespace,
then you should build a seperate header file that includes all the files to be wrapped 
inside of a namespace:

  namespace to_wrap {
    #include "file1.h"
    #include "file2.h"
    #include "file3.h"
    ...
  }

Extension has two ways of being used: block syntax for simple projects and immediate
syntax for more control over the whole process.

=== Block Mode

For basic reading and wrapping needs, the block syntax makes rb++ very easy to write and
read

  Extension.new "extension" do |e|
    ...
  end

=== Immediate Mode

For those that want more fine-grained control over the parsing / building / writing / compiling
process, immediate syntax is also available

  e = Extension.new "extension"
  ...
  e.build    # => Generates the C++ code
  e.write    # => Writes out to files
  e.compile  # => Compiles into an extension

Please note the ##build ##write and ##compile methods. These are required for an extension to be
built. These calls are made automatically in Block Mode. See the RbPlusPlus::Extension class
for more details.

== Basic Usage

For the most basic usage, where there are C++ header files to wrap and it's simple enough
to not need extra processing, there are only two required calls: Extension.sources and 
Extension.namespace. Extension.sources has a few ways to be called (as RbGCCXML.parse):

  # A single header file
  Extension.new "extension" do |e|
    e.sources "/path/to/header.h"
  end

  # An array of header files
  Extension.new "extension" do |e|
    e.sources ["/path/to/header.h", "/path/there.h"]
  end

  # A glob
  Extension.new "extension" do |e|
    e.sources "/path/to/*.h"
  end

  # An array of globs
  Extension.new "extension" do |e|
    e.sources ["/path/to/*.h", "/elsewhere/*.hpp"]
  end

One special method that's also required in the Immediate Mode is Extension.working_dir=. This
specifies where rb++ will put the generated code. In Block Mode, the default is to put the code
in __FILE__/generated, but as rb++ cannot ascertain the __FILE__ information without a block, 
it will need to be stated explicitly. This does work in Block Mode, it will just overrite the 
default.

  e = Extension.new "extension" 
  e.working_dir = "/path/to/generate/files/"

The last required method is Extension.namespace. As mentioned above, all extensions 
are built from code in a given C++ namespace. That namespace needs to be specified before
Rb++ will start any processing

  # Wrap all code under the 'to_wrap' namespace
  Extension.new "extension" do |e|
    e.namespace "to_wrap"
  end

There is one place where Extension.namespace isn't exactly required, and that's when you're
specifying extra Ruby Modules that will contain the wrapped code.

== More Detailed Usage

Because C++ does not easily wrap into Ruby code for many reasons, rb++ is much more capable than just
the basic usage above. There are many different features available to help define and build the wrapper. 

=== Modules

An extension can include 0..n modules in which code will be wrapped. Any given module needs to be given
a ##namespace call. This defines which C++ code will be wrapped into this module.

  Extension.new "extension" do |e|
    e.sources ...
    # If there is no global-space code to be wrapped
    # .namespace is not required here

    e.module "MyModule" do |m|
      m.namespace "my_module"
    end
  end

This will create an extension with the module +MyModule+ in which all the C++ code under the +my_module+
namespace will be wrapped.

== Possible 'Gotchas'

* Method / function names are underscored by default. So <tt>YourClass::doSomething</tt> becomes 
<tt>YourClass#do_something</tt>

== Misc Options

=== File Writing Options

By default, rb++ will write out the extension in multiple files, following the convention of

  extension_name.cpp
  ClassName.rb.hpp
  ClassName.rb.cpp
  ModuleName_ClassName.rb.hpp
  ModuleName_ClassName.rb.cpp
  ...

rb++ can instead write out the extension code in a single file (extension_name.cpp) with Extension.writer_mode

  Extension.new "extension" do |e|
    e.writer_mode :single 
  end
    
=== Compiling options

rb++ takes care of setting up the extension to be properly compiled, but sometimes certain
compiler options can't be deduced. rb++ has options to specify library paths (-L), libraries (-l),
and include paths (-I) to add to the compilation lines, as well as just adding your own flags 
directly to the command line. These are options on Extension.sources

  Extension.new "extension" do |e|
    e.sources *header_dirs,
      :library_paths => *paths,    # Adds to -L
      :libraries => *libs,         # Adds to -l
      :include_paths => *includes, # Adds to -I
      :cxxflags => *flags,         # For those flags that don't match the above three
      :ldflags => *flags,          # For extra linking flags that don't match the above
  end

Any compiler errors and the full build log will be found in rbpp_compile.log.