Documentation/rust/arch-support.rst | 2 +- arch/riscv/Kconfig | 30 +++++++++++++++++++++++++++++- init/Kconfig | 6 ++++++ rust/Makefile | 7 ++++++- scripts/Kconfig.include | 1 + 5 files changed, 43 insertions(+), 3 deletions(-)
Commit 33549fcf37ec ("RISC-V: disallow gcc + rust builds") disabled GCC
+ Rust builds for RISC-V due to differences in extension handling
compared to LLVM.
Add a Kconfig symbol to indicate the version of libclang used by Rust
bindgen and add conditions for the availability of libclang to the
RISC-V extension Kconfig symbols that depend on the cc-option function.
For Zicsr/Zifencei special handling, since LLVM/Clang always enables
these two extensions, either don't pass them to -march, or pass them
explicitly and Rust bindgen libclang must recognize them.
Clang does not support -mno-riscv-attribute flag, filter it out to
resolve error: unknown argument: '-mno-riscv-attribute'.
Define BINDGEN_TARGET_riscv to pass the target triplet to Rust bindgen
libclang for RISC-V to resolve error: unsupported argument 'medany' to
option '-mcmodel=' for target 'unknown'. Improve to output a clearer
error message if the target triplet is undefined for Rust bindgen
libclang.
Update the documentation, GCC + Rust builds are now supported.
---
Discussion:
https://lore.kernel.org/linux-riscv/68496eed-b5a4-4739-8d84-dcc428a08e20@gmail.com/
Patch v1:
https://lore.kernel.org/linux-riscv/20250903190806.2604757-1-SpriteOvO@gmail.com/
GCC + Rust builds for RISC-V are disabled about a year ago due to differences in
extension handling compared to LLVM, as discussed in
https://lore.kernel.org/all/20240917000848.720765-1-jmontleo@redhat.com/
This patch re-enables GCC + Rust builds. Compared to v1, v2 reverts the
separation of get-rust-bindgen-libclang script and improves Kconfig conditions
based on Conor's review.
The separation of get-rust-bindgen-libclang script is reverted based on the
concerns raised by Miguel. However, it's worth noting that we now have 3
different places rust/Makefile scripts/{Kconfig.include,rust_is_avilable.sh}
where manually calling bindgen rust_is_available_bindgen_libclang.h + sed to get
the version of libclang, and in particular, for our newly added Kconfig symbol,
we now use awk to canonicalize the version to an integer. I would still like to
do the script separation later for better maintainability and readability if
possible, which can be discussed further later when Miguel has time.
Signed-off-by: Asuna Yang <SpriteOvO@gmail.com>
---
Documentation/rust/arch-support.rst | 2 +-
arch/riscv/Kconfig | 30 +++++++++++++++++++++++++++++-
init/Kconfig | 6 ++++++
rust/Makefile | 7 ++++++-
scripts/Kconfig.include | 1 +
5 files changed, 43 insertions(+), 3 deletions(-)
diff --git a/Documentation/rust/arch-support.rst b/Documentation/rust/arch-support.rst
index 6e6a515d08991a130a8e79dc4ad7ad09da244020..5282e0e174e8de66b4c6fec354cf329fd2aec873 100644
--- a/Documentation/rust/arch-support.rst
+++ b/Documentation/rust/arch-support.rst
@@ -18,7 +18,7 @@ Architecture Level of support Constraints
``arm`` Maintained ARMv7 Little Endian only.
``arm64`` Maintained Little Endian only.
``loongarch`` Maintained \-
-``riscv`` Maintained ``riscv64`` and LLVM/Clang only.
+``riscv`` Maintained ``riscv64`` only.
``um`` Maintained \-
``x86`` Maintained ``x86_64`` only.
============= ================ ==============================================
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 51dcd8eaa24356d947ebe0f1c4a701a3cfc6b757..3e892864f930778218073e8ee5980eb8f4e1594a 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -191,7 +191,7 @@ config RISCV
select HAVE_REGS_AND_STACK_ACCESS_API
select HAVE_RETHOOK if !XIP_KERNEL
select HAVE_RSEQ
- select HAVE_RUST if RUSTC_SUPPORTS_RISCV && CC_IS_CLANG
+ select HAVE_RUST if RUSTC_SUPPORTS_RISCV && TOOLCHAIN_MATCHES_ZICSR_ZIFENCEI
select HAVE_SAMPLE_FTRACE_DIRECT
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
select HAVE_STACKPROTECTOR
@@ -629,6 +629,8 @@ config TOOLCHAIN_HAS_V
depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32imv)
depends on LLD_VERSION >= 140000 || LD_VERSION >= 23800
depends on AS_HAS_OPTION_ARCH
+ # https://github.com/llvm/llvm-project/commit/e6de53b4de4aecca4ac892500a0907805896ed27
+ depends on !RUST || RUST_BINDGEN_LIBCLANG_VERSION >= 140000
config RISCV_ISA_V
bool "Vector extension support"
@@ -693,6 +695,8 @@ config TOOLCHAIN_HAS_ZABHA
depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64ima_zabha)
depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zabha)
depends on AS_HAS_OPTION_ARCH
+ # https://github.com/llvm/llvm-project/commit/6b7444964a8d028989beee554a1f5c61d16a1cac
+ depends on !RUST || RUST_BINDGEN_LIBCLANG_VERSION >= 190100
config RISCV_ISA_ZABHA
bool "Zabha extension support for atomic byte/halfword operations"
@@ -711,6 +715,8 @@ config TOOLCHAIN_HAS_ZACAS
depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64ima_zacas)
depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zacas)
depends on AS_HAS_OPTION_ARCH
+ # https://github.com/llvm/llvm-project/commit/614aeda93b2225c6eb42b00ba189ba7ca2585c60
+ depends on !RUST || RUST_BINDGEN_LIBCLANG_VERSION >= 200100
config RISCV_ISA_ZACAS
bool "Zacas extension support for atomic CAS"
@@ -730,6 +736,8 @@ config TOOLCHAIN_HAS_ZBB
depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zbb)
depends on LLD_VERSION >= 150000 || LD_VERSION >= 23900
depends on AS_HAS_OPTION_ARCH
+ # https://github.com/llvm/llvm-project/commit/33d008b169f3c813a4a45da220d0952f795ac477
+ depends on !RUST || RUST_BINDGEN_LIBCLANG_VERSION >= 140000
# This symbol indicates that the toolchain supports all v1.0 vector crypto
# extensions, including Zvk*, Zvbb, and Zvbc. LLVM added all of these at once.
@@ -745,6 +753,8 @@ config TOOLCHAIN_HAS_ZBA
depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zba)
depends on LLD_VERSION >= 150000 || LD_VERSION >= 23900
depends on AS_HAS_OPTION_ARCH
+ # https://github.com/llvm/llvm-project/commit/33d008b169f3c813a4a45da220d0952f795ac477
+ depends on !RUST || RUST_BINDGEN_LIBCLANG_VERSION >= 140000
config RISCV_ISA_ZBA
bool "Zba extension support for bit manipulation instructions"
@@ -780,6 +790,8 @@ config TOOLCHAIN_HAS_ZBC
depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zbc)
depends on LLD_VERSION >= 150000 || LD_VERSION >= 23900
depends on AS_HAS_OPTION_ARCH
+ # https://github.com/llvm/llvm-project/commit/33d008b169f3c813a4a45da220d0952f795ac477
+ depends on !RUST || RUST_BINDGEN_LIBCLANG_VERSION >= 140000
config RISCV_ISA_ZBC
bool "Zbc extension support for carry-less multiplication instructions"
@@ -803,6 +815,8 @@ config TOOLCHAIN_HAS_ZBKB
depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zbkb)
depends on LLD_VERSION >= 150000 || LD_VERSION >= 23900
depends on AS_HAS_OPTION_ARCH
+ # https://github.com/llvm/llvm-project/commit/7ee1c162cc53d37f717f9a138276ad64fa6863bc
+ depends on !RUST || RUST_BINDGEN_LIBCLANG_VERSION >= 140000
config RISCV_ISA_ZBKB
bool "Zbkb extension support for bit manipulation instructions"
@@ -890,6 +904,20 @@ config TOOLCHAIN_NEEDS_OLD_ISA_SPEC
versions of clang and GCC to be passed to GAS, which has the same result
as passing zicsr and zifencei to -march.
+config TOOLCHAIN_MATCHES_ZICSR_ZIFENCEI
+ def_bool y
+ # https://github.com/llvm/llvm-project/commit/22e199e6afb1263c943c0c0d4498694e15bf8a16
+ depends on TOOLCHAIN_NEEDS_OLD_ISA_SPEC || !TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI || RUST_BINDGEN_LIBCLANG_VERSION >= 170000
+ help
+ LLVM/Clang >= 17.0.0 starts recognizing Zicsr/Zifencei in -march, passing
+ them to -march doesn't generate an error anymore, and passing them or not
+ doesn't have any real difference, it still follows ISA before version
+ 20190608 - Zicsr/Zifencei are included in base ISA.
+
+ The current latest version of LLVM/Clang still does not require explicit
+ Zicsr/Zifencei to enable these two extensions, Clang just accepts them in
+ -march and then silently ignores them.
+
config FPU
bool "FPU support"
default y
diff --git a/init/Kconfig b/init/Kconfig
index e3eb63eadc8757a10b091c74bbee8008278c0521..0859d308a48591df769c7dbaef6f035324892bd3 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -82,6 +82,12 @@ config RUSTC_LLVM_VERSION
int
default $(rustc-llvm-version)
+config RUST_BINDGEN_LIBCLANG_VERSION
+ int
+ default $(rustc-bindgen-libclang-version)
+ help
+ This is the version of `libclang` used by the Rust bindings generator.
+
config CC_CAN_LINK
bool
default $(success,$(srctree)/scripts/cc-can-link.sh $(CC) $(CLANG_FLAGS) $(USERCFLAGS) $(USERLDFLAGS) $(m64-flag)) if 64BIT
diff --git a/rust/Makefile b/rust/Makefile
index bfa915b0e58854045b367557342727fee4fe2808..8c6f84487c41880816d1e55ba4c0df0e5af4e8fd 100644
--- a/rust/Makefile
+++ b/rust/Makefile
@@ -290,20 +290,25 @@ bindgen_skip_c_flags := -mno-fp-ret-in-387 -mpreferred-stack-boundary=% \
-fno-inline-functions-called-once -fsanitize=bounds-strict \
-fstrict-flex-arrays=% -fmin-function-alignment=% \
-fzero-init-padding-bits=% -mno-fdpic \
- --param=% --param asan-%
+ --param=% --param asan-% -mno-riscv-attribute
# Derived from `scripts/Makefile.clang`.
BINDGEN_TARGET_x86 := x86_64-linux-gnu
BINDGEN_TARGET_arm64 := aarch64-linux-gnu
BINDGEN_TARGET_arm := arm-linux-gnueabi
BINDGEN_TARGET_loongarch := loongarch64-linux-gnusf
+BINDGEN_TARGET_riscv := riscv64-linux-gnu
BINDGEN_TARGET_um := $(BINDGEN_TARGET_$(SUBARCH))
BINDGEN_TARGET := $(BINDGEN_TARGET_$(SRCARCH))
+ifeq ($(BINDGEN_TARGET),)
+$(error add '--target=' option to rust/Makefile)
+else
# All warnings are inhibited since GCC builds are very experimental,
# many GCC warnings are not supported by Clang, they may only appear in
# some configurations, with new GCC versions, etc.
bindgen_extra_c_flags = -w --target=$(BINDGEN_TARGET)
+endif
# Auto variable zero-initialization requires an additional special option with
# clang that is going to be removed sometime in the future (likely in
diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include
index 33193ca6e8030e659d6b321acaea1acd42c387a4..00462b29030515fcaaa49613e87e2a33320468ae 100644
--- a/scripts/Kconfig.include
+++ b/scripts/Kconfig.include
@@ -67,6 +67,7 @@ m64-flag := $(cc-option-bit,-m64)
rustc-version := $(shell,$(srctree)/scripts/rustc-version.sh $(RUSTC))
rustc-llvm-version := $(shell,$(srctree)/scripts/rustc-llvm-version.sh $(RUSTC))
+rustc-bindgen-libclang-version := $(shell,$(BINDGEN) $(srctree)/scripts/rust_is_available_bindgen_libclang.h 2>&1 | sed -nE 's:.*clang version ([0-9]+\.[0-9]+\.[0-9]+).*:\1:p' | awk -F'.' '{print $1 * 10000 + $2 * 100 + $3}')
# $(rustc-option,<flag>)
# Return y if the Rust compiler supports <flag>, n otherwise
---
base-commit: f777d1112ee597d7f7dd3ca232220873a34ad0c8
change-id: 20250909-gcc-rust-v2-7084003bc619
Best regards,
--
Asuna Yang <SpriteOvO@gmail.com>
On Tue, Sep 09, 2025 at 06:53:11PM +0200, Asuna Yang wrote: > Commit 33549fcf37ec ("RISC-V: disallow gcc + rust builds") disabled GCC > + Rust builds for RISC-V due to differences in extension handling > compared to LLVM. > > Add a Kconfig symbol to indicate the version of libclang used by Rust > bindgen and add conditions for the availability of libclang to the > RISC-V extension Kconfig symbols that depend on the cc-option function. > > For Zicsr/Zifencei special handling, since LLVM/Clang always enables > these two extensions, either don't pass them to -march, or pass them > explicitly and Rust bindgen libclang must recognize them. > > Clang does not support -mno-riscv-attribute flag, filter it out to > resolve error: unknown argument: '-mno-riscv-attribute'. > > Define BINDGEN_TARGET_riscv to pass the target triplet to Rust bindgen > libclang for RISC-V to resolve error: unsupported argument 'medany' to > option '-mcmodel=' for target 'unknown'. Improve to output a clearer > error message if the target triplet is undefined for Rust bindgen > libclang. > > Update the documentation, GCC + Rust builds are now supported. > > --- FWIW, this --- breaks git, and anything after this line (including your signoff) is lost when the patch is applied. > Discussion: > https://lore.kernel.org/linux-riscv/68496eed-b5a4-4739-8d84-dcc428a08e20@gmail.com/ > Patch v1: > https://lore.kernel.org/linux-riscv/20250903190806.2604757-1-SpriteOvO@gmail.com/ > > GCC + Rust builds for RISC-V are disabled about a year ago due to differences in > extension handling compared to LLVM, as discussed in > https://lore.kernel.org/all/20240917000848.720765-1-jmontleo@redhat.com/ > > This patch re-enables GCC + Rust builds. Compared to v1, v2 reverts the > separation of get-rust-bindgen-libclang script and improves Kconfig conditions > based on Conor's review. > > The separation of get-rust-bindgen-libclang script is reverted based on the > concerns raised by Miguel. However, it's worth noting that we now have 3 > different places rust/Makefile scripts/{Kconfig.include,rust_is_avilable.sh} > where manually calling bindgen rust_is_available_bindgen_libclang.h + sed to get > the version of libclang, and in particular, for our newly added Kconfig symbol, > we now use awk to canonicalize the version to an integer. I would still like to > do the script separation later for better maintainability and readability if > possible, which can be discussed further later when Miguel has time. > > Signed-off-by: Asuna Yang <SpriteOvO@gmail.com> > diff --git a/init/Kconfig b/init/Kconfig > index e3eb63eadc8757a10b091c74bbee8008278c0521..0859d308a48591df769c7dbaef6f035324892bd3 100644 > --- a/init/Kconfig > +++ b/init/Kconfig > @@ -82,6 +82,12 @@ config RUSTC_LLVM_VERSION > int > default $(rustc-llvm-version) > > +config RUST_BINDGEN_LIBCLANG_VERSION > + int > + default $(rustc-bindgen-libclang-version) > + help > + This is the version of `libclang` used by the Rust bindings generator. The riscv patchwork CI stuff is really unhappy with this change: init/Kconfig:87: syntax error init/Kconfig:87: invalid statement init/Kconfig:88: invalid statement init/Kconfig:89:warning: ignoring unsupported character '`' init/Kconfig:89:warning: ignoring unsupported character '`' init/Kconfig:89:warning: ignoring unsupported character '.' init/Kconfig:89: unknown statement "This" Is this bogus, or can rustc-bindgen-libclang-version return nothing under some conditions where rust is not available? Should this have 2 default lines like some other options in the file?
On Wed, Sep 10, 2025 at 03:27:19PM +0100, Conor Dooley wrote: > On Tue, Sep 09, 2025 at 06:53:11PM +0200, Asuna Yang wrote: > > Commit 33549fcf37ec ("RISC-V: disallow gcc + rust builds") disabled GCC > > + Rust builds for RISC-V due to differences in extension handling > > compared to LLVM. > > > > Add a Kconfig symbol to indicate the version of libclang used by Rust > > bindgen and add conditions for the availability of libclang to the > > RISC-V extension Kconfig symbols that depend on the cc-option function. > > > > For Zicsr/Zifencei special handling, since LLVM/Clang always enables > > these two extensions, either don't pass them to -march, or pass them > > explicitly and Rust bindgen libclang must recognize them. > > > > Clang does not support -mno-riscv-attribute flag, filter it out to > > resolve error: unknown argument: '-mno-riscv-attribute'. > > > > Define BINDGEN_TARGET_riscv to pass the target triplet to Rust bindgen > > libclang for RISC-V to resolve error: unsupported argument 'medany' to > > option '-mcmodel=' for target 'unknown'. Improve to output a clearer > > error message if the target triplet is undefined for Rust bindgen > > libclang. > > > > Update the documentation, GCC + Rust builds are now supported. > > > > --- > > FWIW, this --- breaks git, and anything after this line (including your > signoff) is lost when the patch is applied. FTR, there is good documentation about '---' in patch mails: https://docs.kernel.org/process/submitting-patches.html#commentary Kind regards, Nicolas
On 9/10/25 10:27 PM, Conor Dooley wrote: > FWIW, this --- breaks git, and anything after this line (including your > signoff) is lost when the patch is applied. I used b4 command to prepare and send the cover letter and patch for v2, not sure what happened. I see that other people's patches have a [PATCH 0/n] email as a start that describes their patch series, this is called a cover-letter in b4 and git-send-email right? > The riscv patchwork CI stuff is really unhappy with this change: > init/Kconfig:87: syntax error > init/Kconfig:87: invalid statement > init/Kconfig:88: invalid statement > init/Kconfig:89:warning: ignoring unsupported character '`' > init/Kconfig:89:warning: ignoring unsupported character '`' > init/Kconfig:89:warning: ignoring unsupported character '.' > init/Kconfig:89: unknown statement "This" > > Is this bogus, or can rustc-bindgen-libclang-version return nothing > under some conditions where rust is not available? > Should this have 2 default lines like some other options in the file? This is because rustc-bindgen-libclang-version can't find the bindgen and returns nothing. Sorry I forgot to mention this, it's another reason why I wanted to separate the script, in a separate script we can easily fallback to return 0 when an error is encountered. Adding a second line `default 0` doesn't work, I'll try to fix it. BTW, when I fix it, if the diff isn't too large, do I need to open a v3 patch, or simply replying to the thread just fine?
On Thu, Sep 11, 2025 at 12:46:01PM +0800, Asuna wrote: > On 9/10/25 10:27 PM, Conor Dooley wrote: > > FWIW, this --- breaks git, and anything after this line (including your > > signoff) is lost when the patch is applied. > > I used b4 command to prepare and send the cover letter and patch for v2, not > sure what happened. Dunno. Maybe while editing your commit message you omitted the signoff somehow? I don't use b4-submit, so I don't know how it formats stuff. If it inserted the --- and what was below it was your intended cover letter, your patch itself might be missing the signoff? > > I see that other people's patches have a [PATCH 0/n] email as a start that > describes their patch series, this is called a cover-letter in b4 and > git-send-email right? Yes it is. Not really needed if you only have one patch though. > > The riscv patchwork CI stuff is really unhappy with this change: > > init/Kconfig:87: syntax error > > init/Kconfig:87: invalid statement > > init/Kconfig:88: invalid statement > > init/Kconfig:89:warning: ignoring unsupported character '`' > > init/Kconfig:89:warning: ignoring unsupported character '`' > > init/Kconfig:89:warning: ignoring unsupported character '.' > > init/Kconfig:89: unknown statement "This" > > > > Is this bogus, or can rustc-bindgen-libclang-version return nothing > > under some conditions where rust is not available? > > Should this have 2 default lines like some other options in the file? > > This is because rustc-bindgen-libclang-version can't find the bindgen and > returns nothing. Sorry I forgot to mention this, it's another reason why I > wanted to separate the script, in a separate script we can easily fallback > to return 0 when an error is encountered. > > Adding a second line `default 0` doesn't work, I'll try to fix it. BTW, when > I fix it, if the diff isn't too large, do I need to open a v3 patch, or > simply replying to the thread just fine? Feel free to reply with the diff if you're looking to discuss the implantation, but for the sake of the various bits of automation (patchwork, ci bots etc) please submit a v3 when you're happy with what you've produced.
On Tue, Sep 9, 2025 at 6:55 PM Asuna Yang <spriteovo@gmail.com> wrote: > > The separation of get-rust-bindgen-libclang script is reverted based on the > concerns raised by Miguel. However, it's worth noting that we now have 3 > different places rust/Makefile scripts/{Kconfig.include,rust_is_avilable.sh} > where manually calling bindgen rust_is_available_bindgen_libclang.h + sed to get > the version of libclang, and in particular, for our newly added Kconfig symbol, > we now use awk to canonicalize the version to an integer. I would still like to > do the script separation later for better maintainability and readability if > possible, which can be discussed further later when Miguel has time. To clarify, since this probably targets the next cycle, there is time to discuss and get feedback to do whatever we feel it is best (personally, I can take a look after Kangrejos at some point). Is there a particular rush for this? Having said that, this v2 looks substantially simpler than v1, which is nice, and perhaps RISC-V wants to land it already. Up to them in that case. (I see the `ifeq ($(BINDGEN_TARGET),)` is still there -- in general I would suggest splitting things if they don't depend on each other, but it is not a huge deal. I would also probably have split the `rustc-bindgen-libclang-version` into its own, but at least that is a dependency). Thanks! Cheers, Miguel
On 9/10/25 1:12 AM, Miguel Ojeda wrote: > To clarify, since this probably targets the next cycle, there is time > to discuss and get feedback to do whatever we feel it is best > (personally, I can take a look after Kangrejos at some point). Is > there a particular rush for this? Nah, no rush, as long as it works so that RISC-V distros can deliver Rust-based components, that's the main issue I'm trying to address.
© 2016 - 2025 Red Hat, Inc.