[Mac] Extension doesn't load when installed in several locations (user folder/machine folder)

Hi,
We’re encountering a strange behavior with our extension on MacOS.

Depending on the user’s choice, our installer will either put the extension in:

  • $HOME/Library/Application Support/SketchUp XXXX/SketchUp/Plugins/ (“install for me only”)
  • /Library/Application Support/SketchUp XXXX/SketchUp/Plugins/ (“install for all users”)

In either of those cases, the extension works fine.

However, if the extension is installed in both locations, then it does not seem to load.
It does not appear in the Extensions menu in the toolbar, but it appears in the Extension Manager.

This only happens with:

  • SketchUp 2019
  • SketchUp 2020

The extension works well if installed in both locations with 2017 & 2018.

Thanks for your help.

I don’t know if there is a platform difference but having the same extension loading twice sounds like something that could cause a whole array of problems, especially if you update one of the installs and have two conflicting versions. I’m thinking it could be worth looking into if the installer can be made to prevent this. If you try to install for a single user the installer could warn if the software is already installed for all users. I don’t know if you need admin privileges on Mac to install for all users, but if so the installer could also check if the software is installed for any one individual user, and remove it.

I agree that loading the same extension from two sources could cause hard-to-diagnose problems. Sounds like a time to use the loaded check and skip the rest of it is true. Or do your own equivalent using a module variable.

If the plugin adheres to the SketchupExtension class, then I think it’s also a good idea to check if your extension object has already been defined with the extension registrar script, and if so skip instantiating it.

Example …

module SkatterCompany
  module Skatter

    unless defined?(EXTENSION)
      EXTENSION = SketchupExtension.new(
        'Skatter',
        File.join(
          File.dirname(__FILE__),
          Module.nesting[0].name.gsub('::','_'),
          "loader.rb"
        )
      ).instance_eval {
        self.version = '2.1.0'
        self.creator = 'Skatter Company'
        self.copyright = '(c) '<<Time.now.year
        self.description = 'Skatter inserts many component instances.'
        Sketchup.register_extension(self,true)
        self # returned for constant assignment
      }
    end

  end
end

EDIT: Punchbug @slbaumgartner ! :grin: (Beat me to it while I was typing my example.)

Indeed. Even though it’s relatively common to have different versions of a software installed both “locally” and “globally”, we absolutely don’t want to load them both.

The expected behavior is for the local per-user install to be loaded first, and not the other one. Please correct me if I’m wrong but I think that’s the usual way most software support per user/per machine configurations :slight_smile:

SketchUp 2017 & 2018 seem to handle this case gracefully for instance.

Microsoft is the only repeated file/folder in the two libraries on any of the six mac’s I have here…

I wouldn’t consider that to be common…

application extensions nearly always use the same lib as the app’s support folder, i.e. the User path…

john

1 Like

Hi @john_drivenupthewall

Well, I guess that’s because you’ve been consistent with the way you install software :slight_smile: Same thing on my computers, I prefer not to mess around with the installation type.

The thing is, some users do, for their own reasons (such as a corporate environment with specific IT rules).

That would defeat the purpose of the “install for all users” mode, which some users have to/want to use.

Right now, it looks like a SketchUp bug to me, especially since it works fine before SketchUp 2019.

Hi @DanRathbun, thanks for the feedback.

I made a simple repro case from your snippet and the official Hello World example by @thomthom.

The code is here: https://gist.github.com/merwaaan/d8dd9e11f5afc1409d3dd3bc487906be

Steps:

  • Copy the fake extension to $HOME/Library/Application Support/SketchUp 2019/SketchUp/Plugins/ (at this point it works)
  • Copy it also to /Library/Application Support/SketchUp 2019/SketchUp/Plugins/ (does not work anymore)
  • If you remove the extension from either of those locations, then it works again

SketchUp 2019, 2020 have this issue.
SketchUp 2017, 2018 work OK.

1 Like

This is a SU bug, I did notice this when I was developing an extension for SU.
In the system Library was the version I was using under my work account, and in my developer account I have it in the User Library, and saw the change beginning last year.

I guess the load and use/call order inside SU are not consistent.

1 Like

Btw, are you using Sketchup.find_support_file or looking up files by a relative path?

We use relative paths.

I just experimented a bit with Sketchup.find_support_file() but it only returns paths in the local user directory and does not seem to support extensions stored in the “global” SketchUp directory.

what is the use case for ‘both’…

it does do strange things…

I suspect a 2.5 ruby issue, but it may be an SU change…

more digging required…

john

I was thinking there might be a clash between the load order on SketchUp start and for find_support_file but then that’s not the problem. Relative paths are generally considered much better as they allow the extension to be loaded from any location.

What exactly fails on load? Are the files loaded but just the menu not occurring? Then it could perhaps be a struggling load guard.

@eneroth3 What happens when starting SketchUp:

  • The extension menu items do not appear in the “Extensions” menu anymore
  • The extension is listed in the “Extension manager” though
  • I did not witness any other symptoms (no visible error message, nothing the the Ruby console)

It happens even with this minimal working example (which checks for double loading, as per Dan’s suggestion):

What happens if you run FakeCompany::FakeExtension.methods? Does it list create_cube (or whatever methods your extension defines)?

You could also try adding puts __FILE__ to the files just to see if they actually load. An initial call to SKETCHUP_CONSOLE.show at the top of your registrar could help showing if there are any issues.

It seems like the extension is not loaded. If I call FakeCompany::FakeExtension.methods() with the extension installed in both locations, I get:

Error: uninitialized constant FakeCompany

(If the extension is installed in a single location, it works as intended)

That’s odd. If the extension shows up in the Extension Manager, the registrar must have been loaded and defined the extension’s namespace module.

Actually the extension doesn’t really show up in the Extensions Manager.

It looks like this:

Instead of this:

(Lowercase name, no version, no author, no copyright, no description, unsigned)

To me, it looks like transmutr.rb is recognized and listed as “transmutr” (lowercase), but its content is ignored and the SketchupExtension object is not registered.

1 Like

That makes more sense. Then it seems SketchUp struggles to load duplicated files.

I wonder what happens if this file is placed in either one or two plugin directories.

# load_test.rb
UI.messagebox("Loaded #{__FILE__}")

Does the message show once, twice or zero times?

The message does not show up at all if the extension is installed in both locations.

1 Like