Skip to content

Commit

Permalink
[DO NOT MERGE] nix-based build system!
Browse files Browse the repository at this point in the history
  • Loading branch information
nbdd0121 committed Jan 11, 2024
1 parent 7abf2d6 commit 05a4d3f
Show file tree
Hide file tree
Showing 5 changed files with 261 additions and 0 deletions.
8 changes: 8 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@
];
};
in {
legacyPackages.sw = let
rules = import ./rules {inherit pkgs;};
common = pkgs.callPackage sw/c/common {inherit rules;};
demo = pkgs.callPackage sw/c/demo {inherit rules common;};
in {
inherit common demo;
};

devShells.default = pkgs.mkShellNoCC {
name = "labenv";
buildInputs = with pkgs; [
Expand Down
175 changes: 175 additions & 0 deletions rules/cc.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
{
pkgs,
lib,
stdenv,
toolchain ? {
cc = "/no-toolchain-defined";
cflags = [];
ld = "/no-toolchain-defined";
ldflags = [];
asm = "/no-toolchain-defined";
asmflags = [];
},
}: let
include = {
src,
deps ? [],
}:
pkgs.runCommandLocal (builtins.baseNameOf src) {} ''
mkdir -p $out/include
ARGS=()
for dep in $deps; do
if [ -d $dep/include ]; then
ln -s $src/include/* $out/include/
fi
done
ln -s ${src} $out/include/${builtins.baseNameOf src}
'';

# If a raw file path is specified, turn that into a header derivation.
autowrap_header = f:
if !(builtins.isPath f)
then f
else if lib.hasSuffix ".h" f
then include {src = f;}
else throw "unknown file type: ${f}";

# Turn all raw file paths into derivations.
# Files will be grouped so that source files can depend on header files.
autowrap_deps = deps: let
src = builtins.filter (f: builtins.isPath f && !(lib.hasSuffix ".h" f)) deps;
other = builtins.filter (f: !(builtins.isPath f) || lib.hasSuffix ".h" f) deps;
wrapped = map autowrap_header other;
src_drv =
map (
f:
if lib.hasSuffix ".S" f
then
asm {
src = f;
deps = wrapped;
}
else if lib.hasSuffix ".c" f
then
object {
src = f;
deps = wrapped;
}
else throw "unknown file type: ${f}"
)
src;
in
src_drv ++ wrapped;

asm = {
src,
deps ? [],
extra-asmflags ? [],
asmflags ? toolchain.asmflags ++ extra-asmflags,
}:
stdenv.mkDerivation {
name = (lib.removeSuffix ".S" (builtins.baseNameOf src)) + ".o";
inherit src asmflags;
inherit (toolchain) asm;
deps = autowrap_deps deps;
dontUnpack = true;
buildPhase = ''
ARGS=()
for dep in $deps; do
if [ -d $dep/include ]; then
ARGS+=(-I$dep/include)
fi
done
mkdir -p $out/obj
$asm $asmflags -c -o $out/obj/$name $src ''${ARGS[@]}
'';
};

object = {
src,
deps ? [],
extra-cflags ? [],
cflags ? toolchain.cflags ++ extra-cflags,
}:
stdenv.mkDerivation {
name = (lib.removeSuffix ".c" (builtins.baseNameOf src)) + ".o";
inherit src cflags;
inherit (toolchain) cc;
deps = autowrap_deps deps;
dontUnpack = true;
buildPhase = ''
ARGS=()
for dep in $deps; do
if [ -d $dep/include ]; then
ARGS+=(-I$dep/include)
fi
done
mkdir -p $out/obj
$cc $cflags -c -o $out/obj/$name $src ''${ARGS[@]}
'';
};

static = {
name,
deps,
}:
stdenv.mkDerivation {
inherit name;
srcs = autowrap_deps deps;
dontUnpack = true;
buildPhase = ''
ARGS=()
for src in $srcs; do
if [ -d $src/obj ]; then
ARGS+=($src/obj/*)
fi
if [ -d $src/include ]; then
mkdir -p $out/include
ln -s $src/include/* $out/include/
fi
done
mkdir -p $out/lib
ar rcs $out/lib/$name ''${ARGS[@]}
'';
};

binary = {
name,
deps ? [],
extra-ldflags ? [],
ldflags ? toolchain.ldflags ++ extra-ldflags,
}:
stdenv.mkDerivation {
inherit name ldflags;
inherit (toolchain) ld;
srcs = autowrap_deps deps;
dontUnpack = true;
buildPhase = ''
ARGS=()
for src in $srcs; do
if [ -d $src/obj ]; then
ARGS+=($src/obj/*)
fi
if [ -d $src/lib ]; then
ARGS+=($src/lib/*)
fi
done
mkdir -p $out/bin
$ld $ldflags -o $out/bin/$name ''${ARGS[@]}
'';
};

set = deps:
pkgs.symlinkJoin {
name = "";
paths = autowrap_deps deps;
};
in {
inherit asm include object static binary set;
}
3 changes: 3 additions & 0 deletions rules/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{pkgs}: {
cc = pkgs.callPackage ./cc.nix {};
}
64 changes: 64 additions & 0 deletions sw/c/common/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
rules,
pkgs,
lowrisc-toolchain-gcc-rv32imcb,
}: let
toolchain = rec {
cc = "${lowrisc-toolchain-gcc-rv32imcb}/bin/riscv32-unknown-elf-gcc";
cflags = ["-march=rv32imc" "-mabi=ilp32" "-mcmodel=medany" "-Wall" "-fvisibility=hidden" "-ffreestanding"];
ld = cc;
ldflags = ["-nostartfiles" "-T" "${../../common/link.ld}"];
asm = cc;
asmflags = ["-march=rv32imc"];
};

rules_cc = rules.cc.override {
inherit toolchain;
};

passthru = with rules_cc; rec {
inherit toolchain rules_cc;

crt0 = asm {
src = ./crt0.S;
deps = [./demo_system_regs.h];
};

gpio = object {
src = ./gpio.c;
deps = [./gpio.h ./uart.h ./dev_access.h ./demo_system.h ./demo_system_regs.h];
extra-cflags = ["-O3"];
};

uart = object {
src = ./uart.c;
deps = [./gpio.h ./uart.h ./dev_access.h ./demo_system.h ./demo_system_regs.h];
};

pwm = object {
src = ./pwm.c;
deps = [./gpio.h ./uart.h ./pwm.h ./dev_access.h ./demo_system.h ./demo_system_regs.h];
};

spi = object {
src = ./spi.c;
deps = [./gpio.h ./uart.h ./spi.h ./dev_access.h ./demo_system.h ./demo_system_regs.h];
};

timer = object {
src = ./timer.c;
deps = [./gpio.h ./uart.h ./timer.h ./dev_access.h ./demo_system.h ./demo_system_regs.h];
};

demo_system = object {
src = ./demo_system.c;
deps = [./gpio.h ./uart.h ./dev_access.h ./demo_system.h ./demo_system_regs.h];
};

common = static {
name = "common.a";
deps = [crt0 gpio uart pwm spi timer ./demo_system.c] ++ [./gpio.h ./uart.h ./timer.h ./spi.h ./pwm.h ./dev_access.h ./demo_system.h ./demo_system_regs.h];
};
};
in
passthru.common // passthru
11 changes: 11 additions & 0 deletions sw/c/demo/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
rules,
common,
lowrisc-toolchain-gcc-rv32imcb,
}:
with common.rules_cc; {
hello_world = binary {
name = "hello_world";
deps = [hello_world/main.c common];
};
}

0 comments on commit 05a4d3f

Please sign in to comment.