Version Check in C Extension

Hello!

How can I check for the Ruby version inside a C extension? I found some
constants in version.h, but I don't think that file is included via
ruby.h and it has a very common name that may conflicts with similar
files in other projects. So, I don't think it is wise to include
version.h in a Ruby extension.

Is there another way to check if the extension gets compiled with Ruby
1.8 or 1.9?

Regards,
Elias

How can I check for the Ruby version inside a C extension?

Try to avoid to test the ruby version, but rather test the functionality
that you want in extconf.rb.

For example

moulon% ruby -rmkmf -ve 'have_func("rb_frame_this_func")'
ruby 1.8.4 (2005-12-24) [i486-linux]
checking for rb_frame_this_func()... no
moulon%

moulon% ./ruby -rmkmf -ve 'have_func("rb_frame_this_func")'
ruby 1.9.0 (2006-07-14) [i686-linux]
checking for rb_frame_this_func()... yes
moulon%

Guy Decoux

In your extconf.rb file construct a -D option from the RUBY_VERSION constant:

VERSION_NUMBER = '0x'+RUBY_VERSION.tr('.','')
$CPPFLAGS = "-DRUBY_VERSION=#{VERSION_NUMBER}"

···

elias.athanasopoulos@gmail.com wrote:

Hello!

How can I check for the Ruby version inside a C extension? I found some
constants in version.h, but I don't think that file is included via
ruby.h and it has a very common name that may conflicts with similar
files in other projects. So, I don't think it is wise to include
version.h in a Ruby extension.

Is there another way to check if the extension gets compiled with Ruby
1.8 or 1.9?

Regards,
Elias

Hello!

ts wrote:

> How can I check for the Ruby version inside a C extension?

Try to avoid to test the ruby version, but rather test the functionality
that you want in extconf.rb.

For example

moulon% ruby -rmkmf -ve 'have_func("rb_frame_this_func")'
ruby 1.8.4 (2005-12-24) [i486-linux]
checking for rb_frame_this_func()... no
moulon%

moulon% ./ruby -rmkmf -ve 'have_func("rb_frame_this_func")'
ruby 1.9.0 (2006-07-14) [i686-linux]
checking for rb_frame_this_func()... yes
moulon%

Right. This is the problem I have to deal with. My extension uses
rb_frame_last_func() which is subsituted with rb_frame_this_func() in
1.9. So, I have to alter the actual code to use rb_frame_last_func() or
rb_frame_this_func() according to the ruby version installed in the
system.

So, checking in the Makefile will not help.

Regards,
Elias

So, checking in the Makefile will not help.

This is bdb

static VALUE
bdb_indexes(int argc, VALUE *argv, VALUE obj)
{
    VALUE indexes;
    int i;

#if HAVE_RB_ARY_VALUES_AT
    rb_warn("Common#%s is deprecated; use Common#values_at",
#if HAVE_RB_FRAME_THIS_FUNC
            rb_id2name(rb_frame_this_func()));
#else
            rb_id2name(rb_frame_last_func()));
#endif
#endif

Guy Decoux

Hello!

ts wrote:

This is bdb

static VALUE
bdb_indexes(int argc, VALUE *argv, VALUE obj)
{
    VALUE indexes;
    int i;

#if HAVE_RB_ARY_VALUES_AT
    rb_warn("Common#%s is deprecated; use Common#values_at",
#if HAVE_RB_FRAME_THIS_FUNC
            rb_id2name(rb_frame_this_func()));
#else
            rb_id2name(rb_frame_last_func()));
#endif
#endif

Thanx!

Regards,
Elias

Hello!

ts wrote:

static VALUE
bdb_indexes(int argc, VALUE *argv, VALUE obj)
{
    VALUE indexes;
    int i;

#if HAVE_RB_ARY_VALUES_AT
    rb_warn("Common#%s is deprecated; use Common#values_at",
#if HAVE_RB_FRAME_THIS_FUNC
            rb_id2name(rb_frame_this_func()));
#else
            rb_id2name(rb_frame_last_func()));
#endif
#endif

Again, in my Debian box:

elathan@velka:/usr/lib/ruby/1.9/i486-linux> find . | xargs grep HAVE_RB
./config.h:#define HAVE_RB_FD_INIT 1
./intern.h:#if defined(NFDBITS) && defined(HAVE_RB_FD_INIT)
./intern.h:#define HAVE_RB_DEFINE_ALLOC_FUNC 1
elathan@velka:/usr/lib/ruby/1.9/i486-linux>

Should I generate the macro HAVE_RB_FRAME_THIS_FUNC in the Makefile? I
thought Ruby 1.9 had it by default defined in its internals.

Regards,
Elias

Should I generate the macro HAVE_RB_FRAME_THIS_FUNC in the Makefile? I
thought Ruby 1.9 had it by default defined in its internals.

Part of extconf.rb for bdb

["rb_frame_this_func", "rb_block_proc", "rb_io_stdio_file"].each do |f|
   if have_func(f)
      $CFLAGS += " -DHAVE_#{f.upcase}"
   end
end

["insert", "values_at"].each do |f|
   print "checking for Array##{f}... "
   if [].respond_to?(f)
      puts "yes"
      $CFLAGS += " -DHAVE_RB_ARY_#{f.upcase}"
   else
      puts "no"
   end
end

Guy Decoux

Hi,

At Mon, 28 Aug 2006 22:15:09 +0900,
Athanasopoulos wrote in [ruby-talk:211102]:

Should I generate the macro HAVE_RB_FRAME_THIS_FUNC in the Makefile?

have_func does it.

I thought Ruby 1.9 had it by default defined in its internals.

No.

···

--
Nobu Nakada

have_func does it.

yes, but create_header must be called

Guy Decoux

Hi,

At Mon, 28 Aug 2006 23:41:58 +0900,
ts wrote in [ruby-talk:211133]:

> have_func does it.

yes, but create_header must be called

have_func stores the macros in $defs, and they are directly
placed in Makefile as CPPFLAGS, unless create_header is called.

···

--
Nobu Nakada