Xcode工程文件 project.pbxproj小结。转载

编译时如何看到每个文件的编译选项_导出 Clang 可视化编译耗时分析报告 —— ftimetrace 的使用... 前言笔者最近加入了新的团队,开始负责编译打包相关工作,因而开始学习优化编译时间相关技术。讲真,蛮开心的,每天都有挑战,同时每天都有收获,天天都在涨姿势,所以想记录下来并分享出来,也方便以后自己需要时回顾。本文主要介绍如何利用 clang 的 -ftime-trace 导出编译期间耗时 profile,是一篇基础的 step by step 文章。本文大致会介绍以下内容:简介LLVM&... 阅读详情

源地址: http://www.jianshu.com/p/e82ec6a56fc2

Xcode工程文件project.pbxproj小结

简介

project.pbxproj 文件被包含于 Xcode 工程文件 *.xcodeproj 之中,存储着 Xcode 工程的各项配置参数。它本质上是一种旧风格的 Property List 文件,历史可追溯到 NeXT 的 OpenStep。由于有Xcode工具的存在,我们一般不需要与pbxproj直接打交道,通过General、Build Settungs或者Info等面板,就可以完成项目工程配置信息的修改。
一般格式如下:
数组用小括号括起来并用逗号隔开元素;字典用大括号括起来并用分号隔开键值对,键值之间用等号连接;二进制数据用尖括号括起来

接下来我们就依据一个具体的project.pbxproj文件来看看文件的具体内容;
首先使用Xcode新建一个项目文件,然后找到工程文件*.xcodeproj 邮件显示包内容就可以看到project.pbxproj文件,使用熟悉的编辑器打开,可以看到一些貌似混乱却又组织严密的内容。

文件的组织规则

对于NeXTSTEP格式的Property List 文件来说,整个的project.pbxproj文件就是一个字典,里面最外层有5个键值对,key分别为:

archiveVersion  
classes  
objectVersion  
objects   
rootObject

其中重要的 Key 是 objects 和 rootObject。其他字段目前看来是固定的:

archiveVersion = 1;
classes = {
};
objectVersion = 46;


上面说到这个文件看似混乱,实质上却是组织清晰,最好的方法就是顺着 rootObject 的各个属性对应的 UUID 在 objects 中找到对应的对象,然后一层层看下去。这样整个文件的配置信息存放方式就慢慢摸清了(rootObject就好像一个入口函数),具体的配置实现是在 objects这个域里面的,里面每一项的又是一个字典,key是UUID,Value 依然是个字典。下面可以看到rootObject对应的value也可以在objects中找到具体的值。objects 中的键值对被分成了若干个 section,虽然 section 的顺序是 Xcode 私有 API 钦定的,但每个 section 内部的键值对会根据 Key 的字典序排列,以此增加可读性。
此外,这里还要补充一下:
project.pbxproj文件使用UUID 作为交叉引用的索引,保证每个配置信息对象的唯一性。因为 UUID 根据机器硬件和时间戳生成,避免了多人在同一时间段操作修改工程文件带来的问题。也就是说工程中每项配置对象都有个唯一的 UUID,然后其他配置对象想引用某个配置对象直接使用它的 UUID 即可。这就跟我们编程时使用指针指向某个对象的地址一样,其他对象的属性想引用它,只需要给属性传个指针地址就行了。


下面我就从rootObject开始简单的走一遍,大概了解一下此文件的配置方式。

rootObject
rootObject = 662A377C1DB7D8B00038B7DB /* Project object */;

从注释上就可以看出指向一个UUID为662A377C1DB7D8B00038B7DB的Project object字典

Project object
/* Begin PBXProject section */
    662A377C1DB7D8B00038B7DB /* Project object */ = {
        isa = PBXProject;
        attributes = {
            LastUpgradeCheck = 0800;
            ORGANIZATIONNAME = Apress;
            TargetAttributes = {
                662A37831DB7D8B00038B7DB = {
                    CreatedOnToolsVersion = 8.0;
                    ProvisioningStyle = Automatic;
                };
                662A379C1DB7D8B00038B7DB = {
                    CreatedOnToolsVersion = 8.0;
                    ProvisioningStyle = Automatic;
                    TestTargetID = 662A37831DB7D8B00038B7DB;
                };
                662A37A71DB7D8B00038B7DB = {
                    CreatedOnToolsVersion = 8.0;
                    ProvisioningStyle = Automatic;
                    TestTargetID = 662A37831DB7D8B00038B7DB;
                };
            };
        };
        buildConfigurationList = 662A377F1DB7D8B00038B7DB /* Build configuration list for PBXProject "HelloWorld" */;
        compatibilityVersion = "Xcode 3.2";
        developmentRegion = English;
        hasScannedForEncodings = 0;
        knownRegions = (
            en,
            Base,
        );
        mainGroup = 662A377B1DB7D8B00038B7DB;
        productRefGroup = 662A37851DB7D8B00038B7DB /* Products */;
        projectDirPath = "";
        projectRoot = "";
        targets = (
            662A37831DB7D8B00038B7DB /* HelloWorld */,
            662A379C1DB7D8B00038B7DB /* HelloWorldTests */,
            662A37A71DB7D8B00038B7DB /* HelloWorldUITests */,
        );
    };
