Skip to content

Commit

Permalink
Merge pull request Rust-for-Linux#306 from nbdd0121/macros
Browse files Browse the repository at this point in the history
Rename libmodule to libmacros
  • Loading branch information
ojeda authored May 29, 2021
2 parents b24c08c + 863bd2e commit 0164898
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 136 deletions.
24 changes: 12 additions & 12 deletions rust/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
obj-$(CONFIG_RUST) += core.o compiler_builtins.o helpers.o
extra-$(CONFIG_RUST) += exports_core_generated.h

extra-$(CONFIG_RUST) += libmodule.so
extra-$(CONFIG_RUST) += libmacros.so

extra-$(CONFIG_RUST) += bindings_generated.rs
obj-$(CONFIG_RUST) += alloc.o kernel.o
Expand Down Expand Up @@ -35,21 +35,21 @@ quiet_cmd_rustdoc = RUSTDOC $<
--output $(objtree)/rust/doc --crate-name $(subst rustdoc-,,$@) \
-Fmissing-docs @$(objtree)/include/generated/rustc_cfg $<

rustdoc: rustdoc-module rustdoc-compiler_builtins rustdoc-kernel
rustdoc: rustdoc-macros rustdoc-compiler_builtins rustdoc-kernel

rustdoc-module: private rustdoc_target_flags = --crate-type proc-macro \
rustdoc-macros: private rustdoc_target_flags = --crate-type proc-macro \
--extern proc_macro
rustdoc-module: $(srctree)/rust/module.rs FORCE
rustdoc-macros: $(srctree)/rust/macros/lib.rs FORCE
$(call if_changed,rustdoc_host)

rustdoc-compiler_builtins: $(srctree)/rust/compiler_builtins.rs FORCE
$(call if_changed,rustdoc)

rustdoc-kernel: private rustdoc_target_flags = --extern alloc \
--extern build_error \
--extern module=$(objtree)/rust/libmodule.so
rustdoc-kernel: $(srctree)/rust/kernel/lib.rs rustdoc-module \
$(objtree)/rust/libmodule.so $(objtree)/rust/bindings_generated.rs FORCE
--extern macros=$(objtree)/rust/libmacros.so
rustdoc-kernel: $(srctree)/rust/kernel/lib.rs rustdoc-macros \
$(objtree)/rust/libmacros.so $(objtree)/rust/bindings_generated.rs FORCE
$(call if_changed,rustdoc)

ifdef CONFIG_CC_IS_CLANG
Expand Down Expand Up @@ -127,9 +127,9 @@ quiet_cmd_rustc_procmacro = $(RUSTC_OR_CLIPPY_QUIET) P $@
sed -i '/^\#/d' $(depfile)

# Procedural macros can only be used with the `rustc` that compiled it.
# Therefore, to get `libmodule.so` automatically recompiled when the compiler
# Therefore, to get `libmacros.so` automatically recompiled when the compiler
# version changes, we add `core.o` as a dependency (even if it is not needed).
$(objtree)/rust/libmodule.so: $(srctree)/rust/module.rs \
$(objtree)/rust/libmacros.so: $(srctree)/rust/macros/lib.rs \
$(objtree)/rust/core.o FORCE
$(call if_changed_dep,rustc_procmacro)

Expand Down Expand Up @@ -170,11 +170,11 @@ $(objtree)/rust/build_error.o: $(srctree)/rust/build_error.rs \
$(objtree)/rust/compiler_builtins.o FORCE
$(call if_changed_dep,rustc_library)

