Skip to content

Commit 3ecca30

Browse files
committed
[DO NOT MERGE] nix-based build system!
1 parent 104a4fc commit 3ecca30

File tree

6 files changed

+274
-39
lines changed

6 files changed

+274
-39
lines changed

flake.lock

+8-38
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

+13-1
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
66
flake-utils.url = "github:numtide/flake-utils";
77
lowrisc-nix = {
8-
url = "github:lowRISC/lowrisc-nix";
8+
url = "github:lowRISC/lowrisc-nix/pull/4/merge";
99
inputs.nixpkgs.follows = "nixpkgs";
10+
inputs.flake-utils.follows = "flake-utils";
1011
};
1112
deps = {
1213
url = "path:./dependencies";
@@ -30,6 +31,9 @@
3031
# Add extra packages we might need
3132
# Currently this contains the lowrisc riscv-toolchain, and spike
3233
deps.overlay_pkgs
34+
(final: prev: {
35+
inherit (inputs.lowrisc-nix.packages.${system}) lowrisc-toolchain-gcc-rv32imcb;
36+
})
3337
];
3438
};
3539

@@ -62,7 +66,15 @@
6266
zlib
6367
# vivado
6468
]);
69+
70+
rules = import ./rules {inherit pkgs;};
6571
in {
72+
legacyPackages.sw = let
73+
common = pkgs.callPackage sw/c/common {inherit rules;};
74+
demo = pkgs.callPackage sw/c/demo {inherit rules common;};
75+
in {
76+
inherit common demo;
77+
};
6678
devShells.default = pkgs.mkShell {
6779
name = "labenv";
6880
buildInputs = project_deps;

rules/cc.nix

+175
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
{
2+
pkgs,
3+
lib,
4+
stdenv,
5+
toolchain ? {
6+
cc = "/no-toolchain-defined";
7+
cflags = [];
8+
ld = "/no-toolchain-defined";
9+
ldflags = [];
10+
asm = "/no-toolchain-defined";
11+
asmflags = [];
12+
},
13+
}: let
14+
include = {
15+
src,
16+
deps ? [],
17+
}:
18+
pkgs.runCommandLocal (builtins.baseNameOf src) {} ''
19+
mkdir -p $out/include
20+
21+
ARGS=()
22+
for dep in $deps; do
23+
if [ -d $dep/include ]; then
24+
ln -s $src/include/* $out/include/
25+
fi
26+
done
27+
28+
ln -s ${src} $out/include/${builtins.baseNameOf src}
29+
'';
30+
31+
# If a raw file path is specified, turn that into a header derivation.
32+
autowrap_header = f:
33+
if !(builtins.isPath f)
34+
then f
35+
else if lib.hasSuffix ".h" f
36+
then include {src = f;}
37+
else throw "unknown file type: ${f}";
38+
39+
# Turn all raw file paths into derivations.
40+
# Files will be grouped so that source files can depend on header files.
41+
autowrap_deps = deps: let
42+
src = builtins.filter (f: builtins.isPath f && !(lib.hasSuffix ".h" f)) deps;
43+
other = builtins.filter (f: !(builtins.isPath f) || lib.hasSuffix ".h" f) deps;
44+
wrapped = map autowrap_header other;
45+
src_drv =
46+
map (
47+
f:
48+
if lib.hasSuffix ".S" f
49+
then
50+
asm {
51+
src = f;
52+
deps = wrapped;
53+
}
54+
else if lib.hasSuffix ".c" f
55+
then
56+
object {
57+
src = f;
58+
deps = wrapped;
59+
}
60+
else throw "unknown file type: ${f}"
61+
)
62+
src;
63+
in
64+
src_drv ++ wrapped;
65+
66+
asm = {
67+
src,
68+
deps ? [],
69+
extra-asmflags ? [],
70+
asmflags ? toolchain.asmflags ++ extra-asmflags,
71+
}:
72+
stdenv.mkDerivation {
73+
name = (lib.removeSuffix ".S" (builtins.baseNameOf src)) + ".o";
74+
inherit src asmflags;
75+
inherit (toolchain) asm;
76+
deps = autowrap_deps deps;
77+
dontUnpack = true;
78+
buildPhase = ''
79+
ARGS=()
80+
for dep in $deps; do
81+
if [ -d $dep/include ]; then
82+
ARGS+=(-I$dep/include)
83+
fi
84+
done
85+
86+
mkdir -p $out/obj
87+
$asm $asmflags -c -o $out/obj/$name $src ''${ARGS[@]}
88+
'';
89+
};
90+
91+
object = {
92+
src,
93+
deps ? [],
94+
extra-cflags ? [],
95+
cflags ? toolchain.cflags ++ extra-cflags,
96+
}:
97+
stdenv.mkDerivation {
98+
name = (lib.removeSuffix ".c" (builtins.baseNameOf src)) + ".o";
99+
inherit src cflags;
100+
inherit (toolchain) cc;
101+
deps = autowrap_deps deps;
102+
dontUnpack = true;
103+
buildPhase = ''
104+
ARGS=()
105+
for dep in $deps; do
106+
if [ -d $dep/include ]; then
107+
ARGS+=(-I$dep/include)
108+
fi
109+
done
110+
111+
mkdir -p $out/obj
112+
$cc $cflags -c -o $out/obj/$name $src ''${ARGS[@]}
113+
'';
114+
};
115+
116+
static = {
117+
name,
118+
deps,
119+
}:
120+
stdenv.mkDerivation {
121+
inherit name;
122+
srcs = autowrap_deps deps;
123+
dontUnpack = true;
124+
buildPhase = ''
125+
ARGS=()
126+
for src in $srcs; do
127+
if [ -d $src/obj ]; then
128+
ARGS+=($src/obj/*)
129+
fi
130+
if [ -d $src/include ]; then
131+
mkdir -p $out/include
132+
ln -s $src/include/* $out/include/
133+
fi
134+
done
135+
136+
mkdir -p $out/lib
137+
ar rcs $out/lib/$name ''${ARGS[@]}
138+
'';
139+
};
140+
141+
binary = {
142+
name,
143+
deps ? [],
144+
extra-ldflags ? [],
145+
ldflags ? toolchain.ldflags ++ extra-ldflags,
146+
}:
147+
stdenv.mkDerivation {
148+
inherit name ldflags;
149+
inherit (toolchain) ld;
150+
srcs = autowrap_deps deps;
151+
dontUnpack = true;
152+
buildPhase = ''
153+
ARGS=()
154+
for src in $srcs; do
155+
if [ -d $src/obj ]; then
156+
ARGS+=($src/obj/*)
157+
fi
158+
if [ -d $src/lib ]; then
159+
ARGS+=($src/lib/*)
160+
fi
161+
done
162+
163+
mkdir -p $out/bin
164+
$ld $ldflags -o $out/bin/$name ''${ARGS[@]}
165+
'';
166+
};
167+
168+
set = deps:
169+
pkgs.symlinkJoin {
170+
name = "";
171+
paths = autowrap_deps deps;
172+
};
173+
in {
174+
inherit asm include object static binary set;
175+
}

rules/default.nix

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{pkgs}: {
2+
cc = pkgs.callPackage ./cc.nix {};
3+
}

sw/c/common/default.nix

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{
2+
rules,
3+
pkgs,
4+
lowrisc-toolchain-gcc-rv32imcb,
5+
}: let
6+
toolchain = rec {
7+
cc = "${lowrisc-toolchain-gcc-rv32imcb}/bin/riscv32-unknown-elf-gcc";
8+
cflags = ["-march=rv32imc" "-mabi=ilp32" "-mcmodel=medany" "-Wall" "-fvisibility=hidden" "-ffreestanding"];
9+
ld = cc;
10+
ldflags = ["-nostartfiles" "-T" "${../../common/link.ld}"];
11+
asm = cc;
12+
asmflags = ["-march=rv32imc"];
13+
};
14+
15+
rules_cc = rules.cc.override {
16+
inherit toolchain;
17+
};
18+
19+
passthru = with rules_cc; rec {
20+
inherit toolchain rules_cc;
21+
22+
crt0 = asm {
23+
src = ./crt0.S;
24+
deps = [./demo_system_regs.h];
25+
};
26+
27+
gpio = object {
28+
src = ./gpio.c;
29+
deps = [./gpio.h ./uart.h ./dev_access.h ./demo_system.h ./demo_system_regs.h];
30+
extra-cflags = ["-O3"];
31+
};
32+
33+
uart = object {
34+
src = ./uart.c;
35+
deps = [./gpio.h ./uart.h ./dev_access.h ./demo_system.h ./demo_system_regs.h];
36+
};
37+
38+
pwm = object {
39+
src = ./pwm.c;
40+
deps = [./gpio.h ./uart.h ./pwm.h ./dev_access.h ./demo_system.h ./demo_system_regs.h];
41+
};
42+
43+
spi = object {
44+
src = ./spi.c;
45+
deps = [./gpio.h ./uart.h ./spi.h ./dev_access.h ./demo_system.h ./demo_system_regs.h];
46+
};
47+
48+
timer = object {
49+
src = ./timer.c;
50+
deps = [./gpio.h ./uart.h ./timer.h ./dev_access.h ./demo_system.h ./demo_system_regs.h];
51+
};
52+
53+
demo_system = object {
54+
src = ./demo_system.c;
55+
deps = [./gpio.h ./uart.h ./dev_access.h ./demo_system.h ./demo_system_regs.h];
56+
};
57+
58+
common = static {
59+
name = "common.a";
60+
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];
61+
};
62+
};
63+
in
64+
passthru.common // passthru

sw/c/demo/default.nix

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
rules,
3+
common,
4+
lowrisc-toolchain-gcc-rv32imcb,
5+
}:
6+
with common.rules_cc; {
7+
hello_world = binary {
8+
name = "hello_world";
9+
deps = [hello_world/main.c common];
10+
};
11+
}

0 commit comments

Comments
 (0)