Swift库与总结

8 阅读3分钟

Swift库与总结

参考文档

Modules

1. module -> 头文件->目标文件的关系
2. modulemap ->头文件 -> 目标文件的映射
3.  module:定义一个module
    export:导出当前代表的头文件使用的头文件
    export * :匹配目录下所有的头文件
    module * :目录下所有的头文件都当作一个子module
    explicit : 显式声明一个module的名称
4. Swift库使用OC代码:不能使用桥接文件
                1. oc的头文件放到modulemap下
                2. oc的头文件放到私有的modulemap下
                3. 协议的方式 投机取巧
5. Swift静态库的合并
        难点:.swiftmodule 文件(Swift的头文件)
    1. libtool 合并静态库本身
    2. 用到的头文件和Swift头文件和modulemap文件通过目录的形式放到一起
    3. OC要用合并的静态库:clang: other c flags :-fmodule-map-file <modulemap path>
    4. Swift要用合并的静态库 : SwiftC :other swift flags 显式告诉SwiftC <modulemap dir>
6. OC映射到Swift方式
    1.2. <工程名称>.apinotes

Module(模块)

Module(模块)-最小的代码单元。
一个Module是机器代码和数据的最小单位,可以独立于其他代码单位进行链接。通常,Module是通过编译单个源文件生成的目标文件。例如,当前的test.m被编译成目标文件test.o时,当前的目标文件就代表了一个Module。但是,有一个问题,Module在调用的时候会产生开销,比如我们在使用一个静态库的时候,可以这样使用

@import TestStaticFramework;
这个静态库中可能包含了许多的.o文件。岂不是要导入很多的Module。并不需要。在静态链接的时候,也就是静态库链接到主项目或者动态库时,最后生成可执行文件或者动态库时。静态链接器可以把多个Module链接优化成一个,来减少本来多个Module直接调用的问题。

每次包含标头时,编译器都必须可传递地预处理和解析该标头及其包含的每个标头中的文本。必须对应用程序中的每个翻译单元重复此过程,这涉及大量的冗余工作。

在具有N个翻译单元和每个翻译单元中包含M个标头的项目中,即使M个标头中的大多数在多个翻译单元之间共享,编译器仍在执行M x N个工作。

#include伪指令被预处理程序视为文本包含,因此在包含时必须接受任何活动的宏定义。如果任何活动宏定义碰巧与库中的名称冲突,则可能会破坏库API或导致库头本身的编译失败。

此外,导入模块时将自动提供使用该模块所需的任何链接器标志

std.io模块仅编译一次,并且将模块导入转换单元是恒定时间操作(与模块系统无关)。因此,每个软件库的API仅解析一次,从而将M x N编译问题减少为M + N问题。

每个模块都被解析为一个独立的实体,因此它具有一致的预处理器环境。

此外,在遇到导入声明时,当前的预处理器定义将被忽略,

@import上面的声明导入std模块的全部内容(其中将包含例如整个C或C ++标准库),并在当前翻译单元中提供其API。要仅导入模块的一部分,可以使用点语法来特定特定的子模块

模块会自动将#include指令转换为相应的模块导入

module.modulemap 用来描述头文件与module之间映射的关系

https://clang.llvm.org/docs/APINotes.html

# -fmodules:允许使用module语言来表示头文件
# -fmodule-map-file:module map的路径。如不指明默认module.modulemap
# -fmodules-cache-path:编译后的module缓存路径
clang  -fmodules -fmodule-map-file=Cat.modulemap -fmodules-cache-path=../prebuilt -c use.c -o use.o