Skip to content

Commit abb091e

Browse files
authored
Merge pull request #43 from EmbeddedEnterprises/runtime-registry
feat: create a manifest for the built configurations + include glibc/abi
2 parents fb608b6 + c81b6fd commit abb091e

File tree

6 files changed

+104
-27
lines changed

6 files changed

+104
-27
lines changed

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
},
3737
"bin": "build/main.js",
3838
"scripts": {
39-
"clean": "shx rm -rf build",
39+
"clean": "shx rm -rf build ./test/.tmp",
4040
"lint.eslint": "eslint . --cache --cache-location ./.cache/.eslintcache \"./**/*.{js,ts,mjs,mts,cjs,cts,json,yaml,yml}\" --fix",
4141
"lint.biome": "biome check --write --unsafe .",
4242
"lint": "turbo run lint.eslint lint.biome",
@@ -87,6 +87,7 @@
8787
"@types/tar": "^6.1.13",
8888
"@types/url-join": "~4.0.3",
8989
"@types/which": "~3.0.4",
90+
"@types/escape-quotes": "^1.0.0",
9091
"@upleveled/babel-plugin-remove-node-prefix": "^1.0.5",
9192
"turbo": "^2.4.4",
9293
"cross-env": "^7.0.3",
@@ -113,9 +114,10 @@
113114
"tar": "^6",
114115
"url-join": "^4.0.1",
115116
"which": "^2",
116-
"node-downloader-helper": "^2.1.7"
117+
"node-downloader-helper": "^2.1.7",
118+
"escape-quotes": "^1.0.2"
117119
},
118-
"packageManager": "pnpm@10.6.5",
120+
"packageManager": "pnpm@10.7.0",
119121
"$schema": "https://raw.githubusercontent.com/SchemaStore/schemastore/master/src/schemas/json/package.json",
120122
"pnpm": {
121123
"onlyBuiltDependencies": ["core-js", "esbuild"]

pnpm-lock.yaml

Lines changed: 19 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/lib.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ export type BuildConfigurationDefaulted = {
1717

1818
// list of additional definitions to fixup node quirks for some specific versions
1919
additionalDefines: string[]
20+
21+
/** The ABI number that is used by the runtime. */
22+
abi?: number
23+
24+
/** The libc that is used by the runtime. */
25+
libc?: string
2026
}
2127

2228
export type BuildConfiguration = Partial<BuildConfigurationDefaulted>

src/main.ts

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
/* eslint-disable node/shebang */
44

5-
import { join, resolve } from "path"
6-
import { copy, ensureDir, pathExists, readJson, remove } from "fs-extra"
5+
import { join, relative, resolve } from "path"
6+
import { copy, ensureDir, pathExists, readFile, readJson, remove, writeFile } from "fs-extra"
77
import { ArgumentBuilder } from "./argumentBuilder.js"
88
import { determineBuildMode } from "./buildMode.js"
99
import { type BuildOptions, defaultBuildConfiguration, defaultBuildOptions } from "./lib.js"
@@ -127,19 +127,28 @@ async function main(): Promise<void> {
127127
// Copy back the previously built binary
128128
process.stdout.write(`> Copying ${configs.projectName}.node to target directory... `)
129129
await ensureDir(targetDir)
130-
if (configs.generatorToUse.includes("Visual Studio")) {
131-
if (DEBUG_LOG !== undefined) {
132-
console.log("Applying copy fix for MSVC projects")
133-
}
134-
await copy(
135-
join(stagingDir, configs.buildType, `${configs.projectName}.node`),
136-
join(targetDir, `${configs.projectName}.node`),
137-
)
138-
} else {
139-
await copy(join(stagingDir, `${configs.projectName}.node`), join(targetDir, `${configs.projectName}.node`))
140-
}
130+
131+
const addonPath = join(targetDir, `${configs.projectName}.node`)
132+
const sourceAddonPath = configs.generatorToUse.includes("Visual Studio")
133+
? join(stagingDir, configs.buildType, `${configs.projectName}.node`)
134+
: join(stagingDir, `${configs.projectName}.node`)
135+
await copy(sourceAddonPath, addonPath)
136+
141137
console.log("[ DONE ]")
142138

139+
console.log("Adding the built config to the manifest file...")
140+
141+
// read the manifest if it exists
142+
const manifestPath = join(configs.targetDirectory, "manifest.json")
143+
let manifest: Record<string, string> = {}
144+
if (await pathExists(manifestPath)) {
145+
const manifestContent = await readFile(manifestPath, "utf-8")
146+
manifest = JSON.parse(manifestContent)
147+
}
148+
// add the new entry to the manifest
149+
manifest[JSON.stringify(config)] = relative(configs.targetDirectory, addonPath)
150+
await writeFile(manifestPath, JSON.stringify(manifest, null, 2))
151+
143152
console.log("----------------- END CONFIG -----------------")
144153
}
145154
}

