Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Developing Ruby gems with native extensions

Developing Ruby gems with native extensions

Presented at Geneva.rb on 21st January 2015

Dimiter Petrov

January 21, 2015
Tweet

More Decks by Dimiter Petrov

Other Decks in Programming

Transcript

  1. Developing Ruby gems
    with native extensions
    by @crackofdusk
    1 / 16

    View Slide

  2. Why use native
    extensions?
    2 / 16

    View Slide

  3. Bindings to existing native libraries
    3 / 16

    View Slide

  4. Speed up hot code paths
    4 / 16

    View Slide

  5. Why not use native
    extensions
    5 / 16

    View Slide

  6. The current speed is acceptable
    6 / 16

    View Slide

  7. The speed can be improved by an
    algorithmic change
    7 / 16

    View Slide

  8. You are uncomfortable with C and there is a
    another communication channel with the
    underlying system
    (HTTP, UNIX sockets, ...)
    8 / 16

    View Slide

  9. Let’s dive in
    9 / 16

    View Slide

  10. $ tree
    .
    ├── ext
    │ └── hello
    │ ├── extconf.rb
    │ └── hello.c
    └── hello.gemspec
    ext/hello/extconf.rb
    require 'mkmf'
    have_library('hello')
    create_makefile('hello/hello')
    ext/hello/hello.c
    #include
    void Init_hello() {
    // ...
    }
    hello.gemspec
    Gem::Specification.new do |spec|
    # ...
    spec.extensions <<
    'ext/hello/extconf.rb'
    end
    10 / 16

    View Slide

  11. $ cd ext/hello
    $ ruby extconf.rb
    checking for main() in -lhello... no
    creating Makefile
    $ make
    compiling hello.c
    linking shared-object hello/hello.so
    $ irb
    irb(main):001:0> require './hello'
    => true
    11 / 16

    View Slide

  12. $ tree
    .
    ├── ext
    │ └── hello
    │ ├── extconf.rb
    │ └── hello.c
    ├── lib
    └── Rakefile
    $ rake compile
    ...
    $ ls lib/
    hello.so
    $ irb -Ilib
    irb(main):001:0> require 'hello'
    => true
    Rakefile
    require 'rake/extensiontask'
    Rake::ExtensionTask.new('hello')
    With the rake-compiler gem
    12 / 16

    View Slide

  13. extconf.rb
    Checks compilation conditions and generates a Makefile. For example:
    require 'mkmf'
    HEADER_DIRS = [
    # ...
    ]
    LIB_DIRS = [
    # ...
    ]
    unless find_header('foo/foo.h', *HEADER_DIRS)
    abort "libfoo is missing. Please install libfoo"
    end
    unless find_library('foo', 'foo_imported_function', *LIB_DIRS)
    abort "libfoo is missing. Please install libfoo"
    end
    create_makefile('foo/foo')
    See the MakeMakefile documentation for all available checks.
    13 / 16

    View Slide

  14. Library initialization and entry point
    When the interpreter loads the library LIBRARY, it executes the Init_LIBRARY()
    function.
    #include
    #include
    void Init_foo(void) {
    VALUE mFoo = rb_define_module("Foo");
    rb_define_singleton_method(mFoo, "bar", bar, 1);
    //...
    }
    14 / 16

    View Slide

  15. Ruby Extension API
    Used by the library to interact with the Ruby interpreter from the C code.
    It provides functions to:
    check data types
    convert between different types
    define classes, modules, constants, methods
    invoke Ruby methods
    raise exceptions
    handle allocations and deallocations
    wrap C pointers into Ruby objects
    etc.
    The documentation is in the README.EXT file that comes with the CRuby source
    code.
    15 / 16

    View Slide

  16. Further reading
    Official documentation about making extension libraries for Ruby:
    https://github.com/ruby/ruby/blob/trunk/README.EXT
    Rubygems guide about gems with extensions:
    http://guides.rubygems.org/gems-with-extensions/
    The rake-compiler gem:
    https://github.com/rake-compiler/rake-compiler
    Writing Ruby C extensions:
    http://tenderlovemaking.com/2009/12/18/writing-ruby-c-extensions-part-
    1.html
    http://tenderlovemaking.com/2010/12/11/writing-ruby-c-extensions-part-
    2.html
    Native extensions with Java:
    https://blog.jcoglan.com/2012/08/02/your-first-ruby-native-extension-java/
    16 / 16

    View Slide