I'm attempting to create a ruby native extension, but when I run rake which uses ext/example_project/extconf.rb to build my project and run my tests under test/, I get the following error when the tests are run:
./home/jbuesking/.rbenv/versions/2.3.0/bin/ruby: symbol lookup error:
/home/jbuesking/repositories/example_project/lib/example_project/example_project.so: undefined symbol: some_function
I'm pretty sure my files are not being linked correctly and that I need to alter my extconf.rb and/or Rakefile in some way, but I'm not sure how.
I've created a simple repository that demonstrates the issue over on GitHub. It'll fail with the same error if you clone it and run rake from the projects root.
Some additional information:
- I used the ruby gem
hoeto create the project viasow example_project - The failing function is attempting to call a function defined in the subdirectory
ext/example_project/c_example_project. My actual project uses a git submodule from theext/example_projectdirectory, which in turn sets up the submodule as a subdirectory. The submodule is a c project with a flattened structure (all files in the root directory). Note: That wording may be confusing, but the key point is that there's a nested c project defined atext/example_project/c_example_projectwhich has methods I'm trying to call.
Let me know if any clarification is needed, and I'll do my best to provide it.
So, there are some interesting issues you have here. By default, mkmf doesn't actually support specifying multiple directories for building sources.
There is a workaround, as seen here (Takehiro Kubo's comment about setting objs):
https://www.ruby-forum.com/topic/4224640
Basically, you construct the
$objsglobal in yourextconf.rbfile yourself.Using your github code, here's what I added to the extconf.rb and got to work
extconf.rb
Notice I'm actually constructing an absolute path to each of the c sources, for some reason rake-compiler was freaking out if we were just globbing with
{.,c_example_project}/*.c, presumably since it's running the extconf.rb file from another directory.In addition, your tests/c extensions have a few errors in them. Making the following change in
example_project.cfixes the test failure:Explanation
Basically even though you're checking the c_example_project.h header in your extconf.rb, you're not actually generating the object file where
some_functionis defined. So, when linking the final dynamic library that ruby loads up, there's no definition forsome_functionand you get your error.