Recently in RubyInline Category

Writing Extensions using Hoe

| | Comments (1)

Despite popular belief, it is possible and easy to write extensions with projects based on Hoe. It is possible to do both classic and inline extensions. Let's take a look at what both of them look like.

Classic Extensions

This is a standard extconf.rb based extension, with the build mechanism folded into the Rakefile instead of also having a Makefile in the ext directory.

Rakefile

EXT = "ext/blah.#{Hoe::DLEXT}"                        # 1

class Blah
  VERSION = '1.0.0'                                   # 2
end

Hoe.new('blah', Blah::VERSION) do |p|
  p.developer('FIX', 'FIX@example.com')

  p.spec_extras[:extensions] = "ext/extconf.rb"       # 3
  p.clean_globs << EXT << "ext/*.o" << "ext/Makefile"
end

task :test => EXT

file EXT => ["ext/extconf.rb", "ext/blah.c"] do       # 4
  Dir.chdir "ext" do
    ruby "extconf.rb"
    sh "make"
  end
end

1) EXT defines the path to the built extension, used below for dependencies and the clean_globs array.

2) Normal Hoe-based projects require the library in the Rakefile in order to grab the VERSION constant. This means you only have to update the version in a single location, but can use that value for packaging and deploying. We can't do that here (since the extension isn't necessarily built yet), so we cheat by duplicating the version constant. Violates DRY, but it is not that big of a deal.

3) The hoe spec also uses spec_extras to define :extensions to specify that we've got an extconf.rb file to use.

4) Finally, and most importantly, we have a file rule for EXT that executes extconf.rb to generate a Makefile and then executes make to build the extension binary.

ext/ext/extconf.rb

require 'mkmf'
create_makefile("blah")

Nothing special here to explain.

ext/ext/blah.c

#include "ruby.h"

static VALUE blah(VALUE self) {
  puts("hello world");
  return Qnil;
}

#ifdef __cplusplus
extern "C" {
#endif
  void Init_blah() {
    VALUE c = rb_define_class("Blah", rb_cObject);
    rb_define_method(c, "blah", (VALUE(*)(ANYARGS))blah, 0);
  }
#ifdef __cplusplus
}
#endif

Here is your basic C extension for ruby. We've got a function blah and an Init_blah function that declares the Blah class with a blah method and binds it to the blah C function.

Remember, this is as easy as it gets. blah doesn't take any arguments and it doesn't actually do anything.

Inline Extensions

Inline makes your life a lot easier than the above.

Rakefile

require './lib/blah.rb'

Hoe.new('blah', Blah::VERSION) do |p|
  p.developer('FIX', 'FIX@example.com')
end

Every mechanism above is replaced with a simple Hoe spec. It gets its VERSION from lib/blah.rb as usual because everything is just happy ruby and there are no bootstrap steps. There are no extra dependencies or anything to take care of because inline does everything for you.

lib/blah.rb

require 'rubygems'
require 'inline'

class Blah
  VERSION = '1.0.0'

  inline(:C) do |builder|
    builder.c %{
      void blah() {
        puts("hello world");
      }
    }
  end
end

Here we have a regular ruby class Blah with a VERSION constant defined. The only thing special is the call to inline with :C as the specifier of what type of builder we want. That builder is then told to define a C function with a C function signature of void blah(). Our simple hello world is inside and pretty much the same as above. The main difference is that there is no return value, that's because Inline knows that a C function returning void should return nil automatically. Inline deals with all arguments and return values automatically.

Another difference with the classic extension example, is I'm not forced to always run rake before I can play. I can run a test file directly, and if the C source has changed, inline deals with it automatically behind the scenes.

Conclusion

For everything I do, there is little reason to use anything but inline. There are times where you need to write a classic extension. Luckily, it isn't much work to make it work in a classic Rake/Hoe setup.

Inline allows you to write foreign code within your ruby code. It automatically determines if the code in question has changed and builds it only when necessary. The extensions are then automatically loaded into the class/module that defines it.

You can even write extra builders that will allow you to write inlined code in any language. Use Inline::C as a template and look at Module#inline for the required API.

Changes:

3.7.0 / 2008-06-09

Ruby Inline is an analog to Perl's Inline::C. Out of the box, it allows you to embed C/++ external module code in your ruby script directly. By writing simple builder classes, you can teach how to cope with new languages (fortran, perl, whatever). The code is compiled and run on the fly when needed.

