0

I've created some code in c that I'd like to call from ruby. I've used this article as a guide, but I'm having problems getting it to run without linking issues.

To start, I have to directly copy the source files into my ext/NAME/ directory. They don't seem to be picked up if I git submodule them into that directory, meaning they'd be under some subdirectory like ext/NAME/CLIB_GIT_SUBMODULE_FILES/.

Next, it seems like I have to run my c projects makefile, otherwise I run into segfaults. If I run my makefile, object files (.o) are created in the ext/NAME directory, and now when I try to run rake (which runs my test cases under /test/ I see linking issues like:

linking shared-object NAME/NAME.so
gcc: error: SOMEFILE_ONE.o: No such file or directory
gcc: error: SOMEFILE_TWO.o: No such file or directory
gcc: error: SOMEFILE_THREE.o: No such file or directory
make: *** [ruby_fast_numerizer.so] Error 1
rake aborted!

Note that when I run the makefile under ext/NAME/ it creates SOMEFILE_ONE.o, etc.

I'm not sure what's going on at this point :( The guides all seem to be writing new c code in the ext/NAME directory, not wrapping an existing c library. I tried looking at other projects for guidance like nokogiri, but they're doing a whole lot more which makes it hard to sift through.

Any help is much appreciated!

JesseBuesking
  • 6,496
  • 4
  • 44
  • 89

1 Answers1

0

Building an extension

Normally, ext/NAME/extconf.rb uses mkmf (MakeMakefile) to write a new Makefile with all the configuration to build a Ruby extension from the provided sources. MakeMakefile has defaults for where to find source code, headers, and all the other pieces, but you can override them (using dir_config for example).

The generated Makefile will have instructions to compile source files and link everything with the relevant Ruby libraries to produce a native Ruby extension.

If you have an existing C library which has nothing to do with Ruby, it probably has its own Makefile and build process. Don't confuse Ruby's generated Makefile with your own!

Loading a library

For wrapping an existing C library, I would not build a native extension at all, but instead load the library with FFI. The two major FFI options are Fiddle (comes with Ruby, but tutorials are scarce) or the ffi gem (better documented, but requires a gem).

Additional resources

RJHunter
  • 2,829
  • 3
  • 25
  • 30
  • I'll take a look at FFI and let you know if that resolves my problem! – JesseBuesking Oct 30 '16 at 19:13
  • Actually, I'm not sure if this is what I need. I'd like to eventually turn this into a gem and FFI will simplify the interface part but doesn't handle building the c library as well, unless it does and I'm missing that? – JesseBuesking Oct 30 '16 at 19:18
  • You got it right, FFI helps with *loading* and *calling* an already-installed C library (one that has nothing to do with Ruby). For comparison, consider the Nokogiri gem: the nokogiri extension doesn't *build* `libxml2` -- you have to have it installed already. The nokogiri extension does do some compilation, but only for the stuff specific to the Ruby extension. – RJHunter Oct 30 '16 at 22:27
  • What does "you can override them using dir_config" mean? – Nakilon Sep 08 '21 at 04:51