Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails以外の開発一般

brew upgrade でのエラー対処からCommand Line Toolsについてまとめてみる

BPSの福岡拠点として一緒にお仕事をさせてもらっているウイングドアのウメバヤシです。

最近、brew upgradeをした際に、Command Line Tools(以下「CLT」)が原因でエラーが出たのでその解決をしました。

その時にCLTについても少し調べてみたのですが、ネットで検索してヒットする情報の中には、間違った認識のものや、あやふやな内容のものが結構多いなという印象を受けました。

なので今回は、Homebrewのエラーの解決方法と、信頼できるソースや検証した結果を元に、CLTについてできるだけ正しく解説していきます。

検証環境

* PC : MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)
* OS : macOS Big Sur バージョン 11.2.3(20D91)
* Homebrew : 3.0.5
* xcode-select : version 2384
* Xcode, xcodebuild : Xcode 12.1 Build version 12A7403, Xcode 12.4 Build version 12D4e

目次

brew upgrade でのエラーと解決方法

まずエラーの内容はこちらです。

$ brew upgrade

 ~~~

Error: Your Command Line Tools (CLT) does not support macOS 11.
It is either outdated or was modified.
Please update your Command Line Tools (CLT) or delete it if no updates are available.
Update them from Software Update in System Preferences or run:
  softwareupdate --all --install --force

If that doesn't show you any updates, run:
  sudo rm -rf /Library/Developer/CommandLineTools
  sudo xcode-select --install

Alternatively, manually download them from:
  https://developer.apple.com/download/more/.

Error: An exception occurred within a child process:
  SystemExit: exit

CLTがmacOS 11 に対応してないと怒られています。
以前、macOSをBig Surにアップデートしたことが原因のようでした。

通常ならソフトウェアアップデートでCLTのアップデートが降りてくるはずなのですが、この時点ではアップデートのリストを取得しても降りてきませんでした。

$ softwareupdate --list
Software Update Tool

Finding available software
No new software available.

参考: man page softwareupdate section 8

また、CLTはXcode経由で入れたと思っていたので、最新のXcodeをインストールしてCLTを新しいバージョンに切り替えてもエラーは解決しませんでした。

結論としては、エラー内容の指示通りに以下のコマンドを実施して、CLTを再インストールすることでエラーが解消し、Homebrewでパッケージのアップグレードができるようになりました。

$ sudo rm -rf /Library/Developer/CommandLineTools
$ sudo xcode-select --install

同じエラーに遭遇していて、「とりあえずHomebrewだけ機能するようにしたい!」という方はこちらを試してみてください。

Homebrewの構成を確認せずにそのままエラー解決してしまったので、エラー発生時のCLTのバージョンが不明で、根本的な原因はわからずじまいなのですが、以下の参考のように同じ現象の方はいるようでした。

詳しくは後述しますが、CLTには「システムにインストールされているCLT」「Xcodeのパッケージに埋め込まれているCLT」の2種類が存在します。
※(便宜上、以下「システムのCLT」「XcodeのCLT」という。)

以下のissueで少し言及されていますが、HomebrewはシステムのCLTとXcodeのCLTのどちらも探しに行くようで、今回のエラーはシステムのCLTがうまくアップデートできていなかったことが原因ではないか、と考えています。
https://github.com/Homebrew/brew/issues/10745#issuecomment-787520357

brew --configで構成を確認すると、CLTとXcodeの項目でそれぞれが認識されているのがわかります。

$ brew --config

 ~~~

CLT: 12.4.0.0.1.1610135815
Xcode: 12.1 => /Applications/Xcode-12.1.app/Contents/Developer

// システムのCLTのみ存在する場合
// CLT: 12.4.0.0.1.1610135815
// Xcode: N/A

// XcodeのCLTのみ存在する場合
// CLT: N/A
// Xcode: 12.1 => /Applications/Xcode-12.1.app/Contents/Developer

brew upgradeのエラー解決については以上です。

以降からはCLTについて解説していきます。

Command Line Tools (CLT)とは

ここで言うCLTとは、macOSで使用する開発者向けのコマンドラインツール群のことで、Command Line Tools for Xcodeのことをさします。

