I am having a hard time building a derivation with make, not finding the necessary files. I have no issue compiling from a developer shell, so definitely not an issue with ill-formed paths in the Makefile
. It must be something obvious that I cannot grasp. Here are the relevant parts of my flake.nix:
{
inputs.nixpkgs.url = "github:NixOS/nixpkgs";
outputs = { self, nixpkgs }:
let
system = "x86_64-linux";
pkgs = import nixpkgs { inherit system; };
riscv-toolchain = import nixpkgs {
localSystem = system;
crossSystem = {
config = "riscv32-none-elf";
libc = "newlib-nano";
abi = "ilp32";
};
};
fe310-toolchain = riscv-toolchain.stdenv.mkDerivation {
name = "riscv-fe310-firmware";
src = ./.;
buildInputs = with pkgs; [
riscv-toolchain.buildPackages.gcc
];
buildPhase = ''
make -f fw/fe310/Makefile
'';
installPhase = ''
mkdir -p $out
cp -rv . $out
'';
};
in
{
packages = {
x86_64-linux = {
fe310 = fe310-toolchain;
};
};
};
}
Which gives me the following error:
> fw/fe310/Makefile:5: /crypto/crypto_obj.mk: No such file or directory
> make: *** No rule to make target '/crypto/crypto_obj.mk'. Stop.
Whereas the file crypto_obj.mk
lives in the directory ./ext/crypto/
, the Makefile
is located in ./fw/fe310/
. The location of crypto_obj.mk
is set with crypto_dir = $(ext_dir)/crypto
on the Makefile
then $(ext_dir)
with ext_dir := $(abspath $(fe310_dir)/../../ext)
and $(fe310_dir)
with fe310_dir := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
on common.mk
. Again, this does not pose any problem when using a developer shell.
I get the exact same error when specifying the path to the Makefile with the makefile
attribute and leaving the default values for each phase intact:
fe310-toolchain = riscv-toolchain.stdenv.mkDerivation {
name = "riscv-fe310-firmware";
src = ./.;
makefile = [ "fw/fe310/Makefile" ];
buildInputs = with pkgs; [
riscv-toolchain.buildPackages.gcc
];
I finally tried moving the source tree to $out
, prefixing all necessary paths with $out
, just for the sake of testing them, and that seems to do the trick:
dontInstall = true;
configurePhase = ''
export fe310_dir=$out/fw/fe310
export ext_dir=$out/ext
export ecp_dir=$out/ecp
mkdir -p $out
cp -rv . $out
'';
buildPhase = ''
make -f $out/fw/fe310/Makefile
'';
Then on the Makefile
I apend $(fe310_dir)
where relevant:
include $(fe310_dir)/common.mk
...
subdirs = $(fe310_dir)/bsp/drivers $(fe310_dir)/bsp/gloss $(fe310_dir)/bsp/metal $(fe310_dir)/eos $(fe310_dir)/eos/i2c $(fe310_dir)/eos/eve $(fe310_dir)/eos/eve/screen $(fe310_dir)/eos/eve/widget $(ext_dir)/fsfat
However, there must be a better way to do this, one that frees me from touching the Makefile
.
The source tree and Makefile can be found here. Any hint much appreciated!