Compare commits

...

7 Commits

Author SHA1 Message Date
Ehmry - 38f48c8d07 Add note to README­about resolving ERIS URNs 2023-09-29 11:18:31 +01:00
Ehmry - ccc2f4f79f Modify type of ERIS­manifest
Convert the manifest to have a more general type.
2023-09-29 11:18:31 +01:00
Ehmry - 4d3d152f50 Update dhall-nim to 20230928 2023-09-28 12:17:09 +01:00
Ehmry - 96f77470ad Make the syndicate test a proper package 2023-09-28 12:17:09 +01:00
Ehmry - 0860d69886 Deflakification 2023-09-28 11:52:07 +01:00
Ehmry - c42bb909f2 nimPackages: update cbor and dhall 2023-09-21 19:51:41 +02:00
Ehmry - 272a141fc1 Deprecate top-level `{build,host,target}Platform` 2023-06-16 10:09:09 +01:00
19 changed files with 395 additions and 98 deletions

View File

@ -133,6 +133,12 @@ within the Genode source tree is an *explicit input hash*.
nix build -L .#checks.x86_64-linux.«TEST_NAME».nodes.machine.config.genode.init.children.«CHILD_NAME».package
```
### A binary is loading ERIS URNs, where do the URNs come from?
```sh
nix run .#readelferislinks result/bin/*
```
## Pronunciation
[![As read by Dan Castellaneta](./doc/sigil.opus)](./doc/sigil.opus)

226
default.nix Normal file
View File

@ -0,0 +1,226 @@
let
nixpkgs = builtins.fetchTarball {
url =
"https://github.com/ehmry/nixpkgs/archive/32751f50996939c2ac11229ecd0ce2ec68d05ac6.tar.gz";
sha256 = "08g8p0byv33scay40cd8p44szrvz0qhwbnxsyvlv19fz0nf7yzwk";
};
systems = {
localSystem = [ "x86_64-linux" ]; # build platforms
crossSystem = [ "aarch64-genode" "x86_64-genode" ]; # target platforms
};
lib = let prev = import "${nixpkgs}/lib";
in prev.extend (final: prev: {
systemSpace =
# All combinations of build and target systems
prev.cartesianProductOfSets systems;
forAllLocalSystems =
# Apply a function over all self-hosting (Linux) systems.
f:
prev.genAttrs systems.localSystem (system: f system);
forAllCrossSystems =
# Apply a function over all cross-compiled systems (Genode).
f:
with builtins;
let
f' = { localSystem, crossSystem }:
let system = localSystem + "-" + crossSystem;
in {
name = crossSystem;
value = f { inherit system localSystem crossSystem; };
};
list = map f' final.systemSpace;
attrSet = listToAttrs list;
in attrSet;
forAllSystems =
# Apply a function over all Linux and Genode systems.
f:
(final.forAllCrossSystems f) // (final.forAllLocalSystems (system:
f {
inherit system;
localSystem = system;
crossSystem = system;
}));
getMainProgram = pkg:
with builtins;
if hasAttr "mainProgram" pkg.meta then
pkg.meta.mainProgram
else
trace "${pkg.name} is missing meta.mainProgram" pkg.pname;
getEris = filename: pkg:
with builtins;
let
manifest = fromJSON (unsafeDiscardStringContext
(readFile "${pkg}/nix-support/eris-manifest.json"));
entry = manifest.${filename};
in {
inherit (entry) cap;
closure = map (ce:
if ce.cap == entry.cap then
ce // {
# hack to build a string with context to propagate a
# dependency on the rest of the closure
path = "${pkg}${
substring (stringLength pkg) (stringLength ce.path) ce.path
}";
}
else
ce) entry.closure;
};
getErisMainProgram = pkg:
final.getEris (final.getMainProgram pkg) (prev.getOutput "bin" pkg);
getErisLib = filename: pkg:
final.getEris filename (prev.getOutput "lib" pkg);
uuidFrom = seed:
let digest = builtins.hashString "sha256" seed;
in (lib.lists.foldl ({ str, off }:
n:
let chunk = builtins.substring off n digest;
in {
str = if off == 0 then chunk else "${str}-${chunk}";
off = off + n;
}) {
str = "";
off = 0;
} [ 8 4 4 4 12 ]).str;
nixosSystem =
# A derivative of the function for generating Linux NixOS systems.
# This one is not so well tested…
{ modules, ... }@args:
import "${nixpkgs}/nixos/lib/eval-config.nix" (args // {
lib = final;
baseModules =
# TODO: do not blacklist modules for the Linux guests
with builtins;
let
isNotModule = suffix:
let x = "${nixpkgs}/nixos/modules/${suffix}";
in y: x != y;
filters = map isNotModule
(import ./nixos-modules/base-modules-blacklist.nix);
isCompatible = p: let p' = toString p; in all (f: f p') filters;
in filter isCompatible
(import "${nixpkgs}/nixos/modules/module-list.nix");
modules = modules ++ [
({ config, lib, ... }: {
options = with lib; {
system.boot.loader.id = mkOption {
internal = true;
default = "";
};
system.boot.loader.kernelFile = mkOption {
internal = true;
default = pkgs.stdenv.hostPlatform.platform.kernelTarget;
type = types.str;
};
system.boot.loader.initrdFile = mkOption {
internal = true;
default = "initrd";
type = types.str;
};
systemd.defaultUnit = mkOption {
default = "multi-user.target";
type = types.str;
};
};
config = {
boot.loader.grub.enable = lib.mkDefault false;
fileSystems."/" = { };
networking.enableIPv6 = lib.mkForce false;
systemd.network.enable = lib.mkForce false;
system.build.toplevel = config.system.build.initXml;
};
})
];
});
});
flakes = {
nimble = builtins.getFlake
"github:nix-community/flake-nimble/54dd3e91c0b61ea63eb4065f95b97f3f0fc98b06";
eris = builtins.getFlake
"git+https://codeberg.org/eris/nix-eris?ref=refs/heads/trunk&rev=c190cc13e5f2518913a266180a26b54d39dbcc87";
};
in rec {
inherit lib;
overlay = import ./overlay;
legacyPackages = let
overlays = [ flakes.nimble.overlay flakes.eris.overlays.default overlay ];
in lib.forAllSystems ({ system, localSystem, crossSystem }:
if system == "x86_64-linux" then
import nixpkgs { inherit overlays; }
else
import nixpkgs {
inherit localSystem;
crossSystem = {
system = crossSystem;
useLLVM = true;
};
config.allowUnsupportedSystem = true;
inherit overlays;
});
packages =
# Genode native packages, not packages in the traditional
# sense in that these cannot be installed within a profile.
lib.forAllCrossSystems ({ system, localSystem, crossSystem }:
lib.filterAttrs (_: v: v != null)
legacyPackages.${crossSystem}.genodePackages);
nixosModules =
# Modules for composing Genode and NixOS.
import ./nixos-modules { inherit legacyPackages; };
checks =
# Checks for continous testing.
let tests = import ./tests;
in with (lib.forAllCrossSystems ({ system, localSystem, crossSystem }:
tests {
inherit lib system localSystem crossSystem;
hostPkgs = legacyPackages.${localSystem};
testPkgs = legacyPackages.${crossSystem};
modulesPath = "${nixpkgs}/nixos/modules";
} // {
ports = legacyPackages.${localSystem}.symlinkJoin {
name = "ports";
paths = (builtins.attrValues packages.${system}.genodeSources.ports);
};
})); {
x86_64-linux = aarch64-genode // x86_64-genode;
};
hydraJobs = lib.attrsets.mapAttrs lib.hydraJob checks;
}

View File

@ -12,7 +12,8 @@
nixConfig = {
extra-substituters = [ "https://sigil.cachix.org" ];
extra-trusted-public-keys = [ "sigil.cachix.org-1:poBTiAr1x94vX0ONljw+R22Hmxd5rtHi9UYdHlRaWoM=" ];
extra-trusted-public-keys =
[ "sigil.cachix.org-1:poBTiAr1x94vX0ONljw+R22Hmxd5rtHi9UYdHlRaWoM=" ];
};
outputs = { self, eris, nixpkgs, nimble }:
@ -84,14 +85,21 @@
manifest = fromJSON (unsafeDiscardStringContext
(readFile "${pkg}/nix-support/eris-manifest.json"));
entry = manifest.${filename};
in entry // {
cap = "(${pkg}/nix-support/eris-manifest.dhall).${filename}.cap";
path = "${pkg}${
substring (stringLength pkg) (stringLength entry.path)
entry.path
}"; # hack to build a string with context
in {
inherit (entry) cap;
closure = map (ce:
if ce.cap == entry.cap then
ce // {
# hack to build a string with context to propagate a
# dependency on the rest of the closure
path = "${pkg}${
substring (stringLength pkg) (stringLength ce.path)
ce.path
}";
}
else
ce) entry.closure;
};
getErisMainProgram = pkg:
final.getEris (final.getMainProgram pkg) (prev.getOutput "bin" pkg);

View File

@ -23,7 +23,7 @@
( VFS.vfs
[ VFS.leafAttrs
"plugin"
(toMap { load = ${vfsRump.cap}, fs = "cd9660", ram = "12M", writeable="no" })
(toMap { load = "${vfsRump.cap}", fs = "cd9660", ram = "12M", writeable="no" })
]
)
'';

View File

@ -107,7 +107,7 @@ let
let XML = Sigil.Prelude.XML
in
${./store-wrapper.dhall}
{ binaries.rtc_drv = ${rtc_drv.cap}
{ binaries.rtc_drv = "${rtc_drv.cap}"
, extraCoreChildren = ${extraCoreChildren}
, subinit = ${config.genode.init.configFile}
, storeSize = $(stat --format '%s' ${tarball})
@ -232,20 +232,24 @@ in {
}];
genode.core.romModules = with builtins;
(lib.lists.flatten ((map (getAttr "roms") (attrValues children')) ++ (map
({ cap, path, ... }: {
name = cap;
value = path;
}) (attrValues coreErisCaps)))) ++ [
{
name = ''"init"'';
value = "${pkgs.genodePackages.init}/bin/init";
}
{
name = ''"report_rom"'';
value = "${pkgs.genodePackages.report_rom}/bin/report_rom";
}
];
let
childRomEntries =
lib.lists.flatten (map (getAttr "roms") (attrValues children'));
coreErisCapEntries = lib.lists.flatten (map ({ cap, closure }:
map ({ cap, path }: {
name = ''"${cap}"'';
value = path;
}) closure) (attrValues coreErisCaps));
in childRomEntries ++ coreErisCapEntries ++ [
{
name = ''"init"'';
value = "${pkgs.genodePackages.init}/bin/init";
}
{
name = ''"report_rom"'';
value = "${pkgs.genodePackages.report_rom}/bin/report_rom";
}
];
genode.core.children.jitter_sponge = {
package = pkgs.genodePackages.jitter_sponge;

View File

@ -32,15 +32,15 @@ in {
ahciConfig = lib.optionalString cfg.ahci.enable (with cfg.ahci; ''
, ahci_drv = Some {
, binary = ${ahciEris.cap}
, binary = "${ahciEris.cap}"
, atapi = ${toDhall atapiSupport}
}
'');
usbConfig = lib.optionalString cfg.usb.enable (with cfg.usb.host; ''
, usb_block_drv = Some { binary = ${usbEris.usb_block_drv.cap} }
, usb_block_drv = Some { binary = "${usbEris.usb_block_drv.cap}" }
, usb_host_drv = Some {
, binary = ${usbEris.usb_host_drv.cap}
, binary = "${usbEris.usb_host_drv.cap}"
, bios_handoff = ${toDhall biosHandoff}
, ehci = ${toDhall ehciSupport}
, ohci = ${toDhall ohciSupport}
@ -54,7 +54,7 @@ in {
in Manager.toChildAttributes
Manager::{
, part_block.binary = ${partBlockEris.cap}
, part_block.binary = "${partBlockEris.cap}"
${ahciConfig}
${usbConfig}
, verbose = ${toDhall cfg.verbose}

View File

@ -73,14 +73,11 @@
lib.attrsets.mapAttrs (_:
{ binary, configFile, extraErisInputs, package, ... }:
let
toRoms = { cap, closure, path }:
[{
name = cap;
toRoms = { closure, ... }:
map ({ cap, path }: {
name = ''"${cap}"'';
value = path;
}] ++ (lib.mapAttrsToList (name: value: {
name = ''"${value}"'';
value = name;
}) closure);
}) closure;
extraRoms = map toRoms extraErisInputs;
in if binary != null then {
config = ''${configFile} "${binary}"'';
@ -88,7 +85,7 @@
} else
let bin = lib.getErisMainProgram package;
in {
config = "${configFile} ${bin.cap}";
config = ''${configFile} "${bin.cap}"'';
roms = toRoms bin ++ extraRoms;
}) children;
};

View File

@ -6,13 +6,13 @@ let
# on whether the host or target system is Genode.
overrideHost = attrs: drv:
if hostPlatform.isGenode then drv.override attrs else drv;
if stdenv.hostPlatform.isGenode then drv.override attrs else drv;
overrideAttrsHost = f: drv:
if hostPlatform.isGenode then drv.overrideAttrs f else drv;
if stdenv.hostPlatform.isGenode then drv.overrideAttrs f else drv;
overrideAttrsTarget = f: drv:
if targetPlatform.isGenode then drv.overrideAttrs f else drv;
if stdenv.targetPlatform.isGenode then drv.overrideAttrs f else drv;
addPatches' = patches: attrs: { patches = attrs.patches or [ ] ++ patches; };
@ -25,7 +25,7 @@ let
nullPkgs =
# Nullify these packages to find problems early.
if hostPlatform.isGenode then
if stdenv.hostPlatform.isGenode then
builtins.listToAttrs (map (name: {
inherit name;
value = final.hello;
@ -140,7 +140,7 @@ in nullPkgs // {
linuxPackages =
# Dummy package.
if hostPlatform.isGenode then {
if stdenv.hostPlatform.isGenode then {
extend = _: final.linuxPackages;
features = { };
kernel = {
@ -153,7 +153,7 @@ in nullPkgs // {
} else
prev.linuxPackages;
llvmPackages = if targetPlatform.isGenode then
llvmPackages = if stdenv.targetPlatform.isGenode then
final.llvmPackages_11
else
prev.llvmPackages;
@ -171,7 +171,7 @@ in nullPkgs // {
# Packages from the Nimble flake with adjustments.
prev.nimPackages.overrideScope' (final': prev':
with final'; {
buildNimPackage = if hostPlatform.isGenode then
buildNimPackage = if stdenv.hostPlatform.isGenode then
({ nimFlags ? [ ], ... }@args:
prev'.buildNimPackage (args // {
nimBackend = "cpp";
@ -181,16 +181,27 @@ in nullPkgs // {
else
prev'.buildNimPackage;
cbor = buildNimPackage rec {
pname = "cbor";
version = "20230619";
src = fetchFromSourcehut {
owner = "~ehmry";
repo = "nim_${pname}";
rev = version;
hash = "sha256-F6T/5bUwrJyhRarTWO9cjbf7UfEOXPNWu6mfVKNZsQA=";
};
};
dhall = buildNimPackage rec {
pname = "dhall";
version = "20221007";
version = "20230928";
src = prev.fetchFromSourcehut {
owner = "~ehmry";
repo = "${pname}-nim";
rev = version;
hash = "sha256-wDD9ZRQ6FcQrPLFMCFJcsBIXFzE3wLYqL12AF1KPE0g=";
hash = "sha256-IoSA6yVFiAXuoApjWiz4DohnenlQdTAhfE3VeMSZKtM=";
};
buildInputs = [ bigints cbor ];
propagatedBuildInputs = [ cbor ];
};
genode = prev'.genode.overrideAttrs ({ ... }: rec {
@ -253,10 +264,13 @@ in nullPkgs // {
solo5-tools = callPackage ./solo5-tools { };
stdenv = overrideHost (old: {
extraNativeBuildInputs = old.extraNativeBuildInputs
++ [ final.buildPackages.erisPatchHook ];
}) prev.stdenv;
stdenv = if prev.stdenv.hostPlatform.isGenode then
stdenv.override (prev': {
extraNativeBuildInputs = prev'.extraNativeBuildInputs
++ [ final.buildPackages.erisPatchHook ];
})
else
prev.stdenv;
tor = overrideAttrsHost (attrs: {
patches = attrs.patches or [ ] ++ [

View File

@ -3,6 +3,26 @@ import cbor, dhall/[render, terms], eris
const selfDescribedCbor = 55799
type
Manifest = Table[string, ManifestEntry]
ManifestEntry = object
path: string
closure: Table[string, ErisCap]
proc parseManifestFile(path: string): Manifest =
let js = parseFile(path)
for key, val in js.pairs:
var
entry: ManifestEntry
entryCap = val["cap"].getStr.parseErisUrn
for e in val["closure"].items:
var
cap = e["cap"].getStr.parseErisUrn
path = e["path"].getStr
if cap == entryCap: entry.path = path
entry.closure[path] = cap
result[key] = entry
proc writeErisLinks(path: string; node: CborNode) =
# Inspired by "Package Metadata for Core Files"
# - https://systemd.io/COREDUMP_PACKAGE_METADATA/
@ -25,16 +45,31 @@ proc toCbor(cap: ErisCap): CborNode =
result = initCborBytes(cap.bytes)
result.tag = erisCborTag
proc toDhall(js: JsonNode): Value =
case js.kind
of JString:
result = newValue(js.str)
of JObject:
result = newRecordLiteral(js.fields.len)
for key, val in js.fields.pairs:
result.table[key] = val.toDhall
else:
raiseAssert "unhandled JSON value"
proc toDhall(entry: ManifestEntry): Value =
var closure = newSeqOfCap[Value](entry.closure.len)
for path, cap in entry.closure.pairs:
closure.add newRecordLiteral(
{ "cap": newValue $cap, "path": newValue path })
newRecordLiteral {
"cap": newValue $(entry.closure[entry.path]),
"closure": newValue closure,
}
proc toDhall(manifest: Manifest): Value =
result = newRecordLiteral(manifest.len)
for name, entry in manifest.pairs:
result.table[name] = entry.toDhall
proc toJson(entry: ManifestEntry): JsonNode =
var closure = newJArray()
for path, cap in entry.closure.pairs:
closure.add %*{ "cap": %($cap), "path": %path }
%*{ "cap": %($entry.closure[entry.path]), "closure": closure }
proc toJson(manifest: Manifest): JsonNode =
result = newJObject()
for name, entry in manifest.pairs:
result[name] = entry.toJSON
proc isElf(path: string): bool =
var magic: array[4, char]
@ -66,7 +101,7 @@ proc main =
erisLinks: CborNode
var
outputManifests = initTable[string, JsonNode]()
outputManifests = initTable[string, Manifest]()
pendingFiles = initDeque[PendingFile]()
failed = false
if getEnv("outputs") == "":
@ -78,7 +113,7 @@ proc main =
if fileExists(outputRoot / jsonManifestSubPath):
stderr.writeLine "Not running ERIS patch hook again"
quit 0
outputManifests[outputRoot] = newJObject()
outputManifests[outputRoot] = Manifest()
let buildInputs = getEnv("buildInputs").splitWhitespace
@ -149,14 +184,15 @@ proc main =
let manifestPath = storePath / jsonManifestSubPath
if fileExists(manifestPath):
let
manifest = parseFile(manifestPath)
manifest = parseManifestFile(manifestPath)
entry = manifest[filePath.extractFilename]
for path, urn in entry["closure"].pairs:
result[path] = parseErisUrn urn.getStr
let otherClosure = fileClosure(path)
for otherPath, otherCap in otherClosure.pairs:
# merge the closure of the dependency
result[otherPath] = otherCap
for path, cap in entry.closure.pairs:
if path != filePath:
result[path] = cap
let otherClosure = fileClosure(path)
for otherPath, otherCap in otherClosure.pairs:
# merge the closure of the dependency
result[otherPath] = otherCap
closureCache[filePath] = result
for outputRoot in outputManifests.keys:
@ -196,7 +232,7 @@ proc main =
pendingFiles.addLast(pendingFile)
break selfReferenceCheck
var
closure = newJObject()
closure = initTable[string, ErisCap]()
replaceCmd = patchelf & " --set-rpath '' " & filePath
for need, replacementPath in pendingFile.replacements.pairs:
if replacementPath == "": continue
@ -204,11 +240,11 @@ proc main =
cap = fileCap(replacementPath)
urn = $cap
stderr.writeLine "replace reference to ", need, " with ", urn
closure[replacementPath] = %urn
pendingFile.erisLinks[ replacementPath.toCbor] = cap.toCbor
closure[replacementPath] = cap
pendingFile.erisLinks[replacementPath.toCbor] = cap.toCbor
replaceCmd.add(" --replace-needed $# $#" % [need, urn])
for path, cap in fileClosure(replacementPath).pairs:
closure[path] = %($cap)
closure[path] = cap
pendingFile.erisLinks[path.toCbor] = cap.toCbor
if runPatchelf and pendingFile.replacements.len != 0:
@ -238,11 +274,13 @@ proc main =
quit("Adding note to $1 failed" % pendingFile.filePath)
moveFile(tmpFile, pendingFile.filePath)
outputManifests[pendingFile.outputRoot][filePath.extractFilename] = %* {
"cap": $fileCap(filePath),
"closure": closure,
"path": filePath
}
var cap = fileCap(filePath)
closure[filePath] = cap
outputManifests[pendingFile.outputRoot][filePath.extractFilename] =
ManifestEntry(
closure: closure,
path: filePath,
)
if pendingFiles.len == prevPrevLen:
failed = true
@ -260,7 +298,7 @@ proc main =
for outputRoot, manifest in outputManifests:
let supportDir = outputRoot / "nix-support"
createDir(supportDir)
writeFile(outputRoot / jsonManifestSubPath, $manifest)
writeFile(outputRoot / dhallManifestSubPath, $(manifest.toDhall))
writeFile(outputRoot / jsonManifestSubPath, $manifest.toJson)
writeFile(outputRoot / dhallManifestSubPath, $manifest.toDhall)
main()

View File

@ -52,6 +52,8 @@ in upstream // (with final; {
portInputs = with genodeSources.ports; [ libc libssh openssl zlib ];
};
syndicate_test = nimPackages.callPackage ./syndicate_test { };
worldSources = prev.fetchFromGitHub {
owner = "genodelabs";
repo = "genode-world";

View File

@ -4,7 +4,7 @@ let
inherit (final) lib;
inherit (prev.buildPackages) buildPackages;
platform = final.targetPlatform;
platform = final.stdenv.targetPlatform;
arch = with platform;
if isx86_64 then

View File

@ -28,7 +28,7 @@ in stdenv.mkDerivation {
configurePhase = with stdenv; ''
runHook preConfigure
sh configure.sh
${lib.optionalString (hostPlatform.isAarch64) "rm -fr tests/test_fpu"}
${lib.optionalString (stdenv.hostPlatform.isAarch64) "rm -fr tests/test_fpu"}
rm -fr tests/test_tls
runHook postConfigure
'';

View File

@ -0,0 +1,11 @@
{ buildNimPackage, genode, npeg, preserves, syndicate }:
buildNimPackage {
pname = "syndicate_test";
version = "unstable";
nimDefines.posix = { };
src = ./src;
propagatedBuildInputs = [ genode npeg preserves syndicate ];
nimBinOnly = true;
meta.mainProgram = "syndicate_test";
}

View File

@ -0,0 +1 @@
bin = @["syndicate_test.nim"]

View File

@ -24,9 +24,9 @@
${./bash.dhall} {
, bash = "${pkgs.bash}"
, coreutils = "${pkgs.coreutils}"
, cached_fs_rom = ${extraErisInputs'.cached_fs_rom.cap}
, vfs = ${extraErisInputs'.vfs.cap}
, vfs_pipe = ${extraErisInputs'.vfs_pipe.cap}
, cached_fs_rom = "${extraErisInputs'.cached_fs_rom.cap}"
, vfs = "${extraErisInputs'.vfs.cap}"
, vfs_pipe = "${extraErisInputs'.vfs_pipe.cap}"
}
'';
extraInputs = with pkgs.genodePackages; [ pkgs.bash libc posix ];

View File

@ -16,14 +16,14 @@ let
./hello.nix
./log.nix
./nim.nix
./syndicate
./syndicate.nix
./tor.nix
./usb.nix
./vmm_x86.nix
];
core = builtins.filter (core:
builtins.any (x: x == testPkgs.hostPlatform.system) core.platforms) [
builtins.any (x: x == testPkgs.stdenv.hostPlatform.system) core.platforms) [
/* # Need to fix the QEMU boot parameters?
{
prefix = "hw-pc-";

View File

@ -3,16 +3,7 @@
machine = { pkgs, ... }: {
genode.init.verbose = true;
genode.init.children.syndicate_service = {
package = with pkgs.nimPackages;
buildNimPackage rec {
pname = "syndicate";
version = "unstable";
nimDefines.posix = { };
src = ./src;
propagatedBuildInputs = [ genode npeg preserves syndicate ];
nimBinOnly = true;
meta.mainProgram = "test";
};
package = pkgs.genodePackages.syndicate_test;
extraInputs = with pkgs.genodePackages; [ libc stdcxx ];
configFile = builtins.toFile "nim.dhall" ''
let Sigil = env:DHALL_SIGIL

View File

@ -1 +0,0 @@
bin = @["test.nim"]