MACOSX_DEPLOYMENT_TARGETは、プロジェクト・ターゲット・xcconfig・コマンドラインのどこにでも書ける。複数の階層に書くと、最終的にどの値が使われるのか分かりにくい。xcodebuild -showBuildSettingsを使うと、最終的な値を確認できる。
$ xcodebuild -project [プロジェクト名].xcodeproj -scheme [スキーム名] -showBuildSettings 2>/dev/null | grep -E "^\s+MACOSX_DEPLOYMENT_TARGET ="
MACOSX_DEPLOYMENT_TARGET = 12.0
実行例はXcode 27.0、macOS 27.0.1のもの。
最終的な値を確認する (-showBuildSettings)
-showBuildSettingsは、ビルドを実行せずに、ターゲットの最終的なビルド設定を表示する。出力は500行を超えるため、grepで絞り込む。
$ xcodebuild -project [プロジェクト名].xcodeproj -scheme [スキーム名] -showBuildSettings 2>/dev/null | grep -E "^\s+(MACOSX_DEPLOYMENT_TARGET|SDK_VERSION) ="
MACOSX_DEPLOYMENT_TARGET = 12.0
SDK_VERSION = 27.0
-schemeの代わりに-targetでも指定できる。構成を切り替えるときは-configurationを付ける。
$ xcodebuild -project [プロジェクト名].xcodeproj -target [ターゲット名] -configuration Release -showBuildSettings 2>/dev/null | grep -E "^\s+(CONFIGURATION|MACOSX_DEPLOYMENT_TARGET) ="
CONFIGURATION = Release
MACOSX_DEPLOYMENT_TARGET = 12.0
2>/dev/nullは、標準エラー出力に出る警告を隠すために付けている。-schemeを指定すると、複数の宛先が一致した旨の警告が表示される。
JSONで取得する
-jsonを付けると、JSONで出力される。jqで値を取り出せる。
$ xcodebuild -project [プロジェクト名].xcodeproj -scheme [スキーム名] -showBuildSettings -json 2>/dev/null | jq -r '.[0].buildSettings.MACOSX_DEPLOYMENT_TARGET'
12.0
スキームやターゲットを指定する
プロジェクトに複数のターゲットがあるときは、-schemeか-targetを指定する。指定しないと、検証では先頭のターゲットの設定だけが表示された。
設定できる階層と優先順位
MACOSX_DEPLOYMENT_TARGETを設定できる階層と、優先順位は次のとおりである。上にあるものが優先される。
| 優先順位 | 階層 | 設定場所 |
|---|---|---|
| 1 | コマンドライン | xcodebuildに渡すMACOSX_DEPLOYMENT_TARGET=[値] |
| 2 | ターゲットのBuild Settings | ターゲットのXCBuildConfiguration |
| 3 | ターゲットのxcconfig | ターゲットの構成に割り当てたxcconfig |
| 4 | プロジェクトのBuild Settings | プロジェクトのXCBuildConfiguration |
| 5 | プロジェクトのxcconfig | プロジェクトの構成に割り当てたxcconfig |
| 6 | 既定値 | ビルドに使うSDKのバージョン |
階層を1つずつ足したときの-showBuildSettingsの結果は次のとおりである。
| 設定した階層(値) | 最終的な値 |
|---|---|
| なし | 27.0 |
| プロジェクトのxcconfig(13.0) | 13.0 |
| 上に加えて、プロジェクトのBuild Settings(26.0) | 26.0 |
| 上に加えて、ターゲットのxcconfig(15.0) | 15.0 |
| 上に加えて、ターゲットのBuild Settings(12.0) | 12.0 |
| 上に加えて、コマンドライン(14.0) | 14.0 |
どこにも設定しないと、ビルドに使うSDKのバージョン(検証では27.0)が使われる。意図せず最新のmacOSでしか動かないバイナリになるため、明示的に設定しておく。
シェルの環境変数MACOSX_DEPLOYMENT_TARGETは、検証では最終的な値に影響しなかった。どこにも設定していない状態でMACOSX_DEPLOYMENT_TARGET=14.0を環境変数に指定しても、27.0のままだった。他の階層に設定があるときも、環境変数の値は使われなかった。
$ MACOSX_DEPLOYMENT_TARGET=14.0 xcodebuild -project [プロジェクト名].xcodeproj -scheme [スキーム名] -showBuildSettings 2>/dev/null | grep -E "^\s+MACOSX_DEPLOYMENT_TARGET ="
MACOSX_DEPLOYMENT_TARGET = 27.0
コマンドラインで上書きする
xcodebuildの末尾にMACOSX_DEPLOYMENT_TARGET=[値]を渡すと、他の階層の設定を上書きできる。-showBuildSettingsの出力には、上書きした設定がBuild settings from command line:として表示される。冒頭のgrepをそのまま使うと、この表示と最終的な設定の2行が出力される。
$ xcodebuild -project [プロジェクト名].xcodeproj -scheme [スキーム名] -showBuildSettings MACOSX_DEPLOYMENT_TARGET=14.0 2>/dev/null | grep -E -A1 "^Build settings from command line"
Build settings from command line:
MACOSX_DEPLOYMENT_TARGET = 14.0
プロジェクトとターゲットの値が食い違う場合
プロジェクトに26.0、ターゲットに12.0を設定すると、ターゲットの値が優先され、最終的な値は12.0になる。
一方、ターゲット側に値を設定していないターゲットは、プロジェクトの値を引き継ぐ。プロジェクトに26.0を設定し、ターゲットAだけに12.0を設定した場合は、次のようになる。
$ xcodebuild -project [プロジェクト名].xcodeproj -scheme [スキームA] -showBuildSettings 2>/dev/null | grep -E "^\s+MACOSX_DEPLOYMENT_TARGET ="
MACOSX_DEPLOYMENT_TARGET = 12.0
$ xcodebuild -project [プロジェクト名].xcodeproj -scheme [スキームB] -showBuildSettings 2>/dev/null | grep -E "^\s+MACOSX_DEPLOYMENT_TARGET ="
MACOSX_DEPLOYMENT_TARGET = 26.0
テストターゲットなど、値を持たないターゲットには、プロジェクトの値が使われる。アプリのターゲットだけを下げても、他のターゲットは下がらない。
どの階層に設定があるかを調べる
-showBuildSettingsは、最終的な値だけを表示し、どの階層の値なのかは表示しない。プロジェクトとターゲットのBuild Settingsは、project.pbxprojをplutilでJSONに変換して、jqで一覧にできる。
$ plutil -convert json -o - [プロジェクト名].xcodeproj/project.pbxproj | jq -r '
.objects as $o
| $o[.rootObject] as $p
| ([{owner: "project", list: $p.buildConfigurationList}]
+ [$p.targets[] | {owner: ("target " + $o[.].name), list: $o[.].buildConfigurationList}])[]
| .owner as $owner
| $o[.list].buildConfigurations[]
| $o[.]
| "\($owner)\t\(.name)\t\(.buildSettings.MACOSX_DEPLOYMENT_TARGET // "-")"' | sort
project Debug 26.0
project Release 26.0
target [ターゲットA] Debug 12.0
target [ターゲットA] Release 12.0
target [ターゲットB] Debug -
target [ターゲットB] Release -
-は、その階層に設定がないことを表す。ターゲットBには設定がないため、プロジェクトの26.0を引き継ぐ。
xcconfigに書いた設定は、project.pbxprojには含まれない。xcconfigファイルをgrepで探す。
$ grep -rn "MACOSX_DEPLOYMENT_TARGET" --include="*.xcconfig" .
ビルドしたバイナリで確認する
最終的な値は、ビルドしたバイナリのminosにも反映される。vtool -show-buildで確認できる。
$ xcodebuild -project [プロジェクト名].xcodeproj -scheme [スキームA] -derivedDataPath ./dd build
$ xcrun vtool -show-build ./dd/Build/Products/Debug/[ターゲットA] | grep -E "minos|sdk"
minos 12.0
sdk 27.0
minosにはデプロイメントターゲットが、sdkにはビルドに使ったSDKのバージョンが記録される。デプロイメントターゲットを変えても、sdkは変わらない。
ターゲットごとのminosは次のとおりである。
| ビルドの条件 | -showBuildSettingsの値 | バイナリのminos |
|---|---|---|
| ターゲットAにBuild Settingsで12.0を設定 | 12.0 | 12.0 |
| ターゲットBは設定なし(プロジェクトは26.0) | 26.0 | 26.0 |
| ターゲットAをコマンドラインで14.0に上書き | 14.0 | 14.0 |
| どこにも設定しない | 27.0 | 27.0 |
ビルドログの-target arm64-apple-macos12.0でも、コンパイラに渡された値を確認できる。
参考: 【vtool】バイナリのSDKバージョンを確認して公証エラーに対処する
