Using Ruby's C API safely and sanely

Hello Rubyists!

I'm trying to integrate Ruby (both for bindings and embedded interpreter)
into a larger project, namely RPM 5. I'm facing several diffuclties there
and hope that somebody might point out a more elegant way of solving things.

First, querying Ruby's compile-time configuration is rather painful. RPM 5
uses Autoconf, and using extconf.rb as yet another layer of configuration
seems not the best way. Currently, we're using calls to "ruby -rrbconfig -e
puts CONFIG::expand ..." to get information like CFLAGS/include directories,
location of Ruby's library directories, and so on. Is there a better way to
do this? Sadly, Ruby doesn't come with a .pc file or something similar, and
a call like Perl's "perl -V:..." doesn't seem to be implemented, either?

Second, including the ruby.h file leads to the inclusion of Ruby's config.h
file. This is clearly not appreciated, as we need to cope with a lot of
HAVE_FOO_H defines, or even Ruby's PACKAGE_NAME, etc. definitions which of
course override RPM's. Is there a sane way of using Ruby's C API, i.e.
including the Ruby header file, without having Ruby wreak havok on our own
defines?

Thanks alot in advance. Every hint is greatly appreciated.

      Eric

Ruby trunk includes a package configuration file.

You should checkout trunk and use it as base of your project.

···

On Nov 8, 1:45 pm, Eric MSP Veith <eve...@wwweb-library.net> wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello Rubyists!

I'm trying to integrate Ruby (both for bindings and embedded interpreter)
into a larger project, namely RPM 5. I'm facing several diffuclties there
and hope that somebody might point out a more elegant way of solving things.

First, querying Ruby's compile-time configuration is rather painful. RPM 5
uses Autoconf, and using extconf.rb as yet another layer of configuration
seems not the best way. Currently, we're using calls to "ruby -rrbconfig -e
puts CONFIG::expand ..." to get information like CFLAGS/include directories,
location of Ruby's library directories, and so on. Is there a better way to
do this? Sadly, Ruby doesn't come with a .pc file or something similar, and
a call like Perl's "perl -V:..." doesn't seem to be implemented, either?

Second, including the ruby.h file leads to the inclusion of Ruby's config.h
file. This is clearly not appreciated, as we need to cope with a lot of
HAVE_FOO_H defines, or even Ruby's PACKAGE_NAME, etc. definitions which of
course override RPM's. Is there a sane way of using Ruby's C API, i.e.
including the Ruby header file, without having Ruby wreak havok on our own
defines?

Thanks alot in advance. Every hint is greatly appreciated.

--
Luis Lavena

You should give some thought to using FFI. It'll work in ruby, rubinius, and jruby.

···

Sent from my iPhone

On Nov 8, 2010, at 8:45 AM, Eric MSP Veith <eveith@wwweb-library.net> wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello Rubyists!

I'm trying to integrate Ruby (both for bindings and embedded interpreter)
into a larger project, namely RPM 5. I'm facing several diffuclties there
and hope that somebody might point out a more elegant way of solving things.

First, querying Ruby's compile-time configuration is rather painful. RPM 5
uses Autoconf, and using extconf.rb as yet another layer of configuration
seems not the best way. Currently, we're using calls to "ruby -rrbconfig -e
puts CONFIG::expand ..." to get information like CFLAGS/include directories,
location of Ruby's library directories, and so on. Is there a better way to
do this? Sadly, Ruby doesn't come with a .pc file or something similar, and
a call like Perl's "perl -V:..." doesn't seem to be implemented, either?

Second, including the ruby.h file leads to the inclusion of Ruby's config.h
file. This is clearly not appreciated, as we need to cope with a lot of
HAVE_FOO_H defines, or even Ruby's PACKAGE_NAME, etc. definitions which of
course override RPM's. Is there a sane way of using Ruby's C API, i.e.
including the Ruby header file, without having Ruby wreak havok on our own
defines?

Thanks alot in advance. Every hint is greatly appreciated.

           Eric
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEARECAAYFAkzYI6wACgkQhS0drJ3goJJVPwCeO/DMR6sGbg777cfjBrwoz8f/
GNcAn1fvmTOkwzXOgNHhzS7u8FkStJ0s
=KNRE
-----END PGP SIGNATURE-----

