C ext best practices

A

Ara.T.Howard

rubyists-

i'm wrapped a little libary that already has a full on gnu autotools
installation, call it

libfoobar-0.0.0.tgz

obviously, this unpacks like

libfoobar-0.0.0/
libfoobar-0.0.0/README
libfoobar-0.0.0/configure
libfoobar-0.0.0/foobar.c

if i were to wrap this package for ruby, i'd like to be able to

require 'foobar'

what is the preferred means to make an extenstion like this?

* foobar.c defines ruby bindings and extconf.rb must be called with
'--with-foobar-dir' pointing to an install of libfoobar?

* _foobar.c defines ruby bindings and all libfoobar source files are simply
dropped in same directory such that

ruby extconf.rb
make

results in a foobar.so containing all required stuff?

thoughts?

-a
--
===============================================================================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
| URL :: http://www.ngdc.noaa.gov/stp/
| TRY :: for l in ruby perl;do $l -e "print \"\x3a\x2d\x29\x0a\"";done
===============================================================================
 
T

Tim Hunter

rubyists-

i'm wrapped a little libary that already has a full on gnu autotools
installation, call it

libfoobar-0.0.0.tgz

obviously, this unpacks like

libfoobar-0.0.0/
libfoobar-0.0.0/README
libfoobar-0.0.0/configure
libfoobar-0.0.0/foobar.c

if i were to wrap this package for ruby, i'd like to be able to

require 'foobar'

what is the preferred means to make an extenstion like this?

* foobar.c defines ruby bindings and extconf.rb must be called with
'--with-foobar-dir' pointing to an install of libfoobar?

* _foobar.c defines ruby bindings and all libfoobar source files are
simply
dropped in same directory such that

ruby extconf.rb
make

results in a foobar.so containing all required stuff?

thoughts?

-a

Well, I won't argue that it's "best practices" but here's what RMagick
does. RMagick assumes that the ImageMagick library, libMagick, has already
been installed in a separate step.

RMagick uses the standard GNU ./configure, make, make install sequence.
The configure script (built by autoconf) handles any
non-Ruby configuration - such as finding libMagick - and builds a custom
Makefile, extconf.rb, and a metaconfig file for install.rb. The Makefile's
all: target runs install.rb's config and setup steps. The Makefile's
install: target runs install.rb's install step.

Here's RMagick's Makefile.in. This will probably make it clearer than my
prose description. (The ./configure script also accepts a number of
options, like --with-std-ruby, that it passes on to install.rb via
@RUBY_CONFIG_OPTS@.)

# Path to ruby interpreter
RUBY=@RUBY@

# Any extra options from configure script to pass to 'install.rb config'
RUBY_CONFIG_OPTS=@RUBY_CONFIG_OPTS@

all: config.save
$(RUBY) install.rb setup

install:
$(RUBY) install.rb install

clean: config.save
$(RUBY) install.rb clean

distclean: config.save
$(RUBY) install.rb clean
rm -f Makefile ext/RMagick/extconf.rb metaconfig
rm -f config.status Makefile config.cache config.log
rm -rf autom4te.cache

uninstall: config.save
$(RUBY) uninstall.rb $(RUBY_CONFIG_OPTS)

config.save: metaconfig
$(RUBY) install.rb config $(RUBY_CONFIG_OPTS)
 
A

Ara.T.Howard

Well, I won't argue that it's "best practices" but here's what RMagick
does. RMagick assumes that the ImageMagick library, libMagick, has already
been installed in a separate step.

RMagick uses the standard GNU ./configure, make, make install sequence.
The configure script (built by autoconf) handles any
non-Ruby configuration - such as finding libMagick - and builds a custom
Makefile, extconf.rb, and a metaconfig file for install.rb. The Makefile's
all: target runs install.rb's config and setup steps. The Makefile's
install: target runs install.rb's install step.

Here's RMagick's Makefile.in. This will probably make it clearer than my
prose description. (The ./configure script also accepts a number of
options, like --with-std-ruby, that it passes on to install.rb via
@RUBY_CONFIG_OPTS@.)

# Path to ruby interpreter
RUBY=@RUBY@

# Any extra options from configure script to pass to 'install.rb config'
RUBY_CONFIG_OPTS=@RUBY_CONFIG_OPTS@

all: config.save
$(RUBY) install.rb setup

install:
$(RUBY) install.rb install

clean: config.save
$(RUBY) install.rb clean

distclean: config.save
$(RUBY) install.rb clean
rm -f Makefile ext/RMagick/extconf.rb metaconfig
rm -f config.status Makefile config.cache config.log
rm -rf autom4te.cache

uninstall: config.save
$(RUBY) uninstall.rb $(RUBY_CONFIG_OPTS)

config.save: metaconfig
$(RUBY) install.rb config $(RUBY_CONFIG_OPTS)

very nice.

i guess i'm thinking more along the lines of smallish packages, and would like
avoid having site_ruby/1.8/i686/foobar.so depend on
/usr/local/lib/libfoobar.so.... (i just had a bad experience supporting some
software that required LD_RUN_PATH to manage dependancies). it would be ideal
if

foobar.so

was the result of compiling

foobar.c # original C source
_foobar.c # ruby binding to it

obviously this wouldn't apply to packages likely to be updated independently
(like ImageMagick) but might be o.k. for smallish things like cdb, lockfile
utils, etc.

thoughts?

-a
--
===============================================================================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
| URL :: http://www.ngdc.noaa.gov/stp/
| TRY :: for l in ruby perl;do $l -e "print \"\x3a\x2d\x29\x0a\"";done
===============================================================================
 
N

nobu.nokada

Hi,

At Wed, 21 Apr 2004 23:04:11 +0900,
Ara.T.Howard wrote in [ruby-talk:97854]:
i guess i'm thinking more along the lines of smallish packages, and would like
avoid having site_ruby/1.8/i686/foobar.so depend on
/usr/local/lib/libfoobar.so.... (i just had a bad experience supporting some
software that required LD_RUN_PATH to manage dependancies). it would be ideal
if

foobar.so

was the result of compiling

foobar.c # original C source
_foobar.c # ruby binding to it

obviously this wouldn't apply to packages likely to be updated independently
(like ImageMagick) but might be o.k. for smallish things like cdb, lockfile
utils, etc.

Though, makefile created by configure and one created by
extconf.rb, could conflict. I think you would have to separate
the directories.

One thought (but not tested),

---------- depend:
$(DLLIB): src/foobar.$(LIBEXT)

src/foobar.$(LIBEXT):
$(RUBY) -C "$(@D)" -e "exec *ARGV" $(MAKE) $(MFLAGS) $(@F)


---------- extconf.rb:
topdir = Dir.pwd
IO.foreach(File.join($srcdir, "depend")) do |line|
/\$\(DLLLIB\):\s*(.*\.\$\(LIBEXT\))/ =~ line or next
lib = $1
subdir = File.dirname(lib)
Dir.mkdir(subdir) rescue nil
Dir.chdir(subdir) do
srcdir = $srcdir
unless File.expand_path(srcdir, topdir) == File.expand_path(srcdir)
srcdir = File.join("..", srcdir)
end
system(File.join(srcdir, "configure"), *ARGV) or exit
end
$LOCAL_LIBS << " " + lib
end
create_makefile("foobar")
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

narray on windows? 1
idiot's guide to druby using ssh tunnels 4
Class::name 0
parent of TrueClass, FalseClass 9
pretty exceptions 0
drb with udp 1
pthread masters (that's you guy) 1
LD_RUN_PATH 6

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top