Native support for USD tools on an M1 Mac

I saw USD release 22.08 drop a few weeks ago, and notably within its release notes is the sentence: “Added support for native builds on Apple Silicon.”

I struggled quite bit with getting USD both installed and operational because, as it turns out, there’s a bit of quirk to Python that made things more difficult. macOS has stopped including Python3 in its default install, although it appears that if you install Xcode (or developer tools on the CLI), you’ll get a version of Python 3 (3.89) installed on the OS. Since I wasn’t sure what the path for Python3 support was looking like, and it took a while get a M1 native build of python in the first place, I’d switched over to installing Python using the packaging tool `conda`, which has been fairly popular and prevalent for ML folks to use.

To get started, I’d installed miniforge, downloading https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-MacOSX-arm64.sh and then running it to install and update:

sh ~/Downloads/Miniforge3-MacOSX-arm64.sh
source ~/miniforge3/bin/activate
conda update conda -y

With conda installed (and activated), I started installing the various dependencies:

conda install pyopengl
pip install pyside6

And then grabbed the open source distribution of USD from Github and set it to building, with the results installed at /opt/local/USD:

git clone https://github.com/PixarAnimationStudios/USD
cd USD
git checkout release
git pull
python build_scripts/build_usd.py /opt/local/USD

It compiled and installed fine, but any tool I attempted to use crashed immediately with the following error message:

python crashed. FATAL ERROR: Failed axiom: ' Py_IsInitialized() '
in operator() at line 149 of /Users/heckj/src/USD/pxr/base/tf/pyTracing.cpp
writing crash report to [ Sparrow.local:/var/folders/8t/k6nw7pyx2qq77g8qq_g429080000gn/T//st_python.29962 ] ... done.

I opened an issue on USD’s GitHub project, and quickly got some super helpful support from their team. It turns out that an additional build configuration option is needed, specifically for python installed through Conda, because of the way it links to python. The same issue happens regardless of architecture – so it’s quirk for x86 as much as aarch64 architectures.

The key to getting it working is passing adding a build configuration detail:

PXR_PY_UNDEFINED_DYNAMIC_LOOKUP=ON

I originally though that meant just exporting it as environment variables, but that doesn’t do the trick with USD’s build and installation process. Sunya Boonyatera provided the critical knowledge on how to add it in to get it to work:

python build_scripts/build_usd.py /opt/local/USD --build-args USD,"-DPXR_PY_UNDEFINED_DYNAMIC_LOOKUP=ON"

Nick Porcino was kind enough to jump in as well and provide an explanation:

Conda distributed Pythons are statically linked as a way to reduce unexpected system and installation coupling, but Python isn’t, to my knowledge, built in such a way that an external build system can robustly discover whether you are targeting a static or dynamically linked Python so we are forced to deal with it manually.

https://github.com/PixarAnimationStudios/USD/issues/1996#issuecomment-1217039438

Getting to this point wasn’t at all straightforward for me, so I’m hoping that by pushing this detail out there with my blog, Google will have it included in its index for the next individual, whether they’re searching on the error message or searching for how to install USD on an M1 Mac.

Side note – once its all installed, you still need to activate some paths on the CLI to get things available:

export PATH=/opt/local/USD/bin:$PATH
export PYTHONPATH=$PYTHONPATH:/opt/local/USD/lib/python

Published by heckj

Developer, author, and life-long student. Writes online at https://rhonabwy.com/.

3 thoughts on “Native support for USD tools on an M1 Mac

  1. Nice work 🙌
    I’m still stuck with the pxr issues. have you encountered the same error?

    ❯ usdview extras/usd/tutorials/convertingLayerFormats/Sphere.usda
    Traceback (most recent call last):
    File “/opt/local/USD/bin/usdview”, line 28, in
    import pxr.Usdviewq as Usdviewq
    File “/opt/local/USD/lib/python/pxr/Usdviewq/__init__.py”, line 27, in
    from pxr import Tf
    File “/opt/local/USD/lib/python/pxr/Tf/__init__.py”, line 163, in
    PreparePythonModule()
    File “/opt/local/USD/lib/python/pxr/Tf/__init__.py”, line 88, in PreparePythonModule
    module = importlib.import_module(
    File “/Users/yohandarosa/miniforge3/lib/python3.9/importlib/__init__.py”, line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
    ImportError: dlopen(/opt/local/USD/lib/python/pxr/Tf/_tf.so, 0x0002): tried: ‘/opt/local/USD/lib/python/pxr/Tf/_tf.so’ (mach-o file, but is an incompatible architecture (have (x86_64), need (arm64e)))

    Like

    1. I haven’t hit that one myself, but from the error messages you’ve got mismatched architectures in the libraries. It looks like what’s been built into /opt/local/USD is x86_64, which can happen if (when you did the build), you were running the shell under Rosetta.

      You can double check by running the following command:
      `lipo -info /opt/local/USD/lib/python/pxr/Tf/_tf.so`

      WIth my setup, it returns:
      “`
      Non-fat file: /opt/local/USD/lib/python/pxr/Tf/_tf.so is architecture: arm64
      “`

      And check your shell with the command `arch` (zsh on my machine is reporting `arm64`). If you’re running the shell under Rosetta, it’ll report ‘x86_64’.

      Like

      1. Thank you,
        you’re right the lipo command results to:
        Non-fat file: /opt/local/USD/lib/python/pxr/Tf/_tf.so is architecture: x86_64

        but my zsh shell indicates arm64 before and after the build.
        I clean install before with rm -rf /opt/local/USD/*

        and python version is 3.9.13, maybe it’s the cause ?

        Like

Comments are closed.

%d bloggers like this: