diff --git a/overlay/default.nix b/overlay/default.nix index 2544e19..3660a2d 100644 --- a/overlay/default.nix +++ b/overlay/default.nix @@ -264,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 [ ] ++ [ diff --git a/overlay/eris-patch-hook/eris_patch.nim b/overlay/eris-patch-hook/eris_patch.nim index c5b17d1..564c8d8 100644 --- a/overlay/eris-patch-hook/eris_patch.nim +++ b/overlay/eris-patch-hook/eris_patch.nim @@ -3,6 +3,20 @@ import cbor, dhall/[render, terms], eris const selfDescribedCbor = 55799 +type + Manifest = Table[string, ManifestEntry] + ManifestEntry = object + cap, path: string + closure: Table[string, string] + +proc parseManifestFile(path: string): Manifest = + let js = parseFile(path) + for key, val in js.pairs: + var entry: ManifestEntry + entry.cap = val["cap"].getStr + entry.path = val["path"].getStr + result[key] = entry + proc writeErisLinks(path: string; node: CborNode) = # Inspired by "Package Metadata for Core Files" # - https://systemd.io/COREDUMP_PACKAGE_METADATA/ @@ -25,16 +39,33 @@ 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+1) + closure.add newRecordLiteral( + { "cap": newValue $entry.cap, "path": newValue entry.path}) + for path, urn in entry.closure.pairs: + closure.add newRecordLiteral( + { "cap": newValue urn, "path": newValue path }) + newRecordLiteral { + "cap": newValue entry.cap, + "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 = newJObject() + for path, urn in entry.closure.pairs: + closure[path] = %urn + %*{ "cap": entry.cap, "closure": closure, "path": entry.path } + +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 +97,7 @@ proc main = erisLinks: CborNode var - outputManifests = initTable[string, JsonNode]() + outputManifests = initTable[string, Manifest]() pendingFiles = initDeque[PendingFile]() failed = false if getEnv("outputs") == "": @@ -78,7 +109,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,10 +180,10 @@ 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 + for path, urn in entry.closure.pairs: + result[path] = parseErisUrn urn let otherClosure = fileClosure(path) for otherPath, otherCap in otherClosure.pairs: # merge the closure of the dependency @@ -196,7 +227,7 @@ proc main = pendingFiles.addLast(pendingFile) break selfReferenceCheck var - closure = newJObject() + closure = initTable[string, string]() replaceCmd = patchelf & " --set-rpath '' " & filePath for need, replacementPath in pendingFile.replacements.pairs: if replacementPath == "": continue @@ -204,11 +235,11 @@ proc main = cap = fileCap(replacementPath) urn = $cap stderr.writeLine "replace reference to ", need, " with ", urn - closure[replacementPath] = %urn + closure[replacementPath] = urn 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 +269,12 @@ 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 - } + outputManifests[pendingFile.outputRoot][filePath.extractFilename] = + ManifestEntry( + cap: $fileCap(filePath), + closure: closure, + path: filePath, + ) if pendingFiles.len == prevPrevLen: failed = true @@ -260,7 +292,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()