Luis,

Ruby trunk includes a package configuration file.

You should checkout trunk and use it as base of your project.

thanks for the hint. Do you by chance know in which releases the file will
appear? E.g., is there a plan to backport it to the 1.8 series?

The problem basically is that RPM has to deal with whatever version is
installed on the target system, and most distros still ship one of the 1.8
releases. So it's nice to know that there will be a pkg-config file
appearing in the distro's packages in the future, but we cannot base RPM's
embedded ruby or the bindings code on ruby trunk.

      Eric

···

On Monday 08 November 2010, Luis Lavena <luislavena@gmail.com> wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Luis,

> Ruby trunk includes a package configuration file.

> You should checkout trunk and use it as base of your project.

thanks for the hint. Do you by chance know in which releases the file will
appear? E.g., is there a plan to backport it to the 1.8 series?

1.9.3

I believe it will not be backported to 1.8.x branch. Perhaps 1.9.2

The problem basically is that RPM has to deal with whatever version is
installed on the target system, and most distros still ship one of the 1.8
releases. So it's nice to know that there will be a pkg-config file
appearing in the distro's packages in the future, but we cannot base RPM's
embedded ruby or the bindings code on ruby trunk.

Well, the other approach you have is build ruby statically and use it
embedded and not depend of installed package version.

Ruby in this way is way too bigger. build statically and link against
it sounds much safer for your scenario.

Other languages like Lua are easy to embed and simple to handle, but
if you're building your component depending on installed version, you
will suffer the same issues no matter what language are you trying to
embed.

···

On Nov 9, 10:35 am, Eric MSP Veith <eve...@wwweb-library.net> wrote:

On Monday 08 November 2010, Luis Lavena <luislav...@gmail.com> wrote:

--
Luis Lavena

Luis,

> thanks for the hint. Do you by chance know in which releases the file
> will appear? E.g., is there a plan to backport it to the 1.8 series?

1.9.3

I believe it will not be backported to 1.8.x branch. Perhaps 1.9.2

Hm. :frowning:

Well, the other approach you have is build ruby statically and use it
embedded and not depend of installed package version.

Even though the shipped/statically linked solution works well for embedded
Ruby, it doesn't solve the issues for the bindings code, where we *have* to
query a Ruby installation for some paths, e.g. vendorarchdir/sitearchdir.

      Eric

···

On Wednesday 10 November 2010, Luis Lavena <luislavena@gmail.com> wrote:

On my previous experience dealing with embedding Ruby, I would
recommend you do not depend on system or user installed Ruby.

If you want your program be built and depend on that condition, expect
lot of problems due weirdness of each environment, compilers,
packaging rules, etc.

Other approach you could take is create a Ruby C Extension that acts
as bridge between your application and that installed Ruby. Distribute
it as gem and ask the user install it.

Provide a configuration to locate that compiled extension and connect
to the Ruby interpreter from it.

Then you don't care about the installed Ruby details as long you can
communicate with this bridge.

Something similar is done by Phusion Passenger (in general lines) but
expect lot of work due the above mentioned weirdness.

Other than that, would suggest you provide more details about your
'embedding' conditions directly to Ruby-Core for better answers.

···

On Nov 10, 11:42 am, Eric MSP Veith <eve...@wwweb-library.net> wrote:

> Well, the other approach you have is build ruby statically and use it
> embedded and not depend of installed package version.

Even though the shipped/statically linked solution works well for embedded
Ruby, it doesn't solve the issues for the bindings code, where we *have* to
query a Ruby installation for some paths, e.g. vendorarchdir/sitearchdir.

                    Eric

--
Luis Lavena

Thanks for the hints. And I'll take the topic to Ruby-Core then. :slight_smile:

      Eric

···

On Wednesday 10 November 2010, Luis Lavena <luislavena@gmail.com> wrote:

Other approach you could take is create a Ruby C Extension that acts
as bridge between your application and that installed Ruby. Distribute
it as gem and ask the user install it.
[...]

Other than that, would suggest you provide more details about your
'embedding' conditions directly to Ruby-Core for better answers.