美文网首页
关于xcode buildSettings 里面一些关键字的介绍

关于xcode buildSettings 里面一些关键字的介绍

作者: 思绪飘零ing | 来源:发表于2022-09-07 16:05 被阅读0次

    1。Header Search Paths 和 User Header Search Path

    名词介绍: 这两个关键词是用来链接项目外的类文件的。 就是 我们使用类一般都是加到项目中来。 但是 我们还是 把 文件不放进项目来。 项目中也想使用这个类 就可以在这两个地方配置 路径。 然后 在项目中 就可以使用该类了。 cocopoads 的pod 库 就是利用这个原理做到的。
    1.1。区别: 我们知道 OC 引入头文件 有 #import <> , #import " " 和 #include < > , #include " " 。共同之处 <> h和" ". 在 OC中 我们知道一般我们引用系统类用<> ,引用我们自己的类 用 " ",那这是为什么呢? 解释这个问题 就能搞清楚 这俩个关键词的 区别了。 在OC中,文件 一共分为系统文件以及我们创建的文件两类。 所以我们在 引入头文件的时候。OC最终 是要找到这个文件位置的。所以它会拼接得到绝对路径。 所以重点来了。 用 <> 引入的方式 他只会从系统级别查找文件(就是只会拼接路径的时候拼接系统目录+<file.h>去找文件)和 我们在Header Search Paths 里面配置的路径去找文件 是否存在。而用 "" 引入头文件。 OC会在系统级别查找文件和从用户目录空间中搜索文件并且它也会在User Header Search Paths配置的路径找文件。
    eg: 你试试 #import "UIKit/UIKit.h"也是ok的
    总结:<> 是从系统目录空间 (对应 Header Search Paths)中搜索文件, "" 是从用户目录空间(对应 User Header Search Paths)中搜索文件。若在Header Search Paths中设置SomeClass的路径后, 上面两种方式都可以使用. 但在User Header Search Paths中设置后, #import <SomeClass.h> 会编译报错。

    2。Framework Search Paths 和Library Search Paths

    2.1 名词介绍: Framework Search Paths 项目中导入 *.Framework 的时候 需要告诉xcode Framework 路径 就需要 把 Framework 路径配置在这里 。 xcode 在add Framework的时候会自动添加。 *** cocopoads 引入framework 这里也会自动添加路径。
    2.2 名词介绍:Library Search Paths 项目中导入 *.a 库 会在Library Search Paths 里面添加出 .a 库的路径。 在add的时候 xcode 也会自动添加。 ** cocopoads 导入.a的时候 也会自动添加路径。 我们 可以再报错找不到库的时候 来检查这里路径是否正确。
    2.2 Header Search Paths 咱们在往工程project 里面add framework 的时候 可以理解为 把 framework 跟系统的framework类比的处理逻辑。 再我们把 framework 放到一个pod 库里面 如果配置了 ”public_header_files“ 就类似要求 再Header Search Paths配置这些文件路径 我们 就可以在代码里面使用像自己创建的文件那样引用了。(同事说这样写会swfit项目报错。但是我看afn等第三方也是这么做的 待验证)

    3。recursive 。

    3.1。名词解释:recursive:遍历该目录(以及子目录),non-recursive:默认路径设置;不遍历该目录(指的是 只找这个目录下的文件不会遍历子目录的文件)。如果路径的属性为recursive,那么编译的时候在找库的路径的时候,会遍历该目录下的所有子目录的库文件。PS:在搭建项目的时候,可以创建一个专门放库文件的文件夹并且设置其属性为recursive。

    4。 Apple移动设备默认指令集

    4.1 名词解释:苹果各代设备的处理器(处理器可以理解处理代码的软件)都不同。在处理代码上不同设备有着不同的指令集。 指令集会影响设备能否处理代码的一个东西。iOS使用了arm处理器,并根据设备的硬件性能开发了不同的指令集.
    目前为止Apple移动设备默认指令集:

    armv6:主要是用在早期的iOS上,如iPhone, iPhone2, iPhone3G, 第一代、第二代 iPod Touch or iPhone2G/3G、iPod 1G/2G;
    armv7:iPhone 3GS/4/4s、iPod 3G/4G、iPad 1G/2G/3G、iPad mini
    armv7s:iPhone5、iPhone5c、iPad4
    arm64:iPhone5s及以后、iPad Air、iPad mini2
    arm64e:在iPhone XR, iPhone XS等,在arm64指令集基础上引入了新的PAC机制

    所有的指令集原则上向下兼容,新的指令集会兼容原来的指令集,只是不能充分利用硬件的优势无法发挥更好的性能.如iPhone4S的CPU默认使用armv7指令集,但是也同时兼容armv6指令集,之前使用armv6架构打包的软件依然可以在iPhone4s上使用,只是会慢一点.而且arm指令集出现在真机设备上,模拟器使用X86架构,没有arm指令集(新版mac上的模拟器也是arm架构了).

    4。 Build Active Architecture Only

    4.1。名词解释:Build 开头的名词,是指项目在build/或者打包的时候对生成产物的影响。 (我们正常build项目 会在product 文件夹下边生产。这些产物 framework /.a就是你这样项目生成的。)(而在制作framework /.a库的时候 也是通过build 生成产物得到framework /.a的) 而在得到产物的时候编译器该如何生成产物 根据buildsettings 里面的设置 生成产物。Build Active Architecture Only 就是影响其中一个的字段。Build Active Architecture Only value为 NO/YES 当设置为YES的时候你此时选择的设备(模拟器/真机)build 的时候生产的产物就只有该(模拟器/真机)的指令集。 意思就是 比如你在build 一个framework或者是项目的时候选择了iPhone4S 真机 生成的产物 只有 iPhone4S的armv7指令集。 所以 这里生成的产物 就不能在armv6指令集的设备上下载 使用。而当Build Active Architecture Only 设置为 NO 的时候 他就不根据你链接的设备build 构建产物了。 而是 根据build settings 里面的Architectures设置的生成产物。Architectures后面介绍。
    4.2 关于framework 以及说的项目build 的时候 产物问题 如果不理解。这里简单解释下。 framework 学习一下 制作framework 就会知道 前期做好准备 。 最后一步生成framework的时候 就是build 一下 就会在Products 文件目录下生成framework 了。 而项目就会生成一个.app 这就是产物。 framework是可以给别人安装的。所以 此framework 就需要包括 模拟器指令集。 否则模拟器运行不起来。 就要包括真机指令集 不然 跑不了缺失指令集的设备。如果主工程打包设置冲突 还会导致打包失败。

    5 bitcode

    5.1 名词解释 : 分享一篇文章 bitcode 是xcode在打包编译的时候 最后形成可执行文件过程中的的一种中间代码。意思就是 咱们的 .h .m 文件 或者是framework静态库文件 在打包过程中 会先转换成bitcode 代码 然后bitcode 代码 再转换成 .o文件最后形成手机的可执行文件。 我们xcode 里面的 设置bitcode 并不是上面的bitcode 中间代码的概念。 而是 我们把 bitcode 设置为YES 的时候 我们在打包的时候 我们在将代码转换成bitcode 代码之后 bitcode 代码会被苹果再次进行优化 然后转换成可执行文件.o 文件。
    5.2 LLVM 编译过程:
    (1)预处理*****预先处理代码。 比如 宏嵌入到对应的位置,头文件的导入,去除注释等。
    (2)词法分析。
    (3)语法分析。
    (4)生成语法书AST。
    (5)静态分析。利用clang 的 静态分析工具 clang static analyzer 的checkers 进行代码分

    析。并提出修改意见。

    (6)生成 LLVM IR。将 AST 自上向下遍历逐步翻译成 LLVM IR。 就是生成bitcode中间代码。(.oc 的bitcode代码) (如果打包的时候选择了bitcode=YES 苹果还会对bitcode 进行优化 )
    (7)生成汇编。.s文件
    (8)生成目标文件。 .o 文件。(也称为 链接。 利用连接器 链接 源代码 跟静态库二进制 )
    (9)生成可执行文件。 通过链接多个目标文件 形成mach-o 可执行文件。

    https://github.com/LeoMobileDeveloper/Blogs/blob/master/iOS/iOS%E7%BC%96%E8%AF%91%E8%BF%87%E7%A8%8B%E7%9A%84%E5%8E%9F%E7%90%86%E5%92%8C%E5%BA%94%E7%94%A8.md

    6 clang

    6.1:名词介绍:编译架构LLVM前端 对oc代码 进行编译成bitcode 中间代码的 编译器 clang 命令行

    7 MACH-O

    7.1 名词介绍: MACH-O 文件。 其实是指一类文件的统称 类型 。 并不是特指某一个种格式文件。 MACH-O 文件 是指的是 能够在苹果设备上 直接执行的文件的类型的一种统称。 比如 咱们 熟知的 iOS 的 ipa包里面的 可执行文件(就是黑色的那个文件)。还有我们的framework .a 静态库/动态库(.a 没有动态库)。以及我们 正常代码打包成的 .O 文件(类型是 object类型) 都是MACH-O 文件的一种
    7.2 MACH-O 文件一般包括四个部分组成
    (1) MACH-O header 文件(头文件)
    (1.1) Magic Number 指的是 处理器 是 64位还是32位的
    (1.2) CPU Type 指的是 CUP 类型 是指该可执行文件 可在什么指令集的处理器下工作 arm64 arm v7 arm v7s arm v6 x86 i32
    (1.3) file Type 指的是该文件的类型
    (1.4) Number of load Commands 指的是 load Commonds(加载指令 ) 的数量 load Commonds 下边有介绍 也是 MCH-O文件组成的一部分
    (1.5) Size of load Commands load Commonds 占用的字节 。 指的是 下边 load Commonds 里面 占用的字节 。[图片上传中...(load-command.png-e8044c-1621233703365-0)]
    (1.6) flags 标识二进制文件所需要系统提供支持的功能记录,主要与系统的加载、链接有关。(就是我二进制文件需要外部提供支持 这些东西该如何支持 等信息)
    MACH-O-HEADER.png
    (2) load Commonds 文件(加载命令)文件, 名词介绍:执行该可执行文件 需要的依赖外部的二进制文件的加载命令(就是比如我们的framework .a 或者动态库。系统动态库)等改如何加载到进程中。
    (2.1) cmd 是load command的类型,LC_SEGMENT_64的含义是将这个64位的段映射到进程地址空间,即加载命令 64 代表是 64位 还有 32 的参数。
    (2.2)commandSize 72 // 代表load command的大小
    (2.3)segment name __TEXT // 16字节的段名字 __TEXT
    (2.4)vmaddr 0x0000000100000000 // 段的虚拟内存起始地址
    (2.5) vmsize 0x00000000036a4000 // 段的虚拟内存大小
    (2.6) fileoff 0 // 段在文件中的偏移量
    (2.7) filesize 57294848 // 段在文件中的大小
    (2.8) maxprot 0x00000005 // 段页面所需要的最高内存保护(4=r,2=w,1=x)
    (2.9) initprot 0x00000005 // 段页面初始的内存保护
    (2.10) nsects 8 // 段中包含section的数量 就是根据他导入所需二进制代码的
    (2.11) flags 0x0 // 其他杂项标志位
    (2.12) 其他常见 load command
    • LC_SEGMENT_64: 将该段(64位)映射到进程地址空间中
    • LC_DYLD_INFO_ONLY:加载动态链接库信息(重定向地址、弱引用绑定、懒加载绑定、开放函数等的偏移值等信息)
    • LC_SYMTAB:载入符号表地址
    • LC_DYSYMTAB:载入动态符号表地址
    • LC_LOAD_DYLINKER:加载动态加载库,可以看出示例使用的是/usr/lib/dyld
    • LC_UUID:确定文件的唯一标识,crash解析中也会有这个,去检测dysm文件和crash文件是否匹配
    • LC_VERSION_MIN_MACOSX/LC_VERSION_MIN_IPHONEOS:确定二进制文件要求的最低操作系统版本
    • LC_SOURCE_VERSION:构建该二进制文件使用的源代码版本
    • LC_MAIN:设置程序主线程的入口地址和栈大小
    • LC_ENCRYPTION_INFO_64:获取加密信息
    • LC_LOAD_DYLIB:加载额外的动态库
    • LC_FUNCTION_STARTS:定义一个函数起始地址表,使调试器和其他程序易于看到一个地址是否在函数内
    • LC_DATA_IN_CODE:定义在代码段内的非指令的表
    • LC_CODE_SIGNATURE:获取应用签名信息
      这一步 只是告知程序 如何使用mach-o可执行文件。 而不是正常的 程序启动调用顺序。而是在程序启动 到那一步 做什么 这里能正确执行到,
    load-command.png
    (3)section 。名词解释 是指我们正常的代码 打包成 .o文件最后链接起来成为可执行文件 里面的.o 文件

    sectname __text // 第一个是__text ,就是主程序代码
    segname __TEXT // 该section所属的 segment名,第一个是__TEXT
    addr 0x0000000100006110 // 该section在内存的启始位置,0x100006110
    size 0x000000000358a268 // size 该section的大小,0x358a268
    offset 24848 // 24848 0x6110
    align 2^4 (16) // 字节大小对齐,16
    reloff 0 // 重定位入口的文件偏移 0
    nreloc 0 // 需要重定位的入口数量 0
    flags 0x80000400 // 包含section的type和attributes
    reserved1 0 // ...保留用
    reserved2 0 // ...保留用
    mach-o 可执行文件 内存方向理解文字
    从MCH-O文件角度 来理解程序启动过程 。静态库会被最终打进可执行文件里面 所以静态库 并不会影响速度。
    装载的过程也可以理解为进程建立的过程,操作系统只需要做以下三件事情:

    1.创建一个独立的虚拟地址空间
    2.读取可执行文件头,并且建立虚拟空间与可执行文件的映射关系
    3.将CPU的指令寄存器设置成可执行文件的入口地址,启动运行.
    启动速度有更好的文章

    8 iOS 符号

    名词解释:简单来说,类、函数和变量的统称;类名、函数名或变量名称为符号名(Symbol Name);

    符号让库文件 framework .a 以及各个.o文件可以被引用,让目标文件可以相互链接生成可执行文件;
    符号还可以帮助开发者定位问题,比较常见的是:将Crash日志中的地址信息转化成对应的函数名以及文件名、文件行号信息;
    Release模式会将二进制中裁剪掉符号的,不过Release模式下默认有dSYM文件,可以根据dSYM文件来做符号化。

    按类型分,符号可以分三类:

    全局符号:目标文件外可见的符号,可以被其他目标文件引用,或者需要其他目标文件定义;
    局部符号:只在目标文件内可见的符号,指只在目标文件内可见的函数和变量;
    调试符号:包括行号信息的调试符号信息,行号信息中记录了函数和变量所对应的文件和文件行号。

    9 dSYM 文件

    名词解释:在每次编译完成之后,都会生成一个 dsym 文件。dsym 文件中,存储了 16 进制的函数地址映射。
    当 App 执行打包后的二进制文件时,实际是通过地址来调用方法的。我们可能会用三方的统计工具,例如 Fabric 在 App Crash 时会帮我们抓到 crash 时的调用栈,这些调用栈里会包含 crash 地址的调用信息。这时可以通过 dSYM 文件由地址映射到具体的函数位置。
    所以我们在debug 模式下 可以将buildsettings 里面的 Debug Information Format 的 degug 下设置为 DWARF 不生省dsym 文件 以增加编译速度。
    编译速度 关闭xcode 终端执行 defaults write com.apple.dt.Xcode
    DSYM 符号表文章
    dSYM 文件是否会生成 根据xcode 以下几个字段控制 名词下边会介绍

    9.1 Generate Debug Symbols:设置为YES,编译生成目标文件时会生成调试信息;设置为 NO,那么 dwarf 段不会生成,也不会有 dSYM 文件生成,并且调试过程使用的断点也不会生效,因为地址已经无法和对应代码行关联起来了。这个设置为NO 后面都不起作用 设置为YES 后面的属性才会有作用

    9.2 Debug Information Format : 如果设置为 DWARF 则不会把调试表导出 如果设置为 DWARF with dSYN File 就代表调试行数符号 生成到 dSYN文件里面 。

    10 Generate Debug Symbols

    名词介绍:设置为YES,编译生成目标文件时会生成调试信息;设置为 NO,那么 dwarf 段不会生成,也不会有 dSYM 文件生成,并且调试过程使用的断点也不会生效,因为地址已经无法和对应代码行关联起来了。(我们的断点也是这么反编译而来的)

    文章
    编译过程 文件地址信息追踪

    11 Other Linker Flags

    三个参数 -ObjC 后面 的 -l --framework 意思死 -ObjC 的 参数的 那些库 是走这个参数 -l 是 .a库 -framework 是framework -l 直接 是接在后面 -framework 是换一行接库的名字

    ShowBuildOperationDuration YES 然后就能看到xcode 编译时间了 在xcode 的 上边栏 的 那里

    相关文章

      网友评论

          本文标题:关于xcode buildSettings 里面一些关键字的介绍

          本文链接:https://www.haomeiwen.com/subject/khzfjltx.html