首页 > 其他分享 >Xcode 工程分析

Xcode 工程分析

时间:2023-02-24 14:35:42浏览次数:30  
标签:分析 文件 target 工程 Xcode project 编译 workspace

1. 背景

Xcode作为日常开发iOS程序的IDE,支持C、C++、Objective-C、Swift、Ruby等语言进行编写。日常开发入口就是Xcode workspace或者Xcode project。

workspace是一个Xcode文档,它将项目和其他文件、project分组。一个workspace可以包含任意数量的Xcode project,以及资源文件(JSON、脚本、图片、视频等)。workspace除了组织每个project中的文件外,还提供了所包含项目及其目标之间的隐式和显式关系。

project就是一个 Xcode 工程,它是实际管理工程下 targets 、源码、资源文件、framework 等。project 只是一个容器,本身是无法被编译的,所以每个 project 至少应该有一个可编译的 target, target下需要包含可编译的源码。

在日常开发中难免会去在非Xcode的环境下去操作workspace或者project中的依赖关系,所以搞懂workspace、project、源码和资源文件之间的关系就显得特别重要,因为知道怎么来的才知道去如何做。

 

2. 了解workspace全貌

图片

由上图可以简单看出workspace和project的关系:

  • 一个workspace里可以包含多个project

  • 一个project里包含多个target

  • configuration 即Xcode中的Debug/Release 等工程配置

  • scheme 配置target编译参数

  • 每个target即每次编译生成对应产物:app或者framework

     

3. 探寻workspace

新创建一个空的workspace,直接看他的层级树:

图片

可以看到workspace主要包含三个层级:

  • xcworkspacedata,workspace的配置文件,实际上就是一个XML文件。

  • xcshareddata:可共享的配置,包含scheme、script等信息。

  • xcuserdata:当前用的配置,包含本地scheme、script、断点信息等。

 

以报价项目为例详细查看 contents.xcworkspacedata的内容:

图片

FileRef 顾名思义它是标记了每个文件在workspace中的路径关系,这个关系决定的在Xcode中的project的展示层级。

location的关键字包含如下:

  • self:当前文件夹下的同名project

  • group:指定目录下的xcodeproj文件

  • container:workspace当前目录下的不同名的xcodeproj文件

  • absolute:绝对路径下的文件

 

4. 探寻project

由对workspace的探寻我们可以看到,workspace确实只是把project等文件组织起来的一个工作空间,本身并不具备对源码、资源的编译、整合能力,进一步探寻到project文件,我们才能看到源码、资源文件等是怎么被整合起来的。

图片

由上图可看到,xcodeproj里包含了三个大的层级,xcuserdata里包含的常用的scheme和配置文件,还包含了一个xcodeworkspace,这是为了保证Xcode的兼容性,维持Xcode管理文件逻辑的统一。

xcodeproj中包含了开发中所需要的全部文件,管理了当前工程所有的源码、资源文件、配置文件等。重点是pbxproj文件,它与我们正常编译代码密切相关,管理target、文件之间的引用依赖关系、合并代码时候产生的文件冲突就在这里。

 

4.1

深入pbxproj

pbxproj全拼是Project Builder Xcode Project,它其实是我们熟悉的plist文件的一种,但是它不像我们常用的plist文件有着优越的可读性,由于历史原因它才被Xcode一直保存下来。

pbxproj中定义了target、script、文件、configuration等之间的引用关系,我们看到的Xcode项目布局实际上是可视化了pbxproj。

直接看看pbxproj的内部布局吧:

图片

可以看到,最外层包含了这些属性:

  • archiveVersion 当前文件版本

  • classes 占位符

  • objectVersion 当前文件需要的 Xcode最低版本

  • objects 以每个object的uuid为key的字典,存放了object属性

  • rootObject 当前文件的根object (isa = PBXProject)

 

objects里实际上存放的就是每个文件之间的依赖关系,我们称每个文件是一个Xcode object,这个Xcode object不仅仅可以是源码文件,也可以是group、framework、app、target、scheme等。

由上图的rootObject = D9658FA7290BA51D00A72187,我们简单看一下它作为Xcode object的内部结构:

图片

可以看到比较重要的信息是isa、mainGroup、configration、target,其他信息也都包含了Xcode中我们见到的、可以配置的全部信息。

这只是PBXProject中的信息,全部信息可在官网进行查询。下面列出了所有的类型配置:

  • PBXProject:Project 配置,编译工程所需信息

  • PBXNativeTarget:Target 的配置

  • PBXTargetDependency:Target 依赖关系配置

  • PBXContainerItemProxy:部署的元素

  • XCConfigurationList:Xcode中configuration配置

  • XCBuildConfiguration:Xcode 的 Build Settings 配置

  • PBXVariantGroup:storyboard 文件配置

  • PBXBuildFile:各类文件配置

  • PBXFileReference:各类文件引用配置

  • PBXGroup:Xcode中的group

  • PBXSourcesBuildPhase:需要编译的编译源文件

  • PBXFrameworksBuildPhase:需要编译的framework

  • PBXResourcesBuildPhase:除源码外的资源文件

 

他们之间的关系大致如下

图片

