iOS静/动态库开发支持bitcode

2023-10-27 21:10
文章标签 动态 开发 支持 ios bitcode

本文主要是介绍iOS静/动态库开发支持bitcode,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

bitcode是什么

Bitcode is an intermediate representation of a compiled program. Apps you upload to iTunes Connect that contain bitcode will be compiled and linked on the App Store. Including bitcode will allow Apple to re-optimize your app binary in the future without the need to submit a new version of your app to the store.

根据官方文档的解释,bitcode是被编译程序的一种中间形式的代码。包含bitcode配置的程序将会在App store上被编译和链接。bitcode允许苹果在后期重新优化程序的二进制文件,而不需要重新提交一个新的版本到App store上。
我们知道,iOS编译使用的是Clang/LLVM编译工具链。LLVM是编译器和工具链技术的集合,Clang 是LLVM的前端。C,C++ 和 Objective-C代码通过Clang编译生成中间代码LLVM IR,再经由后端生成目标平台上的本地字节码。
LLVM比较特别的地方在于LLVM IR,它把编译过程分为了三层。第一层支持多种语言作为输入,无论是OC,C++,Swift代码,最终转化为中间代码LLVM IR。第二层是共享优化器,专门对中间代码优化。第三层是不同目标平台字节码生成。这样的好处在于:想要增加增加一门新语言,只需要增加前端;想要支持新的CPU架构,只需要增加后端。

img_b7a651ff42be1a8226aeff62d6fb6329.png
LLVM架构

bitcode本质上就是LLVM IR的字节流格式,我们可以尝试生成IR代码,看一看庐山真面目。首先,创建一个test.c:

 #include <stdio.h> int main(int argc, char **argv) { printf("hello world\n"); return 0; }

调用clang指令-emit-llvm:

 clang test.c -S -emit-llvm -o test.bc

生成的test.bc代码如下:

; ModuleID = 'test.c'
source_filename = "test.c"
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.14.0"@.str = private unnamed_addr constant [13 x i8] c"hello world\0A\00", align 1; Function Attrs: noinline nounwind optnone ssp uwtable
define i32 @main(i32, i8**) #0 {%3 = alloca i32, align 4%4 = alloca i32, align 4%5 = alloca i8**, align 8store i32 0, i32* %3, align 4store i32 %0, i32* %4, align 4store i8** %1, i8*** %5, align 8%6 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i32 0, i32 0))ret i32 0
}declare i32 @printf(i8*, ...) #1attributes #0 = { noinline nounwind optnone ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }!llvm.module.flags = !{!0, !1}
!llvm.ident = !{!2}!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 7, !"PIC Level", i32 2}
!2 = !{!"Apple LLVM version 10.0.0 (clang-1000.11.45.5)"}

可以看到,生成的中间代码IR相比汇编代码更为直观易懂。下面简单总结一下bitcode的优缺点:
优点:Apple可以根据目标机型编译生成性能最优,包大小最小的可执行文件。当编译器更新时,Apple可以对提交包含bitcode的应用进行优化而不需要我们重新编译提交。
缺点:bitcode本质上是LLVM IR,相比汇编代码更容易被分析,安全性会下降。

如何支持bitcode

Framework支持bitcode就是在编译好的目标文件中增加一个__LLVM段用来存放编译生成的中间代码IR。应用支持bitcode的前提是项目中所有第三方库都支持bitcode,否则就只能关闭bitcode选项。
bitcode选项在xcode工程配置中默认是打开的,如果Framework是纯OC代码,只需要在工程选项Other C flags中增加-fembed-bitcode即可。如果Framework依赖了其他第三方库,需要所有第三方库也需要支持bitcode。假如第三方库使用clang编译,需要增加编译选项-fembed-bitcode
编译完成后,通过otool命令查看目标文件是否包含存放bitcode的__LLVM段:

otool -l xxx | grep __LLVM

如果已经包含bitcode,会有如下结果:

segname __LLVM
segname __LLVM

如何剥离bitcode

如果想要剥离掉bitcode,通过xcode提供的bitcode_strip命令也可以很方便的做到:

xcrun bitcode_strip input [ -r | -m | -l ] -o output

这篇关于iOS静/动态库开发支持bitcode的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/288402

相关文章

C#如何动态创建Label,及动态label事件

《C#如何动态创建Label,及动态label事件》:本文主要介绍C#如何动态创建Label,及动态label事件,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#如何动态创建Label,及动态label事件第一点:switch中的生成我们的label事件接着,

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

SpringCloud动态配置注解@RefreshScope与@Component的深度解析

《SpringCloud动态配置注解@RefreshScope与@Component的深度解析》在现代微服务架构中,动态配置管理是一个关键需求,本文将为大家介绍SpringCloud中相关的注解@Re... 目录引言1. @RefreshScope 的作用与原理1.1 什么是 @RefreshScope1.

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

Python基于wxPython和FFmpeg开发一个视频标签工具

《Python基于wxPython和FFmpeg开发一个视频标签工具》在当今数字媒体时代,视频内容的管理和标记变得越来越重要,无论是研究人员需要对实验视频进行时间点标记,还是个人用户希望对家庭视频进行... 目录引言1. 应用概述2. 技术栈分析2.1 核心库和模块2.2 wxpython作为GUI选择的优

SpringKafka消息发布之KafkaTemplate与事务支持功能

《SpringKafka消息发布之KafkaTemplate与事务支持功能》通过本文介绍的基本用法、序列化选项、事务支持、错误处理和性能优化技术,开发者可以构建高效可靠的Kafka消息发布系统,事务支... 目录引言一、KafkaTemplate基础二、消息序列化三、事务支持机制四、错误处理与重试五、性能优

利用Python开发Markdown表格结构转换为Excel工具

《利用Python开发Markdown表格结构转换为Excel工具》在数据管理和文档编写过程中,我们经常使用Markdown来记录表格数据,但它没有Excel使用方便,所以本文将使用Python编写一... 目录1.完整代码2. 项目概述3. 代码解析3.1 依赖库3.2 GUI 设计3.3 解析 Mark

利用Go语言开发文件操作工具轻松处理所有文件

《利用Go语言开发文件操作工具轻松处理所有文件》在后端开发中,文件操作是一个非常常见但又容易出错的场景,本文小编要向大家介绍一个强大的Go语言文件操作工具库,它能帮你轻松处理各种文件操作场景... 目录为什么需要这个工具?核心功能详解1. 文件/目录存javascript在性检查2. 批量创建目录3. 文件

基于Python开发批量提取Excel图片的小工具

《基于Python开发批量提取Excel图片的小工具》这篇文章主要为大家详细介绍了如何使用Python中的openpyxl库开发一个小工具,可以实现批量提取Excel图片,有需要的小伙伴可以参考一下... 目前有一个需求,就是批量读取当前目录下所有文件夹里的Excel文件,去获取出Excel文件中的图片,并

mybatis-plus 实现查询表名动态修改的示例代码

《mybatis-plus实现查询表名动态修改的示例代码》通过MyBatis-Plus实现表名的动态替换,根据配置或入参选择不同的表,本文主要介绍了mybatis-plus实现查询表名动态修改的示... 目录实现数据库初始化依赖包配置读取类设置 myBATis-plus 插件测试通过 mybatis-plu