From f605720f44514a4a9b56d6b12e0ef3b30ce0b9bf Mon Sep 17 00:00:00 2001 From: Douglas Reis Date: Tue, 2 Jun 2026 10:57:41 +0100 Subject: [PATCH] nix: Add a FHS shell with the toolchain to build linux for mocha Signed-off-by: Douglas Reis --- flake.lock | 6 +- flake.nix | 36 ++++++- nix/CrossToolchain.cmake.in | 47 +++++++++ nix/cheri_toolchain.nix | 189 ++++++++++++++++++++++++++++++++++++ 4 files changed, 273 insertions(+), 5 deletions(-) create mode 100644 nix/CrossToolchain.cmake.in create mode 100644 nix/cheri_toolchain.nix diff --git a/flake.lock b/flake.lock index d57a66a94..29934e80a 100644 --- a/flake.lock +++ b/flake.lock @@ -88,11 +88,11 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1780410653, - "narHash": "sha256-GgjcPoL9ZDuasunwIP0I9JTkP2oGvoZ93Vzwbwz1ldI=", + "lastModified": 1780500542, + "narHash": "sha256-XKbtr82IfB5RXhBzWgsTnuZcS230Lq9NdFE13IM/Zi8=", "owner": "lowRISC", "repo": "lowrisc-nix", - "rev": "560d419c61cb216001f05db14ac64a310b64e4af", + "rev": "c134ded39dab6c6dc15ad4675a446269c12756ff", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 4c5f4e43f..96bc2adc9 100644 --- a/flake.nix +++ b/flake.nix @@ -72,6 +72,8 @@ }; ftditool-cli = inputs.ftditool.packages.${system}.default; + cheri-toolchain = pkgs.callPackage ./nix/cheri_toolchain.nix {inherit (lrPkgs) llvm_cheri;}; + commonPackages = with pkgs; [ bison cmake @@ -93,8 +95,8 @@ in { formatter = pkgs.alejandra; devShells = rec { - default = cheri; - cheri = pkgs.mkShell { + default = baremetal; + baremetal = pkgs.mkShell { name = "mocha-cheri"; nativeBuildInputs = commonPackages @@ -110,6 +112,36 @@ UV_PYTHON = pythonSet.python.interpreter; }; }; + linux = + (pkgs.buildFHSEnv { + name = "mocha-linux"; + targetPkgs = pkgs: + commonPackages + ++ (with pkgs; [ + cheri-toolchain.cheriStdenv.cc + autoconf + automake + bc + bison + bmake + byacc + flex + libarchive + libarchive.dev + libelf + libtool + pkg-config + zlib + zlib.dev + ]); + profile = '' + export HOSTCC="${pkgs.llvmPackages_21.clang}/bin/clang"; + export HOSTCXX="${pkgs.llvmPackages_21.clang}/bin/clang++"; + export HOSTLD="${pkgs.llvmPackages_21.lld}/bin/ld.lld"; + export LLVM=1 + export ARCH=riscv + ''; + }).env; }; apps = { diff --git a/nix/CrossToolchain.cmake.in b/nix/CrossToolchain.cmake.in new file mode 100644 index 000000000..6bd161b8a --- /dev/null +++ b/nix/CrossToolchain.cmake.in @@ -0,0 +1,47 @@ +# Copyright lowRISC contributors. +# +# SPDX-License-Identifier: MIT + +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR riscv64) + +set(CMAKE_C_COMPILER "@llvmCheri@/bin/clang") +set(CMAKE_C_COMPILER_TARGET "riscv64-linux-musl") +set(CMAKE_CXX_COMPILER "@llvmCheri@/bin/clang++") +set(CMAKE_CXX_COMPILER_TARGET "riscv64-linux-musl") +set(CMAKE_ASM_COMPILER "@llvmCheri@/bin/clang") +set(CMAKE_ASM_COMPILER_TARGET "riscv64-linux-musl") + +set(CMAKE_AR + "@llvmCheri@/bin/llvm-ar" + CACHE FILEPATH "ar") +set(CMAKE_RANLIB + "@llvmCheri@/bin/llvm-ranlib" + CACHE FILEPATH "ranlib") +set(CMAKE_NM + "@llvmCheri@/bin/llvm-nm" + CACHE FILEPATH "nm") +set(CMAKE_STRIP + "@llvmCheri@/bin/llvm-strip" + CACHE FILEPATH "strip") +set(CMAKE_LINKER + "@llvmCheri@/bin/ld.lld" + CACHE FILEPATH "linker") + +set(CHERI_COMMON_FLAGS + "-target riscv64-linux-musl -B@llvmCheri@/bin -march=rv64imafdczcherihybrid_zcherilevels -mabi=l64pc128d -mno-relax -Xclang -target-feature -Xclang +cheri-bounded-vararg -Xclang -target-feature -Xclang +cheri-bounded-memarg-caller -Xclang -target-feature -Xclang +cheri-bounded-memarg-callee -isystem @linuxHeadersPurecap@/usr/include -ggdb -gz -Wno-error=unused-command-line-argument -ffreestanding -Werror=implicit-function-declaration -Werror=format -Werror=incompatible-pointer-types -Werror=cheri-capability-misuse -Werror=cheri-bitwise-operations -Werror=pass-failed -Werror=cheri-prototypes -Werror=undefined-internal" +) + +set(CHERI_LINKER_FLAGS "${CHERI_COMMON_FLAGS} -fuse-ld=lld") + +set(CMAKE_C_FLAGS_INIT "${CHERI_COMMON_FLAGS}") +set(CMAKE_CXX_FLAGS_INIT "${CHERI_COMMON_FLAGS}") +set(CMAKE_ASM_FLAGS_INIT "${CHERI_COMMON_FLAGS}") +set(CMAKE_EXE_LINKER_FLAGS_INIT "${CHERI_LINKER_FLAGS}") +set(CMAKE_SHARED_LINKER_FLAGS_INIT "${CHERI_LINKER_FLAGS}") +set(CMAKE_MODULE_LINKER_FLAGS_INIT "${CHERI_LINKER_FLAGS}") + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) diff --git a/nix/cheri_toolchain.nix b/nix/cheri_toolchain.nix new file mode 100644 index 000000000..512cb12c2 --- /dev/null +++ b/nix/cheri_toolchain.nix @@ -0,0 +1,189 @@ +# Copyright lowRISC contributors. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +{ + lib, + stdenv, + gnumake, + cmake, + rsync, + fetchFromGitHub, + llvm_cheri, + pkgsCross, +}: rec { + linux-headers-purecap = stdenv.mkDerivation { + pname = "linux-headers-purecap"; + version = "6.18"; + + src = fetchFromGitHub { + owner = "CHERI-Alliance"; + repo = "linux"; + rev = "af04d488044fa684760d6480f3623e51b46568ca"; + fetchSubmodules = true; + hash = "sha256-Gjjs+vV0meFHOAt9i88WMzpFEq8IZ1oXDFVXb7ZuLI8="; + }; + + nativeBuildInputs = [ + gnumake + rsync + ]; + + dontConfigure = true; + dontBuild = true; + + installPhase = '' + runHook preInstall + + make -j$NIX_BUILD_CORES headers_install \ + ARCH=riscv \ + INSTALL_HDR_PATH=$out/usr + + runHook postInstall + ''; + + meta = { + description = "CHERI RISC-V 64 purecap Linux kernel (codasip-cheri-riscv-6.18)"; + platforms = ["x86_64-linux"]; + }; + }; + + muslc-linux-riscv64-purecap = stdenv.mkDerivation { + pname = "muslc-linux-riscv64-purecap"; + version = "std093"; + + src = fetchFromGitHub { + owner = "CHERI-Alliance"; + repo = "musl"; + rev = "12d15cddabcfb3f4f0612730f7147e7cf8c5579f"; + fetchSubmodules = true; + hash = "sha256-8cEUnBQSsWEUoe5gLR/3jFO3KwTddJOhDTDnNZgUIXQ="; + }; + + nativeBuildInputs = [ + gnumake + llvm_cheri + ]; + + dontConfigure = false; + + configurePhase = '' + runHook preConfigure + + # Dynamically fetch the resource dir + RESOURCE_DIR=$(${llvm_cheri}/bin/clang -print-resource-dir) + + ./configure \ + --prefix= \ + --disable-shared \ + CC="clang \ + -target riscv64-linux-musl \ + -march=rv64imafdczcherihybrid_zcherilevels \ + -mabi=l64pc128d \ + -mno-relax \ + -Xclang -target-feature -Xclang +cheri-bounded-vararg \ + -Xclang -target-feature -Xclang +cheri-bounded-memarg-caller \ + -Xclang -target-feature -Xclang +cheri-bounded-memarg-callee \ + -idirafter $RESOURCE_DIR/include" + + runHook postConfigure + ''; + + installPhase = '' + runHook preInstall + + make install-headers DESTDIR=$out + make install-libs DESTDIR=$out + + runHook postInstall + ''; + + dontFixup = true; + }; + + compiler-rt-builtins-purecap = stdenv.mkDerivation { + pname = "compiler-rt-builtins-purecap"; + version = "std093"; + + src = llvm_cheri.src; + sourceRoot = "source/compiler-rt/lib/builtins"; + + nativeBuildInputs = [ + cmake + llvm_cheri + ]; + + llvmCheri = llvm_cheri; + linuxHeadersPurecap = linux-headers-purecap; + + preConfigure = '' + substituteAll ${./CrossToolchain.cmake.in} CrossToolchain.cmake + ''; + + cmakeFlags = [ + "--toolchain=../CrossToolchain.cmake" + (lib.cmakeFeature "CMAKE_BUILD_TYPE" "RelWithDebInfo") + (lib.cmakeFeature "LLVM_CONFIG_PATH" "NOTFOUND") + (lib.cmakeBool "CMAKE_DISABLE_FIND_PACKAGE_LLVM" true) + (lib.cmakeBool "COMPILER_RT_EXCLUDE_ATOMIC_BUILTIN" false) + (lib.cmakeBool "COMPILER_RT_BAREMETAL_BUILD" false) + (lib.cmakeBool "COMPILER_RT_DEFAULT_TARGET_ONLY" true) + (lib.cmakeFeature "TARGET_TRIPLE" "riscv64-linux-musl") + (lib.cmakeFeature "CMAKE_SYSROOT" "${muslc-linux-riscv64-purecap}") + (lib.cmakeBool "COMPILER_RT_DEBUG" true) + (lib.cmakeFeature "CMAKE_C_COMPILER" "${llvm_cheri}/bin/clang") + (lib.cmakeFeature "CMAKE_CXX_COMPILER" "${llvm_cheri}/bin/clang++") + (lib.cmakeFeature "CMAKE_ASM_COMPILER" "${llvm_cheri}/bin/clang") + ]; + + postInstall = '' + mkdir -p $out/lib + + ln -fsn $out/lib/linux/libclang_rt.builtins-riscv64.a $out/lib/libclang_rt.builtins-riscv64.a + ln -fsn $out/lib/linux/libclang_rt.builtins-riscv64.a $out/lib/libgcc.a + + ln -fsn $out/lib/linux/clang_rt.crtbegin-riscv64.o $out/lib/crtbeginT.o + ln -fsn $out/lib/linux/clang_rt.crtbegin-riscv64.o $out/lib/crtbeginS.o + ln -fsn $out/lib/linux/clang_rt.crtend-riscv64.o $out/lib/crtend.o + ln -fsn $out/lib/linux/clang_rt.crtend-riscv64.o $out/lib/crtendS.o + ''; + + dontFixup = true; + }; + + cheriBintools = pkgsCross.riscv64.wrapBintoolsWith { + bintools = llvm_cheri; + libc = muslc-linux-riscv64-purecap; + coreutils = pkgsCross.riscv64.buildPackages.coreutils; + extraBuildCommands = '' + for tool in ar as nm objcopy objdump ranlib readelf size strings strip; do + # Link bare names: llvm-nm -> nm + if [ -x "$out/bin/$tool" ]; then + ln -s "$tool" "$out/bin/llvm-$tool" + fi + done + ''; + }; + + cheriCC = pkgsCross.riscv64.wrapCCWith { + cc = llvm_cheri; + bintools = cheriBintools; + libc = muslc-linux-riscv64-purecap; + extraBuildCommands = '' + echo "-isystem ${linux-headers-purecap}/usr/include" >> $out/nix-support/cc-cflags + echo "-B${compiler-rt-builtins-purecap}/lib" >> $out/nix-support/cc-cflags + echo "-L${compiler-rt-builtins-purecap}/lib" >> $out/nix-support/cc-ldflags + ''; + }; + + cheriStdenv = pkgsCross.riscv64.stdenv.override { + cc = cheriCC; + allowedRequisites = null; + + targetPlatform = + stdenv.targetPlatform + // { + config = "riscv64-linux-musl"; + libc = "musl"; + }; + }; +}