Shell command (executable) fails when launched with backticks from SketchUp

I built a Ruby 2.7 version of gsl, using the master branch of the repo.

See Release Zip files with extension gems · MSP-Greg/sketchup-ext-gem · GitHub. Download the file gsl_mstr_ruby27.zip. In the SU Ruby console, require/load the test_gsl_load.rb file, and you should see the output from puts GSL::VERSION.

Still the same problem. I completely disabled my extension and run

require "C:/Users/ruggiero/Downloads/test_gsl_load.rb"

and still get the same error

Error: #<LoadError: 127: The specified procedure could not be found.   - C:/Users/ruggiero/Downloads/gsl_gem/gsl_native.so>
C:/Program Files/SketchUp/SketchUp 2021/Tools/RubyStdLib/rubygems/core_ext/kernel_require.rb:92:in `require'
C:/Program Files/SketchUp/SketchUp 2021/Tools/RubyStdLib/rubygems/core_ext/kernel_require.rb:92:in `require'
C:/Users/ruggiero/Downloads/gsl_gem/gsl.rb:31:in `<top (required)>'
C:/Users/ruggiero/Downloads/test_gsl_load.rb:1:in `require_relative'
C:/Users/ruggiero/Downloads/test_gsl_load.rb:1:in `<top (required)>'
C:/Program Files/SketchUp/SketchUp 2021/Tools/RubyStdLib/rubygems/core_ext/kernel_require.rb:92:in `require'
C:/Program Files/SketchUp/SketchUp 2021/Tools/RubyStdLib/rubygems/core_ext/kernel_require.rb:92:in `require'
<main>:in `<main>'
SketchUp:in `eval'

FWIW my $LOAD_PATH already included the path to the gsl gem lib directory and libgls and libgslcblas were already in

C:\Program Files\SketchUp\SketchUp 2021\Tools\RubyStdLib\platform_specific that is in $LOAD_PATH. My installer puts them there.

Just to be sure I removed them and launched a fresh SU and I have the same error when running your build.

BTW sqlite, another native gem, works.

I’ll see what I can find with the ‘The specified procedure could not be found’.

BTW sqlite, another native gem, works.

How is that code loading libsqlite3-0.dll?

It has been a long time, but I think this was the logic.

  1. I first installed sqlite3 with pacman from Ruby Installer + Devkit
  2. Installed the sqlite gem
  3. Checked the dll dependencies of sql_native with objdump
  4. Copied the dlls from the msys folder in the Ruby installation to C:\Program Files\SketchUp\SketchUp 2021\Tools\RubyStdLib\platform_specific

Now I have those dlls in my repo so I do not need to recreate them very often

I’ll look at this more later. It’s odd.

I don’t know if you’re familiar with the distinctions between Ruby build types (mingw, ucrt, and mswin), but building extensions with mingw builds (the current publicly available Ruby 2.7) and then using them in SU 2021 and later may cause issues.

Last night I backported the changes needed and built a ucrt Ruby 2.7, which uses the same msvc runtime as SU 2021 & 2022. I rebuilt the gsl gem with it.

So, if you could try downloading the gsl_mstr_ruby27_ucrt.zip file from the GitHub release above, it might work.

Note that the gsl dll’s and the gsl_native.so file are ucrt, not mingw, so they differ from the files you’ve built and also the files in gsl_mstr_ruby27.zip

I had just a general (you could say vague) understanding of it. I will definitely try the new file you have created later today. I really appreciate your help!

If one uses objdump on SU 2021’s x64-msvcrt-ruby270.dll, output is:

ADVAPI32.dll
api-ms-win-crt-convert-l1-1-0.dll
api-ms-win-crt-environment-l1-1-0.dll
api-ms-win-crt-filesystem-l1-1-0.dll
api-ms-win-crt-heap-l1-1-0.dll
api-ms-win-crt-math-l1-1-0.dll
api-ms-win-crt-runtime-l1-1-0.dll
api-ms-win-crt-stdio-l1-1-0.dll
api-ms-win-crt-string-l1-1-0.dll
api-ms-win-crt-time-l1-1-0.dll
api-ms-win-crt-utility-l1-1-0.dll
imagehlp.dll
IPHLPAPI.DLL
KERNEL32.dll
SHELL32.dll
USER32.dll
VCRUNTIME140.dll
WS2_32.dll

If one uses objdump on a standard stand-alone Ruby 2.7 build, output is:

ADVAPI32.dll
imagehlp.dll
IPHLPAPI.DLL
KERNEL32.dll
libgmp-10.dll
libssp-0.dll
msvcrt.dll
SHELL32.dll
USER32.dll
WS2_32.dll

SU’s Ruby is using VCRUNTIME140.dll, api-ms-win-crt-runtime-l1-1-0.dll, and several api-ms-win-crt-* dlls, stand-alone Ruby is using msvcrt.dll.

The Ruby 2.7 ucrt build I created outputs as below, which is a much better match:

ADVAPI32.dll
api-ms-win-crt-convert-l1-1-0.dll
api-ms-win-crt-environment-l1-1-0.dll
api-ms-win-crt-filesystem-l1-1-0.dll
api-ms-win-crt-heap-l1-1-0.dll
api-ms-win-crt-locale-l1-1-0.dll
api-ms-win-crt-math-l1-1-0.dll
api-ms-win-crt-private-l1-1-0.dll
api-ms-win-crt-runtime-l1-1-0.dll
api-ms-win-crt-stdio-l1-1-0.dll
api-ms-win-crt-string-l1-1-0.dll
api-ms-win-crt-time-l1-1-0.dll
api-ms-win-crt-utility-l1-1-0.dll
imagehlp.dll
IPHLPAPI.DLL
KERNEL32.dll
libgmp-10.dll
libssp-0.dll
SHELL32.dll
USER32.dll
WS2_32.dll

Back in March of 2016, in another topic on the Trimble Connect extension having the same error message, I posted …

In that topic thread Bugra noted that this or a similar error could occur if an incompatible file of the same name has been installed by another application into "C:/Windows/system32". This was correctable I think by being sure to load from the correct disk location rather than relying upon searching through the environment PATH list.

Anyway I think Greg is on the right trail here … that this is a matter of compatibility.

I am sorry to say that it gives the same error.

From Ruby console:

require "C:/Users/ruggiero/Downloads/gsl_mstr_ruby27_ucrt/gsl27u/test_gsl_load.rb"


Error: #<LoadError: 127: The specified procedure could not be found.   - C:/Users/ruggiero/Downloads/gsl_mstr_ruby27_ucrt/gsl27u/gsl_gem/gsl_native.so>
C:/Program Files/SketchUp/SketchUp 2021/Tools/RubyStdLib/rubygems/core_ext/kernel_require.rb:92:in `require'
C:/Program Files/SketchUp/SketchUp 2021/Tools/RubyStdLib/rubygems/core_ext/kernel_require.rb:92:in `require'
C:/Users/ruggiero/Downloads/gsl_mstr_ruby27_ucrt/gsl27u/gsl_gem/gsl.rb:31:in `<top (required)>'
C:/Users/ruggiero/Downloads/gsl_mstr_ruby27_ucrt/gsl27u/test_gsl_load.rb:1:in `require_relative'
C:/Users/ruggiero/Downloads/gsl_mstr_ruby27_ucrt/gsl27u/test_gsl_load.rb:1:in `<top (required)>'
C:/Program Files/SketchUp/SketchUp 2021/Tools/RubyStdLib/rubygems/core_ext/kernel_require.rb:92:in `require'
C:/Program Files/SketchUp/SketchUp 2021/Tools/RubyStdLib/rubygems/core_ext/kernel_require.rb:92:in `require'
<main>:in `<main>'
SketchUp:in `eval'