/* End PBXProject section */


PBXProject顾名思义就是工程,对应构建可执行的二进制目标程序或库,里面包含了编译工程所需的全部信息。
1、isa 可以把每个value看做一个对象,可以发现每一个value都有一个isa字段,代表value的类型。
2、attributes 属性,包含一些编译器的基本信息,版本,以及项目中的target,每一个target一个UUID其中,Xcode自动创建的项目里面有三个target一个就是所要编译的APP主target,其余两个为test Target,可以看到其余两个target中有一个字段TestTargetID指向主target,可以理解为依赖相关吧。
3、buildConfigurationList 配置列表 指向一个配置字典 XCConfigurationList 类型类型(稍后讲)
4、compatibilityVersion 应该是兼容版本 目前看来是 Xcode 3.2
5、developmentRegion 语言版本,English英语
6、hasScannedForEncodings 是否已经扫描了文件编码信息
7、knownRegions 不同区域的本地资源文件列表
8、mainGroup Xcode的文件组织形式,可以理解为文件层次 PBXGroup 类型
9、productRefGroup 编译后的输出文件 PBXGroup 类型
10、projectDirPath,projectRoot 项目路径和项目的根目录 目前为空
11、targets 项目下的三个target对象 PBXNativeTarget类型

从上到下,我们来看一下所用的类型。


XCConfigurationList
/* Begin XCConfigurationList section */
    662A377F1DB7D8B00038B7DB /* Build configuration list for PBXProject "HelloWorld" */ = {
        isa = XCConfigurationList;
        buildConfigurations = (
            662A37AF1DB7D8B00038B7DB /* Debug */,
            662A37B01DB7D8B00038B7DB /* Release */,
        );
        defaultConfigurationIsVisible = 0;
        defaultConfigurationName = Release;
    };
    662A37B11DB7D8B00038B7DB /* Build configuration list for PBXNativeTarget "HelloWorld" */ = {
        isa = XCConfigurationList;
        buildConfigurations = (
            662A37B21DB7D8B00038B7DB /* Debug */,
            662A37B31DB7D8B00038B7DB /* Release */,
        );
        defaultConfigurationIsVisible = 0;
    };
    662A37B41DB7D8B00038B7DB /* Build configuration list for PBXNativeTarget "HelloWorldTests" */ = {
        isa = XCConfigurationList;
        buildConfigurations = (
            662A37B51DB7D8B00038B7DB /* Debug */,
            662A37B61DB7D8B00038B7DB /* Release */,
        );
        defaultConfigurationIsVisible = 0;
    };
    662A37B71DB7D8B00038B7DB /* Build configuration list for PBXNativeTarget "HelloWorldUITests" */ = {
        isa = XCConfigurationList;
        buildConfigurations = (
            662A37B81DB7D8B00038B7DB /* Debug */,
            662A37B91DB7D8B00038B7DB /* Release */,
        );
        defaultConfigurationIsVisible = 0;
    };
/* End XCConfigurationList section */

XCConfigurationList是一个构建配置相关元素的列表,里面有一个项目文件(HelloWorld),三个target(HelloWorld、HelloWorldTests和HelloWorldUITests)对应于你在Xcode界面中看到的这样,如图,每一个都有相对应的配置属性buildConfigurations,而每个配置属性都有两个的版本(Debug和Release)
那Debug和Release又对应什么呢?是XCBuildConfiguration:

