ヴェズルフェルニルの研究ノート

座右の銘「ただ一人犀の角のように歩め」的な研究活動ノート

【Homebrew】macOS High Sierraでの最新版LLVMのインストール

macOSのパッケージマネージャーとしてHomebrewを利用しています。GitHubなどから入手したプログラムソースをビルドしてMacで利用するには、Homebrewは必須のツールです。Homebrewがなければ、Macでのオープンソースを利用したソフトウェア開発はできないとも言えます。

ところが、現行のHomebrew(本記事執筆時点はバージョン3.6.1)ではmacOS 10.13 High Sierra はサポート対象外となっており、何かパッケージをインストールする度に次のような警告が表示されます。

Warning: You are using macOS 10.13.  
We (and Apple) do not provide support for this old version.  
You will encounter build failures with some formulae.  
Please create pull requests instead of asking for help on Homebrew's GitHub,  
Twitter or any other official channels. You are responsible for resolving  
any issues you experience while you are running this  
old version. 

Homebrewの多くフォーミュラはすでにBig Sur以降用に更新されているようで、一部のフォーミュラはそのままではHigh Sierraにインストールできなくなってしまっています。

事情があって、High Sierraを使い続けている人は結構多いのではないでしょうか。そういう私も2台のMacでまだHigh Sierraを使っています(マルチパーティションでBig Surと共存させたりしていますが)。一つの大きな理由として、NVIDIA GPUボードがHigh Sierraまでしか利用できないことがあります。NVIDIA GPUボード用ドライバがHigh Sierra対応版までしかリリースされておらず、macOS 10.14 Mojave以降ではCUDAや機械学習・ディープラーニングのソフトウェア開発ができません。

HomebrewでHigh Sierraにインストールできないフォーミュラの一つとしてLLVMがというものがあります。Command Line Toolsにも入っているclangコンパイラを含んでいるLLVMの最新版ですが、この最新版LLVMにはclangも最新版バージョンが収納されています。この最新版LLVMをインストールできないことはHomebrewを利用したソフトウェア開発にとって大きな障害となります。多くのフォーミュアがこの最新バージョンのclangでビルドすることを前提として更新されており、それらは先に最新版LLVMがインストールされるからです。OpenCVやQtなどのメジャーなフォーミュラが最新版LLVMに依存しているため、High Sierraでは現行のHomebrewを使ってこれらをインストールすることができません。

GitHubから入手したいくつかのプログラムをビルドしようとして、この障害に何度か遭遇しましたが、試行錯誤しながら解決することができました。同じ問題によって困っている人は多いと思うので、その解決方法を本記事に書いておきます。

LLVMインストール時のエラー障害

High Sierra上でHomebrewを使って最新版LLVM(本記事執筆時点はバージョン14.0.6)をインストールしようとすると、以下のようなエラーが起きます。

% brew install llvm
... ...
==> Downloading https://github.com/llvm/llvm-project/releases/download/llvmorg-14.0.6/llvm-project-14.0.6.src.tar.xz
/usr/local/Homebrew/Library/Homebrew/shims/shared/curl --disable --cookie /dev/null --globoff --show-error --user-agent Homebrew/3.6.1\ \(Macintosh\;\ Intel\ Mac\ OS\ X\ 10.13.6\)\ curl/7.54.0 --header Accept-Language:\ en --retry 3 --location --silent --head --request GET https://github.com/llvm/llvm-project/releases/download/llvmorg-14.0.6/llvm-project-14.0.6.src.tar.xz
Already downloaded: /Users/yuhri/Library/Caches/Homebrew/downloads/ca2953276467b5dcc28485aa2b1afc3bcf32bbf84d5e0236f6284234afca2d8d--llvm-project-14.0.6.src.tar.xz
... ...
tar --extract --no-same-owner --file /Users/yuhri/Library/Caches/Homebrew/downloads/ca2953276467b5dcc28485aa2b1afc3bcf32bbf84d5e0236f6284234afca2d8d--llvm-project-14.0.6.src.tar.xz --directory /private/tmp/d20220915-7100-llrho7
cp -pR /private/tmp/d20220915-7100-llrho7/llvm-project-14.0.6.src/. /private/tmp/llvm-20220915-7100-9zovwz/llvm-project-14.0.6.src
==> cmake -G Unix Makefiles .. -DLLVM_ENABLE_PROJECTS=clang;clang-tools-extra;lld;lldb;mlir;polly -DLLVM_ENABLE_RUNTIMES=compiler-rt;libcxx;libcxxabi;libunwind;
==> cmake --build .
... ...
[ 80%] Built target lldELF
make: *** [all] Error 2

