Does SketchUp 2022 for Mac break C++ extensions not recompiled for M1?

,

Hi all,

We’ve received a few reports from users on Mac with M1 chips that our C++-based extension doesn’t load in SketchUp 2022.

If we try just that, we indeed get this Ruby error:

#<LoadError: dlopen(/Users/lindale/dev/Skatter/_install/skatter/core/Skatter.bundle, 0x0009): tried: '/Users/lindale/dev/Skatter/_install/skatter/core/Skatter.bundle' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e'))

That message is rather clear! SketchUp 2022 is compiled for M1 chips and it fails to load our native extension which has been compiled for the Intel architecture.

The extension loads fine if we launch SketchUp with the architecture that matches our extension (but obviously it would not be practical to ask our users to do that):

> env /usr/bin/arch -x86_64 /Applications/SketchUp\ 2022/SketchUp.app/Contents/MacOS/SketchUp


  1. Can any SketchUp developer or other extension developer confirm if C++ extensions must be rebuilt for M1 to be compatible with SketchUp 2022 for M1?

We were confident that Rosetta would be able to translate the dynamic library that contains our extension’s code on the fly when it gets loaded, but it doesn’t seem that easy.

I have not found any information about this case (process compiled for M1 loading a dynamic library not compiled for M1) in Apple’s developer resources.

  1. Is it possible to make it work with some specific build configuration?

I found no other posts about this issue in the developers forums or in SketchUp’s developer resources. We might have missed it but otherwise that seems like a significant breaking change so I still have a tiny glimmer of hope that we just missed some hidden setting that would solve this instantly :slight_smile:

(Note: obviously compiling our extension as an universal binary compatible with M1 would solve the issue but we cannot do that at the moment.)

Thanks!

Actually SketchUp for MacOS is now a universal binary.

It will, and does as you yourself showed when you tell the M1 machine to run SketchUp as x86 using Rosetta.

When you do not (run SketchUp under the Rosetta emulator) then of course you get the incompatibility error.

The SketchUp C SDK Index page says quite clearly …

macOS

Starting with SketchUp 2022.0, universal binaries are supported. Universal binaries on macOS run natively on both Apple silicon and Intel-based Mac computers.

SketchUp 2022 was built with target SDK 10.14.

The developer examples on GitHub have been updated to include the project settings for compiling universal binaries on MacOS.

See:

@tt_su Perhaps update the “macOS Notes” for more info ?

Why not? Does this need to be done on an M1 machine ?

Thank you for the thorough answer @DanRathbun

I was under the impression that Rosetta would kick in in that specific case and translate the code loaded from the library.

Isn’t that the whole point of the emulator? To keep binaries made for the previous architecture functioning seamlessly?
I suppose that this does not apply for dynamic libraries though.

It says that universal binaries are now supported, not that the old way of doing things is deprecated.

Yes, we have a prototype in place with a CMake configuration similar to what you linked. However we cannot produce universal binaries for now due to some of our dependencies not being ready yet, as well as some obscure Xcode 13 bug that requires a long-awaited patch.

Anyway, I guess we’ll just have to push through and spend more time on that issue.

… answering my own question …

Building a Universal macOS Binary - Apple Developer says in starting:

Note

You can build a universal binary on either an Apple silicon or Intel-based Mac computer, but you cannot debug the arm64 slice of your binary on an Intel-based Mac computer. It’s possible to debug both slices of a universal binary on Apple silicon, but you must run the x86_64 slice under Rosetta translation.

… and …

Xcode 12.2 and later is a requirement for building universal binaries. Earlier versions of Xcode don’t contain the support needed to build and test universal versions of your macOS code.

Download the latest public version of Xcode from the App Store.

Not a Mac guy myself, but from what others have said Rosetta seems to work at the App level.

Obviously, as you’ve found, an APP running natively on ARM cannot use Intel-x86-only libraries.

Apple Developer: About the Rosetta Translation Environment says (in bright yellow box):

Important

The system prevents you from mixing arm64 code and x86_64 code in the same process. Rosetta translation applies to an entire process, including all code modules that the process loads dynamically.

So, yea, if the App process is native untranslated ARM, it cannot load translated x86_64 libs.

3 Likes

Thanks a lot for that confirmation!

To conclude, if anyone has similar issues, the final answer to the topic’s title is: yes, C++ extensions must specifically target M1 to work in SketchUp 2022 on M1 Macs.

2 Likes

but, “specifically target” can include either compiling only for ARM_64 or compiling a universal binary for both architectures.

I think that using the former (2 separate architecture specific binary files) that the Ruby file that loads your binary extension file(s) must “sniff” out the architecture and load from the proper subfolder accordingly.

If instead using a universal binary, the MacOS system should properly load the architecture matching slice from the binary libs. This then is simpler with regard to the Ruby load control file as it just loads the one (or one set) of binary files. Ie, no architecture sniffing conditional expression should be needed.

If you build a universal Ruby C Extension binary it will load on both SU2022 and SU2021.