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.012.0
ターゲットBは設定なし(プロジェクトは26.0)26.026.0
ターゲットAをコマンドラインで14.0に上書き14.014.0
どこにも設定しない27.027.0

ビルドログの-target arm64-apple-macos12.0でも、コンパイラに渡された値を確認できる。

参考: 【vtool】バイナリのSDKバージョンを確認して公証エラーに対処する