OpenUSDをmacOS (Apple silicon) でビルドする

本記事ではOpenUSD v26.08をmacOS (Apple silicon) でビルドする手順を示す。

3年前の2023年3月にPixar USDをmacOS (Apple silicon) でビルドするという記事を書いた。 当時はUSD v23.02を、Apple siliconのMacBook (Apple M1 Max) 上でmacOS 12.6.3、Xcode 14.2、Python 3.9.16を使ってビルドした。 記事公開後の2023年8月にはAlliance for OpenUSDが発表され、USDのバージョンアップも進んだ。 この3年でmacOSとXcodeのバージョンも上がっている。

そのため、当時の記事の内容は古くなっている。 そこで現在の環境でビルド手順を確認し直した。 この記事で分かることは以下の通り。

  • OpenUSD v26.08をmacOS (Apple silicon) でソースビルドする具体的な手順
  • Homebrewの最新CMake (4.x系) でもビルドが通る理由
  • USDのPythonバインディングがビルドに使ったPythonの共有ライブラリに直接リンクされる仕組み
  • v26.08までに変わったビルド上の注意点 (Pythonのインストール先、boost/zlibなどの依存関係の変化)

ビルド手順の大まかな流れは次のとおりだ。詳細は以降で説明する。

1
2
3
4
5
git clone https://github.com/PixarAnimationStudios/OpenUSD
brew install cmake
pyenv install 3.11.15 && pyenv local 3.11.15 && python -m venv env
python ./build_scripts/build_usd.py ../buildspace
usdview ../buildspace/share/usd/tutorials/convertingLayerFormats/Sphere.usda

環境

以下の環境で確認している。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ uname -m
arm64

$ sysctl -n machdep.cpu.brand_string
Apple M1 Max

$ sw_vers
ProductName:	macOS
ProductVersion:	15.7.7
BuildVersion:	24G720

$ xcodebuild -version
Xcode 16.2
Build version 16C5032a

$ cmake --version
cmake version 4.4.0

$ brew --version
Homebrew 6.0.12

$ python --version
Python 3.11.15

ソースコードの取得

Alliance for OpenUSDの発足以降、 OpenUSD という名称が広く使われるようになり、GitHubリポジトリも PixarAnimationStudios/USD から PixarAnimationStudios/OpenUSD へ変わった。 運営側がこの名称の広まりに合わせてリポジトリ名を変更したのだろう。 旧URLにはリダイレクトが設定されているので、 git clone 自体はどちらのURLでも通る。

ビルドにはタグ v26.08 を使う。これは2026年7月時点での最新版だ。

1
2
3
4
mkdir workspace && cd workspace
git clone https://github.com/PixarAnimationStudios/OpenUSD
cd OpenUSD
git checkout v26.08

ビルドの準備

Xcode

Xcode 16.2本体を使う。 xcode-select -p/Applications/Xcode.app/Contents/Developer を指していることを確認する。

CMake

HomebrewでCMakeを導入する。

1
brew install cmake

結論から言うと、本記事の構成では執筆時点でHomebrewからインストールされるCMake 4.4.0でも問題なくビルドできた。

1
2
3
4
5
6
7
8
9
brew info cmake
==> cmake ✔: stable 4.4.0 (bottled), HEAD
Cross-platform make
https://www.cmake.org/
Installed (on request)
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/c/cmake.rb
License: BSD-3-Clause
==> Installed Versions
cmake ✔ 4.4.0 (4,158 files, 68.3MB) [Linked]

ただしVERSIONS.mdに記載されているmacOSでのテスト済みバージョンはv3.27.9であり、メジャーバージョンを2つも上げることになる。 そこでビルドに悪影響が出ないか調べた。 CMake 4.xでは、 cmake_minimum_required に3.5未満を指定している古いプロジェクトの設定が失敗するようになった。 試しに cmake_minimum_required(VERSION 3.0) とだけ書いたプロジェクトを手元のCMake 4.4.0で設定すると、次のエラーで止まる。

