1 // Copyright 2016 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef TOOLS_GN_XCODE_OBJECT_H_ 6 #define TOOLS_GN_XCODE_OBJECT_H_ 7 8 #include <iosfwd> 9 #include <map> 10 #include <memory> 11 #include <string> 12 #include <vector> 13 14 // Helper classes to generate Xcode project files. 15 // 16 // This code is based on gyp xcodeproj_file.py generator. It does not support 17 // all features of Xcode project but instead just enough to implement a hybrid 18 // mode where Xcode uses external scripts to perform the compilation steps. 19 // 20 // See 21 // https://chromium.googlesource.com/external/gyp/+/master/pylib/gyp/xcodeproj_file.py 22 // for more information on Xcode project file format. 23 24 // PBXObjectClass ------------------------------------------------------------- 25 26 enum PBXObjectClass { 27 // Those values needs to stay sorted in alphabetic order. 28 PBXAggregateTargetClass, 29 PBXBuildFileClass, 30 PBXContainerItemProxyClass, 31 PBXFileReferenceClass, 32 PBXFrameworksBuildPhaseClass, 33 PBXGroupClass, 34 PBXNativeTargetClass, 35 PBXProjectClass, 36 PBXResourcesBuildPhaseClass, 37 PBXShellScriptBuildPhaseClass, 38 PBXSourcesBuildPhaseClass, 39 PBXTargetDependencyClass, 40 XCBuildConfigurationClass, 41 XCConfigurationListClass, 42 }; 43 44 const char* ToString(PBXObjectClass cls); 45 46 // Forward-declarations ------------------------------------------------------- 47 48 class PBXAggregateTarget; 49 class PBXBuildFile; 50 class PBXBuildPhase; 51 class PBXContainerItemProxy; 52 class PBXFileReference; 53 class PBXFrameworksBuildPhase; 54 class PBXGroup; 55 class PBXNativeTarget; 56 class PBXObject; 57 class PBXProject; 58 class PBXResourcesBuildPhase; 59 class PBXShellScriptBuildPhase; 60 class PBXSourcesBuildPhase; 61 class PBXTarget; 62 class PBXTargetDependency; 63 class XCBuildConfiguration; 64 class XCConfigurationList; 65 66 using PBXAttributes = std::map<std::string, std::string>; 67 68 // PBXObjectVisitor ----------------------------------------------------------- 69 70 class PBXObjectVisitor { 71 public: 72 PBXObjectVisitor(); 73 virtual ~PBXObjectVisitor(); 74 virtual void Visit(PBXObject* object) = 0; 75 76 private: 77 PBXObjectVisitor(const PBXObjectVisitor&) = delete; 78 PBXObjectVisitor& operator=(const PBXObjectVisitor&) = delete; 79 }; 80 81 // PBXObjectVisitorConst ------------------------------------------------------ 82 83 class PBXObjectVisitorConst { 84 public: 85 PBXObjectVisitorConst(); 86 virtual ~PBXObjectVisitorConst(); 87 virtual void Visit(const PBXObject* object) = 0; 88 89 private: 90 PBXObjectVisitorConst(const PBXObjectVisitorConst&) = delete; 91 PBXObjectVisitorConst& operator=(const PBXObjectVisitorConst&) = delete; 92 }; 93 94 // PBXObject ------------------------------------------------------------------ 95 96 class PBXObject { 97 public: 98 PBXObject(); 99 virtual ~PBXObject(); 100 id()101 const std::string id() const { return id_; } 102 void SetId(const std::string& id); 103 104 std::string Reference() const; 105 106 virtual PBXObjectClass Class() const = 0; 107 virtual std::string Name() const = 0; 108 virtual std::string Comment() const; 109 virtual void Visit(PBXObjectVisitor& visitor); 110 virtual void Visit(PBXObjectVisitorConst& visitor) const; 111 virtual void Print(std::ostream& out, unsigned indent) const = 0; 112 113 private: 114 std::string id_; 115 116 PBXObject(const PBXObject&) = delete; 117 PBXObject& operator=(const PBXObject&) = delete; 118 }; 119 120 // PBXBuildPhase -------------------------------------------------------------- 121 122 class PBXBuildPhase : public PBXObject { 123 public: 124 PBXBuildPhase(); 125 ~PBXBuildPhase() override; 126 127 void AddBuildFile(std::unique_ptr<PBXBuildFile> build_file); 128 129 // PBXObject implementation. 130 void Visit(PBXObjectVisitor& visitor) override; 131 void Visit(PBXObjectVisitorConst& visitor) const override; 132 133 protected: 134 std::vector<std::unique_ptr<PBXBuildFile>> files_; 135 136 private: 137 PBXBuildPhase(const PBXBuildPhase&) = delete; 138 PBXBuildPhase& operator=(const PBXBuildPhase&) = delete; 139 }; 140 141 // PBXTarget ------------------------------------------------------------------ 142 143 class PBXTarget : public PBXObject { 144 public: 145 PBXTarget(const std::string& name, 146 const std::string& shell_script, 147 const std::string& config_name, 148 const PBXAttributes& attributes); 149 ~PBXTarget() override; 150 151 void AddDependency(std::unique_ptr<PBXTargetDependency> dependency); 152 153 // PBXObject implementation. 154 std::string Name() const override; 155 void Visit(PBXObjectVisitor& visitor) override; 156 void Visit(PBXObjectVisitorConst& visitor) const override; 157 158 protected: 159 std::unique_ptr<XCConfigurationList> configurations_; 160 std::vector<std::unique_ptr<PBXBuildPhase>> build_phases_; 161 std::vector<std::unique_ptr<PBXTargetDependency>> dependencies_; 162 PBXSourcesBuildPhase* source_build_phase_ = nullptr; 163 PBXResourcesBuildPhase* resource_build_phase_ = nullptr; 164 std::string name_; 165 166 private: 167 PBXTarget(const PBXTarget&) = delete; 168 PBXTarget& operator=(const PBXTarget&) = delete; 169 }; 170 171 // PBXAggregateTarget --------------------------------------------------------- 172 173 class PBXAggregateTarget : public PBXTarget { 174 public: 175 PBXAggregateTarget(const std::string& name, 176 const std::string& shell_script, 177 const std::string& config_name, 178 const PBXAttributes& attributes); 179 ~PBXAggregateTarget() override; 180 181 // PBXObject implementation. 182 PBXObjectClass Class() const override; 183 void Print(std::ostream& out, unsigned indent) const override; 184 185 private: 186 PBXAggregateTarget(const PBXAggregateTarget&) = delete; 187 PBXAggregateTarget& operator=(const PBXAggregateTarget&) = delete; 188 }; 189 190 // PBXBuildFile --------------------------------------------------------------- 191 192 class PBXBuildFile : public PBXObject { 193 public: 194 PBXBuildFile(const PBXFileReference* file_reference, 195 const PBXBuildPhase* build_phase); 196 ~PBXBuildFile() override; 197 198 // PBXObject implementation. 199 PBXObjectClass Class() const override; 200 std::string Name() const override; 201 void Print(std::ostream& out, unsigned indent) const override; 202 203 private: 204 const PBXFileReference* file_reference_ = nullptr; 205 const PBXBuildPhase* build_phase_ = nullptr; 206 207 PBXBuildFile(const PBXBuildFile&) = delete; 208 PBXBuildFile& operator=(const PBXBuildFile&) = delete; 209 }; 210 211 // PBXContainerItemProxy ------------------------------------------------------ 212 class PBXContainerItemProxy : public PBXObject { 213 public: 214 PBXContainerItemProxy(const PBXProject* project, const PBXTarget* target); 215 ~PBXContainerItemProxy() override; 216 217 // PBXObject implementation. 218 PBXObjectClass Class() const override; 219 std::string Name() const override; 220 void Print(std::ostream& out, unsigned indent) const override; 221 222 private: 223 const PBXProject* project_ = nullptr; 224 const PBXTarget* target_ = nullptr; 225 226 PBXContainerItemProxy(const PBXContainerItemProxy&) = delete; 227 PBXContainerItemProxy& operator=(const PBXContainerItemProxy&) = delete; 228 }; 229 230 // PBXFileReference ----------------------------------------------------------- 231 232 class PBXFileReference : public PBXObject { 233 public: 234 PBXFileReference(const std::string& name, 235 const std::string& path, 236 const std::string& type); 237 ~PBXFileReference() override; 238 239 // PBXObject implementation. 240 PBXObjectClass Class() const override; 241 std::string Name() const override; 242 std::string Comment() const override; 243 void Print(std::ostream& out, unsigned indent) const override; 244 path()245 const std::string& path() const { return path_; } 246 247 private: 248 std::string name_; 249 std::string path_; 250 std::string type_; 251 252 PBXFileReference(const PBXFileReference&) = delete; 253 PBXFileReference& operator=(const PBXFileReference&) = delete; 254 }; 255 256 // PBXFrameworksBuildPhase ---------------------------------------------------- 257 258 class PBXFrameworksBuildPhase : public PBXBuildPhase { 259 public: 260 PBXFrameworksBuildPhase(); 261 ~PBXFrameworksBuildPhase() override; 262 263 // PBXObject implementation. 264 PBXObjectClass Class() const override; 265 std::string Name() const override; 266 void Print(std::ostream& out, unsigned indent) const override; 267 268 private: 269 PBXFrameworksBuildPhase(const PBXFrameworksBuildPhase&) = delete; 270 PBXFrameworksBuildPhase& operator=(const PBXFrameworksBuildPhase&) = delete; 271 }; 272 273 // PBXGroup ------------------------------------------------------------------- 274 275 class PBXGroup : public PBXObject { 276 public: 277 explicit PBXGroup(const std::string& path = std::string(), 278 const std::string& name = std::string()); 279 ~PBXGroup() override; 280 path()281 const std::string& path() const { return path_; } name()282 const std::string& name() const { return name_; } 283 284 PBXFileReference* AddSourceFile(const std::string& navigator_path, 285 const std::string& source_path); 286 is_source()287 bool is_source() const { return is_source_; } set_is_source(bool is_source)288 void set_is_source(bool is_source) { is_source_ = is_source; } 289 autosorted()290 bool autosorted() const { return autosorted_; } set_autosorted(bool autosorted)291 void set_autosorted(bool autosorted) { autosorted_ = autosorted; } 292 293 template <typename T, typename... Args> CreateChild(Args &&...args)294 T* CreateChild(Args&&... args) { 295 return static_cast<T*>( 296 AddChildImpl(std::make_unique<T>(std::forward<Args>(args)...))); 297 } 298 299 // PBXObject implementation. 300 PBXObjectClass Class() const override; 301 std::string Name() const override; 302 void Visit(PBXObjectVisitor& visitor) override; 303 void Visit(PBXObjectVisitorConst& visitor) const override; 304 void Print(std::ostream& out, unsigned indent) const override; 305 306 private: 307 PBXObject* AddChildImpl(std::unique_ptr<PBXObject> child); 308 309 std::vector<std::unique_ptr<PBXObject>> children_; 310 std::string name_; 311 std::string path_; 312 bool is_source_ = false; 313 bool autosorted_ = true; 314 315 PBXGroup(const PBXGroup&) = delete; 316 PBXGroup& operator=(const PBXGroup&) = delete; 317 }; 318 319 // PBXNativeTarget ------------------------------------------------------------ 320 321 class PBXNativeTarget : public PBXTarget { 322 public: 323 PBXNativeTarget(const std::string& name, 324 const std::string& shell_script, 325 const std::string& config_name, 326 const PBXAttributes& attributes, 327 const std::string& product_type, 328 const std::string& product_name, 329 const PBXFileReference* product_reference); 330 ~PBXNativeTarget() override; 331 332 void AddResourceFile(const PBXFileReference* file_reference); 333 334 void AddFileForIndexing(const PBXFileReference* file_reference); 335 336 // PBXObject implementation. 337 PBXObjectClass Class() const override; 338 void Print(std::ostream& out, unsigned indent) const override; 339 340 private: 341 const PBXFileReference* product_reference_ = nullptr; 342 std::string product_type_; 343 std::string product_name_; 344 345 PBXNativeTarget(const PBXNativeTarget&) = delete; 346 PBXNativeTarget& operator=(const PBXNativeTarget&) = delete; 347 }; 348 349 // PBXProject ----------------------------------------------------------------- 350 351 class PBXProject : public PBXObject { 352 public: 353 PBXProject(const std::string& name, 354 const std::string& config_name, 355 const std::string& source_path, 356 const PBXAttributes& attributes); 357 ~PBXProject() override; 358 359 void AddSourceFileToIndexingTarget(const std::string& navigator_path, 360 const std::string& source_path); 361 void AddSourceFile(const std::string& navigator_path, 362 const std::string& source_path, 363 PBXNativeTarget* target); 364 void AddAggregateTarget(const std::string& name, 365 const std::string& shell_script); 366 void AddIndexingTarget(); 367 PBXNativeTarget* AddNativeTarget( 368 const std::string& name, 369 const std::string& type, 370 const std::string& output_dir, 371 const std::string& output_name, 372 const std::string& output_type, 373 const std::string& shell_script, 374 const PBXAttributes& extra_attributes = PBXAttributes()); 375 376 void SetProjectDirPath(const std::string& project_dir_path); 377 void SetProjectRoot(const std::string& project_root); 378 void AddTarget(std::unique_ptr<PBXTarget> target); 379 380 // PBXObject implementation. 381 PBXObjectClass Class() const override; 382 std::string Name() const override; 383 std::string Comment() const override; 384 void Visit(PBXObjectVisitor& visitor) override; 385 void Visit(PBXObjectVisitorConst& visitor) const override; 386 void Print(std::ostream& out, unsigned indent) const override; 387 388 private: 389 PBXAttributes attributes_; 390 std::unique_ptr<XCConfigurationList> configurations_; 391 std::unique_ptr<PBXGroup> main_group_; 392 std::string project_dir_path_; 393 std::string project_root_; 394 std::vector<std::unique_ptr<PBXTarget>> targets_; 395 std::string name_; 396 std::string config_name_; 397 398 PBXGroup* sources_ = nullptr; 399 PBXGroup* products_ = nullptr; 400 PBXNativeTarget* target_for_indexing_ = nullptr; 401 402 PBXProject(const PBXProject&) = delete; 403 PBXProject& operator=(const PBXProject&) = delete; 404 }; 405 406 // PBXResourcesBuildPhase ----------------------------------------------------- 407 408 class PBXResourcesBuildPhase : public PBXBuildPhase { 409 public: 410 PBXResourcesBuildPhase(); 411 ~PBXResourcesBuildPhase() override; 412 413 // PBXObject implementation. 414 PBXObjectClass Class() const override; 415 std::string Name() const override; 416 void Print(std::ostream& out, unsigned indent) const override; 417 418 private: 419 PBXResourcesBuildPhase(const PBXResourcesBuildPhase&) = delete; 420 PBXResourcesBuildPhase& operator=(const PBXResourcesBuildPhase&) = delete; 421 }; 422 423 // PBXShellScriptBuildPhase --------------------------------------------------- 424 425 class PBXShellScriptBuildPhase : public PBXBuildPhase { 426 public: 427 PBXShellScriptBuildPhase(const std::string& name, 428 const std::string& shell_script); 429 ~PBXShellScriptBuildPhase() override; 430 431 // PBXObject implementation. 432 PBXObjectClass Class() const override; 433 std::string Name() const override; 434 void Print(std::ostream& out, unsigned indent) const override; 435 436 private: 437 std::string name_; 438 std::string shell_script_; 439 440 PBXShellScriptBuildPhase(const PBXShellScriptBuildPhase&) = delete; 441 PBXShellScriptBuildPhase& operator=(const PBXShellScriptBuildPhase&) = delete; 442 }; 443 444 // PBXSourcesBuildPhase ------------------------------------------------------- 445 446 class PBXSourcesBuildPhase : public PBXBuildPhase { 447 public: 448 PBXSourcesBuildPhase(); 449 ~PBXSourcesBuildPhase() override; 450 451 // PBXObject implementation. 452 PBXObjectClass Class() const override; 453 std::string Name() const override; 454 void Print(std::ostream& out, unsigned indent) const override; 455 456 private: 457 PBXSourcesBuildPhase(const PBXSourcesBuildPhase&) = delete; 458 PBXSourcesBuildPhase& operator=(const PBXSourcesBuildPhase&) = delete; 459 }; 460 461 // PBXTargetDependency ----------------------------------------------------- 462 class PBXTargetDependency : public PBXObject { 463 public: 464 PBXTargetDependency( 465 const PBXTarget* target, 466 std::unique_ptr<PBXContainerItemProxy> container_item_proxy); 467 ~PBXTargetDependency() override; 468 469 // PBXObject implementation. 470 PBXObjectClass Class() const override; 471 std::string Name() const override; 472 void Visit(PBXObjectVisitor& visitor) override; 473 void Visit(PBXObjectVisitorConst& visitor) const override; 474 void Print(std::ostream& out, unsigned indent) const override; 475 476 private: 477 const PBXTarget* target_ = nullptr; 478 std::unique_ptr<PBXContainerItemProxy> container_item_proxy_; 479 480 PBXTargetDependency(const PBXTargetDependency&) = delete; 481 PBXTargetDependency& operator=(const PBXTargetDependency&) = delete; 482 }; 483 484 // XCBuildConfiguration ------------------------------------------------------- 485 486 class XCBuildConfiguration : public PBXObject { 487 public: 488 XCBuildConfiguration(const std::string& name, 489 const PBXAttributes& attributes); 490 ~XCBuildConfiguration() override; 491 492 // PBXObject implementation. 493 PBXObjectClass Class() const override; 494 std::string Name() const override; 495 void Print(std::ostream& out, unsigned indent) const override; 496 497 private: 498 PBXAttributes attributes_; 499 std::string name_; 500 501 XCBuildConfiguration(const XCBuildConfiguration&) = delete; 502 XCBuildConfiguration& operator=(const XCBuildConfiguration&) = delete; 503 }; 504 505 // XCConfigurationList -------------------------------------------------------- 506 507 class XCConfigurationList : public PBXObject { 508 public: 509 XCConfigurationList(const std::string& name, 510 const PBXAttributes& attributes, 511 const PBXObject* owner_reference); 512 ~XCConfigurationList() override; 513 514 // PBXObject implementation. 515 PBXObjectClass Class() const override; 516 std::string Name() const override; 517 void Visit(PBXObjectVisitor& visitor) override; 518 void Visit(PBXObjectVisitorConst& visitor) const override; 519 void Print(std::ostream& out, unsigned indent) const override; 520 521 private: 522 std::vector<std::unique_ptr<XCBuildConfiguration>> configurations_; 523 const PBXObject* owner_reference_ = nullptr; 524 525 XCConfigurationList(const XCConfigurationList&) = delete; 526 XCConfigurationList& operator=(const XCConfigurationList&) = delete; 527 }; 528 529 #endif // TOOLS_GN_XCODE_OBJECT_H_ 530