Process to publish extensions with multiple version compatibilities?

Hi there,

Despite looking thoroughly for similar topics or in the doc, I could not find satisfactory answer to my problem.

I am developing an extension relying on some external libs (in an .so file). I understood (and my tests have shown) that the libs need to be compiled with some specific Ruby version to be compatible with corresponding SketchUp versions. That’s fine.

My question is, when it comes to submitting the the extension for publishing, which version shall be submitted to the team? only the one compatible with the most recent SU version or all of them? if yes to the latter, is there a specific way of packaging them?

Thanks for your help.

All of them. Ie the RBZ package must be 100% complete as if you were going to only publish it unencrypted.
(But if you check the box for encryption on the signing portal, the signed RBZ returned will be encrypted.)

The easiest way is to have subfolders named for the ruby versions beneath platform folders.
… and then build your loading paths with File::join

# From a file **within** your extension's subfolder ...

os =( Sketchup.platform == :platform_win ? 'win' : 'mac' )
ver = RUBY_VERSION.to_f.to_s

# Load the library files, omitting file type ...

this_lib = File.join( __dir__, os, ver, 'this_lib' )
require this_lib

that_lib = File.join( __dir__, os, ver, 'that_lib' )
require that_lib

REF:


Example folder/file tree ... (click to expand) ...
.../Plugins
  |
  +-- GeoShinobi_NiftyWidget.rb
  |
  +-- GeoShinobi_NiftyWidget
         |
         +-- ( extensions files | other subfolders as needed )
         |
         +-- mac
         |    |
         |    +-- 2.2
         |    |    |
         |    |    +-- this_lib.bundle
         |    |    +-- that_lib.bundle
         |    |
         |    +-- 2.5
         |    |    |
         |    |    +-- this_lib.bundle
         |    |    +-- that_lib.bundle
         |    |
         |    +-- 2.7
         |         |
         |         +-- this_lib.bundle
         |         +-- that_lib.bundle
         +-- win
              |
              +-- 2.2
              |    |
              |    +-- this_lib.so
              |    +-- that_lib.so
              |
              +-- 2.5
              |    |
              |    +-- this_lib.so
              |    +-- that_lib.so
              |
              +-- 2.7
                   |
                   +-- this_lib.so
                   +-- that_lib.so

Thanks heaps for this detailed answers. Perhaps useful to add to the official doc :ok_hand:

Ruby maintains ABI compatibility between major.minor versions. Hence, an *.so file that works with Ruby 2.7.2 will work with any Ruby version 2.7.x, assuming a platform match.

Hence, rather than using RUBY_VERSION.to_f.to_s, I might suggest either

RbConfig::CONFIG['ruby_version'] #=> 2.7.0

or

"#{RbConfig::CONFIG['MAJOR']}.#{RbConfig::CONFIG['MINOR']}" #=> 2.7

Both of the above are used in ‘pre-compiled’ extension gems.

Also, note that with Windows, the below transition is a change from mingw to mswin builds…

SU 2020 2.5.5 mingw
SU 2021 2.7.2 mswin

EDIT: Want to make clear that what Dan suggested will work fine (RUBY_VERSION.to_f.to_s) with all current released versions of Ruby.

I have an aversion to treating version data as a numeric sequence, as truncating zeros can lead to incorrect data, eg, ‘3.10’ may be converted to ‘3.1’. No Ruby versions have been released with a minor version greater than 9, so in practice, treating the major.minor string as a float is ok.

Oh, this true. Basically I was using the #to_f call to truncate the “teeny” bug version. (Lazy of me, I know.)

How about ?

RUBY_VERSION.split('.')[0..1].join('.')
#=> "2.7"

It works for minor releases above 9 …

"3.10.4".split('.')[0..1].join('.')
#=> "3.10"

Any other nifty ways … String#scan or regular expressions ?

Maybe the following, as it actually somewhat verifies the string?

RUBY_VERSION[/\A\d+\.\d+/]
puts '30.100.1'[/\A\d+\.\d+/] #=> 30.100
puts '3.10A.A'[/\A\d+\.\d+/]  #=> 3.10

I like this last example better.