Cannot install ruby gem in OSX

(1) This library was gemified, but unfortunately it is uncompiled.

(2) The version you cite is actually a year out of date. This is a good example of what Thomas was talking about. There then exists the high probability that someone else will package to later version, or if you packaged the later, someone else would likely package the earlier.

This is the latest version 5.0.3 which uses the 5.x Clipper library:
https://rubygems.org/gems/ruby_clipper
Which points at project:

So to do what Thomas says, you need to change the “rbclipper.cpp” file a bit.

Change line 353 to:

VALUE top   = rb_define_module("Rojj");

… or whatever your toplevel namespace module name is.

And change line 354 to:

VALUE mod   = rb_define_module_under(top,"Clipper");


Then the “version.rb” file needs to be also wrapped within your toplevel module.
Example:

module Rojj::Clipper
  # Keep first two components sync'd to Clipper's major/minor.
  # Last is our build number based on that.  Hopefully there
  # won't be too much churn re: Clipper's version vs. the bindings.
  VERSION = "5.0.3"
end
1 Like

Thanks a lot Dan for the detailed answer. Will test this and let you know.

OK. It was more complicated than i thought. A bit of help would be greatly appreciated.

Dan, are you saying that i should download the latest version of the gem, make the modifications you suggest and then install from the local (modified) gem file?

After that I should be able to move the compiled files to the SU plugin folder as I do in Windows 7?

Sorry if the questions are dumb, but I am a bit stuck.

Yes.

The only files that really belong in the “Plugins” folder, are the SketchupExtension class registration scripts. All plugin files and support libraries should be in sub-directories.

In the case of custom compiled gems, it is really best to convert their file & folder structure to be SketchupExtension class compatible. That means putting the compiled .so file in a plugin subdirectory (named ToplevelModule_GemName,) and write a SketchupExtension registration script for the “Plugins” directory (named ToplevelModule_GemName.rb.)

However … if you modify it as outlined above, it will become a library module wrapped within YOUR toplevel module. Noone else will be expected to use it in that way, and it will not clash with any other distribution. No one else’s distribution will be expected to wrap the gem module within your namespace, so it is safe from other plugins.

If it will only be distro’d with your plugin (and your plugin is SketchupExtension class compatible,) then you won’t need to do the above. Just package the library file along with your plugin’s other files in it’s plugin subdirectory (named ToplevelModule_PluginName.) Some where usually at the top of your plugin’s loader script, you would make a call like:
require File.dirname(__FILE__)<<"/ToplevelModule_GemName.so"
or if you know the plugin sub-dir name will not change:
require "ToplevelModule_PluginName/ToplevelModule_GemName.so"

If you look at some of Thomas’ plugins, you’ll see how he deals with distributing Mac compiled libs, along with two separate libs for Windows (32bit and 64bit.)

You can probably make things easier for your distribution by simply extracting the gem content (which you now have wrapped in your namespace) into the support folder of your extension directly.

1 Like

I said that, but it was hidden in all my rambling. (sorry)

No success so far.

Downloaded the rep from here (version 5.03)

Replaced line 352 (not 353) with

VALUE top   = rb_define_module("RG");

and line 354 with

VALUE mod   = rb_define_module_under(top,"Clipper");

Also updated version.rb with

module RG::Clipper
  # Keep first two components sync'd to Clipper's major/minor.
  # Last is our build number based on that.  Hopefully there
  # won't be too much churn re: Clipper's version vs. the bindings.
  VERSION = "5.0.3"
end

Then I run

rake install

but i get the error