/* Begin XCBuildConfiguration section */
    662A37AF1DB7D8B00038B7DB /* Debug */ = {
        isa = XCBuildConfiguration;
        buildSettings = {
            ALWAYS_SEARCH_USER_PATHS = NO;
            CLANG_ANALYZER_NONNULL = YES;
            CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
            CLANG_CXX_LIBRARY = "libc++";
            CLANG_ENABLE_MODULES = YES;
            CLANG_ENABLE_OBJC_ARC = YES;
            CLANG_WARN_BOOL_CONVERSION = YES;
            CLANG_WARN_CONSTANT_CONVERSION = YES;
            CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
            CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
            CLANG_WARN_EMPTY_BODY = YES;
            CLANG_WARN_ENUM_CONVERSION = YES;
            CLANG_WARN_INFINITE_RECURSION = YES;
            CLANG_WARN_INT_CONVERSION = YES;
            CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
            CLANG_WARN_SUSPICIOUS_MOVES = YES;
            CLANG_WARN_UNREACHABLE_CODE = YES;
            CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
            "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
            COPY_PHASE_STRIP = NO;
            DEBUG_INFORMATION_FORMAT = dwarf;
            ENABLE_STRICT_OBJC_MSGSEND = YES;
            ENABLE_TESTABILITY = YES;
            GCC_C_LANGUAGE_STANDARD = gnu99;
            GCC_DYNAMIC_NO_PIC = NO;
            GCC_NO_COMMON_BLOCKS = YES;
            GCC_OPTIMIZATION_LEVEL = 0;
            GCC_PREPROCESSOR_DEFINITIONS = (
                "DEBUG=1",
                "$(inherited)",
            );
            GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
            GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
            GCC_WARN_UNDECLARED_SELECTOR = YES;
            GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
            GCC_WARN_UNUSED_FUNCTION = YES;
            GCC_WARN_UNUSED_VARIABLE = YES;
            IPHONEOS_DEPLOYMENT_TARGET = 10.0;
            MTL_ENABLE_DEBUG_INFO = YES;
            ONLY_ACTIVE_ARCH = YES;
            SDKROOT = iphoneos;
        };
        name = Debug;
    };
    662A37B01DB7D8B00038B7DB /* Release */ = {
        isa = XCBuildConfiguration;
        buildSettings = {
            ALWAYS_SEARCH_USER_PATHS = NO;
            CLANG_ANALYZER_NONNULL = YES;
            CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
            CLANG_CXX_LIBRARY = "libc++";
            CLANG_ENABLE_MODULES = YES;
            CLANG_ENABLE_OBJC_ARC = YES;
            CLANG_WARN_BOOL_CONVERSION = YES;
            CLANG_WARN_CONSTANT_CONVERSION = YES;
            ·
            ·
            ·
            IPHONEOS_DEPLOYMENT_TARGET = 10.0;
            MTL_ENABLE_DEBUG_INFO = NO;
            SDKROOT = iphoneos;
            VALIDATE_PRODUCT = YES;
        };
        name = Release;
    };
      ·
      ·
      ·
/* End XCBuildConfiguration section */


XCBuildConfiguration构建具体的配置元素,也就是Xcode的Build Setting面板中所涉及的选项。至于每个字段所代表的含义可再深入研究。


PBXGroup
/* Begin PBXGroup section */
    662A377B1DB7D8B00038B7DB = {
        isa = PBXGroup;
        children = (
            662A37861DB7D8B00038B7DB /* HelloWorld */,
            662A37A01DB7D8B00038B7DB /* HelloWorldTests */,
            662A37AB1DB7D8B00038B7DB /* HelloWorldUITests */,
            662A37851DB7D8B00038B7DB /* Products */,
        );
        sourceTree = "<group>";
    };
    662A37851DB7D8B00038B7DB /* Products */ = {
        isa = PBXGroup;
        children = (
            662A37841DB7D8B00038B7DB /* HelloWorld.app */,
            662A379D1DB7D8B00038B7DB /* HelloWorldTests.xctest */,
            662A37A81DB7D8B00038B7DB /* HelloWorldUITests.xctest */,
        );
        name = Products;
        sourceTree = "<group>";
    };
    662A37861DB7D8B00038B7DB /* HelloWorld */ = {
        isa = PBXGroup;
        children = (
            662A378A1DB7D8B00038B7DB /* AppDelegate.h */,
            662A378B1DB7D8B00038B7DB /* AppDelegate.m */,
            662A378D1DB7D8B00038B7DB /* ViewController.h */,
            662A378E1DB7D8B00038B7DB /* ViewController.m */,
            662A37901DB7D8B00038B7DB /* Main.storyboard */,
            662A37931DB7D8B00038B7DB /* Assets.xcassets */,
            662A37951DB7D8B00038B7DB /* LaunchScreen.storyboard */,
            662A37981DB7D8B00038B7DB /* Info.plist */,
            662A37871DB7D8B00038B7DB /* Supporting Files */,
        );
        path = HelloWorld;
        sourceTree = "<group>";
    };
    662A37871DB7D8B00038B7DB /* Supporting Files */ = {
        isa = PBXGroup;
        children = (
            662A37881DB7D8B00038B7DB /* main.m */,
        );
        name = "Supporting Files";
        sourceTree = "<group>";
    };
    662A37A01DB7D8B00038B7DB /* HelloWorldTests */ = {
        isa = PBXGroup;
        children = (
            662A37A11DB7D8B00038B7DB /* HelloWorldTests.m */,
            662A37A31DB7D8B00038B7DB /* Info.plist */,
        );
        path = HelloWorldTests;
        sourceTree = "<group>";
    };
    662A37AB1DB7D8B00038B7DB /* HelloWorldUITests */ = {
        isa = PBXGroup;
        children = (
            662A37AC1DB7D8B00038B7DB /* HelloWorldUITests.m */,
            662A37AE1DB7D8B00038B7DB /* Info.plist */,
        );
        path = HelloWorldUITests;
        sourceTree = "<group>";
    };