HomebrewはLLVMをソースからビルドしてインストールしようと試みますが、このエラーによってビルド処理が停止するため、LLVMのインストールは失敗してしまいます。

High Sierraに最新版LLVMをインスールする手順

上記のエラー障害を解決して、High Sierra上でHomebrewを使ってLLVMをインスールする手順を以降に説明します。

Xcode 10.1をインストールする

まずXcodeをHigh Sierraへインストールしておく必要があります。Xcode 10.1がHigh Sierraで利用可能な最終バージョンですが、これをApple Developerサイトからダウンロードした上で解凍し、Applicationsフォルダへコピーしてください。

Homebrewをインストール済みならCommand Line Toolsは単独でインストールされているはずで、フォーミュラのビルドは通常こちらを使って行われます。しかし、LLVMのインストールではXcodeに含まれる一部のツールがビルド処理で使われます。

すでにXcode 10.1をインストール済みなら、この操作を行う必要はありません。

なお、HombrewがXcodeの存在を認識しているかどうかは、以下のコマンドによって確認できます。

% brew config
HOMEBREW_VERSION: 3.6.1
ORIGIN: https://github.com/Homebrew/brew
HEAD: 6e2b162c4786e075323f038d46bfb566d91889e7
Last commit: 5 days ago
Core tap ORIGIN: https://github.com/Homebrew/homebrew-core
Core tap HEAD: 4d6529affa1851ffb992a33fe5641b0cd739c895
Core tap last commit: 2 hours ago
Core tap branch: master
HOMEBREW_PREFIX: /Users/yuhri/homebrew
HOMEBREW_REPOSITORY: /Users/yuhri/homebrew
HOMEBREW_CELLAR: /Users/yuhri/homebrew/Cellar
HOMEBREW_CASK_OPTS: []
HOMEBREW_DISPLAY: /private/tmp/com.apple.launchd.gBCDRKkzIz/org.xquartz:0
HOMEBREW_MAKE_JOBS: 24
Homebrew Ruby: 2.6.8 => /Users/yuhri/homebrew/Library/Homebrew/vendor/portable-ruby/2.6.8_1/bin/ruby
CPU: 24-core 64-bit westmere
Clang: 10.0.0 build 1000
Git: 2.17.2 => /Library/Developer/CommandLineTools/usr/bin/git
Curl: 7.54.0 => /usr/bin/curl
macOS: 10.13.6-x86_64
CLT: 10.1.0.0.1.1539992718
Xcode: 10.1

Xcodeがインストールされていないと、 "Xcode: N/A" と表示されます。

Command Line ToolsをXcode側へ切り替える

xcode-select コマンドを使って、Xcode側のCommand Line Toolsが使われるように変更します。

% xcode-select -p
/Library/Developer/CommandLineTools
$ sudo xcode-select -s /Applications/Xcode.app
Password:
% xcode-select -p
/Applications/Xcode.app/Contents/Developer

LLVMのインストールを”--debug”オプション付きで開始する

brew コマンドには --debug というオプションがありますが、このオプションを指定してLLVMのインストールを開始します。

% brew install --debug llvm

--debug オプションをつけると、エラーが起きた時点で、以下のようなメッセージが表示されてHomebrewのインストール処理が停止します。