Just out of curiosity I tried both builds (gsl_mstr_ruby27.zip and gsl_mstr_ruby27_ucrt.zip) from the system Ruby and they both work. Not sure if that helps.

I can repo the issue in SU 2022. I’ve never seen

LoadError: 127: The specified procedure could not be found.

I’ve worked with a lot of extension gems on all OS’s. But, I haven’t run many in SU…

And, as you found (thanks for checking), it works with stand-alone Ruby.

Not sure, right now all I’m seeing is very dense forest.

SU 2021 & 2022 (and future builds) are using a Ruby mswin build with VCRUNTIME140.dll, but parts of it mimic Ruby mingw builds.

This helps the Trimble team with debugging, and also helps with mystery errors caused by different msvc runtimes being loaded in the same process.

So, to compile extension gems, ideally one should use a special stand-alone Ruby build. I’ve got that built, and still having the issue above.

So, sometime soon I’ll build a stand-alone Ruby that mimics the SU Ruby, and see if I can repo the issue with it. I’ll also try with other extension gems like sqlite3 and nokogiri.

If you recall any other extension gems that people have used, feel free to mention them.

——————————————— Off-topic ———————————————

I’ve always felt that Trimble should allow for extension gems, maybe a user supported repo that contains popular pre-compiled gems that would be allowed and available to all plugin authors.

Most of the extension gems that I’ve seen mentioned are pretty mature, so large API changes are unlikely. Or, if the ‘user supported repo’ contained current versions, most plugin authors would be happy?