/* End PBXGroup section */

PBXGroup 文件组织形式文件的组织结构,可以嵌套,可以看到子文件列表放在key为children的字典中value是一个数组,如果数组中的值指向的是一个文件夹类型的,则再生成一个字典,一直到底指向最初的文件,PBXFileReference类型

PBXFileReference
/* Begin PBXFileReference section */
    662A37841DB7D8B00038B7DB /* HelloWorld.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloWorld.app; sourceTree = BUILT_PRODUCTS_DIR; };
    662A37881DB7D8B00038B7DB /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
    662A378A1DB7D8B00038B7DB /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
    662A378B1DB7D8B00038B7DB /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
    ·
    ·
    ·
    662A37A81DB7D8B00038B7DB /* HelloWorldUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HelloWorldUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
    662A37AC1DB7D8B00038B7DB /* HelloWorldUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HelloWorldUITests.m; sourceTree = "<group>"; };
    662A37AE1DB7D8B00038B7DB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */

PBXFileReference 项目所引用的每一个外部文件,比如源代码文件、资源文件、库文件、生成目标文件等,每一个外部文件都可以在这里找到,也就是在Xcode的文件导航栏所看到的文件组织形式,如图3。


productRefGroup

类似于mainGroup


PBXNativeTarget
/* Begin PBXNativeTarget section */
    662A37831DB7D8B00038B7DB /* HelloWorld */ = {
        isa = PBXNativeTarget;
        buildConfigurationList = 662A37B11DB7D8B00038B7DB /* Build configuration list for PBXNativeTarget "HelloWorld" */;
        buildPhases = (
            662A37801DB7D8B00038B7DB /* Sources */,
            662A37811DB7D8B00038B7DB /* Frameworks */,
            662A37821DB7D8B00038B7DB /* Resources */,
        );
        buildRules = (
        );
        dependencies = (
        );
        name = HelloWorld;
        productName = HelloWorld;
        productReference = 662A37841DB7D8B00038B7DB /* HelloWorld.app */;
        productType = "com.apple.product-type.application";
    };
    662A379C1DB7D8B00038B7DB /* HelloWorldTests */ = {
        isa = PBXNativeTarget;
        buildConfigurationList = 662A37B41DB7D8B00038B7DB /* Build configuration list for PBXNativeTarget "HelloWorldTests" */;
        buildPhases = (
            662A37991DB7D8B00038B7DB /* Sources */,
            662A379A1DB7D8B00038B7DB /* Frameworks */,
            662A379B1DB7D8B00038B7DB /* Resources */,
        );
        buildRules = (
        );
        dependencies = (
            662A379F1DB7D8B00038B7DB /* PBXTargetDependency */,
        );
        name = HelloWorldTests;
        productName = HelloWorldTests;
        productReference = 662A379D1DB7D8B00038B7DB /* HelloWorldTests.xctest */;
        productType = "com.apple.product-type.bundle.unit-test";
    };
    662A37A71DB7D8B00038B7DB /* HelloWorldUITests */ = {
        isa = PBXNativeTarget;
        buildConfigurationList = 662A37B71DB7D8B00038B7DB /* Build configuration list for PBXNativeTarget "HelloWorldUITests" */;
        buildPhases = (
            662A37A41DB7D8B00038B7DB /* Sources */,
            662A37A51DB7D8B00038B7DB /* Frameworks */,
            662A37A61DB7D8B00038B7DB /* Resources */,
        );
        buildRules = (
        );
        dependencies = (
            662A37AA1DB7D8B00038B7DB /* PBXTargetDependency */,
        );
        name = HelloWorldUITests;
        productName = HelloWorldUITests;
        productReference = 662A37A81DB7D8B00038B7DB /* HelloWorldUITests.xctest */;
        productType = "com.apple.product-type.bundle.ui-testing";
    };
  /* End PBXNativeTarget section */