This package enables UNIX-style development via Terminal by installing command line developer tools, as well as macOS SDK frameworks and headers. Many useful tools are included, such as the Apple LLVM compiler, linker, and Make. If you use Xcode, these tools are also embedded within the Xcode IDE.

Command Line Tools for Xcode 12.4 の説明より

Command Line Tools - Apple Developer
※リンク先サイトを利用するにはApple IDでのサインインが必要です。

Xcode自体にも埋め込まれていると記載されています。

CLTには「システムのCLT」「XcodeのCLT」の2種類が存在し、この2つはインストールされているディレクトリが違い、それぞれ共存することができます。

この違いを意識すると、以降の内容がわかりやすくなると思います。

CLTのインストール方法

ここでCLTのインストール方法を紹介しておきます。

ちなみにHomebrewを利用するにはCLTが必要で、そのためにXcodeをインストールする必要があるという情報が少なくないですが、Homebrewを使うだけならXcodeのインストールは不要で、システムのCLTだけインストールすることで利用可能です。

一部、Xcodeのインストールが必要な機能もあるようですが、基本的にはどちらかのCLTが存在すれば機能するようでした。試しにそれぞれ片方のCLTを削除してみてもbrew doctorは通りました。

Most formulae require a compiler. A handful require a full Xcode installation. You can install Xcode, the CLT, or both; Homebrew supports all three configurations.

Installation — Homebrew Documentation

インストール方法は主に3パターンあります。

1. Xcodeをインストールすると自動的にインストールされる

現在はXcodeをインストールすると、XcodeのパッケージにCLTも埋め込まれているので、自動的にインストールされていることになります。
※「現在は」というのはXcodeバージョン6.1以降から自動インストールされるようになったという情報がありましたが、正確なソースが見つからなかったのでそのように表現しています。

この場合CLTは「XcodeのCLT」としてインストールされるため、/Path/to/Xcode.app/Contents/Developerにインストールされます。

XcodeはApp Storeアプリからインストールしてもいいですが、常に最新版を使うわけじゃないので、アップデート通知が鬱陶しかったり、AppleIDと紐づいたり、たまにいつまで経ってもインストールが終わらなかったりと、色々面倒なので、私は以下のDeveloperサイトから任意のバージョンをダウンロードして入れています。また、この方法で複数バージョンのインストールも可能です。

More Software Downloads - Apple Developer
※リンク先サイトを利用するにはApple IDでのサインインが必要です。

Xcodeは容量がかなり大きいので、Xcode自体は使わないという場合や、ドライブを圧迫したくない場合はCLTだけインストールすることも可能ですので、その場合は次以降の方法でのインストールがおすすめです。

2. コマンドラインからインストールする

以下のコマンドを実行することでXcodeをインストールせずにCLTだけインストールできます。

xcode-select --install

厳密には「CLTの自動インストールを行うためのダイアログを表示する」コマンドみたいですね。
参考:man page xcode-select section 1

実行するとダイアログとライセンスが表示されて、指示に従っていけばインストールできます。

この場合は「システムのCLT」としてインストールされるため、/Library/Developer/CommandLineToolsにインストールされます。

3. Apple Developerサイトからインストーラをダウンロードしてインストールする

以下のサイトからインストーラをダウンロードして実行することでもインストールできます。
サイトを利用するにはApple IDでのサインインが必要です。
Command Line Tools - Apple Developer

この場合も2と同じように、「システムのCLT」として/Library/Developer/CommandLineToolsにインストールされます。

xcode-select と xcodebuild

CLTについて調べているとよくこの2つのコマンドが出てきますが、双方を混同しているような情報や、それぞれがCLTだという厳密に言うと正しくない情報もちらほらあるので、それぞれの説明を以下にまとめます。

コマンド 説明
xcode-select Xcodeなどで使用する開発者ツール(CLT)の場所(ディレクトリ)を管理(選択)するためのツール。
xcodebuild その名の通りXcodeのプロジェクトやワークスペースをビルドするためのツール。CLTの中の一つ。

man page xcode-select section 1
man page xcodebuild section 1

