Raphael Ottoni
Raphael Ottoni

Reputation: 516

Requiring lib (openmp) in ruby C extension gem [OSX]

I am starting to develop ruby gem extensions in C and I am stuck with a problem that appears to be simple.

What I am trying to do is to create a simple gem extension that will execute some code in C that uses openmp.

Here are my extconf.rb and my c code:

extconf.rb

require "mkmf"
extension_name = "visualize_helper"
dir_config("visualize_helper")
CONFIG["CC"] = "gcc-5"
$CXXFLAGS += ' -fopenmp '
$CFLAGS += ' -fopenmp '
have_library('gomp', "main")
create_makefile "visualize_helper/visualize_helper"

I needed to change the compiler CONFIG["CC"] because OSX default gcc compiler is a CLANG one, so a installed gcc-5 through brew.

visualize_helper.c

#include <ruby.h>
#include <stdlib.h>
#include <omp.h>

static VALUE openmp_test(VALUE self, VALUE string) {

  int nthreads, tid;
  FILE *f = fopen("/tmp/open_mp", "w");

  /* Fork a team of threads giving them their own copies of variables */
  #pragma omp parallel private(nthreads, tid)
  {

     /* Obtain thread number */
     tid = omp_get_thread_num();
     fprintf(f,"Hello World from thread = %d\n", tid);

     /* Only master thread does this */
     if (tid == 0)
     {
       nthreads = omp_get_num_threads();
       fprintf(f,"Number of threads = %d\n", nthreads);
     }

  }  /* All threads join master thread and disband */

  fclose(f);
  return string;
}

// Main function called when the gem is loaded
void Init_visualize_helper(void) {

  // Register the method openmp_test as a singleton for the class
  rb_define_singleton_method(mVisualizeHelper, "openmp_test",openmp_test, 1 );
}

When a try to compile, at the first step which is to create the Makefile:

ruby extconf.rb

I get the following error:

checking for Init_visualize_helper() in -lgomp... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.        
You may need configuration options.

Provided configuration options:
    --with-opt-dir
    --without-opt-dir
    --with-opt-include
    --without-opt-include=${opt-dir}/include
    --with-opt-lib
    --without-opt-lib=${opt-dir}/lib
    --with-make-prog
    --without-make-prog
    --srcdir=.
    --curdir
    --ruby=/Users/rapha/.rvm/rubies/ruby-2.1.5/bin/ruby
    --with-visualize_helper-dir
    --without-visualize_helper-dir
    --with-visualize_helper-include
    --without-visualize_helper-include=${visualize_helper-dir}/include
    --with-visualize_helper-lib
    --without-visualize_helper-lib=${visualize_helper-dir}/lib
    --with-gomplib
    --without-gomplib
/Users/rapha/.rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/mkmf.rb:456:in  `try_do': The compiler failed to generate an executable file.   (RuntimeError)
You have to install development tools first.
    from /Users/rapha/.rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/mkmf.rb:541:in `try_link0'
    from /Users/rapha/.rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/mkmf.rb:556:in `try_link'
    from /Users/rapha/.rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/mkmf.rb:742:in `try_func'
    from /Users/rapha/.rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/mkmf.rb:973:in `block in have_library'
    from /Users/rapha/.rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/mkmf.rb:918:in `block in checking_for'
    from /Users/rapha/.rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/mkmf.rb:351:in `block (2 levels) in postpone'
    from /Users/rapha/.rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/mkmf.rb:321:in `open'
    from /Users/rapha/.rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/mkmf.rb:351:in `block in postpone'
    from /Users/rapha/.rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/mkmf.rb:321:in `open'
    from /Users/rapha/.rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/mkmf.rb:347:in `postpone'
    from /Users/rapha/.rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/mkmf.rb:917:in `checking_for'
    from /Users/rapha/.rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/mkmf.rb:968:in `have_library'
    from extconf.rb:7:in `<main>'

mkmf.log

"gcc -o conftest -I/Users/rapha/.rvm/rubies/ruby-2.1.5/include/ruby-2.1.0/x86_64-darwin14.0 -I/Users/rapha/.rvm/rubies/ruby-2.1.5/include/ruby-2.1.0/ruby/backward -I/Users/rapha/.rvm/rubies/ruby- 2.1.5/include/ruby-2.1.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE - D_DARWIN_UNLIMITED_SELECT -D_REENTRANT   -O3 - I/Users/mpapis/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 - pipe -fopenmp  conftest.c  -L. -L/Users/rapha/.rvm/rubies/ruby-2.1.5/lib  -L. -L/Users/mpapis/.sm/pkg/active/lib -fPIC -Bstatic -fstack-protector    -arch x86_64   -lruby-static -framework CoreFoundation  -lpthread -ldl - lobjc "
ld: warning: directory not found for option '- L/Users/mpapis/.sm/pkg/active/lib'
ld: library not found for -lgomp
clang: error: linker command failed with exit code 1 (use -v to see invocation)
checked program was:
/* begin */
1: #include "ruby.h"
2:
3: int main(int argc, char **argv)
4: {
5:   return 0;
6: }
/* end */

Things I have tried

The very first three things that comes to my eyes are:

I updated my Xcode version to 7.2.1, my RVM to 1.27.0, I even tried to compile ruby 2.1.5 and 2.3.0 through rvm instead of using the binaries.

A little more info

If I remove both lines of have_lib('gomp',X) the I compile and generate the makefile, and if a check the makefile I see the:

CC = gcc-5 

Upvotes: 3

Views: 127

Answers (1)

Raphael Ottoni
Raphael Ottoni

Reputation: 516

To solve this issue, I end up creating a link on /usr/local/bin/gcc to gcc-5:

 ln -s /usr/local/bin/gcc-5 /usr/local/bin/gcc

and removing the following line from extconf.rb:

CONFIG["CC"] = "gcc-5"

Upvotes: 1

Related Questions