From 40cbc3f043eeea8b8f27ece943f42437a264239b Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Tue, 24 Sep 2019 01:14:15 +0200 Subject: Initial Rust support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we have several lines of work:   - Integrating with the kernel tree and build system (Nick's & mine, both uploaded as branches, based on `rustc`; and another one I have been working on, based on `cargo`).   - Bindings and the first bits of functionality (Alex's & Geoffrey's, based on `cargo`). This patch effectively merges the work we have been doing and integrates it in the latest mainline kernel tree. This does *not* mean anything needs to stay as-is, but this gives us a working, common base to work and experiment upon. Hopefully, it will also attract external people to join! As a summary, I added: - `cargo` integration with the kernel `Makefile`s:   + Virtual `cargo` workspace to have a single lock file and to share deps between `cargo` jobs. + Picks the same optimization level as configured for C. + Verbose output on `V=1`. + A `cargoclean` target to clean all the Rust-related artifacts. - Initial support for built-in modules (i.e. `Y` as well as `M`): + It is a hack, we need to implement a few things (see the `TODO`s), but it is enough to start playing with things that depend on `MODULE`. + Passes `--cfg module` to built-in modules to be able to compile conditionally inside Rust. + Increased `KSYM_NAME_LEN` length to avoid warnings due to Rust long mangled symbols.   - Rust infrastructure in a new top level folder `rust/`: + A `kernel` package which contains the sources from Alex & Geoffrey's work plus some changes:     * Adapted `build.rs`. * Removed the `THIS_MODULE` emulation until it is implemented.     * Removed `Makefile` logic and the code that `cfg`-depended on kernel version (no need in mainline). * Moved the helpers to be triggered via normal compilation, renamed them under `rust_*` and exported via `EXPORT_SYMBOL` instead. * Added a prelude. + A `shlex` package which serves as an example of an "inline" dependency (i.e. package checked out copy to avoid the network) - The example driver was setup at `drivers/char/rust_example/`. - Misc + The beginning of `Documentation/rust/` with a quick start guide. + `MAINTAINERS` entry. + SPDXs for all files. Other notes that aren't in `TODO`s:   - We could minimize the network requirements (use `bindgen` binary, use more inline dependencies...), but it is not clear it would be a good idea for the moment due to `core`/`alloc`/`compiler-builtins`. - The intention of `rust/` is to have a place to put extra dependencies and split the `kernel` package into several in the future if it grows. It could resemble the usual kernel tree structure. - With several drivers being built-in, `cargo` recompiles `kernel` and triggers duplicate symbol errors when merging thin archives. We need to make it only compile `kernel` once.   - When the above works, then `make`'s `-j` calling concurrent `cargo`s (e.g. several drivers at the same time) should be OK, I think. According to https://github.com/rust-lang/cargo/pull/2486 it shouldn't miscompile anything, but if they start locking on each other we will have make jobs waiting that could have been doing something else. Signed-off-by: Miguel Ojeda --- scripts/Makefile.lib | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'scripts/Makefile.lib') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 3d599716940c..939062f389d3 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -20,6 +20,8 @@ endif # flags that take effect in current and sub directories KBUILD_AFLAGS += $(subdir-asflags-y) KBUILD_CFLAGS += $(subdir-ccflags-y) +KBUILD_RUSTCFLAGS += $(subdir-rustcflags-y) +KBUILD_CARGOFLAGS += $(subdir-cargoflags-y) # Figure out what we need to build from the various variables # =========================================================================== @@ -126,6 +128,14 @@ _c_flags = $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), \ $(filter-out $(ccflags-remove-y), \ $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(ccflags-y)) \ $(CFLAGS_$(target-stem).o)) +_rustc_flags = $(filter-out $(RUSTCFLAGS_REMOVE_$(target-stem).o), \ + $(filter-out $(rustcflags-remove-y), \ + $(KBUILD_RUSTCFLAGS) $(rustcflags-y)) \ + $(RUSTCFLAGS_$(target-stem).o)) +_cargo_flags = $(filter-out $(CARGOFLAGS_REMOVE_$(target-stem).o), \ + $(filter-out $(cargoflags-remove-y), \ + $(KBUILD_CARGOFLAGS) $(cargoflags-y)) \ + $(CARGOFLAGS_$(target-stem).o)) _a_flags = $(filter-out $(AFLAGS_REMOVE_$(target-stem).o), \ $(filter-out $(asflags-remove-y), \ $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(asflags-y)) \ @@ -185,7 +195,8 @@ _cpp_flags += -I $(srctree)/$(src) -I $(objtree)/$(obj) endif endif -part-of-module = $(if $(filter $(basename $@).o, $(real-obj-m)),y) +# TODO: quick hack +part-of-module = $(if $(filter $(basename $@).o,$(real-obj-m)),y,$(and $(real-obj-m),$(shell echo $@ | sed -E 's!.+/out/lib.+\.a!y!;t;d'))) quiet_modtag = $(if $(part-of-module),[M], ) modkern_cflags = \ @@ -193,6 +204,16 @@ modkern_cflags = \ $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \ $(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL) $(modfile_flags)) +modkern_rustcflags = \ + $(if $(part-of-module), \ + $(KBUILD_RUSTCFLAGS_MODULE) $(RUSTCFLAGS_MODULE), \ + $(KBUILD_RUSTCFLAGS_KERNEL) $(RUSTCFLAGS_KERNEL)) + +modkern_cargoflags = \ + $(if $(part-of-module), \ + $(KBUILD_CARGOFLAGS_MODULE) $(CARGOFLAGS_MODULE), \ + $(KBUILD_CARGOFLAGS_KERNEL) $(CARGOFLAGS_KERNEL)) + modkern_aflags = $(if $(part-of-module), \ $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE), \ $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL)) @@ -202,6 +223,20 @@ c_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ $(_c_flags) $(modkern_cflags) \ $(basename_flags) $(modname_flags) +# Needed for the Rust bindings +# TODO: we unconditionally pass `KBUILD_CFLAGS_MODULE` to avoid having +# dual bindings, but ideally we should generate two set of bindings +RUST_BINDGEN_CFLAGS = $(c_flags) $(KBUILD_CFLAGS_MODULE) +export RUST_BINDGEN_CFLAGS + +rustc_flags = $(_rustc_flags) $(modkern_rustcflags) + +# Passed by cargo +RUSTFLAGS = $(rustc_flags) +export RUSTFLAGS + +cargo_flags = $(_cargo_flags) $(modkern_cargoflags) + a_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ $(_a_flags) $(modkern_aflags) -- cgit v1.2.3 From 0a99f235bd70ef6a8e5bed61e17f312b9839db56 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Tue, 8 Sep 2020 15:46:13 +0200 Subject: Remove arch/ blocker by passing CONFIG vars to emulate module_init fully Signed-off-by: Miguel Ojeda --- scripts/Makefile.lib | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'scripts/Makefile.lib') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 939062f389d3..a74898ff131a 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -229,7 +229,9 @@ c_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ RUST_BINDGEN_CFLAGS = $(c_flags) $(KBUILD_CFLAGS_MODULE) export RUST_BINDGEN_CFLAGS -rustc_flags = $(_rustc_flags) $(modkern_rustcflags) +rustc_cfg_flags = $(shell sed -nE 's/^(CONFIG_[^=]+)=(y|m)$$/--cfg \1/p' $(srctree)/include/config/auto.conf | xargs) + +rustc_flags = $(_rustc_flags) $(modkern_rustcflags) $(rustc_cfg_flags) # Passed by cargo RUSTFLAGS = $(rustc_flags) -- cgit v1.2.3