... ...
[ 80%] Built target lldELF
make: *** [all] Error 2
/usr/local/Homebrew/Library/Homebrew/shims/shared/git --version
/usr/local/Homebrew/Library/Homebrew/shims/shared/curl --version
/usr/local/Homebrew/Library/Homebrew/ignorable.rb:29:in `block in raise'
BuildError: Failed executing: cmake --build .
1. raise
2. ignore
3. backtrace
4. irb
5. shell
Choose an action: 5
When you exit this shell, you will return to the menu.
%

この”Choose an action:” プロンプトに対して ”5”  を選ぶと、シェルプロンプトに復帰します。

LLVMのビルド・エラーの原因を解決する

シェルプロンプトになったら、以下のように作業ディレクトリを移動します。

% pwd
/private/tmp/llvm-20220915-7100-9zovwz/llvm-project-14.0.6.src
% cd llvm/build

そして、 HostInfoMacOSX.mm というファイルを以下のように編集します。

% vi ../../lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
--- ../../lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm.orig  2022-06-22 16:46:24.000000000 +0000
+++ ../../lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm    2022-09-15 13:18:17.000000000 +0000
@@ -228,7 +228,7 @@
     len = sizeof(is_64_bit_capable);
     ::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0);

-    if (cputype == CPU_TYPE_ARM64 && cpusubtype == CPU_SUBTYPE_ARM64E) {
+    if (cputype == CPU_TYPE_ARM64) {
       // The arm64e architecture is a preview. Pretend the host architecture
       // is arm64.
       cpusubtype = CPU_SUBTYPE_ARM64_ALL;

手動でLLVMのビルド処理を継続する

HostInfoMacOSX.mm の修正が終わったら、以下の一連のコマンドを順次実行していきます。

% cmake . -DLLVM_CREATE_XCODE_TOOLCHAIN=On
...   ...
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/llvm-20220915-7100-9zovwz/llvm-project-14.0.6.src/llvm/build
% cmake --build .
...   ...
[100%] Built target lldb-vscodex
/usr/local/Cellar/cmake/3.24.1/bin/cmake -E cmake_progress_start /tmp/llvm-20220915-7100-9zovwz/llvm-project-14.0.6.src/llvm/build/CMakeFiles 0
% cmake --build . --target install
...   ...
-- Installing: /usr/local/Cellar/llvm/14.0.6_1/lib/cmake/llvm/./FindSphinx.cmake
-- Installing: /usr/local/Cellar/llvm/14.0.6_1/lib/cmake/llvm/./FindGRPC.cmake
-- Installing: /usr/local/Cellar/llvm/14.0.6_1/lib/cmake/llvm/./TableGen.cmake
% cmake --build . --target install-xcode-toolchain

上記の最後のコマンドによるビルド処理が終わると、以下のようなメッセージが表示されます。

ここでの"Choose an action:"プロンプトでは、すべて "2" を選択します。

...   ...
-- Installing: /usr/local/Cellar/llvm/14.0.6_1/Toolchains/LLVM14.0.6.xctoolchain//usr/lib/cmake/llvm/./FindSphinx.cmake
-- Installing: /usr/local/Cellar/llvm/14.0.6_1/Toolchains/LLVM14.0.6.xctoolchain//usr/lib/cmake/llvm/./FindGRPC.cmake
-- Installing: /usr/local/Cellar/llvm/14.0.6_1/Toolchains/LLVM14.0.6.xctoolchain//usr/lib/cmake/llvm/./TableGen.cmake
Built target install-xcode-toolchain
/usr/local/Cellar/cmake/3.24.1/bin/cmake -E cmake_progress_start /tmp/llvm-20220915-7100-9zovwz/llvm-project-14.0.6.src/llvm/build/CMakeFiles 0
%
1. raise
2. ignore
3. backtrace
4. irb
5. shell
Choose an action: 2
==> cmake --build . --target install
Last 15 lines from /Users/yuhri/Library/Logs/Homebrew/llvm/03.cmake:
2022-09-15 07:06:11 +0000

cmake
--build
.
--target
install

Error: could not load cache
/usr/local/Homebrew/Library/Homebrew/shims/shared/curl --version
/usr/local/Homebrew/Library/Homebrew/ignorable.rb:29:in `block in raise'
BuildError: Failed executing: cmake --build . --target install
1. raise
2. ignore
3. backtrace
4. irb
5. shell
Choose an action: 2

