project.pbxproj は NeXTSTEP の Old-style ASCII Property List(OpenStep plist)形式で記述されたテキストファイルである。Xcode プロジェクトのビルドターゲット、ファイル参照、ビルド設定などすべての構成情報を保持する。
以下の文字のみで構成される文字列はクォートなしで記述できる:
A-Z a-z 0-9 _ . $ / \ [ ] + - * @ ! < > | & ^ ~ % # ` ? '
例:
isa = PBXBuildFile;
path = Sources/Models/User.swift;
productType = com.apple.product-type.framework;
スペースや上記以外の文字を含む場合は二重引用符で囲む:
name = "Supporting Files";
compatibilityVersion = "Xcode 14.0";
sourceTree = "<group>";
shellScript = "echo \"Hello World\"\n";
クォート文字列内で使用できるエスケープ:
| シーケンス | 意味 |
|---|---|
\" |
二重引用符 |
\\ |
バックスラッシュ |
\n |
改行 |
\t |
タブ |
\r |
キャリッジリターン |
\0 |
ヌル文字 |
空文字列は "" と記述する:
projectDirPath = "";
projectRoot = "";
2つの用途がある:
UUID アノテーション — UUID の直後にファイル名やオブジェクト名を付記する:
3106FB60... /* ProtectedTests.swift */
A8491E1D... /* SwiftyJSON.swift in Sources */
2E4FEFDB... /* Build configuration list for PBXProject "MyApp" */
セクション区切り — objects 辞書内で ISA ごとのブロックを区切る:
/* Begin PBXBuildFile section */
...
/* End PBXBuildFile section */
ファイル先頭のマジックコメントにのみ使用される:
// !$*UTF8*$!
name = Debug;
path = "path with spaces";
丸括弧で囲み、要素はカンマ区切り。末尾要素の後にもカンマを付ける:
files = (
3106FB61... /* file.swift in Sources */,
A8491E1D... /* other.swift in Sources */,
);
空配列:
dependencies = (
);
波括弧で囲み、エントリは key = value; 形式。各エントリはセミコロンで終端する:
buildSettings = {
SWIFT_VERSION = 5.0;
PRODUCT_BUNDLE_IDENTIFIER = "org.example.App";
};
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 56;
objects = {
...
};
rootObject = <UUID> /* Project object */;
}
| キー | 値 | 説明 |
|---|---|---|
archiveVersion |
1 |
常に 1 |
classes |
{} |
常に空辞書 |
objectVersion |
数値 | フォーマットバージョン(後述) |
objects |
辞書 | 全オブジェクトを UUID キーで格納 |
rootObject |
UUID | PBXProject オブジェクトの UUID |
インデントにはタブ文字(\t)を使用する。
| objectVersion | compatibilityVersion | 対応 Xcode |
|---|---|---|
| 46 | Xcode 3.2 | — |
| 47 | Xcode 6.3 | Xcode 6.3 |
| 52 | Xcode 3.2 | — |
| 53 | Xcode 11.4 | Xcode 11.4 |
| 54 | Xcode 3.2 / Xcode 10.0 | Xcode 10 |
| 55 | Xcode 9.3 | Xcode 9.3 |
| 56 | Xcode 14.0 | Xcode 14 |
| 70 | Xcode 15.0 | Xcode 15 |
archiveVersion は常に 1 で変化しない。
objects はプロジェクト内の全オブジェクトを UUID キーで格納するフラットな辞書である。
objects = {
/* Begin PBXBuildFile section */
<UUID> /* name */ = { ... };
<UUID> /* name */ = { ... };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
<UUID> /* name */ = { ... };
/* End PBXFileReference section */
...
};
- ISA 名のアルファベット順にセクションが並ぶ(
PBX*→XC*) - 各セクションは
/* Begin XXX section */と/* End XXX section */で囲まれる - セクション間には空行が入る
- 各セクション内のエントリは UUID の昇順でソートされる
エントリの記述形式は ISA によって決まる:
インライン形式(1行)— PBXBuildFile, PBXFileReference, PBXFileSystemSynchronizedRootGroup:
3106FB61... /* file.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3106FB60... /* file.swift */; };
展開形式(複数行)— その他すべての ISA:
821507281E57468200C75711 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = ( ... );
runOnlyForDeploymentPostprocessing = 0;
};
- 24文字の16進大文字(96ビット):
3106FB6119A2B12000CCFAE6 - Xcode がオブジェクト作成時に自動生成する
- プロジェクト内で一意
- UUID の直後に
/* ... */コメントで人間が読める名前が付記される
3106FB60... /* ProtectedTests.swift */
配列要素やキーの値として UUID を参照する場合も同様にコメントが付く:
fileRef = 3106FB60... /* ProtectedTests.swift */;
objects 辞書内のセクション出現順(ISA 名アルファベット順)に記載する。
| # | ISA | 用途 | 形式 | 主要キー |
|---|---|---|---|---|
| 1 | PBXAggregateTarget |
ビルド成果物を持たない複合ターゲット(スクリプト実行等) | 展開 | buildConfigurationList, buildPhases, dependencies, name, productName |
| 2 | PBXBuildFile |
ファイル参照×ビルドフェーズの関連付け | インライン | fileRef, [settings], [platformFilters] |
| 3 | PBXContainerItemProxy |
ターゲット依存関係のプロキシ | 展開 | containerPortal, proxyType(1=依存/2=外部), remoteGlobalIDString, remoteInfo |
| 4 | PBXCopyFilesBuildPhase |
ファイルコピーフェーズ(Embed Frameworks 等) | 展開 | dstPath, dstSubfolderSpec(7=Resources/10=Frameworks/13=SharedSupport/16=Plugins), files, [name] |
| 5 | PBXFileReference |
ファイル・ビルド成果物への参照 | インライン | lastKnownFileType or explicitFileType, path, sourceTree, [name], [fileEncoding] |
| 6 | PBXFileSystemSynchronizedRootGroup |
フォルダ同期グループ(Xcode 15+) | インライン | explicitFileTypes, explicitFolders, name, path, sourceTree |
| 7 | PBXFrameworksBuildPhase |
フレームワークリンクフェーズ | 展開 | files |
| 8 | PBXGroup |
仮想グループ(ナビゲータのフォルダ構造) | 展開 | children, [path], [name], sourceTree |
| 9 | PBXHeadersBuildPhase |
ヘッダコピーフェーズ | 展開 | files |
| 10 | PBXNativeTarget |
ビルドターゲット(アプリ、フレームワーク、テスト等) | 展開 | buildConfigurationList, buildPhases(順序=実行順), buildRules, dependencies, name, productName, productReference, productType |
| 11 | PBXProject |
プロジェクトルート(1件のみ、rootObject から参照) |
展開 | attributes, buildConfigurationList, compatibilityVersion, developmentRegion, knownRegions, mainGroup, productRefGroup, targets |
| 12 | PBXReferenceProxy |
他プロジェクト成果物へのプロキシ参照 | 展開 | fileType, path, remoteRef, sourceTree |
| 13 | PBXResourcesBuildPhase |
リソースコピーフェーズ | 展開 | files |
| 14 | PBXShellScriptBuildPhase |
シェルスクリプト実行フェーズ | 展開 | shellPath, shellScript, inputPaths, outputPaths, [name], [alwaysOutOfDate] |
| 15 | PBXSourcesBuildPhase |
ソースコンパイルフェーズ | 展開 | files |
| 16 | PBXTargetDependency |
ターゲット間依存 | 展開 | target, targetProxy |
| 17 | PBXVariantGroup |
ローカライズファイルグループ(Storyboard 等) | 展開 | children, name, sourceTree |
| 18 | XCBuildConfiguration |
ビルド設定(Debug / Release) | 展開 | buildSettings, name |
| 19 | XCConfigurationList |
設定リスト(Project / Target ごと) | 展開 | buildConfigurations, defaultConfigurationName |
| 20 | XCRemoteSwiftPackageReference |
リモート SPM パッケージ参照 | 展開 | repositoryURL, requirement(kind: upToNextMajorVersion/exactVersion/branch/revision) |
| 21 | XCSwiftPackageProductDependency |
SPM プロダクト依存 | 展開 | package, productName |
備考:
- ビルドフェーズ系 ISA(#7, #9, #13, #15)はすべて
buildActionMask = 2147483647,runOnlyForDeploymentPostprocessing = 0を持つ(固定値) PBXBuildFile.settings.ATTRIBUTESの値:Public,Private,Project,CodeSignOnCopy,RemoveHeadersOnCopyPBXNativeTarget.productTypeの値:com.apple.product-type.application,.framework,.library.static,.bundle.unit-test,.bundle.ui-testing,.tool,.xcode-extension
project.pbxproj の全オブジェクトは objects 辞書にフラットに格納されているが、UUID による参照でツリー構造を形成する。rootObject からすべてのオブジェクトをたどることができる。
rootObject
└─ PBXProject
├─ mainGroup ─→ PBXGroup(ルート)
│ ├─ PBXGroup(サブグループ)
│ │ ├─ PBXFileReference
│ │ └─ PBXVariantGroup
│ │ └─ PBXFileReference(ローカライズ版)
│ └─ PBXFileSystemSynchronizedRootGroup
│
├─ productRefGroup ─→ PBXGroup(Products)
│ └─ PBXFileReference(ビルド成果物)
│
├─ targets ─→ PBXNativeTarget / PBXAggregateTarget
│ ├─ buildPhases ─→ PBXSourcesBuildPhase
│ │ └─ files ─→ PBXBuildFile
│ │ └─ fileRef ─→ PBXFileReference
│ ├─ dependencies ─→ PBXTargetDependency
│ │ ├─ target ─→ PBXNativeTarget
│ │ └─ targetProxy ─→ PBXContainerItemProxy
│ └─ buildConfigurationList ─→ XCConfigurationList
│ └─ buildConfigurations ─→ XCBuildConfiguration
│
└─ buildConfigurationList ─→ XCConfigurationList(プロジェクトレベル)
└─ buildConfigurations ─→ XCBuildConfiguration
sourceTree はファイルパスの基準点を指定する。path と組み合わせて実際のディスク上のパスを決定する。
| sourceTree 値 | 基準 |
|---|---|
"<group>" |
親グループの解決済みパスからの相対パス |
SOURCE_ROOT |
プロジェクトファイル(.xcodeproj)の親ディレクトリ |
BUILT_PRODUCTS_DIR |
ビルド出力ディレクトリ |
SDKROOT |
SDK ルートディレクトリ |
DEVELOPER_DIR |
Xcode.app の Developer ディレクトリ |
"<group>" の場合、パス解決はルートグループから再帰的に行われる:
- ルートグループ(mainGroup)の
path(通常は空 = プロジェクトルート)を起点とする - 子グループの
pathを連結していく - 最終的な PBXFileReference の
pathを連結して実パスを得る
例: ルートグループ(path なし) → サブグループ(path = iCarousel) → ファイル(path = iCarousel.h) → 実パスは iCarousel/iCarousel.h
Xcode は ISA に応じて辞書の記述形式を使い分ける:
| 形式 | 対象 ISA |
|---|---|
| インライン(1行) | PBXBuildFile, PBXFileReference, PBXFileSystemSynchronizedRootGroup |
| 展開(複数行) | 上記以外のすべての ISA |
インライン形式は大量に存在するエントリ(ファイル参照、ビルドファイル)をコンパクトに記述するために使われる。展開形式は配列や入れ子辞書を含む構造的なオブジェクトに使われる。