1
2
3
4
5
6
7
8
9
$ cmake -S . -B build
CMake Error at CMakeLists.txt:1 (cmake_minimum_required):
  Compatibility with CMake < 3.5 has been removed from CMake.

  Update the VERSION argument <min> value.  Or, use the <min>...<max> syntax
  to tell CMake that the project requires at least <min> but has been updated
  to work with policies introduced by <max> or earlier.

  Or, add -DCMAKE_POLICY_VERSION_MINIMUM=3.5 to try configuring anyway.

USDが内部でビルドするサードパーティのlibjpeg-turboとlibtiffもこれに該当し、 build_usd.py 側はこの2つに -DCMAKE_POLICY_VERSION_MINIMUM=3.5 を自動で付与するようになっている。 ただし build_usd.py はこの2つをOpenImageIOを有効にした場合にのみダウンロードするので、本記事のようにデフォルト構成でビルドする場合はそもそもダウンロードされない。 したがって、この記事の手順ではCMake 4.xの影響を意識する必要はなかった。

Python

OpenUSD自体はPythonの入手方法を指定しておらず、Homebrewでも公式インストーラーでも構わない。 ここではバージョンを切り替えやすいpyenvで用意し、venvで仮想環境を作るという、あくまで筆者の作業環境の都合を採用する。

バージョン

VERSIONS.mdに記載されているmacOSでのテスト済みバージョンのPythonは3.9.13だが、ここでは執筆時点で最新版のPython 3.11.15を使う。 BlenderのLTS版のv4.5とHoudini 21はどちらも組み込みのPythonが3.11系なので、これらのDCCでビルドしたUSDのPythonバインディングを使うことを考えて3.11系に合わせた。

Blenderの内蔵のPythonバージョンの確認方法

1
2
3
4
5
/Applications/Blender.app/Contents/MacOS/Blender --background --python-expr "import sys; print(sys.version)"
Blender 4.5.11 LTS (hash 4db51e9d1e1e built 2026-06-23 01:45:40)
3.11.11 (main, Apr 25 2025, 12:39:20) [Clang 17.0.0 (clang-1700.0.13.3)]

Blender quit

Houdiniの内蔵のPythonバージョンの確認方法

1
2
% /Applications/Houdini/Houdini21.0.729/Frameworks/Houdini.framework/Versions/21.0/Resources/bin/hython --version
Python 3.11.7

したがって本記事ではPython 3.11系を採用する。

仮想環境

1
2
3
4
5
pyenv install 3.11.15
pyenv local 3.11.15

python -m venv env
source env/bin/activate

ライブラリ

1
2
python -m pip install --upgrade pip
python -m pip install PySide6 PyOpenGL numpy Jinja2

READMEが要求しているのはPySide6とPyOpenGLだけだが、numpyを入れておかないとusdview起動時に以下の警告が出るため、あわせてインストールしている。

1
Unable to import OpenGL.arrays.numpymodule.NumpyHandler: No numpy module present: No module named 'numpy'

usdviewの動作自体に支障はないが、numpyを入れておけば警告は出ない。

Jinja2も同様に必須ではないが、無いと build_usd.py がスキーマ生成用のツール ( usdGenSchemausdgenschemafromsdrusdInitSchema ) のビルドを省略し、 --dry_run や実際のビルドの出力に次の行が出る。

1
Omitted (Jinja2 not found): usdGenSchema, usdgenschemafromsdr, usdInitSchema.

この記事で確認するusdviewの起動にこれらのツールは要らないが、この記事では併せてJinja2もインストールする。

USDをビルドする

build_usd.py には --dry_run オプションがあり、実際にビルドを始める前に設定内容だけを確認できる。 ビルドを始める前に、まずこれで設定を見ておく。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
$ python ./build_scripts/build_usd.py --dry_run ../buildspace

