Skip to content

Commit 8584c78

Browse files
committed
Documentation support
Requires nightly 2021-02-20 due to added support for argument files, see rust-lang/rust#82261. Signed-off-by: Miguel Ojeda <[email protected]>
1 parent d189aae commit 8584c78

File tree

11 files changed

+190
-5
lines changed

11 files changed

+190
-5
lines changed

.github/workflows/ci.yaml

+7-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
arch: [x86_64, arm64]
1414
toolchain: [gcc, clang, llvm]
1515
config: [debug, release]
16-
rustc: [2021-01-24]
16+
rustc: [2021-02-20]
1717
output: [src] # [src, build]
1818
install: [rustup] # [rustup, standalone]
1919
sysroot: [common] # [common, custom]
@@ -27,23 +27,23 @@ jobs:
2727
- arch: x86_64
2828
toolchain: gcc
2929
config: debug
30-
rustc: 2021-01-31
30+
rustc: 2021-02-20
3131
output: build
3232
install: rustup
3333
sysroot: custom
3434

3535
- arch: arm64
3636
toolchain: clang
3737
config: release
38-
rustc: 2021-02-07
38+
rustc: 2021-02-20
3939
output: build
4040
install: standalone
4141
sysroot: common
4242

4343
- arch: x86_64
4444
toolchain: llvm
4545
config: debug
46-
rustc: 2021-02-11
46+
rustc: 2021-02-20
4747
output: build
4848
install: standalone
4949
sysroot: custom
@@ -177,3 +177,6 @@ jobs:
177177
# Report
178178
- run: ls -l ${{ env.BUILD_DIR }}drivers/char/rust_example.o ${{ env.BUILD_DIR }}drivers/char/rust_example_3.ko ${{ env.BUILD_DIR }}rust/*.o ${{ env.BUILD_DIR }}vmlinux ${{ env.BUILD_DIR }}${{ env.IMAGE_PATH }}
179179
- run: size ${{ env.BUILD_DIR }}drivers/char/rust_example.o ${{ env.BUILD_DIR }}drivers/char/rust_example_3.ko ${{ env.BUILD_DIR }}rust/*.o ${{ env.BUILD_DIR }}vmlinux
180+
181+
# Docs
182+
- run: make ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_SYSROOT }} -j3 rustdoc

Documentation/doc-guide/kernel-doc.rst

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ when it is embedded in source files.
1111
reasons. The kernel source contains tens of thousands of kernel-doc
1212
comments. Please stick to the style described here.
1313

14+
.. note:: kernel-doc does not cover Rust code: please see
15+
:ref:`Documentation/rust/docs.rst <rust_docs>` instead.
16+
1417
The kernel-doc structure is extracted from the comments, and proper
1518
`Sphinx C Domain`_ function and type descriptions with anchors are
1619
generated from them. The descriptions are filtered for special kernel-doc

Documentation/process/changes.rst

+7
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ iptables 1.4.2 iptables -V
5858
openssl & libcrypto 1.0.0 openssl version
5959
bc 1.06.95 bc --version
6060
Sphinx\ [#f1]_ 1.3 sphinx-build --version
61+
rustdoc (optional) nightly rustdoc --version
6162
====================== =============== ========================================
6263

6364
.. [#f1] Sphinx is needed only to build the Kernel documentation
@@ -332,6 +333,12 @@ Sphinx
332333
Please see :ref:`sphinx_install` in :ref:`Documentation/doc-guide/sphinx.rst <sphinxdoc>`
333334
for details about Sphinx requirements.
334335

336+
rustdoc
337+
-------
338+
339+
``rustdoc`` is used to generate Rust documentation. Please see
340+
:ref:`Documentation/rust/docs.rst <rust_docs>` for more information.
341+
335342
Getting updated software
336343
========================
337344

Documentation/rust/coding.rst

+5
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,8 @@ configuration:
3939
#[cfg(CONFIG_X="m")] // `CONFIG_X` is enabled as a module (`m`)
4040
#[cfg(not(CONFIG_X))] // `CONFIG_X` is disabled
4141
42+
43+
Documentation
44+
-------------
45+
46+
Please see :ref:`Documentation/rust/docs.rst <rust_docs>`.

Documentation/rust/docs.rst

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
.. _rust_docs:
2+
3+
Docs
4+
====
5+
6+
Rust kernel code is not documented like C kernel code (i.e. via kernel-doc).
7+
Instead, we use the usual system for documenting Rust code: the ``rustdoc``
8+
tool, which uses Markdown (a *very* lightweight markup language).
9+
10+
This document describes how to make the most out of the kernel documentation
11+
for Rust.
12+
13+
14+
Reading the docs
15+
----------------
16+
17+
An advantage of using Markdown is that it attempts to make text look almost as
18+
you would have written it in plain text. This makes the documentation quite
19+
pleasant to read even in its source form.
20+
21+
However, the generated HTML docs produced by ``rustdoc`` provide a *very* nice
22+
experience, including integrated instant search, clickable items (types,
23+
functions, constants, etc. -- including to all the standard Rust library ones
24+
that we use in the kernel, e.g. ``core``), categorization, links to the source
25+
code, etc.
26+
27+
Like for the rest of the kernel documentation, pregenerated HTML docs for
28+
the libraries (crates) inside ``rust/`` that are used by the rest of the kernel
29+
are available at `kernel.org`_.
30+
31+
// TODO: link when ready
32+
33+
.. _kernel.org: http://kernel.org/
34+
35+
Otherwise, you can generate them locally. This is quite fast (same order as
36+
compiling the code itself) and you do not need any special tools or environment.
37+
This has the added advantage that they will be tailored to your particular
38+
kernel configuration. To generate them, simply use the ``rustdoc`` target with
39+
the same invocation you use for compilation, e.g.::
40+
41+
make ARCH=... CROSS_COMPILE=... CC=... -j... rustdoc
42+
43+
44+
Writing the docs
45+
----------------
46+
47+
If you already know Markdown, learning how to write Rust documentation will be
48+
a breeze. If not, understanding the basics is a matter of minutes reading other
49+
code. There are also many guides available out there, a particularly nice one
50+
is at `GitHub`_.
51+
52+
.. _GitHub: https://guides.github.com/features/mastering-markdown/#syntax
53+
54+
This is how a well-documented Rust function may look like (derived from the Rust
55+
standard library)::
56+
57+
/// Returns the contained [`Some`] value, consuming the `self` value,
58+
/// without checking that the value is not [`None`].
59+
///
60+
/// # Safety
61+
///
62+
/// Calling this method on [`None`] is *[undefined behavior]*.
63+
///
64+
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
65+
///
66+
/// # Examples
67+
///
68+
/// ```
69+
/// let x = Some("air");
70+
/// assert_eq!(unsafe { x.unwrap_unchecked() }, "air");
71+
/// ```
72+
pub unsafe fn unwrap_unchecked(self) -> T {
73+
match self {
74+
Some(val) => val,
75+
76+
// SAFETY: the safety contract must be upheld by the caller.
77+
None => unsafe { hint::unreachable_unchecked() },
78+
}
79+
}
80+
81+
This example showcases a few ``rustdoc`` features and some common conventions
82+
(that we also follow in the kernel):
83+
84+
* The first paragraph must be a single sentence briefly describing what
85+
the documented item does. Further explanations must go in extra paragraphs.
86+
87+
* ``unsafe`` functions must document the preconditions needed for a call to be
88+
safe under a ``Safety`` section.
89+
90+
* While not shown here, if a function may panic, the conditions under which
91+
that happens must be described under a ``Panics`` section.
92+
93+
* If providing examples of usage would help readers, they must be written in
94+
a section called ``Examples``.
95+
96+
* Rust items (functions, types, constants...) will be automatically linked
97+
(``rustdoc`` will find out the URL for you).
98+
99+
* Following the Rust standard library conventions, any ``unsafe`` block must be
100+
preceded by a ``SAFETY`` comment describing why the code inside is sound.
101+
102+
While sometimes the reason might look trivial and therefore unneeded, writing
103+
these comments is not just a good way of documenting what has been taken into
104+
account, but also that there are no *extra* implicit constraints.
105+
106+
To learn more about how to write documentation for Rust and extra features,
107+
please take a look at the ``rustdoc`` `book`_.
108+
109+
.. _book: https://doc.rust-lang.org/rustdoc/how-to-write-documentation.html

Documentation/rust/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ read the :ref:`Documentation/rust/quick-start.rst <rust_quick_start>` guide.
99

1010
quick-start
1111
coding
12+
docs
1213
arch-support
1314

1415
.. only:: subproject and html

Documentation/rust/quick-start.rst

+17-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ rustc
2121
*****
2222

2323
A recent *nightly* Rust toolchain (with, at least, ``rustc``) is required,
24-
e.g. ``nightly-2021-01-24``. Our goal is to use a stable toolchain as soon
24+
e.g. ``nightly-2021-02-20``. Our goal is to use a stable toolchain as soon
2525
as possible, but for the moment we depend on a handful of nightly features.
2626

2727
If you are using ``rustup``, run::
@@ -80,6 +80,22 @@ the component manually::
8080
The standalone installers also come with ``rustfmt``.
8181

8282

83+
rustdoc
84+
*******
85+
86+
Optionally, if you install the ``rustdoc`` tool, then you will be able
87+
to generate HTML documentation for Rust code, including for the libraries
88+
(crates) inside ``rust/`` that are used by the rest of the kernel.
89+
90+
If you are using ``rustup``, its ``default`` profile already installs the tool,
91+
so you should be good to go. If you are using another profile, you can install
92+
the component manually::
93+
94+
rustup component add rustdoc
95+
96+
The standalone installers also come with ``rustdoc``.
97+
98+
8399
Configuration
84100
-------------
85101

Makefile

+13
Original file line numberDiff line numberDiff line change
@@ -1669,6 +1669,9 @@ help:
16691669
@echo 'Documentation targets:'
16701670
@$(MAKE) -f $(srctree)/Documentation/Makefile dochelp
16711671
@echo ''
1672+
@echo ' rustdoc - Generate Rust documentation'
1673+
@echo ' (requires kernel .config)'
1674+
@echo ''
16721675
@echo 'Architecture specific targets ($(SRCARCH)):'
16731676
@$(if $(archhelp),$(archhelp),\
16741677
echo ' No architecture specific help defined for $(SRCARCH)')
@@ -1722,6 +1725,16 @@ PHONY += $(DOC_TARGETS)
17221725
$(DOC_TARGETS):
17231726
$(Q)$(MAKE) $(build)=Documentation $@
17241727

1728+
1729+
# Rust documentation target
1730+
# ---------------------------------------------------------------------------
1731+
1732+
# Using the singular to avoid running afoul of `no-dot-config-targets`.
1733+
PHONY += rustdoc
1734+
rustdoc: prepare0
1735+
$(Q)$(MAKE) $(build)=rust $@
1736+
1737+
17251738
# Misc
17261739
# ---------------------------------------------------------------------------
17271740

rust/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22

33
bindings_generated.rs
44
exports_*_generated.h
5+
doc/

rust/Makefile

+24
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,30 @@ extra-$(CONFIG_RUST) += bindings_generated.rs libmodule.so
66
extra-$(CONFIG_RUST) += exports_core_generated.h exports_alloc_generated.h
77
extra-$(CONFIG_RUST) += exports_kernel_generated.h
88

9+
RUSTDOC = rustdoc
10+
11+
rustdoc_flags = $(filter-out --emit=% --out-dir=%, $(rustc_flags))
12+
13+
quiet_cmd_rustdoc = RUSTDOC $<
14+
cmd_rustdoc = \
15+
RUST_BINDINGS_FILE=$(abspath $(objtree)/rust/bindings_generated.rs) \
16+
$(RUSTDOC) $(rustdoc_flags) $(rustdoc_target_flags) -L $(objtree)/rust/ \
17+
--output $(objtree)/rust/doc --crate-name $(subst rustdoc-,,$@) \
18+
-Wmissing-docs @$(objtree)/include/generated/rustc_cfg $<
19+
20+
rustdoc: rustdoc-module rustdoc-kernel
21+
22+
rustdoc-module: rustdoc_target_flags = --crate-type proc-macro \
23+
--extern proc_macro
24+
rustdoc-module: $(srctree)/rust/module.rs FORCE
25+
$(call if_changed,rustdoc)
26+
27+
rustdoc-kernel: rustdoc_target_flags = --extern alloc \
28+
--extern module=$(objtree)/rust/libmodule.so
29+
rustdoc-kernel: $(srctree)/rust/kernel/lib.rs rustdoc-module \
30+
$(objtree)/rust/libmodule.so $(objtree)/rust/bindings_generated.rs FORCE
31+
$(call if_changed,rustdoc)
32+
933
ifdef CONFIG_CC_IS_CLANG
1034
bindgen_c_flags = $(c_flags)
1135
else

rust/kernel/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ compile_error!("Missing kernel configuration for conditional compilation");
1313
use core::panic::PanicInfo;
1414

1515
mod allocator;
16+
17+
#[doc(hidden)]
1618
pub mod bindings;
19+
1720
pub mod c_types;
1821
pub mod chrdev;
1922
mod error;

0 commit comments

Comments
 (0)