つまり、使用する開発者ツール(CLT)のディレクトリをxcode-selectで管理(選択)して、そのツールの中にxcodebuildが存在するということです。

xcodebuildはXcodeのCLTに含まれていて、システムのCLTには含まれていないようでした。

もう少し細かくみていきます。

xcode-select

macOSに標準で入ってるツールのようで、以下の場所に存在します。

$ which xcode-select
/usr/bin/xcode-select

xcodebuild

同じ名前のコマンドが/usr/bin内に存在します。

$ which xcodebuild
/usr/bin/xcodebuild

ただし、実はこれは「アクティブなデベロッパディレクトリからxcodebuildを実行する」というコマンドで、Xcodeがインストールされていない(CLTにxcodebuildが含まれていない)状態では以下のような出力になります。

$ xcodebuild -version
xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance

xcodebuildを使うにはXcodeが必要で、/Library/Developer/CommandLineToolsがアクティブな開発者ディレクトリになっている、と怒られています。

これは、CLTを単体でインストールした場合は/Library/Developer/CommandLineToolsにシステムのCLTとしてインストールされており、それにはxcodebuildは含まれておらず、Xcodeをインストールしていない場合はxcode-selectによってこのディレクトリがアクティブな開発者ディレクトリとして設定されているからです。

Xcodeのパッケージの内容を表示してディレクトリを潜ってみるとわかりますが、xcodebuildは/Path/to/Xcode.app/Contents/Developer/usr/bin/xcodebuildに存在します。

CLTのバージョン(アクティブなディレクトリ)を切り替える方法

たとえば複数バージョンのXcodeなどで開発している場合は、それぞれのXcodeを使用する際にCLTのバージョンもXcodeに合わせて切り替える必要があります。
特別な理由がない限りは、Xcode 12.3で開発する場合はCLTも12.3のもの、Xcode 12.4で開発する場合はCLTも12.4のもの、という具合です。

GUIで切り替える方法

Xcodeをインストールしている場合、CLTの切り替えはGUIで変更できます。
「Xcode」-「Preferences」の「Locations」タブの「Command Line Tools」の項目から設定できます。

コマンドラインから切り替える方法

コマンドラインで変更する場合は、xcode-select を使用してアクティブなディレクトリを変更することで切り替えらます。

sudo xcode-select --switch /Path/to/CommandLineTools
// 例
// sudo xcode-select --switch /Library/Developer/CommandLineTools
// sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer

CLTについて理解することで必要に応じて使い分けができる

CLTのインストールやアップデートと聞くと「あー、またあの重いXcodeをインストールしないといけないのか」と思う方もいるかもしれませんが、正しく理解するとHomebrewなどの場合はシステムのCLTをインストールするだけでもいいことがわかりました。(容量でいうと10GB以上→500MB以下まで軽減できます。)

Xcodeを複数バージョン使用している場合は、システムのCLTもインストールしつつ、XcodeのCLTを切り替えながら開発するという使い方になると思います。

何気なく使っているツールがどこに実体があったり、どういった仕組みで動いているかは、使う分にはあまり意識することはないかもしれませんが、深く知っているとトラブル対応がスムーズになったり、無駄のないミニマムな環境構築にもつながってくると思います。

ただ、マニュアルにもそこまで深いところまで詳しく書かれていなかったり、調べるのにも時間がかかったりするので、知ってて損はないですがどこまで追求するかはケースバイケースだと思っています。

この情報が何かの役に立てば幸いです。

おまけ

CLT周りのコマンドはあまり使うことがなくて忘れがちなので、備考録として一部まとめておきます。

// CLTのインストール
$ sudo xcode-select --install

// xcode-select のバージョン確認
$ xcode-select --version

// CLTのアクティブなディレクトリの確認
$ xcode-select -p

// CLTのアクティブなディレクトリの変更
$ sudo xcode-select --switch /Path/to/CommandLineTools

// xcodebuild のバージョン確認(※ -(ハイフン)がひとつなのに注意)
$ xcodebuild -version

株式会社ウイングドアでは、Ruby on RailsやPHPを活用したwebサービス、webサイト制作を中心に、
スマホアプリや業務系システムなど様々なシステム開発を承っています。


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。