Just because you ask :slight_smile:
I don’t know if the numo series of gems are very popular, but I did fail to make it work in Windows (almost no problems on macos). It has been a while, but I think it had the same problem.

Well, some of the gems coders have attempted to or wished to use:

  • Nokogiri
  • prawn
  • rest-client
  • yajl (or yajl-ruby)
  • clipper
  • savon
  • google-protobuf
  • rubyXL (needs nokogiri)
  • mysql (or ruby-mysql)

If you recall the following topic thread in which Thomas explained some of the problems with gems:

How to use a local ruby gem inside a Sketchup Extension

As mentioned in the above topic, (even by yourself,) in SketchUp’s shared ObjectSpace we cannot have two varying versions of the same gem loaded at the top level. Extensions incompatible with the latter loaded gem version would break.

For a public library to work, we’d need a toplevel library namespace (say GemLib) and each gem version would need to be module wrapped inside the library, inside a gem submodule, inside a specific version submodule which would act as a mixin module for SketchUp extensions.

This would allow multiple version of a gem to be loaded and used.

So as an example using a invented version number, say an extension needed to use the v2.1.4 of the Prawn gem.

  • It would reside at ".../gemlib/prawn/v2.1.4"
    (Likely the "gemlib" path would be in the $LOAD_PATH array.)

  • It’s code would be wrapped in: GemLib::Prawn::V2_1_4
    which would be a mixin module

…, and used something like:

module BobsUncle
  module NiftyWidget

    require "gemlib/prawn/v2.1.4/prawn"
    include GemLib::Prawn::V2_1_4

  end
end

Another extension might be loading and including a different version of the Prawn gem, but neither would be defining classes or modules at the top level, and each inclusion would create proxies to a specific version mixin module.

The library could also define a simpler means of loading a specific gem version similar to Gem::install … ie:

GemLib.load("prawn", "2.1.4")

… which could return a reference to the loaded mixin module so that it could be called as an argument to include

include GemLib.load("prawn", "2.1.4")

Now, … as I recall, Prawn has a dependency on Nokogiri.

How would such a special SketchUp gem system ensure a compatible dependent gem was loaded and mixed into the same module ?

It starts to seem like it could get as complex as Rubygems itself. (Which might be that SketchUp gets a tweaked edition of Rubygems and a dedicated gem repository.)

We, I have the same issue. I built sqlite3 & nokogiri, and they loaded fine in SU 2022. I hope to look at it more this weekend…

EDIT: narray works fine in stand-alone Ruby, but fails with the same error message as gsl

Any particular gems? I worked a bit with narray. It builds and tests fine on Ubuntu, macOS, & Windows. The Windows mswin build also passed…

Thanks for the reply. I’ll open another thread re gems. I should have been clearer. I’m not proposing a ‘RubyGems for SketchUp’, as that would be a very large undertaking.

Just like a given version of SketchUp forces one to work with a particular Ruby version, and also the versions of its std-lib items, I’m proposing some kind of gem set that would be fixed by either SU version or Ruby version.

So, there would be only one approved version of each of the gems contained in the set, and, as mentioned above, new sets would either follow SU releases or Ruby versions in SU. Note that some gems might not change versions between sets.

A few points:

  1. Popular gems are not introducing breaking changes to their API’s often.

  2. It would be a bit more work, but the ‘gem creation’ could be cloud based. So, all of the code (including compiled code) would be generated in the cloud.

  3. I’m speaking of what could be done on Windows, I’m not that familiar with macOS, so I’m not sure if and how it could be done on that platform.

  4. Any extension gems would be pre-compiled and include any dlls that they’re dependent on. The dll’s would either be from the MSYS2 system or built with microsoft/vcpkg.

  5. This would require custom stand-alone Rubies for building. I could provide them or they could be built in the cloud.

Well this indeed would solve the differing version challenge, that is until some extension breaks etiquette and installs a version they think they need (for some reason.)

I’ve long thought that SketchUp should have it’s own gem server that hosts only compatible gems.

Anyway, as Thomas has said, extensions hosted by Trimble require gem and library code to be wrapped in the extension or it’s author’s namespace modules.

The gem system is too lenient in allowing gems to define classes at the top level. Only the Ruby core should do ever do this.

1 Like

Sorry for the late post. In the past, SU was messy when opening other processes. With SU 2021 & 2022, I just used IO.popen, and it works. Even added a long sleep in the sub-process, and SU stays responsive…

Re your app:

  1. It only works with rubyw, not ruby. Using ruby opens a console window, rubyw does not. Not sure if macOS has an equivalent.

  2. Most Ruby ‘shell’ type commands pass along the ENV to the sub-process. SU sets both GEM_HOME and GEM_PATH. You may need to strip/delete those for your stand-alone to find it’s own gem files? Not.Sure.