Using the package_inline tool Inline allows you to package up your inlined object code for distribution to systems without a compiler.

Changes:

3.6.7 / 2008-03-20

Ruby Inline is an analog to Perl's Inline::C. Out of the box, it allows you to embed C/++ external module code in your ruby script directly. By writing simple builder classes, you can teach how to cope with new languages (fortran, perl, whatever). The code is compiled and run on the fly when needed.

Changes:

3.6.6 / 2007-12-27* 1 minor enhancement:

Ruby Inline is an analog to Perl's Inline::C. Out of the box, it allows you to embed C/++ external module code in your ruby script directly. By writing simple builder classes, you can teach how to cope with new languages (fortran, perl, whatever). The code is compiled and run on the fly when needed.

Changes:

3.6.5 / 2007-11-08

Ruby Inline is an analog to Perl's Inline::C. Out of the box, it allows you to embed C/++ external module code in your ruby script directly. By writing simple builder classes, you can teach how to cope with new languages (fortran, perl, whatever). The code is compiled and run on the fly when needed.

Changes:

3.6.4 / 2007-08-20

Ruby Inline is an analog to Perl's Inline::C. Out of the box, it allows you to embed C/++ external module code in your ruby script directly. By writing simple builder classes, you can teach how to cope with new languages (fortran, perl, whatever). The code is compiled and run on the fly when needed.

3.6.3 / 2007-04-27

  • 7 minor enhancements:

    • Added maprubyconst and mapcconst to C builder.
    • Converted example.rb to a real benchmark setup.
    • Improved error messages.
    • Added options hash for all C builder methods.
    • Options hash can take optional :method_name param to have ruby name diff from c.
    • Converted to a more traditional setup. Now I can heckle!
    • Cleaned up ruby.h search.
  • 2 bug fixes:

    • Added CCDLFLAGS. Should pick up -fPIC on misconfigured 64 bit machines.
    • Broke up all warnings so progress report was cleaner.

InlineFortran 1.0.0 Released

| | Comments (0)

InlineFortran version 1.0.0 has been released!

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

FEATURES/PROBLEMS:

  • Very rudimentary right now. Needs some love.

SYNOPSYS:

inline :Fortran do |builder|
  builder.subroutine('print_integer', ["void", "int"], <<-END)
    subroutine print_integer( integer )
      integer, intent(in) :: integer
      print *, 'integer: ', integer
    end
  END
end

Changes:

1.0.0 / 2006-10-21

  • 1 major enhancement
    • Birthday!

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

RubyInline 3.6.2 Released

| | Comments (0)

RubyInline version 3.6.2 has been released! This is a quick patch for weird versions of GCC and/or linux and makes ParseTree work again on (hopefully) everything under the sun.

Ruby Inline is an analog to Perl's Inline::C. Out of the box, it allows you to embed C/++ external module code in your ruby script directly. By writing simple builder classes, you can teach how to cope with new languages (fortran, perl, whatever). The code is compiled and run on the fly when needed.

% sudo gem update RubyInline

Changes:

3.6.2 / 2006-10-12

  • 2 bug fixes
    • comment stripper much more sane to fix problems on certain linux distros
    • fixed a nit with older C compilers.

4 releases went out the door

| | Comments (0)

I just finished releasing:

  • hoe 1.1.1
  • RubyInline 3.6.1
  • ParseTree 1.6.0
  • and new to the (official) family: ruby2ruby 1.1.0!
% sudo gem update hoe RubyInline ParseTree
% sudo gem install ruby2ruby

The biggies are:

  • ParseTree just got a major enema. 2k lines o' diff with an overall net loss of 800 loc. Awesome
  • ParseTree's new testing infrastructure is solid as all hell.
  • and it is circularly validated via ruby2ruby's tests.
  • We flushed out a bunch of completely unknown bugs by this process. About 6 nodes were broken in one way or another.

Also of note:

  • mingw32 patches for RubyInline
  • lots and lots of nice little bug fixes and enhancements all over.

About this Archive

This page is a archive of recent entries in the RubyInline category.

RubyHitSquad is the previous category.

RubySadism is the next category.

Find recent content on the main index or look in the archives to find all content.

Pages

Powered by Movable Type 4.1