Linux内核文档:如何写符合 kernel-doc 规范的注释

软件发布|下载排行|最新软件

当前位置:首页IT学院IT技术

Linux内核文档:如何写符合 kernel-doc 规范的注释

广漠飘羽   2020-03-20 我要评论
## 简介 Linux内核使用 [Sphinx](http://www.sphinx-doc.org/) 实现把 *Documentation* 目录下的 [reStructuredText](http:/https://img.qb5200.com/download-x/docutils.sourceforge.net/rst.html) 文件转换为非常漂亮的文档。文档既可以通过 **make htmldocs** 转换成 *HTML* 格式,也可以通过 **make pdfdocs** 转换为 *PDF* 格式。 转换生成的文档存放于 *Documentation/output* 目录下。 Linux内核强大的文档功能,除了直接转换 ```.rst```文档之外,还能从源码中汲取API说明,结构体说明等信息。当然要做到这样,源码的注释是有一定要求的。而这篇文档,就是介绍如何写符合 *kernel-doc* 格式要求的注释。 [英文版原文](https://www.kernel.orghttps://img.qb5200.com/download-x/doc/html/latesthttps://img.qb5200.com/download-x/doc-guide/kernel-doc.html),根据个人理解做的翻译,如果有翻译错误的地方,请告知。 ## 注释概述 符合 *kernel-doc* 的注释,都需要从 ```/**``` 开始,其后每一行内容都以 ```*```开头,最后是 ```*/``` 表示结束。例如: ``` /** * This is a sample of comment */ ``` 对于函数和类型的注释,必须放在函数和类型之前,以便于别人在修改代码的时候,可以顺手把注释也改了。对概述类型的注释,可以放到文件顶部的位置。 Linux内核有提供一个工具用于对 *kernel-doc* 的格式进行检查,例如: ``` $ scripts/kernel-doc -v -none drivers/foo/bar.c ``` 当然,在编译的时候,如果添加以下的选项,也会检查文档的格式: ``` make W=n ``` ## 函数文档 规范的格式示例如下: ``` /** * function_name() - Brief description of function. * @arg1: Describe the first argument. * @arg2: Describe the second argument. * One can provide multiple line descriptions * for arguments. * * A longer description, with more discussion of the function function_name() * that might be useful to those using or modifying it. Begins with an * empty comment line, and may include additional embedded empty * comment lines. * * The longer description may have multiple paragraphs. * * Context: Describes whether the function can sleep, what locks it takes, * releases, or expects to be held. It can extend over multiple * lines. * Return: Describe the return value of function_name. * * The return value description can also have multiple paragraphs, and should * be placed at the end of the comment block. */ ``` 函数名后的函数功能简介可以跨越多行,以函数参数描述、返回值描述或其他描述结束。 ### 函数参数 函数参数的描述,必须直接且按顺序放在函数简介之后。需要注意的是,函数参数与函数简介、函数参数与函数参数之间不能有任何空行。 每个函数参数的描述可以跨行,但要注意的是,必须保持缩进对齐,例如 ``` * @argument: some long description * that continues on next lines # that 必须与 some对齐(避免排版乱套,补充说明) ``` 或者 ``` * @argument: * some long description * that continues on next lines ``` ### 函数参数 如果出现不定数量个参数,可以这么表示: ``` * @...: description ``` ### 函数上下文 描述这个函数会在什么场景下调用,就是函数上下文字段所要做的。函数上下文字段用```Context:```表示,应该包含函数是否会休眠,是否会在中断中调用,以及它会持有、释放什么锁,和其他所有调用这个函数需要注意的东西。 例如: ``` * Context: Any context. * Context: Any context. Takes and releases the RCU lock. * Context: Any context. Expects to be held by caller. * Context: Process context. May sleep if @gfp flags permit. * Context: Process context. Takes and releases . * Context: Softirq or process context. Takes and releases , BH-safe. * Context: Interrupt context. ``` ### 函数返回值 函数返回值相关的描述应该放在```Return:```字段。 由于不能识别换行,因此如果你这样写: ``` * Return: * 0 - OK * -EINVAL - invalid argument * -ENOMEM - out of memory ``` 效果只会是: ``` Return: 0 - OK -EINVAL - invalid argument -ENOMEM - out of memory ``` 所以呢,如果你要换行,你需要使用 *ReST List*,例如: ``` * Return: * * 0 - OK to runtime suspend the device * * -EBUSY - Device should not be runtime suspended ``` 另外,如果字段出现类似```key:```这样短语加冒号的形式,会被识别为其他的字段。这点需要注意。 ## struct 和 union 和 enum 类型的注释 通常 *struct* ,*union* 和 *enum* 类型的注释说明是这样的: ``` /** * struct struct_name - Brief description. * @member1: Description of member1. * @member2: Description of member2. * One can provide multiple line descriptions * for members. * * Description of the structure. */ ``` 紧随名字后面的 *Brief description* 可以跨度几行,它以 *@member* 字段、空行或者```*/```表示结束。 ### 成员 *struct*,*union* 和 *enum* 的成员注释格式与函数参数的格式一致,他们都需要简短的描述且支持换行。 在 *struct* 和 *union* 里面也支持注释。支持 ```private``` 和 ```public``` 两种标签。```private``` 标签的成员不会呈现到编译出来的文档上,类似与 *C++* 上的 private 成员。 需要注意的是,```private``` 和 ```public``` 标签必须以```\*```标识开始且不能有缩进,以```*/```标识结束。如果有简介,可以写在```:```与结束标识```*/```之间,例如: ``` /** * struct my_struct - short description * @a: first member * @b: second member * @d: fourth member * * Longer description */ struct my_struct { int a; int b; /* private: internal use only */ int c; /* public: the next one is public */ int d; }; ``` ### 嵌套struct和union 如果出现嵌套定义 ```struct```和```union```,可以参考下面的做法: ``` /** * struct nested_foobar - a struct with nested unions and structs * @memb1: first member of anonymous union/anonymous struct * @memb2: second member of anonymous union/anonymous struct * @memb3: third member of anonymous union/anonymous struct * @memb4: fourth member of anonymous union/anonymous struct * @bar: non-anonymous union * @bar.st1: struct st1 inside @bar * @bar.st2: struct st2 inside @bar * @bar.st1.memb1: first member of struct st1 on union bar * @bar.st1.memb2: second member of struct st1 on union bar * @bar.st2.memb1: first member of struct st2 on union bar * @bar.st2.memb2: second member of struct st2 on union bar */ struct nested_foobar { /* Anonymous union/struct*/ union { struct { int memb1; int memb2; } struct { void *memb3; int memb4; } } union { struct { int memb1; int memb2; } st1; struct { void *memb1; int memb2; } st2; } bar; }; ``` 有两点要注意的: 1. 如果嵌套的```struct```或者```union```有命名,那么应该使用```@foo.bar```的形式,例如上例的```@bar.st1``` 2. 如果是匿名的,那么需要直接使用```@bar```的形式,例如上例的```@memb1``` 细心的小伙伴可能发现,这与C语言上结构体的调用方式非常相似。 ### 内联的成员描述 成员的描述除了放在开头,还可以放在 *struct* 和 *union* 里面。支持单行或者多行,以```/**```开头,以```*/```结束。例如: ``` /* * struct foo - Brief description. * @foo: The Foo member. */ struct foo { int foo; /** * @bar: The Bar member. */ int bar; /** * @baz: The Baz member. * * Here, the member description may contain several paragraphs. */ int baz; union { /** @foobar: Single line description. */ int foobar; }; /** @bar2: Description for struct @bar2 inside @foo */ struct { /** * @bar2.barbar: Description for @barbar inside @foo.bar2 */ int barbar; } bar2; }; ``` ## typedef注释 通常格式如下: ``` /** * typedef type_name - Brief description. * * Description of the type. */ ``` 如果是函数的类型定义,也可以这样: ``` /** * typedef type_name - Brief description. * @arg1: description of arg1 * @arg2: description of arg2 * * Description of the type. * * Context: Locking context. * Return: Meaning of the return value. */ typedef void (*type_name)(struct v4l2_ctrl *arg1, void *arg2); ``` ## 高亮和交叉索引 在各种说明字段中,可以用以下的形式做成索引。 **funcname()** 索引到函数 **@parameter** 索引到函数参数(只在本函数内索引,不会交叉到其他函数) **%CONST** 索引到指定名字的上下文段说明(只在本函数内索引,不会交叉到其他函数) **\`\`literal\`\`** 字面意义,让 kernel-doc 不解析,做纯字符串处理。常用于出现与 kernel-doc 或者 reStructuredText 关键字冲突的情况 **$ENVVAR** 环境变量(只在本函数内索引,不会交叉到其他函数) **&struct name** 索引到其他结构体 **&enum name** 索引到其他的枚举型 **&typedef name** 索引到typedef定义的类型 **&struct_name->member or &struct_name.member** 索引到制定结构体成员 **&name** 泛型类型引用。不建议使用,请使用其他方法 ## 概述说明 为了便于将源代码和注释紧密结合在一起,可以包含自由格式注释的内核文档块,而不是函数、结构、联合、枚举或typedef的内核文档块。例如,这可以用于驱动程序或库代码的操作理论。 这是通过使用带有节标题的DOC:section关键字来完成的。 通用的格式如下: ``` /** * DOC: Theory of Operation * * The whizbang foobar is a dilly of a gizmo. It can do whatever you * want it to do, at any time. It reads your mind. Here's how it works. * * foo bar splat * * The only drawback to this gizmo is that is can sometimes damage * hardware, software, or its subject(s). */ ``` DOC:后面的标题用作源文件中的标题,也用作提取文档注释的标识符。因此,标题在文件中必须是唯一的。

Copyright 2022 版权所有 软件发布 访问手机版

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 联系我们