2回 "2" を選択すると、LLVMのビルド処理が終了し、以降はHomebrewによってインストール処理が継続実行されます。

...   ...
==> Fixing /usr/local/Cellar/llvm/14.0.6_1/lib/python3.9/site-packages/clang/cindex.py permissions from 644 to 444
==> Fixing /usr/local/Cellar/llvm/14.0.6_1/lib/python3.9/site-packages/clang/enumerations.py permissions from 644 to 444
...   ...
==> Changing dylib ID of /Users/yuhri/homebrew/Cellar/llvm/14.0.6_1/lib/libomp.dylib
  from @rpath/libomp.dylib
    to /Users/yuhri/homebrew/opt/llvm/lib/libomp.dylib
==> Changing dylib ID of /Users/yuhri/homebrew/Cellar/llvm/14.0.6_1/lib/libunwind.1.0.dylib
  from @rpath/libunwind.1.dylib
    to /Users/yuhri/homebrew/opt/llvm/lib/libunwind.1.dylib
/Users/yuhri/homebrew/Library/Homebrew/brew.rb (Formulary::FromPathLoader): loading /Users/yuhri/homebrew/opt/llvm/.brew/llvm.rb
==> Caveats
To use the bundled libc++ please add the following LDFLAGS:
  LDFLAGS="-L/Users/yuhri/homebrew/opt/llvm/lib -Wl,-rpath,/Users/yuhri/homebrew/opt/llvm/lib"

llvm is keg-only, which means it was not symlinked into /Users/yuhri/homebrew,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.

If you need to have llvm first in your PATH, run:
  echo 'export PATH="/Users/yuhri/homebrew/opt/llvm/bin:$PATH"' >> ~/.zshrc

For compilers to find llvm you may need to set:
  export LDFLAGS="-L/Users/yuhri/homebrew/opt/llvm/lib"
  export CPPFLAGS="-I/Users/yuhri/homebrew/opt/llvm/include"

==> Summary
🍺  /Users/yuhri/homebrew/Cellar/llvm/14.0.6_1: 11,663 files, 1.8GB, built in 76 minutes 6 seconds
...   ...

そして、最後はLLVMのインストールが成功して終わります。

インストールされたLLVMを確認する

インストールされたLLVMが利用可能かどうかは 、以下のコマンドによって確認できます。

% /usr/bin/clang --version
Apple LLVM version 10.0.0 (clang-1000.11.45.5)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
% /Library/Developer/CommandLineTools/usr/bin/clang --version
Apple LLVM version 10.0.0 (clang-1000.10.44.4)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
% /usr/local/opt/llvm/bin/clang --version
Homebrew clang version 14.0.6
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /usr/local/opt/llvm/bin

/usr/bin/clang がXcode 10.1のclangコンパイラ、/Library/Developer/CommandLineTools/usr/bin/clang がCommand Line Toolsのclang、/usr/local/opt/llvm/bin/clang がインストールしたLLVMのclangです。

Command Line Toolsの選択を元に戻す

上記までの手順でLLVMのインストールは完了ですが、"brew install --debug llvm " コマンドを実行する前に変更したCommand Line Toolsの選択を元に戻しておきます。

% xcode-select -p
/Applications/Xcode.app/Contents/Developer
% sudo xcode-select -s /Library/Developer/CommandLineTools
Password:
% xcode-select -p
/Library/Developer/CommandLineTools

【参考リンク】

stackoverflow.com