Building with settings:
  USD source directory          /Users/hiroakit/workspace/OpenUSD
  USD install directory         /Users/hiroakit/workspace/buildspace
  3rd-party source directory    /Users/hiroakit/workspace/buildspace/src
  3rd-party install directory   /Users/hiroakit/workspace/buildspace
  Build directory               /Users/hiroakit/workspace/buildspace/build
  CMake generator               Default
  CMake toolset                 Default
  Downloader                    curl

  Building                      Shared libraries
    Framework Build             Off
    Variant                     Release
    Target                      native
    UsdValidation               On
    Imaging                     On
      Ptex support:             Off
      OpenVDB support:          Off
      ImageIO support:          On
      OpenImageIO support:      Off
      OpenColorIO support:      Off
      Embree support:           Off
      PRMan support:            Off
      Vulkan support:           Off
    UsdImaging                  On
      usdview:                  On
    MaterialX support           On
    Python support              On
      Python Debug:             Off
      Python docs:              Off
    Documentation               Off
    Tests                       Off
      Mayapy Tests:             Off
      AnimX Tests:              Off
    Examples                    On
    Tutorials                   On
    Tools                       On
    Alembic Plugin              Off
    Draco Plugin                Off

  Dependencies                  TBB, MaterialX, OpenSubdiv

v23.02のときの Dependencies 行は zlib, boost, TBB, OpenSubdiv だったが、v26.08では TBB, MaterialX, OpenSubdiv になっている。 USD本体が既にboostを pxr/external/ 以下に自前のソースツリーとして含んでおり、別途ダウンロードしてビルドする対象ではなくなった。 CHANGELOG.mdによると、この変更はv26.08ではなく24.1125.05あたりで段階的に進んだものだ。 24.11のCHANGELOG.mdには次のように記載されている。

Removed boost dependency from OpenUSD. Note that boost must still be supplied when OpenVDB support is enabled due to its use of boost in headers.

つまりOpenVDBを有効にしないデフォルト構成でビルドする場合は、boostを別途用意する必要はない。 依存関係を自前で用意する手間が一つ減り、ビルド環境の構築がシンプルだ。

zlibは25.05で依存関係から外れており、CHANGELOG.mdには次のように記載されている。