# ICE on `--extern module`: https://github.com/rust-lang/rust/issues/56935
# ICE on `--extern macros`: https://github.com/rust-lang/rust/issues/56935
$(objtree)/rust/kernel.o: private rustc_target_flags = --extern alloc \
--extern build_error \
--extern module=$(objtree)/rust/libmodule.so
--extern macros=$(objtree)/rust/libmacros.so
$(objtree)/rust/kernel.o: $(srctree)/rust/kernel/lib.rs $(objtree)/rust/alloc.o \
$(objtree)/rust/build_error.o \
$(objtree)/rust/libmodule.so $(objtree)/rust/bindings_generated.rs FORCE
$(objtree)/rust/libmacros.so $(objtree)/rust/bindings_generated.rs FORCE
$(call if_changed_dep,rustc_library)
4 changes: 2 additions & 2 deletions rust/kernel/module_param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub trait ModuleParam: core::fmt::Display + core::marker::Sized {
/// Get the current value of the parameter for use in the kernel module.
///
/// This function should not be used directly. Instead use the wrapper
/// `read` which will be generated by [`module::module`].
/// `read` which will be generated by [`macros::module`].
fn value(&self) -> &Self::Value;

/// Set the module parameter from a string.
Expand Down Expand Up @@ -428,7 +428,7 @@ impl<T: Copy + core::fmt::Display + ModuleParam, const N: usize> ModuleParam
/// A C-style string parameter.
///
/// The Rust version of the [`charp`] parameter. This type is meant to be
/// used by the [`module::module`] macro, not handled directly. Instead use the
/// used by the [`macros::module`] macro, not handled directly. Instead use the
/// `read` method generated by that macro.
///
/// [`charp`]: ../../../include/linux/moduleparam.h
Expand Down
2 changes: 1 addition & 1 deletion rust/kernel/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub use alloc::{borrow::ToOwned, string::String};

pub use super::build_assert;

pub use module::{module, module_misc_device};
pub use macros::{module, module_misc_device};

pub use super::{pr_alert, pr_crit, pr_emerg, pr_err, pr_info, pr_notice, pr_warn};

Expand Down
132 changes: 132 additions & 0 deletions rust/macros/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// SPDX-License-Identifier: GPL-2.0

//! Crate for all kernel procedural macros.
#![deny(clippy::complexity)]
#![deny(clippy::correctness)]
#![deny(clippy::perf)]
#![deny(clippy::style)]

mod module;

use proc_macro::TokenStream;

/// Declares a kernel module.
///
/// The `type` argument should be a type which implements the [`KernelModule`]
/// trait. Also accepts various forms of kernel metadata.
///
/// C header: [`include/linux/moduleparam.h`](../../../include/linux/moduleparam.h)
///
/// [`KernelModule`]: ../kernel/trait.KernelModule.html
///
/// # Examples
///
/// ```rust,no_run
/// use kernel::prelude::*;
///
/// module!{
/// type: MyKernelModule,
/// name: b"my_kernel_module",
/// author: b"Rust for Linux Contributors",
/// description: b"My very own kernel module!",
/// license: b"GPL v2",
/// params: {
/// my_i32: i32 {
/// default: 42,
/// permissions: 0o000,
/// description: b"Example of i32",
/// },
/// writeable_i32: i32 {
/// default: 42,
/// permissions: 0o644,
/// description: b"Example of i32",
/// },
/// },
/// }
///
/// struct MyKernelModule;
///
/// impl KernelModule for MyKernelModule {
/// fn init() -> Result<Self> {
/// // If the parameter is writeable, then the kparam lock must be
/// // taken to read the parameter:
/// {
/// let lock = THIS_MODULE.kernel_param_lock();
/// pr_info!("i32 param is: {}\n", writeable_i32.read(&lock));
/// }
/// // If the parameter is read only, it can be read without locking
/// // the kernel parameters:
/// pr_info!("i32 param is: {}\n", my_i32.read());
/// Ok(MyKernelModule)
/// }
/// }
/// ```
///
/// # Supported argument types
/// - `type`: type which implements the [`KernelModule`] trait (required).
/// - `name`: byte array of the name of the kernel module (required).
/// - `author`: byte array of the author of the kernel module.
/// - `description`: byte array of the description of the kernel module.
/// - `license`: byte array of the license of the kernel module (required).
/// - `alias`: byte array of alias name of the kernel module.
/// - `alias_rtnl_link`: byte array of the `rtnl_link_alias` of the kernel module (mutually exclusive with `alias`).
/// - `params`: parameters for the kernel module, as described below.
///
/// # Supported parameter types
///
/// - `bool`: Corresponds to C `bool` param type.
/// - `i8`: No equivalent C param type.
/// - `u8`: Corresponds to C `char` param type.
/// - `i16`: Corresponds to C `short` param type.
/// - `u16`: Corresponds to C `ushort` param type.
/// - `i32`: Corresponds to C `int` param type.
/// - `u32`: Corresponds to C `uint` param type.
/// - `i64`: No equivalent C param type.
/// - `u64`: Corresponds to C `ullong` param type.
/// - `isize`: No equivalent C param type.
/// - `usize`: No equivalent C param type.
/// - `str`: Corresponds to C `charp` param type. Reading returns a byte slice.
/// - `ArrayParam<T,N>`: Corresponds to C parameters created using `module_param_array`. An array
/// of `T`'s of length at **most** `N`.
///
/// `invbool` is unsupported: it was only ever used in a few modules.
/// Consider using a `bool` and inverting the logic instead.
#[proc_macro]
pub fn module(ts: TokenStream) -> TokenStream {
module::module(ts)
}

/// Declares a kernel module that exposes a single misc device.
///
/// The `type` argument should be a type which implements the [`FileOpener`] trait. Also accepts
/// various forms of kernel metadata.
///
/// C header: [`include/linux/moduleparam.h`](../../../include/linux/moduleparam.h)
///
/// [`FileOpener`]: ../kernel/file_operations/trait.FileOpener.html
///
/// # Examples
///
/// ```rust,no_run
/// use kernel::prelude::*;
///
/// module_misc_device! {
/// type: MyFile,
/// name: b"my_miscdev_kernel_module",
/// author: b"Rust for Linux Contributors",
/// description: b"My very own misc device kernel module!",
/// license: b"GPL v2",
/// }
///
/// #[derive(Default)]
/// struct MyFile;
///
/// impl kernel::file_operations::FileOperations for MyFile {
/// kernel::declare_file_operations!();
/// }
/// ```
#[proc_macro]
pub fn module_misc_device(ts: TokenStream) -> TokenStream {
module::module_misc_device(ts)
}
117 changes: 0 additions & 117 deletions rust/module.rs → rust/macros/module.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
// SPDX-License-Identifier: GPL-2.0

//! Proc macro crate implementing the [`module!`] magic.
//!
//! C header: [`include/linux/moduleparam.h`](../../../include/linux/moduleparam.h)
#![deny(clippy::complexity)]
#![deny(clippy::correctness)]
#![deny(clippy::perf)]
#![deny(clippy::style)]

use proc_macro::{token_stream, Delimiter, Group, TokenStream, TokenTree};

fn try_ident(it: &mut token_stream::IntoIter) -> Option<String> {
Expand Down Expand Up @@ -399,86 +390,6 @@ impl ModuleInfo {
}
}

/// Declares a kernel module.
///
/// The `type` argument should be a type which implements the [`KernelModule`]
/// trait. Also accepts various forms of kernel metadata.
///
/// [`KernelModule`]: ../kernel/trait.KernelModule.html
///
/// # Examples
///
/// ```rust,no_run
/// use kernel::prelude::*;
///
/// module!{
/// type: MyKernelModule,
/// name: b"my_kernel_module",
/// author: b"Rust for Linux Contributors",
/// description: b"My very own kernel module!",
/// license: b"GPL v2",
/// params: {
/// my_i32: i32 {
/// default: 42,
/// permissions: 0o000,
/// description: b"Example of i32",
/// },
/// writeable_i32: i32 {
/// default: 42,
/// permissions: 0o644,
/// description: b"Example of i32",
/// },
/// },
/// }
///
/// struct MyKernelModule;
///
/// impl KernelModule for MyKernelModule {
/// fn init() -> Result<Self> {
/// // If the parameter is writeable, then the kparam lock must be
/// // taken to read the parameter:
/// {
/// let lock = THIS_MODULE.kernel_param_lock();
/// pr_info!("i32 param is: {}\n", writeable_i32.read(&lock));
/// }
/// // If the parameter is read only, it can be read without locking
/// // the kernel parameters:
/// pr_info!("i32 param is: {}\n", my_i32.read());
/// Ok(MyKernelModule)
/// }
/// }
/// ```
///
/// # Supported argument types
/// - `type`: type which implements the [`KernelModule`] trait (required).
/// - `name`: byte array of the name of the kernel module (required).
/// - `author`: byte array of the author of the kernel module.
/// - `description`: byte array of the description of the kernel module.
/// - `license`: byte array of the license of the kernel module (required).
/// - `alias`: byte array of alias name of the kernel module.
/// - `alias_rtnl_link`: byte array of the `rtnl_link_alias` of the kernel module (mutually exclusive with `alias`).
/// - `params`: parameters for the kernel module, as described below.
///
/// # Supported parameter types
///
/// - `bool`: Corresponds to C `bool` param type.
/// - `i8`: No equivalent C param type.
/// - `u8`: Corresponds to C `char` param type.
/// - `i16`: Corresponds to C `short` param type.
/// - `u16`: Corresponds to C `ushort` param type.
/// - `i32`: Corresponds to C `int` param type.
/// - `u32`: Corresponds to C `uint` param type.
/// - `i64`: No equivalent C param type.
/// - `u64`: Corresponds to C `ullong` param type.
/// - `isize`: No equivalent C param type.
/// - `usize`: No equivalent C param type.
/// - `str`: Corresponds to C `charp` param type. Reading returns a byte slice.
/// - `ArrayParam<T,N>`: Corresponds to C parameters created using `module_param_array`. An array
/// of `T`'s of length at **most** `N`.
///
/// `invbool` is unsupported: it was only ever used in a few modules.
/// Consider using a `bool` and inverting the logic instead.
#[proc_macro]
pub fn module(ts: TokenStream) -> TokenStream {
let mut it = ts.into_iter();

Expand Down Expand Up @@ -775,34 +686,6 @@ pub fn module(ts: TokenStream) -> TokenStream {
).parse().expect("Error parsing formatted string into token stream.")
}

/// Declares a kernel module that exposes a single misc device.
///
/// The `type` argument should be a type which implements the [`FileOpener`] trait. Also accepts
/// various forms of kernel metadata.
///
/// [`FileOpener`]: ../kernel/file_operations/trait.FileOpener.html
///
/// # Examples
///
/// ```rust,no_run
/// use kernel::prelude::*;
///
/// module_misc_device! {
/// type: MyFile,
/// name: b"my_miscdev_kernel_module",
/// author: b"Rust for Linux Contributors",
/// description: b"My very own misc device kernel module!",
/// license: b"GPL v2",
/// }
///
/// #[derive(Default)]
/// struct MyFile;
///
/// impl kernel::file_operations::FileOperations for MyFile {
/// kernel::declare_file_operations!();
/// }
/// ```
#[proc_macro]
pub fn module_misc_device(ts: TokenStream) -> TokenStream {
let mut it = ts.into_iter();

Expand Down
8 changes: 4 additions & 4 deletions scripts/generate_rust_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,13 @@ def append_crate(display_name, root_module, is_workspace_member, deps, cfg):
)

append_crate(
"module",
srctree / "rust" / "module.rs",
"macros",
srctree / "rust" / "macros" / "lib.rs",
True,
[],
[],
)
crates[-1]["proc_macro_dylib_path"] = "rust/libmodule.so"
crates[-1]["proc_macro_dylib_path"] = "rust/libmacros.so"

append_crate(
"build_error",
Expand All @@ -83,7 +83,7 @@ def append_crate(display_name, root_module, is_workspace_member, deps, cfg):
"kernel",
srctree / "rust" / "kernel" / "lib.rs",
True,
["core", "alloc", "module", "build_error"],
["core", "alloc", "macros", "build_error"],
cfg,
)
crates[-1]["env"]["RUST_BINDINGS_FILE"] = str(bindings_file.resolve(True))
Expand Down

0 comments on commit 0164898

Please sign in to comment.