rake aborted!
There was a NameError while loading clipper.gemspec:
uninitialized constant RG from
  /Users/ruggiero/Downloads/rbclipper-master/clipper.gemspec:4:in `<main>'
....

I have also tried without any modifications to the files.

Once i have replaced ‘vector_salad’ with ‘clipper’ (no idea what vector_salad means) in the clipper.gemspec file and commented

s.licence     = "Boost Software License - Version 1.0"

because of no method error, it seems to work fine.

I have tried to move the ‘.o’ (there are no .so created) files from the gem folder created in my plugin folder, but no success. The require ‘RG/clipper’ does not give any error, but then Clipper is not recognized.

Honestly, I have spent a few hours testing various things, but i am really lost at this point.

Any tip?

To get the “production” gemspec, it’s best to download from the Rubygems gem server:
https://rubygems.org/downloads/ruby_clipper-5.0.3.gem

The gem installer will download the gem from Rubygems server for you.

FYI: gem files are gz archives and can be opened with 7Zip.

Anyway I ran the “setrbvars.bat” in my System Ruby install, then ran irb.bat, and from within the IRB shell I called:

Gem::install "ruby_clipper"

It was built (after having to tell Comodo to allow several programs to run.)
After the rake task it wrote the gemspec file to :
C:\Ruby200\lib\ruby\gems\2.0.0\specifications

This is what it looks like. (So the one you have, has some quirky things in it, meant only for his [the authors] development repo setup.)

# -*- encoding: utf-8 -*-

Gem::Specification.new do |s|
  s.name = "ruby_clipper"
  s.version = "5.0.3"

  # more gem attributes ...
  # see full file attached (below)

end

ruby_clipper-5.0.3.gemspec.rb (1.3 KB)

@DanRathbun,
on the mac system gem install for irb the spec varies on the gem version
s.rubygems_version = "2.0.14"
further investigating shows…

irb(main):015:0> Gem.rubygems_version
=> Gem::Version “2.0.14”

# Ruby Console
Gem.rubygems_version
2.0.3

could the fact they differ break gems on a mac?
john

I don’t know as do not have a Mac. And I purposely installed the same-same as SketchUp has for testing, etc.

Two modes of updating rubygems:

$ gem update --system

… or if that doesn’t work:

$ gem install rubygems-update
$ update_rubygems

But you may get a newer version than what SketchUp has.

That came from:
http://docs.seattlerb.org/rubygems/UPGRADING_rdoc.html

After some good reading of rubygems excellent documentation I got it work on the system Ruby. These are the steps assuming that the gem is downloaded in the Download folder

First download the gem from https://rubygems.org/downloads/ruby_clipper-5.0.3.gem

Unpack the gem

gem unpack ruby_clipper-5.0.3
cd ruby_clipper-5.03

Modify lib/clipper/version.rb adding the top level namespace

module Clipper
......

to

module RG::Clipper #RG is my top level namespace

Now modify the rbclipper.cpp from

VALUE mod   = rb_define_module("Clipper");
VALUE k = rb_define_class_under(mod, "Clipper", rb_cObject);
  rb_define_singleton_method(k, "new",
                         (ruby_method) rbclipper_new, 0);

to

 VALUE top   = rb_define_module("RG"); #Top level namespace
 VALUE mod = rb_define_module_under(top, "Clipper"); #Clipper module under RG namespace
 VALUE k = rb_define_class_under(mod, "Clipper", rb_cObject);
 rb_define_singleton_method(k, "new",
                         (ruby_method) rbclipper_new, 0);

Now clipper is under the top level namespace RG.

We need to create the gemspec file. Move back to Download and extract the gemspec file from the original gem (this has not changed). This command extracts the gemspec file in ruby format (–ruby)

gem spec ruby_clipper-5.0.3.gem --ruby > ruby_clipper-5.0.3/ruby_clipper-5.0.3.gemspec

Now we need to rebuild the gem. Move back to the gem folder

cd ruby_clipper-5.0.3

and build the gem using the gemspec file just created

gem build ruby_clipper-5.0.3.gemspec

At this point we can install the modified gem from the local file (we are still in the gem folder)

sudo gem install --force --local ruby_clipper-5.0.3.gem

--force #Ignore dependencies
--local #Restrict operations to the LOCAL domain

The (modified) gem is now installed in system Ruby.

In irb we can write

require 'clipper'
c = RG::Clipper::Clipper.new

and get

=> #<RG::Clipper::Clipper:0x007f8ea232ca48 @multiplier=1048576>

Now I move

/Library/Ruby/Gems/2.0.0/gems/ruby_clipper-5.0.3/ext/clipper/clipper.bundle

to my SU RG folder

Users/ruggiero/Library/Application Support/SketchUp 2015/SketchUp/Plugins/RG/ext

but when i require clipper

require 'RG/ext/clipper' 

I get a ugly bug splat!!!

Am i doing something wrong?

Thanks

Yup.

In normal “system” Ruby (and actually also in SketchUp Ruby,) when you require a gem that is already installed, the rubygems system pushes the gem’s path with it’s “lib” subdirectory appended, into the $LOAD_PATH array, temporarily.

Then it calls require gemname.
So this means there is usually a script or object file by that name in the “lib” subdirectory, (ie, “clipper.rb”, or “clipper.so”, or “clipper.o” etc.)
It is also common for the gems support subdir to also have that same name.

So it’s the clipper gem’s “lib” subdirectory that is the “ready for primetime” directory.
So to mimic what rubygems does, you put that “lib” subdirectory inside your own plugin subdir, and temporarily push it’s absolute path onto the $LOAD_PATH array (aka $:.)

From your plugin loader.rb:

lib = File.dirname(__FILE__)<<"/lib"
$:.unshift( lib )
require "clipper"
require "clipper/version"
$:.delete( lib )

Add: You could likely in your case, skip the path pushing because there are only two files, but in the case of “rubyzip” there are a whole bunch of files in the “zip” subdir that get loaded via require calls, so the “/lib” path needs to be in the $LOAD_PATH array temporarily.

SO this would also work:

require "RD_ThisPlugin/lib/clipper"
require "RD_ThisPlugin/lib/clipper/version"
1 Like

Thanks Dan.

I have tried both options.

I copy the lib folder in my RG plugin folder, but when I call

require "RG/lib/clipper"

I still have bugsplat

This is the content of my RG folder

RG
├── RG_tests_core.rb
├── clip.rb
└── lib
    ├── clipper
    │   └── version.rb
    └── clipper.bundle

Is it possible that there is a version issue?

Sketchup

puts "#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}"
2.0.0-p247

Mac

ruby 2.0.0p481 (2014-05-08 revision 45883) [universal.x86_64-darwin13]

More generally. If a C extension is self contained, is it always supposed to work in Ruby?

I can’t say much about compiling on Mac, as I don’t have one.

I believe Mac developers install RVM, and then install Ruby 2.0.0-p247, and compile with the same version SketchUp has.

Sorry this is such a pain dealing with gems. The SketchUp rubygems implementation needs work.

It would nice if plugins could just require them. (Ie, a gemserver at sketchup.com.)

It seems that I have to give up then. Thank you very much for your help Dan.

Well if I have to guess I’d say compiler switches.

Can you get the PC edition loading ?

Your other option is to repackage as 3 pre-compiled gem archives, and copy the appropriate one to the users’s SketchUp gem cache directory, then use Gem::install, but you’d need to make the gem a unique name. Likely prepending your “RD_” namespace identifier to the gem file name.

Yes, the PC version works fine. Quite straightforward in that case. I just copy the .so file.

Well you need two, one for 32bit and one for 64bit.