zlib dependency now removed for Linux and macOS builds when explicitly requested. Also added zlib as a requiredDependency if HDF5 is enabled. (PR: #3501, #3551)

一方でこの3年の間に加わった変化もある。 USD側でアセットの整合性を検証する仕組みである UsdValidation が新たに追加され、マテリアルやルックの記述をDCC間でやり取りするためのオープン標準である MaterialX (materialx.org) のサポートもデフォルトで有効になった。 UsdValidationは24.08で導入された時点から既定でOnであり、MaterialXは23.05でデフォルトOnに切り替わった。 どちらもv26.08で新しく変わった点ではなく、v23.02より後から続いている設定だ。

OpenImageIOはデフォルトではOffのままで、有効にするには別途 --openimageio を渡す必要がある。

設定を確認したら、実際にビルドする。

1
python ./build_scripts/build_usd.py ../buildspace

Apple M1 Max、メモリ64GBの環境での実測では、依存ライブラリのビルドも含めて15分程度で終わった。 最後に以下のように表示されればビルド成功。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
STATUS: Installing TBB...
STATUS: Installing MaterialX...
STATUS: Installing OpenSubdiv...
STATUS: Installing USD...

Success! To use USD, please ensure that you have:

    The following in your PYTHONPATH environment variable:
    /Users/hiroakit/workspace/buildspace/lib/python3.11/site-packages

    The following in your PATH environment variable:
    /Users/hiroakit/workspace/buildspace/bin

Pythonバインディングのインストール先が lib/python ではなく lib/python3.11/site-packages になっている点に注意してほしい。 これはv26.08からの変更で、CHANGELOG.mdの[26.08]リリースノートに次のとおり明記されている。

Python modules are now installed under lib/pythonX.Y/site-packages on Linux and MacOS and Lib/site-packages on Windows by default. This location can be customized via the –python-install-dir argument in build_usd.py or PXR_PYTHON_INSTALL_DIR when running cmake. (Issue: #30)

v26.05以前のインストール先は lib/python だったので、古いバージョンのUSDを使う場合はこの記事のパスをそちらに読み替えてほしい。 このパスは次の節で設定する PYTHONPATH にもそのまま関わってくるので、実際に手を動かす際はここで表示された値を使ってほしい。

usdviewで動作確認

ビルドが終わったら、指示されたとおりPYTHONPATHとPATHを通す。

1
2
3
4
export PYTHONPATH=/Users/hiroakit/workspace/buildspace/lib/python3.11/site-packages:$PYTHONPATH
export PATH=/Users/hiroakit/workspace/buildspace/bin:$PATH

usdview ../buildspace/share/usd/tutorials/convertingLayerFormats/Sphere.usda

usdviewが起動し、球体が表示されればビルドは成功している。

./images/figure_01.png

コラム: USDのPythonバインディングとlibpythonの関係

USDのPythonバインディングは、ビルドに使ったPythonの共有ライブラリに直接リンクされる。 実際に otool -L で見ると、コンパイル済みの _tf.solibpython3.11.dylib への絶対パスを直接持っている。

1
2
$ otool -L buildspace/lib/python3.11/site-packages/pxr/Tf/_tf.so | grep python
	/Users/hiroakit/.pyenv/versions/3.11.15/lib/libpython3.11.dylib (compatibility version 3.11.0, current version 3.11.0)

このため、3.11でビルドしたバインディングを別のマイナーバージョン (たとえば3.9) のインタプリタから読み込もうとすると、1つのプロセスの中に2つの libpython が同居することになりクラッシュする。

1
2
$ PYTHONPATH=buildspace/lib/python3.11/site-packages /path/to/python3.9 -c "from pxr import Tf"
Segmentation fault: 11

これはUSDの設計による意図的な挙動である。USDのCMake ( cmake/defaults/Packages.cmake ) はビルドに使うPythonのsysconfigを見て、共有ライブラリ ( .dylib ) であればバインディングをそこへ直接リンクする。 pyenvやHomebrewで入れたPythonは共有ライブラリなので、macOSでは基本的にこの経路に入る。

この記事で pip install したnumpyやPySide6 (の実体であるshiboken6) を同じように見ると、libpythonへのリンクは一つも無い。

1
2
$ otool -L env/lib/python3.11/site-packages/numpy/_core/_multiarray_umath.cpython-311-darwin.so | grep -i python
$ otool -L env/lib/python3.11/site-packages/shiboken6/Shiboken.abi3.so | grep -i python

PyPIで配布するwheel(.whl)はビルドした環境を問わず動く必要があるため、libpythonへの直接リンクを避けてシンボル解決を実行時のホストプロセスに委ねる ( -undefined dynamic_lookup ) のが通例になっている。 USD側にもこれと同じ挙動に切り替えるオプションが用意されており、 -DPXR_PY_UNDEFINED_DYNAMIC_LOOKUP=ON を渡すとPyPI向けのwheel生成を主な動機として直接リンクを避けられる。詳しくはBUILDING.mdのAvoiding linking statically to Pythonを参照されたい。

コラム: numpyの警告メッセージの出所

usdview起動時にnumpyが無いと出る警告の出所はUSDではなくPyOpenGL自身にある。 OpenGL/__init__.py が起動時にnumpy用のフォーマットハンドラをプラグインとして登録しており、実体である OpenGL/arrays/numpymodule.py がnumpyを import してImportErrorを投げる。 それを OpenGL/plugins.pyPlugin.load() がtry/exceptで拾い、クラッシュさせる代わりに log.warning('Unable to import %s: %s', self.import_path, err) として警告に落としているのが、この文言の出所になっている。