PBXNativeTarget,对应于生成的可执行二进制程序或库文件的本地构建目标对象,也就是Xcode我们看到的这三个target目标对象。里面的主要内容是:
1、buildConfigurationList 这个我们在讲述PBXProject时已经介绍过,是一个配置相关元素相关的列表。
2、buildPhases 构建阶段所涉及的源文件(PBXSourcesBuildPhase类型)、框架(PBXFrameworksBuildPhase类型)和资源(PBXResourcesBuildPhase)以数组形式组织。
3、buildRules 指定了不同文件类型该如何编译
4、dependencies 列出了在Xcode build phase tab中列出的target依赖项
5、productReference 目标文件(PBXFileReference)

PBXSourcesBuildPhase
/* Begin PBXSourcesBuildPhase section */
    662A37801DB7D8B00038B7DB /* Sources */ = {
        isa = PBXSourcesBuildPhase;
        buildActionMask = 2147483647;
        files = (
            662A378F1DB7D8B00038B7DB /* ViewController.m in Sources */,
            662A378C1DB7D8B00038B7DB /* AppDelegate.m in Sources */,
            662A37891DB7D8B00038B7DB /* main.m in Sources */,
        );
        runOnlyForDeploymentPostprocessing = 0;
    };
    662A37991DB7D8B00038B7DB /* Sources */ = {
        isa = PBXSourcesBuildPhase;
        buildActionMask = 2147483647;
        files = (
            662A37A21DB7D8B00038B7DB /* HelloWorldTests.m in Sources */,
        );
        runOnlyForDeploymentPostprocessing = 0;
    };
    662A37A41DB7D8B00038B7DB /* Sources */ = {
        isa = PBXSourcesBuildPhase;
        buildActionMask = 2147483647;
        files = (
            662A37AD1DB7D8B00038B7DB /* HelloWorldUITests.m in Sources */,
        );
        runOnlyForDeploymentPostprocessing = 0;
    };
/* End PBXSourcesBuildPhase section */

PBXSourcesBuildPhase 代表构建阶段需要复制的资源文件 文件组织在key为files的value中的数组列表里,每个元素为PBXBuildFile类型。

PBXBuildFile
 /* Begin PBXBuildFile section */
    662A37891DB7D8B00038B7DB /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 662A37881DB7D8B00038B7DB /* main.m */; };
    662A378C1DB7D8B00038B7DB /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 662A378B1DB7D8B00038B7DB /* AppDelegate.m */; };
    662A378F1DB7D8B00038B7DB /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 662A378E1DB7D8B00038B7DB /* ViewController.m */; };
    662A37921DB7D8B00038B7DB /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 662A37901DB7D8B00038B7DB /* Main.storyboard */; };
    662A37941DB7D8B00038B7DB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 662A37931DB7D8B00038B7DB /* Assets.xcassets */; };
    662A37971DB7D8B00038B7DB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 662A37951DB7D8B00038B7DB /* LaunchScreen.storyboard */; };
    662A37A21DB7D8B00038B7DB /* HelloWorldTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 662A37A11DB7D8B00038B7DB /* HelloWorldTests.m */; };
    662A37AD1DB7D8B00038B7DB /* HelloWorldUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 662A37AC1DB7D8B00038B7DB /* HelloWorldUITests.m */; };
/* End PBXBuildFile section */

PBXBuildFile 代表文件元素,被PBXBuildPhase等作为文件包含或被引用的资源,其实里面fileRef指向最终的文件PBXFileReference。

