[Xcode]Xcode中的编译过程以及编译器

编译过程

基本的编译过程分为四个步骤:
  1. 预处理(Pre-process):把宏替换,删除注释,展开头文件,产生 .i 文件。
  2. 编译(Compliling):把之前的 .i 文件转换成汇编语言,产生 .s文件。
  3. 汇编(Asembly):把汇编语言文件转换为机器码文件,产生 .o 文件。
  4. 链接(Link):对.o文件中的对于其他的库的引用的地方进行引用,生成最后的可执行文件(同时也包括多个 .o 文件进行 link)。
然后通过解析 xcode 编译 log,可以发现 xcode 是根据 target 分开进行编译的。
编译过程的控制,在 xcode 中可以通过 Build phases,Build settings以及 Build rules来进行控制。
  • Build phases:主要是用来控制从源文件到可执行文件的整个过程的,所以应该说是面向源文件的,包括编译哪些文件,以及在编译过程中执行一些自定义的脚本什么的
  • Build rules:主要是用来控制如何编译某种类型的源文件的,假如说相对某种类型的原文件进行特定的编译,那么就应该在这里进行编辑了。同时这里也会大量的运用一些 xcode 中的环境变量
  • Build settings:则是对编译工作的细节进行设定,在这个窗口里可以看见大量的设置选项,从编译到打包再到代码签名都有,这里要注意 settings 的 section 分类,同时一般通过右侧的 inspector 就可以很好的理解选项的意义了。

最后,要说一下我们的工程文件.pbxproj,以上的所有的这些选项都保存在这个文件中。当然也包括 target 的信息,项目所有文件的信息,这个文件是一个文本文件,可以用文本编辑器打开。里头的内容基本是可读性比较强的。基本的思路很面向对象,每个东西都有属性,如果属性是另一个对象,值就是那个对象的一个『引用』,就是一串数字(唯一的)作为表示。每个对象都有这样的引用

  在Build phases中增加自定义脚本,每次编译都Build都递增1

#!/bin/bash
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=$(($buildNumber + 1))
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"

编译器

首先,编译器是做什么的?编译器是用来把源代码文件转换为更为低级的语言的(同时还有语句的静态分析),而 xcode 使用的clang 编译器的作用就是把源代码转换为更为低级的 LLVM IR(Intermedia Representation),这个 LLVM IR 是操作系统无关的,然后 LLVM 通过这个中间语言来进行下一步的二进制文件的产出。得益于 LLVM 的三层架构,LLVM 可以有多个输入和输出(LLVM 的第一层架构是用于处理输入的,第二层用于优化 IR ,第三层用于输出)

llvm介绍

llvm(底层虚拟机 low level virtual machine)是一个开源编译器框架,最早的时候是Illinois的一个研究项目,主要负责人是Chris Lattner,他现在就职于Apple. Apple 目前也是llvm项目的主要赞助者之一。
llvm有一个表达形式很好的IR语言,高度模块化的结构,因此它可以作为多种语言的后端,提供与编程语言无关的优化和针对多种CPU的代码生成功能。传统编译器分三个阶段:

不同的前端后端使用统一的 LLVM IR ,如果需要支持新的编程语言或者新的设备平台,只需要开发对应的前端和后端即可。同时基于 LLVM  IR 我们可以很快的开发自己的编程语言。

目前llvm有很多的子项目,针对不同的需求进行了深入的扩展,具体参考llvm官方首页。
其中的Clang子项目实现了支持C/C++/Objective-C的优秀编译器前端,官方数据表明,在某些编译环境下,其编译速度要比gcc快三倍。

猜你喜欢

转载自blog.csdn.net/ouyangshima/article/details/79381701