How to build a cross-compiler package with multiple derivations (clang and runtime libraries)

Hi,

I have been working on building a cross-compiler using Clang and LLVM, designed to compile RISC-V executables on an x86 host machine.

When building it manually, I could build the Clang+LLVM cross-compiler first and use the cross-compiler to build the RISC-V runtime libraries and install it alongside LLVM so that Clang could find them.

When building it with Nix, I defined 3 separate derivations for Clang+LLVM, compiler-rt, and newlib and used symlinkJoin to put them into the same directory structure. However, despite being placed together, Clang failed to find the runtime libraries since the search path was configured during the configurePhase using CMake, which only included the output path of the Clang+LLVM derivation.

$ ls /nix/store/wd5...lqq-clang  # clang only searches this path for runtime libraries
bin  include  lib  libexec  share
$ ls /nix/store/07m...lwv-compiler-rt  # compiled with clang
include  lib
$ ls /nix/store/92i...51g-newlib  # also compiled with clang
riscv64-unknown-elf  share
$ ls `readlink result` # the result of symlinkJoin, but clang won't know runtime libraries are here.
bin  include  lib  libexec  riscv64-unknown-elf  share

Is it possible to install the runtime libraries directly into Clang’s output path? Alternatively, could I install Clang at the location where the runtime libraries are intended to be placed? Or perhaps there’s a better approach to achieve this that I should consider?

Any help or suggestion would be appreciated!

You should be able to override the buildInputs of clang and add the library to it.
like so:

pkgs.clang.override {buildInputs=[libxml2 libllvm <your lib here>]}

That being said i feel nixpkgs is currently astonishingly lacking in cross compilers for risc-v, maybe i should look into packaging them (or someone else who is motivated enough).

1 Like

Thanks @zimward for your reply! I actually have a custom configuration for Clang (llvm-clang.nix), not the one provided by Nixpkgs. But I managed to install the runtime libraries with Clang in the same derivation using the override method.

{ callPackage
}:

let
  llvm-clang = callPackage ./llvm-clang.nix { };
  compiler-rt = callPackage ./compiler-rt.nix {
    inherit llvm-clang;
  };
  newlib = callPackage ./newlib.nix {
    inherit llvm-clang;
  };
in
llvm-clang.override {
  inherit compiler-rt newlib;
}

In the llvm-clang.nix file, I verified if the compiler-rt and newlib packages are available. If they are, I added them to the buildInputs and linked them to the output directory.