PBXFrameworksBuildPhase
/* Begin PBXFrameworksBuildPhase section */
    662A37811DB7D8B00038B7DB /* Frameworks */ = {
        isa = PBXFrameworksBuildPhase;
        buildActionMask = 2147483647;
        files = (
        );
        runOnlyForDeploymentPostprocessing = 0;
    };
    662A379A1DB7D8B00038B7DB /* Frameworks */ = {
        isa = PBXFrameworksBuildPhase;
        buildActionMask = 2147483647;
        files = (
        );
        runOnlyForDeploymentPostprocessing = 0;
    };
    662A37A51DB7D8B00038B7DB /* Frameworks */ = {
        isa = PBXFrameworksBuildPhase;
        buildActionMask = 2147483647;
        files = (
        );
        runOnlyForDeploymentPostprocessing = 0;
    };
/* End PBXFrameworksBuildPhase section */

PBXFrameworksBuildPhase用于framewrok构建的链接阶段

PBXResourcesBuildPhase
/* Begin PBXResourcesBuildPhase section */
    662A37821DB7D8B00038B7DB /* Resources */ = {
        isa = PBXResourcesBuildPhase;
        buildActionMask = 2147483647;
        files = (
            662A37971DB7D8B00038B7DB /* LaunchScreen.storyboard in Resources */,
            662A37941DB7D8B00038B7DB /* Assets.xcassets in Resources */,
            662A37921DB7D8B00038B7DB /* Main.storyboard in Resources */,
        );
        runOnlyForDeploymentPostprocessing = 0;
    };
    662A379B1DB7D8B00038B7DB /* Resources */ = {
        isa = PBXResourcesBuildPhase;
        buildActionMask = 2147483647;
        files = (
        );
        runOnlyForDeploymentPostprocessing = 0;
    };
    662A37A61DB7D8B00038B7DB /* Resources */ = {
        isa = PBXResourcesBuildPhase;
        buildActionMask = 2147483647;
        files = (
        );
        runOnlyForDeploymentPostprocessing = 0;
    };
  /* End PBXResourcesBuildPhase section */

PBXResourcesBuildPhase 构建阶段需要复制的资源文件,包括xib文件、故事板(storyboard)、图片和plist文件等其他资源文件。链接至PBXBuildFile文件


到这里,整个project.pbxproj 文件基本走了一遍,我们也对整个文件的组织结构有了一个初步的了解,里面有些字段的含义也许不是很清楚,但是并不影响我们对文件结构的理解。如果想看更深的一步了解,可以参看这里。
Cocoapods正是通过它的组件Xcodeproj操作project.pbxproj文件来对工程结构进行修改。
最后附上一张整体的流程图:



作者:凌巅
链接:http://www.jianshu.com/p/e82ec6a56fc2
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Cocos2d-x报错`CLANG_ENABLE_MODULES`的编译选项配置 Cocos2d-x开发中CLANG_ENABLE_MODULES编译错误通常由Clang模块支持未启用、版本不兼容或项目配置错误引起。解决方案包括:在Xcode中启用Clang模块支持(Build Settings设为YES)、检查Cocos2d-x与编译器版本兼容性、清理并重建项目。建议通过Xcode图形界面配置,避免手动修改项目文件,并定期检查编译器配置与框架版本。若问题持续,可查阅官方文档或社区讨论获取更多解决方案。 阅读详情

相关推荐

Cocos2d-x报错CLANG_ENABLE_MODULES的编译配置解决方案

在Cocos2d-x开发中,CLANG_ENABLE_MODULES编译错误常见于Clang模块支持未启用或Cocos2d-x版本与编译器不兼容的情况。解决方案包括在Xcode中启用Clang模块支持、更新Cocos2d-x版本、检查项目配置文件、清理并重建项目,以及参考官方文档和社区讨论。通过这些步骤,开发者可以有效解决编译错误,确保项目的稳定性和兼容性。

shejizuopin的博客 1039

project.pbxproj文件介绍

【http://www.jianshu.com/p/6e0f9f213944】 Xcode中project.pbxproj合并冲突的解决 字数1998 阅读943 评论2 喜欢10 引言 Xcode的工程文件是 工程名.xcodeproj,而它其实是个package目录,通过显示包内容,可以查看到它内部主要有project.pbxproj 和 xcuserdata。其中

一头雾水的Blog 6477

Appstore 3.2(f)违规自救指南:从触发到申诉的完整应对策略

本文详细解析了Appstore 3.2(f)违规的应对策略,从触发原因到申诉流程,帮助开发者有效自救。文章涵盖隐瞒行为、账户关联和信息造假三大违规场景的判定逻辑,并提供申诉信写作的黄金法则和长期合规防御措施,确保开发者能够顺利通过苹果审核。

weixin_29304985的博客 658

ReactNative进阶(四十九)project.pbxproj 配置文件详解

