前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >APP生成与运行(一)

APP生成与运行(一)

作者头像
Helloted
发布2022-06-07 14:06:48
1.1K0
发布2022-06-07 14:06:48
举报
文章被收录于专栏:Helloted

一、编译

汇编

CPU 由上亿个晶体管组成,在运行的时候,单个晶体管只能根据电流的流通或关闭来确认两种状态,我们一般说 0 或 1,根据这种状态,人类创造了二进制,通过二进制编码我们可以表示所有的概念。但是,CPU 依然只能执行二进制代码。我们将一组二进制代码合并成一个指令或符号,创造了汇编语言,汇编语言以一种相对好理解的方式来编写,然后通过汇编过程生成 CPU 可以运行的二进制代码并运行在 CPU 上。

编译

编译器将原始程序(Source program)作为输入,翻译产生使用目标语言(Target language)的等价程序。源代码一般为高阶语言 (High-level language), 如C、C++、C# 、Objective-C、Swift、Java 等,而目标语言则是汇编语言或目标机器的目标代码(Object code),有时也称作机器代码(Machine code)

编译型语言和解释型语言

编译程序是整体编译完了,再一次性执行。 而解释程序是一边解释,一边执行。

编译型语言:C系,java

解释型语言:html、javascript

二、LLVM、Clang

LLVM

LLVM本身并不是编译器,只是一套用于开发编译器、解释器等程序语言相关工具的库,主要聚焦于编译器后端功能,如代码生成、代码优化、JIT等。

LLVM1 an umbrella project that hosts and develops a set of close-knit low-level toolchain components (e.g., assemblers, compilers, debuggers, etc.) LLVM 是一个涵盖和开发一系列紧密结合的低级工具链组件(例如,汇编器,编译器,调试器等)的综合项目

传统的编译器通常分为三个部分,前端(frontEnd),优化器(Optimizer)和后端(backEnd),在编译过程中,前端主要负责词法和语法分析,将源代码转化为抽象语法树;优化器则是在前端的基础上,对得到的中间代码进行优化,使代码更加高效;后端则是将已经优化的中间代码转化为针对各自平台的机器代码。

img
img
Clang

Clang 是一个C、C++、Objective-C和Objective-C++编程语言的编译器前端。它采用了LLVM作为其后端。

Clang是2005年由苹果电脑发起,是LLVM编译器工具集的前端(front-end),目的是输出代码对应的抽象语法树(Abstract Syntax Tree, AST),并将代码编译成LLVM Bitcode。接着在后端(back-end)使用LLVM编译成平台相关的机器语言 。Clang支持C、C++、Objective C。

Clang本身性能优异,其生成的AST所耗用掉的内存仅仅是GCC的20%左右,测试证明Clang编译Objective-C代码时速度为GCC的3倍,还能针对用户发生的编译错误准确地给出建议。

三、iOS中的编译

Objective C采用Clang作为前端,而Swift则采用swift()作为前端,二者LLVM(Low level vritual machine)作为编译器后端。编译过程如下图

img
img

来看看一个文件的编译过程,新建Test.m

代码语言:javascript
复制
#import <Foundation/Foundation.h>

int main(){
    @autoreleasepool {
        NSLog(@"%@",@"Hello Leo");
    }
    return 0;
}

在终端输入:

代码语言:javascript
复制
clang -ccc-print-phases -framework Foundation test.m -o test

会看到下列的:

代码语言:javascript
复制
0: input, "Foundation", object 
1: input, "test.m", objective-c
2: preprocessor, {1}, objective-c-cpp-output//预处理
3: compiler, {2}, ir //编译生成IR(中间代码)
4: backend, {3}, assembler//汇编器生成汇编代码
5: assembler, {4}, object//生成机器码
6: linker, {0, 5}, image//链接
7: bind-arch, "x86_64", {6}, image//生成Image,也就是最后的可执行文件
编译器前端

编译器前端的任务是进行:语法分析,语义分析,生成中间代码(intermediate representation )。在这个过程中,会进行类型检查,如果发现错误或者警告会标注出来在哪一行。

img
img
编译器优化

LVVM优化器会进行BitCode的生成,链接期优化等等

img
img
编译器后端

LLVM机器码生成器会针对不同的架构,比如arm64等生成不同的机器码

img
img

四、Xcode执行Build的流程

dSYM 文件

我们在每次编译过后,都会生成一个dsym文件。dsym文件中,存储了16进制的函数地址映射。

在App实际执行的二进制文件中,是通过地址来调用方法的。在App crash的时候,第三方工具(Fabric,友盟等)会帮我们抓到崩溃的调用栈,调用栈里会包含crash地址的调用信息。然后,通过dSYM文件,我们就可以由地址映射到具体的函数位置。

五、提高项目Build速度

查看编译时间

我们需要一个途径,能够看到编译的时间,这样才能有个对比,知道我们的优化究竟有没有效果。 对于XCode 8,关闭XCode,终端输入以下指令

代码语言:javascript
复制
$ defaults write com.apple.dt.Xcode ShowBuildOperationDuration YES
代码优化-forward declaration

@class CLASSNAME,而不是#import CLASSNAME.h。这样,编译器能大大提高#import的替换速度。

对常用工具类打包

打包成Framework或者静态库,这样编译的时候这部分代码就不需要重新编译了。

常用头文件放到预编译文件里

XCode的pch文件是预编译文件,这里的内容在执行XCode build之前就已经被预编译,并且引入到每一个.m文件里了。

编译器选项优化

Debug模式下,不生成dsym文件

上文提到了,dysm文件里存储了调试信息,在Debug模式下,我们可以借助XCode和LLDB进行调试。所以,不需要生成额外的dsym文件来降低编译速度。

Debug开启Build Active Architecture Only

在XCode -> Build Settings -> Build Active Architecture Only 改为YES。这样做,可以只编译当前的版本,比如arm7/arm64等等,记得只开启Debug模式。这个选项在高版本的XCode中自动开启了。

Debug模式下,关闭编译器优化
img
img
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、编译
    • 汇编
      • 编译
        • 编译型语言和解释型语言
        • 二、LLVM、Clang
          • LLVM
            • Clang
            • 三、iOS中的编译
              • 编译器前端
                • 编译器优化
                  • 编译器后端
                  • 四、Xcode执行Build的流程
                    • dSYM 文件
                    • 五、提高项目Build速度
                      • 查看编译时间
                        • 代码优化-forward declaration
                          • 对常用工具类打包
                            • 常用头文件放到预编译文件里
                              • Debug模式下,不生成dsym文件
                                • Debug开启Build Active Architecture Only
                                  • Debug模式下,关闭编译器优化
                                  领券
                                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档