From db6a87a394c73f29f4b5e7fd59d813fd16cabebd Mon Sep 17 00:00:00 2001 From: hhj Date: Sat, 19 Aug 2023 17:37:05 +0800 Subject: [PATCH] Add docs for interface_sdk_c. Signed-off-by: hhj --- docs/capi_naming.md | 83 ++++++++++++++++++++++++++++++ docs/howto_add.md | 120 ++++++++++++++++++++++++++++++++++++++++++++ docs/user_guide.md | 84 +++++++++++++++++++++++++++++++ 3 files changed, 287 insertions(+) create mode 100644 docs/capi_naming.md create mode 100644 docs/howto_add.md create mode 100644 docs/user_guide.md diff --git a/docs/capi_naming.md b/docs/capi_naming.md new file mode 100644 index 000000000..863cada01 --- /dev/null +++ b/docs/capi_naming.md @@ -0,0 +1,83 @@ +# C API接口编码规范 + +## 1 简介 +### 1.1 目的 +OpenHarmony提供了一些C语言系统接口供三方应用开发者使用,为了规范SDK C API的接口,对外提供一个统一接口风格,防止出现不必要的符号冲突,特此制定了此规范。 + +此规范对接口的命名规则,接口头文件,stub库在SDK包中的目录结构进行约束。2章节介绍了OpenHarmony的接口命名规范。 + +### 1.2 术语定义 +* __规则__:必须遵守的设计规则。 +* __建议__:必须加以考虑的约定,规则。 +* __说明__:对规则进行必须要的解释。 +* __示例__:对规则的举例说明。 +* __例外__:对规则的举例说明。 + +### 1.3 约定 +* 此规范描述的路径都是指SDK包中相对于Native包中的目录,不是指代码仓中的原始路径。 +* 全文xxx表示接口功能模块名,类比于C++中的类名;aaa,bbb表示普通的函数名,文件名。 + + +## 2 C API接口命名规则 +在CAPI中出现的接口,分为两类: +1. 业界标准接口或者是生态约定俗成的接口(如libc,opengles) +2. OpenHarmony自研接口 + +### 2.1 业界标准接口命名规则 +#### 2.1.1 【规则】已有业界标准的CAPI接口命名规则按照业界标准来命名。 + +__举例__: +1. libc/libc++采用的是unix_like的命名规则; +2. opengl接口规范采用<库前缀><根命令><可选参数个数><可选参数类型>格式; + +__说明__:针对第三方标准中,根据平台要求扩展的接口,也按照此三方库的推荐命名方式。 + +### 2.2 自研接口命名规则 +#### 2.2.1 【规则】CAPI接口函数标识符命名规则,采用OH_<模块前缀>_<方法名>的方式,命名需要精准,模块前缀采用大驼峰,方法名采用大驼峰规则。 + +__说明__:采用C语言接口,符号是全局课件,容易与别的模块符号产生符号冲突,采用模块前缀进行作用域区分。 + +#### 2.2.2 【规则】模块前缀需要精准,描述接口具体功能,模块名字需要接口领域SIG组审议通过。 +__说明__:模块前缀相当于C++中的类名,不要采用一些通用的名词,或者是范围过大的名字; +__举例__:OH_AI_xxx,AI这个一般指的是一个行业,一类技术的名词;这类名词座位模块名字不合适。 + +#### 2.2.3 【建议】接口文件中其他类型命名规范,基础类型建议都进行typedef进行定义。 +|类别|命名风格|形式| +|----|----|----| +|【建议】结构体类型,枚举类型,联合体,typedef类型|带模块前缀的大驼峰|采用Xxx_AaaBbb| +|局部变量,函数参数,宏参数,结构体字段,联合体成员|小驼峰|aaaBbb| +|全局变量|带‘g_’前缀的小驼峰|g_Xxx_aaaBbb| +|宏(不包括函数式宏),枚举值,goto标签|全大写,下划线分割|XXX_BBB| +|函数宏|带模块前缀的大驼峰|OH_Xxx_AaaBbb| +|常量(在函数外部定义由const修饰的基本数据类型,枚举类型,字符串类型)|全大写下划线分割,或带'g_'前缀的小驼峰|XXX_BBB, g_Xxx_aaaBbb| + +### 2.3 头文件命名规则 + +#### 2.3.1 【规则】头文件文件名采用unix_like的命名规则,名词与名词间用"_"隔离。 +__举例__:采用xxx_aaa.h xxx_aaa_bbb.h,或者xxx/aaa.h xxx/aaa_bbb.h。 +__说明__:如果此头文件在sysroot的include目录下的路径中已经包含xxx模块名,头文件的文件名就不需要带xxx前缀。 + + +#### 2.3.2 【规则】自研接口头文件放置在sysroot/usr/include规则,在此目录下创建子系统目录(名字上APP SIG评审),放置到此子目录下。 +__说明__:子系统下的目录组织形式可以采用模块名目录加头文件的形式,或者采用模块名_文件名.h方式;不建议新建太深的目录结构,开发者代码在引用头文件的时候,需要引用长串路径,不友好。 +``` +|--include +| |--逻辑名(需要上APP SIG评审) +| | |--xxx +| | | |-- aaa.h +| | | |-- bbb.h +| | | +| | |--xxx_ccc.h +| | |--xxx_common.h + +``` + +#### 2.3.3 【规则】三方库头文件按照生态的习惯放置,可以不遵守2.3.2规则。 + +### 2.4 库文件命名规则 +#### 2.4.1 【建议】库文件放置在sysroot/usr/lib根目录,不用建子目录;文件名采用unix_like的命名规则,不用z.so结尾。 +__说明__:是否需要给C API接口独立创建一个so库,这个没有强制要求;如果CAPI接口是重新封装,建议独立一个库,因为C API接口实现库在镜像中必须放置到/system/{lib|lib64}/ndk目录,方便接口管控。 +__说明__:命名采用libxxx.so的命名方式,库名字最好与模块名字相同,如果包含多个模块,建议采用业界常用的名字;如果名字是常用单词,建议前面加oh前缀,如libohxxx.so,避免名字冲突。 + + +#### 2.4.2 【规则】三方库的名字按照生态约定的名字命名。 diff --git a/docs/howto_add.md b/docs/howto_add.md new file mode 100644 index 000000000..59a187f89 --- /dev/null +++ b/docs/howto_add.md @@ -0,0 +1,120 @@ +# C API构建添加指南 +## 范围 +本文旨在说明跟C API相关的如下问题: +* 编译方法 +* 编译结果 +* 编译GN模板 +* 文档 + +## 需要了解的基础知识: + +GN语法,http://3ms.huawei.com/km/groups/3814407/blogs/details/5963185 + +对json描述文件有一定了解 + +## 编译方法 + 使能ndk编译,默认编译linux/windows版本 +``` +./build.sh --product-name ohos-sdk +``` +更加详细的SDK编译指导,请参考[如何编译full-SDK](http://https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/faqs/full-sdk-compile-guide.md)。 + +## 编译结果 + +### 存放位置 +跟os相关的内容(比如工具链,cmake等)会被拷贝到 root_out_dir/sdk-native/os-specific/目录下,其他内容放在root_out_dir/sdk-native/os-irrelevant目录下。归档的C API zip包放在root_out_dir/packages/ohos-sdk-native/[darwin|windows|linux]目录下,命名为native-[darwin|windows|linux]-x64-[x.x.x].zip。 + +### 压缩包目录结构 +``` +|--build +|--build-tools +|--docs +|--llvm +|--sysroot +|--nativeapi_syscap_config.json +|--NOTICE.txt +|--oh-uni-package.json +``` +* build目录:存放cmake的配置文件 +* build-tools目录:存放cmake等工具 +* docs目录:存放sysroot对应的文档 +* llvm目录:存放不同操作系统下的交叉工具链 +* sysroot目录:存放头文件和库 +* nativeapi_syscap_config.json: 存放头文件与syscap的映射关系 +* NOTICE.txt:存放licence声明 + +## 编译模板说明 +如前文所示,OpenHarmony native包由三部分组成;对应地,编译系统提供了一些GN模板,模板定义位于//build/ohos/ndk/ndk.gni。 +* ohos_ndk_library : 对应包里的库文件。 +* ohos_ndk_headers : 对应包里的头文件。 +* ohos_ndk_toolchains :对应包里的工具链。 + +ohos_ndk_headers和ohos_ndk_toolchains目标本质上只做copy + +### ohos_ndk_library(目标名) +输入参数: +output_name: 最终输出的库的名字;选填,默认为目标名。 + +NOTE:库名字按照《C API接口编码规范》 + +下面的例子中,ndk_library的目标名为"libsensor",但是输出的so名字为libsensor.z.so +``` +ohos_ndk_library("libsensor_ndk") { + ndk_description_file = "./libsensor.ndk.json" + min_compact_version = "10" + output_name = "sensor" # 编译系统会自动将名字变成libsensor,如果不设置,就采用libsensor_ndk.so + output_extension = "so" # 设置动态库的后缀名,默认为z.so + system_capability = "SystemCapability.Xxx.Aaa" # 设置这个库关联的SysCap,当前一个库只支持一个SysCap + system_capability_headers = [ # 与这个SysCap相关联的头文件 + "Xxx/Aaa.h", + "Xxx/Bbb.h" + ] +} +``` + **min_compact_version** : 相当于Android的API level,当前library从哪个版本开始支持?如果没有设置,默认设置为从当前版本开始支持。 + +为什么需要变量min_compact_version? +一般地,操作系统的后期版本会提供比前期版本更多的library,比如Android-29提供23个NDK库,但是Android-16仅提供13个NDK库。所以需要提供一个变量来告知编译系统当前库是从哪个版本开始支持的。 + + **ndk_description_file** : 当前library的符号描述文件json格式. 这个文件类似于镜像中的version script文件格式。Harmonyos上采用json格式。为统一起见,ndk_description_file的命名统一为libxxx.ndk.json。Json文件可以通过添加key来提供更丰富的属性,为未来的扩展留下空间。 + +json描述文件的例子如下: +``` +# NOTE:json文件本身不支持注释,这里作者便宜行事。读者使用的时候,请自行删除注释 +[ + { + "first_introduced": "2", # 描述当前接口引入的版本号 + "name": "GetSensorNdkVersion" # 当前接口的名字 + }, + { + "name": "GetSensorNdkObject", + "type": "variable" # 描述当前符号是变量,而不是函数 + } +] +``` + +### ohos_ndk_headers(目标名) +输入参数: + **sources** :想拷贝的文件或目录列表 + **dest_dir** :目标目录,默认值为$ndk_headers_out_dir,$ndk_headers_out_dir为$root_out_dir/sdk-native/sysroot/usr/include。 + +例子:例子中的sensor_ndk_interface.h将会被拷贝到$ndk_headers_out_dir/sensor目录下 +``` +ohos_ndk_headers("sensor_header") { +dest_dir = "$ndk_headers_out_dir/sensor" +sources = [ + "./include/sensor_ndk_interface.h", +] +} +``` + +### ohos_ndk_toolchains + +这个模板只针对mac/win/linux平台的几个工具链,一般开发同学使用不到。 +输入参数含义同ohos_ndk_headers。ohos_ndk_toolchains目标的默认dest_dir为$root_out_dir/sdk-native/sysroot/usr/lib + + +## 文档 +CAPI的文档生成在docs目录,需要安装doxygen工具,在ubuntu上使用`sudo apt-get install doxygen`即可安装。如果编译机上没有安装doxygen,文档将无法生成。 + + diff --git a/docs/user_guide.md b/docs/user_guide.md new file mode 100644 index 000000000..bd71bfed2 --- /dev/null +++ b/docs/user_guide.md @@ -0,0 +1,84 @@ +# C API用户指导 + +## 基础知识 +了解C API基础知识,请参考《[Native API入门](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/native-api-intro.md)》 + + +## 接口开放策略 + +### 不开放原则 + +1. 应用生态提供的核心特性只开放ArkTS API,不开发CAPI。 +2. 不开发ArkUI的CAPI。 +3. 不开发硬件底层接口(HDI)CAPI。 +4. 不开放命令行接口CAPI。 +### 开放原则 +5. 高性能、密集计算业务场景主动开放CAPI。例如:需要高性能的IO、CPU密集计算等场景;音视频编解码、图形计算等场景。 +6. 应用生态业务依赖的场景,主动开放高阶CAPI。例如:对标竞品,媒体高阶CAPI。 +7. 应用生态框架以来的场景,按需开放CAPI。例如:按需开放Unity/electron/CFE框架中依赖的CAPI。 +8. 行业约定或者标准要求的场景按需开放CAPI。此类CAPI独立发布,不放入OpenHarmony CAPI中。例如:金融或者安全行业高密加密算法等,按需独立发布。 + +### 前向兼容性原则 +9. CAPI的前向兼容性原则与ArkTS API策略保持一致。CI流程中会使用自动化工具进行看护。 + + +## CAPI接口设计规范 +### 设计规则 +* 【规则】接口新增或者变更需要到APP_SIG会议进行评审,通过后才能修改。 +* 【规则】接口要考虑OpenHarmony生态的一致性,保证在生态版本设备上的兼容,实现代码需同步发布。 +* 【规则】CAPI相关的接口文件,包含接口列表文件ndk.json,头文件,编译构建脚本三部分;这些内容必须放置在interface_sdk_c仓中,不能对外产生依赖。三方库接口暴露规则同自研仓,接口是处理过的接口文件,不是三方库原生文件。 +* 【规则】接口命名必须符合《[CAPI接口编码规范](./capi_naming.md)》。 +* 【规则】需要发布的接口需要明确在ndk.json文件中声明列出,不允许直接发布镜像中的动态库,都采用stub动态库的方式发布。 + * json文件是一个符号描述数组,举例如下: + ``` + [ + { + "name": "__progname", + "type": "variable" + }, + { + "name": "pthread_cond_clockwait" + } + ] + ``` + name表示符号的名字,type表示符号类型,不写type,默认认为是函数;varible表示这个符号是变量。 +* 【规则】CAPI中头文件中不允许包含不发布的接口声明,类型定义;三方库的接口文件,可 +以备案保留。 +* 【规则】接口必须是C语言接口,不允许出现C++元素,保证引用方是C代码也能使用;提供头文件中的接口需要用C declare声明。 + + * C declare声明 + ``` + #ifdef __cplusplus + extern "C" { + #endif + ... + #ifdef __cplusplus + } + #endif + ``` + * __反例__ + struct/enum声明的类型,如果没有声明typedef类型,在使用时必须加上struct、enum关键字。 + + * __例外__ 直接提供实现库,嵌入到应用包中的接口可以使用C++元素。 + +* 【规则】包含CAPI的实现动态库放到/system/{lib}/ndk目录下。 +* 【规则】每个接口都需要与syscap相关联;一个头文件中的接口只能属于一个syscap,不能包含多个syscap能力;多个文件可以关联相同的syscap。 +* 【规则】自研接口按照文档注释写作规范进行注释,三方库接口有修改的,注释规则按照注释规范进行注释。 +* 【建议】对外提供的接口,采用对外封闭,依赖倒置原则;结构体的具体实现不对外暴露,方便后续扩展修改。 + +### 兼容性规则 +* 【规则】接口发布后,需要保证版本上的兼容性;接口原型,语义,错误处理等都要保持兼容。 +* 【规则】接口删除需提前五个版本进行预告;在使用这个接口的时候实现时进行告警提示;头文件接口注释标注@deprecated。 +* 【规则】不允许进行接口原型变更,可以通过新增接口,废弃老接口的方式进行。 +* 【规则】接口语义不允许变更,语义通过xts用例保持兼容性。接口涉及的结构体,枚举值变更也会影响语义,建议在设计的时候保留一些字段供扩展使用。 +* 【规则】结构体成员,枚举值可以标明废弃,不建议删除。 + +## 文档注释写作规范 +CAPI中暴露的接口,分为自研接口与三方开源库接口。 + +自研接口注释书写规范步骤: +1. 每个头文件都需要书写注释。 +2. 注释书写参考 [Nativ接口注释规范](https://gitee.com/openharmony/docs/blob/master/zh-cn/contribute/template/native-template.md),注释命令必须按照@开头。 +3. 提交注释头文件到 https://gitee.com/openharmony-sig/interface_native_header/tree/master/zh-cn/native_sdk 这个仓。 +4. 等待资料审核,合入;同时翻译一份英文注释头文件到en目录。 +5. 下载这个头文件,覆盖到对应头文件。 -- Gitee