在Xcode中能看见所有的公共配置信息都存在于中。主要包含跟文件相关的BuildFileGroup和;跟编译相关的BuildPhase和(List);以及一些列Target和。开发者比较关键的信息是配置应用PP文件、包名及APP 版本号。

IT全栈 华强工作室 2181

STM32F0实现数字化SPWM纯正弦波逆变器

这个没啥好说的,搭电路的事。其核心思想是两边桥臂分别由两个180度相位差的正弦波与三角载波比较来控制,优点是在开关器件工作频率一样的情况下,输出PWM频率是单极性SPWM的2倍,能够明显减少谐波,因此只需要相对较小的电感和电容滤波器件就可以起到很好的滤波效果,提升了系统的性能,也精简了系统体积,降低了成本。而双极性pwm则是在整个正弦周期内,四只管子都在高频开关状态工作,对角线上的管子一起导通,另一对角线上管子互补导通,实际上只需要一路互补的PWM控制,负载上电压在正电压和负电压之间切换,不出现0v。

forlifefor的专栏 1万+

ThinkBook 16p 2024 BIOS降压定频实战:从解锁CFG Lock到AC Loadline调优

高性能笔记本在满载时频繁撞上温度墙,通常源于固件层默认电压冗余过大,而系统级降压工具又受限于CFG Lock锁定。要根治问题,需要从BIOS固件层面理解电压管理机制——AC/DC Loadline参数控制着CPU在不同负载下的电压请求,通过修改这些负载线值可以安全降低电压,解锁CFG Lock后还能让XTU、ThrottleStop等软件调参工具恢复可用。这种BIOS级调优在工程实践中广泛用于改善散热、稳定频率、压降风扇噪音,尤其适用于联想ThinkBook 16p 2024与拯救者Y9000P等采用HX平

weixin_32496547的博客 385

Xcode 工程文件打不开, cannot be opened because the project

Xcode 工程文件打不开, cannot be opened because the project&n   (2014-01-14 11:27:11) 转载▼ 标签:  ios         当使用svn提交代码发生冲突时候,xcode工程文件会出现打不开的情况,出现这样的提示:XXX.xcode xcodeproj ca

shaomohan的博客 459

论文必备 - YOLOv12热力图可视化,支持指定模型,指定显示层,设置置信度,以及10种可视化实现方式

本文带来的是YOLOv12热力图可视化功能,支持,以及。我们经常看到一些论文里绘制了不同的热力图,一方面能够直观的感受其模型的有效性,另一方面也丰富了论文内容。特别是在使用了注意力模块的网络中,热力图就可以验证注意力机制是否真正聚焦到了预期的重要特征上,以便对模型的有效性和合理性进行评估。例如这篇文章中展示的,就很能够表达作者改进后的模型相比之前模型的优越性。

Limiiiing的博客 1705

iOS 工程文件.xcodeproj无法打开

image.png Bug回放: 本小猿刚提交了一些图片,继续激情的敲代码中,然后另一小媛一脸怀笑的出现在背后,“我刚提交了一些图片,你更新一下”,“好的”,then。。。 纳尼? workspace中主工程文件GovCn目录没了 吓得我赶紧打开主GovCn.xcodeproj文件,结果。。。 惊吓 GovCn.xcodeproj损坏了 翻译:项目“G...

努力,可能成功!放弃,注定失败! 4778

RK3399外设驱动之MIPI

RK3399外设驱动之MIPI 文章目录RK3399外设驱动之MIPIMIPI命令解析入口代码mipi显示配置实例rk3399mipi驱动rk mipi驱动注册过程rk32_mipi_dsi.c解析 内核版本 Linux4.4 平台 rk3399 作者 nineyole MIPI命令解析入口代码 MIPI的入口代码如下:kernel\drivers\video\rockchip\screen\lcd_mipi.c static int __init rk_mipi_screen_in

学无止境 2227

微信公众平台 - 微信内置浏览器 WeixinJSBridge.invoke(‘xxx‘) API 报错:system:access_denied(常见于微信支付、分享朋友圈/转发好友等功能)解决方案

微信支付提示System:access_denied,调用微信支付返回:system:access_denied为什么,安卓版微信支付偶尔出现system:access_denied,微信公众号开发分享出现system:access_denied,system:access_denied如何解决?微信WeixinJSBridge.invoke(‘xxx‘)API调用后出现报错,微信内部H5WeixinJSBridge.invokesystem:access_denied,使用微信jssdk时报ac

🏆 前端领域优质创作者 5144

