如何描述一个工程
工程本身是对代码的组织方式,有一些公共的概念
抽象概念 | 含义 |
---|---|
源文件(Source) | 被编译的文件,最终转化成二进制 |
头文件 (Header) | 不会被编译的文件,声明(Declare)文件,用于协助别的源文件找到定义 |
源文件的产物 | 一个可执行的程序,由多个源文件编译而来 |
目标的管理器 | 可执行程序的管理,例如目标1由A、B、C文件组成,目标2由B、C、D文件组成,其中B、C两个文件被复用 |
管理器的空间 | 目标管理器的管理器,用于组织多个目标在一个范围内工作 |
头文件目录 | 如果存在多个目录,那么头文件路径的前缀会不一致,前缀不同的源文件就需要知道该头文件所在的位置,头文件目录提供这个位置方便源文件在编译中索引 |
源文件目录 | 所有源文件存放的根目录,方便工程以此目录作为绝对目录开始组织源文件 |
静态库目录 | 如果依赖第三方库,需要知道该静态库存放的位置,用于编译 |
动态库目录 | 如果依赖第三方库,需要知道该动态库存放的位置,用于编译 |
iOS、Android、C++ 中如何描述工程
由于上述的公共概念并没有严格的规定,所以对这些概念在不同的平台和语言中也有区别
抽象概念 | iOS | Android | C++ |
---|---|---|---|
源文件 | .mm | .java | .cpp |
头文件 | .h | .hpp | |
源文件的产物 | Target | Package | Executable、Target |
目标的管理器 | Project | Module | Project |
管理器的空间 | Workspace | Project | Directory |
头文件目录 | Include Path | Package | Include |
源文件目录 | Source Root | Source Root | Source Root |
静态库目录 | Library Path | Dependencies | Library Path |
动态库目录 | Framework Path | Dependencies | Library Path |
重点和常见的微妙差别
有一些重点是
- 各种目录不是共享的,一般以源文件的目标作为分割线,不同的目标各自的头文件目录等都是独立的
- 有些语言是没有头文件的,例如Java,并且大家都在往这个方向演进,例如Swift
- 头文件不会参与编译,仅仅是为了让人可读并且知晓定义而存在的
- 头文件目录概念存在原因是因为实际工程中不可能把所有文件都放在同一个目录下(当然也有例外,比如早期的iOS工程就是都在同一个目录下)
- 不同平台的动态库称呼不太一样
这里解释一些微妙的差别
- iOS、Android的Project概念范围不一致,Android中的Project是一个顶级概念,而iOS则用Workspace这个称呼
- Android或者说Java语言对于目标和目标的管理器区别没有那么严格,一般来讲编译的目标都是Module(虽然也可以编译Package),而iOS则是Target,C++等类C语言一般编译目标是Executable,但是CMake中也使用Target这个称呼,存在混用现象(Project更多是管理器作用)
- SourceRoot这个概念很重要,所以任何平台对这个定义都很一致,一般使用src、source、Source等文件夹表示
- 动态库和静态库目录的区分和语言相关性很强,iOS是分开两个目录,Android不区分动态静态、而C++区分动态库和静态库,但是目录统一称呼为Library Path