src/runtimeDistribution.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { extname, join as joinPath } from "path"
22
import glob from "fast-glob"
3-
import { ensureDir, readFile } from "fs-extra"
3+
import { ensureDir, pathExists, readFile } from "fs-extra"
44
import urlJoin from "url-join"
55
import { downloadFile, downloadTgz, downloadToString } from "./download.js"
66
import type { BuildConfigurationDefaulted } from "./lib.js"
@@ -112,6 +112,11 @@ export class RuntimeDistribution {
112112
return Promise.reject(new Error("Invalid version specified by NODE_MODULE_VERSION macro"))
113113
}
114114
this._abi = version
115+
116+
this.config.abi = version
117+
118+
this.config.libc = await detectLibc()
119+
115120
return Promise.resolve()
116121
}
117122

@@ -190,3 +195,17 @@ export class RuntimeDistribution {
190195
}
191196
}
192197
}
198+
199+
async function detectLibc() {
200+
if (process.platform === "linux") {
201+
if (await pathExists("/etc/alpine-release")) {
202+
return "musl"
203+
}
204+
return "glibc"
205+
} else if (process.platform === "darwin") {
206+
return "libc"
207+
} else if (process.platform === "win32") {
208+
return "msvc"
209+
}
210+
return "unknown"
211+
}

test/zeromq.test.ts

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ import { execFileSync } from "child_process"
22
import path, { join } from "path"
33
import { fileURLToPath } from "url"
44
import { isCI } from "ci-info"
5-
import glob from "fast-glob"
6-
import { existsSync, remove } from "fs-extra"
5+
import { existsSync, readJson, remove } from "fs-extra"
76
import { beforeAll, beforeEach, expect, suite, test } from "vitest"
7+
import type { BuildConfigurationDefaulted } from "../src/lib.js"
88
import { HOME_DIRECTORY } from "../src/urlRegistry.js"
9+
910
const dirname = typeof __dirname === "string" ? __dirname : path.dirname(fileURLToPath(import.meta.url))
1011
const root = path.dirname(dirname)
1112

@@ -46,14 +47,37 @@ suite("zeromq", { timeout: 300_000 }, (tests) => {
4647
cwd: zeromqPath,
4748
})
4849

49-
const addons = await glob(`build/${process.platform}/${process.arch}/node/*/addon.node`, {
50-
cwd: zeromqPath,
51-
absolute: true,
52-
onlyFiles: true,
53-
braceExpansion: false,
50+
const addonPath = `${process.platform}/${process.arch}/node/131/addon.node`
51+
52+
// check manifest file
53+
const manifestPath = join(zeromqPath, "build/manifest.json")
54+
expect(existsSync(manifestPath), `Manifest file ${manifestPath} does not exist`).toBe(true)
55+
const manifest = (await readJson(manifestPath)) as Record<string, string>
56+
57+
const configKey = JSON.parse(Object.keys(manifest)[0]) as BuildConfigurationDefaulted
58+
59+
const expectedConfig: BuildConfigurationDefaulted = {
60+
name: "",
61+
dev: false,
62+
os: process.platform,
63+
arch: process.arch,
64+
runtime: "node",
65+
runtimeVersion: process.versions.node,
66+
toolchainFile: null,
67+
CMakeOptions: [],
68+
addonSubdirectory: "",
69+
additionalDefines: [],
70+
abi: configKey.abi,
71+
libc: configKey.libc,
72+
}
73+
74+
expect(manifest).toEqual({
75+
[JSON.stringify(expectedConfig)]: addonPath,
5476
})
5577

56-
expect(addons.length).toBe(1)
78+
// check if the addon.node file exists
79+
const addonNodePath = join(zeromqPath, "build", addonPath)
80+
expect(existsSync(addonNodePath), `Addon node file ${addonNodePath} does not exist`).toBe(true)
5781
})
5882
}
5983
})

0 commit comments

Comments
 (0)