4

My C code is getting harder to manage due to the inflexibility of mkmf. For this reason, I'd like to use another build system.

What does rubygems need in order to build a C extension? How can I integrate a build system like autotools/configure into the workflow?

Gem::Specification.new 'my_gem' do |gem|
  # Will this work?
  gem.extensions = %w(ext/my_gem/configure)
end
Community
  • 1
  • 1
Matheus Moreira
  • 17,106
  • 3
  • 68
  • 107

3 Answers3

5

There are some tools that help is such situation (e.g. rake-compiler gem), but I prefer to use RubyInline gem. It was designed to replace slow, performance critical sections of Ruby code with implementations in other languages (e.g. C is supported out of the box), but it is also used to inline code that calls external C libraries.

A RubyInline example looks as follows:

class MyClass
  inline(:C) do |builder|
    builder.include '<stdio.h>'
    builder.c <<-END
      void my_printf(char * string){
        printf("%s\\n",string);
      }
    END
  end
end
MyClass.new.my_printf("Abc") 
# prints 'Abc'

The nice feature of RubyInline is that you don't have to keep separate files for C and Ruby, some basic argument conversions are supported out of the box and you don't have to write the gluing code. The bad parts are that you don't have the full control over compilation, etc. Personally I find RubyInline a very powerful solution.

Aleksander Pohl
  • 1,675
  • 10
  • 14
  • 1
    +1, I was already using `rake-compiler` and I agree in that `inline` is an amazing tool, but the thing is that I _do_ want to preserve the separate Ruby and C codebases. My reasons for wanting an alternative to `mkmf` is that it imposes an incredibly inflexible folder structure - [all files must be in the same directory as `extconf.rb`](http://stackoverflow.com/q/7698192/512904). I'm considering rolling my own solution to the problem. – Matheus Moreira Mar 03 '12 at 20:03
  • Unfortunately, I don't know such an alternative. – Aleksander Pohl Mar 05 '12 at 11:57
4

If the C code is quite complicated (since you mention autotools and configure I assume it is) why don't you consider building separate C library, which is independent of Ruby? And then build a small and simple Ruby gem with the gluing code. Eventually the C library would become available in repositories for Debian or other Linux distributions and the maintenance of such a solution would be similar to all other gems, that are just wrappers for C libraries.

Aleksander Pohl
  • 1,675
  • 10
  • 14
  • I will strongly consider this. The library in question implements simplified windowing and graphics. Since there are already plenty of alternatives in C and other languages, I thought it wouldn't add much value. – Matheus Moreira Mar 12 '12 at 15:35
0

Take a look at ruby-ffi
It links to existing libraries so does not force any directory structure

Also http://guides.rubygems.org/c-extensions/

deepak
  • 7,230
  • 5
  • 24
  • 26