Xcode 工程文件“.xcodeproj”文件夹解析

项目.xcodeproj 文件夹底下一般有4个文件: project.pbxproj 文件 xcuserdata 文件夹 xcshareddata 文件夹 project.xcworkspace 文件夹 (这里暂不讲解) 下面主要讲解涉及到 .xcschemes 相关文件,其他设置(例如断点一类的)暂不讲解 1.project.pbxproj 文...

chqj_163的专栏 1044

改进YOLOv9的CT图像肺结节检测与分类算法:从原理到实战

本文将详细介绍如何改进YOLOv9算法,使其更好地适应CT图像肺结节检测与分类任务。我们将从数据集准备、模型改进、训练优化到最终部署,完整呈现一个端到端的深度学习项目,并提供完整的代码实现。

YOLO 188

project.pbxproj 的merge问题

基于xcode8.0 1.project.pbxproj 的结构 内部文件{archiveVersion=1 ; classes={};objectVersion=46;objects={};rootObject=/*project object*/} objects 里面的东西有下面一些   1.1.PBXBuildFile   1.2.PBXFileRefer...

weixin_30389003的博客 148

本地部署AI应用:基于Google Gemini的banana-prompt快速上手指南

AI应用开发的核心在于将大模型能力集成到实际场景中,其原理是通过API调用将用户输入转化为模型可理解的指令,再由模型生成响应。这一技术价值在于降低AI应用开发门槛,实现数据本地化处理与隐私保护。在工程实践中,开发者常面临环境配置复杂、API集成繁琐等挑战。本文聚焦于使用banana-prompt工具包,通过TypeScript技术栈和npm包管理,快速在Windows本地部署基于Google Gemini API的AI应用。该方案特别适用于ai-prompts提示词工程和content-creation内容

weixin_27188815的博客 314

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Xcode 8 修改已创建工程的 organizion name

  在创建工程时,会需要填写公司信息,对于已创建的工程,新建文件时,公司信息显示为刚开始创建的公司信息。如果需要对公司名称进行修改,需进行以下   可以 打开工程名.xcodeproj 文件 (显示包内容)->打开 project.pbxproj 文件 找到 “ORGANIZATIONNAME” 把值修改成你要修改的内容即可。 转载于:https://www.cnblog...

132

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

project.pbxproj,最熟悉的”陌生人”

转载请注明出处:http://www.olinone.com/ 作为iOS开发人员,pbxproj文件对于我们来说即熟悉又陌生,熟悉到我们每天都得见面。而除了偶尔遇到的合并冲突,其余时候我们甚至忘记了它的存在。当然,并不是说它不重要,相反,pbxproj文件保存了项目的所有配置关联信息 pbxproj文件主要包含了以下几项主要信息 工程文件关联信息,如PBXBuildFile

明明 621

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Xcode 工程文件打开不出来, cannot be opened because the project file cannot be parsed.

svn更新代码后,打开xcode工程文件,会出现 xxx..xcodeproj cannot be opened because the project file cannot be parsed. 因为.xcodeproj工程文件冲突了,然后还是会强制更新,内部文件出现了冲突,所以解析不了文件。 会出现这样的冲突消息 <<<<<<&...

weixin_30409849的博客 92

修改Xcode工程名称,程序名称---便捷方法

转载 : http://www.2cto.com/kf/201505/401645.html   第一步:修改工程文件夹名称 第二步:打开新文件夹,将.xcodeproj更名,右键点击.xcodeproj并选择Show package contents,弹出一个对话框包含了几个文件.(事实上.xcodeproj是这几个文件打成的包) 第三步:用textEdit打开 project.

oDream122的博客 568

svn更新代码后,无法打开xcode工程文件

svn更新代码后,打开xcode工程文件,会出现xxx..xcodeproj cannot be opened because the project file cannot be parsed.因为.xcodeproj工程文件冲突了,然后还是会强制更新,内部文件出现了冲突,所以解析不...

96

Xcode项目不能打开 cannot be opened because the project file cannot be parsed 解决方法

Xcode 工程文件打开不出来, cannot be opened because the project file cannot be parsed. git更新代码后,打开xcode工程文件,会出现 xxx..xcodeproj cannot be opened because the project file cannot be parsed. 因为.xcodeproj工程文件冲突了 解决...

weixin_34128237的博客 385
上一篇: xcode 项目瘦身神器
下一篇: iOS 使用正则表达式 // 或者 /**/
hsf_study
博客等级 码龄11年 10粉丝 126原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值