了解了各个文件之间的关系,可以为我们以后通过脚本去动态添加、删除、移动文件、修改build settings、scheme等操作打下基础。

 

5. 探寻scheme

scheme不是编译target的必要条件,没有scheme不影响Xcode的编译操作,但是,没有scheme我们就没办法在编译时传入参数条件,插入编译脚本,配置个性化编译配置,所以scheme是Xcode编译时的必须选项。

打开一个scheme源文件,我们可以看到如下布局:

图片

可以看到,最外层包含着build、test、launch、profile、analyze、archive。恰好对应了Xcode中的与之对应的命令,再次验证了Xcode就是pbxproj的可视化呈现。

进入BuildAction可以看到我们在Xcode中添加的预编译脚本和各种环境变量配置,这些配置有的是在编译过程中必不可少的参数,有的是方便我们管理编译产物的必须配置,灵活运用这些配置,可以让Xcode更好的为我们服务。

 

6. 探寻target

target用于指定要构建的产物,即framework或者app。target只包含了当前project中的部分指定的代码和资源文件,每一个target只能构建出一个特定的构建产物,为了丰富构建产物,一个project可以拥有多个target。

target使用Build Settings和Build Phases的形式来进行个性化配置,默认这些配置可以通过project继承,也可以通过手动或者配置文件的方式覆盖其他配置。

target之间可以互相依赖,如果是在同个workspace下,Xcode默认会触发隐式依赖,当然,如果用手动配置依赖关系,则会变为显式依赖。显式依赖的优先级高于隐式依赖。

 

7. 总结与展望

根据上面的介绍,大家一定对Xcode的工程配置有了一定的了解,在了解了这些之后,我们能做些什么呢?其实是有很多玩法的:

  • 根据不同的编译scheme编译指令,提取出编译产物,分发给不同的人员。

  • 根据target的不同,在不改变源码的前提下,每次编译设置不同的环境测试包。

  • 编译过程中检查出警告信息及时上报开发人员。

  • 编译时找出无效代码及文件。

  • 利用cocoapods的动态配置在安装的时候直接引入二进制组件以增加编译速度。

  • 输出指定framework的编译日志到文件方便对比查阅。

 

了解了这些基础配置,以后在项目的工程化方面才有更多手段解决重复度高或者棘手的问题,还有更多的新玩法可以在工作过程中发掘。

 

作者|王一飞

标签:分析,文件,target,工程,Xcode,project,编译,workspace
From: https://www.cnblogs.com/88223100/p/Xcode-Engineering-Analysis.html

相关文章

  • Python数据分析
    数据分析01_abnormal_checkCode1#-*-coding:utf-8-*-23#代码3-1使用describe()方法即可查看数据的基本情况4importpandasaspd5caterin......
  • 瓴羊Quick BI率先提供移动端自助分析整体解决方案,成为行业的领导者!
    瓴羊QuickBI已经率先提供移动自助分析整体解决方案,从而帮助企业客户将数据更好的融入到方方面面,比如日常决策、企业运营和具体工作当中。同时还能够提供基于移动端的自助分......
  • BLE_UART移植OTA工程
    一、移植:1、将app_drv_fifo和ble_uart_service移植到BackupUpgrade_OTA中,注意头文件包含和路径添加。2、将BLE_UART程序中peripheral.c的工程添加进BackupUpgrade_OTA的p......
  • 同花顺涨停分析
    打开同花顺网站-首页-A股-原创,里面写着“涨停复盘”的文章就有表格图查看,一般文章表格发出来的时间都在下午4点左右。投资者在买卖成交后支付给财税部门的税收。上海股票......
  • 软件工程|UML学习
    转载自一文掌握14种UML图-腾讯云开发者社区-腾讯云(tencent.com)什么是UML?UML是UnifiedModelLanguage的缩写,中文是统一建模语言,是由一整套图表组成的标准化建模语......
  • LVGL移植STM32\GD32 keil工程
    LVGL移植STM32\GD32的方法基本一样1.下载LVGL,直接官网或github下载压缩包,也可以使用squarelinestudio生成的文件,但似乎新版的squarelinestudio生产的项目多了一些东西,没......
  • vue源码分析-从new Vue开始
    初学vue,你得知道我们是从newVue开始的:newVue({el:'#app',data:obj,...})那你觉得是不是很有意思,咱们newVue之后,就可以使用他那么多的功能,可见Vue是暴出......
  • TIME_WAIT状态作用和出现的场景分析
    TIME_WAIT状态之所以存在,是为了保证网络的可靠性。首先,这个是TCP状态转换图里面的某个状态,这个可以参考unix网络编程。  从图中可以看出,在一个客户端与服务器通信......
  • 第一卷《社会工程学:信息的艺术》第九章:高考号会泄露哪些信息
    高考号是每个考生独一无二的代号,是一个重要信息,那么现在以账号主人为例,她是2021届泸县五中的学生,但是不知什么情况她却去南宁打工了,虽然她没有参加高考,但如果她参加高考,还......
  • 软件工程开课博客
    自我介绍:我是来自于信息科学与技术学院的软件工程系的一名学生,通过去年下半年的学习,我初步认识到了软件工程专业的相关学习体系和未来毕业就业方向。在今年上半年,我会有一......