Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 40 additions & 20 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,6 @@ jobs:

- uses: pnpm/action-setup@v4
if: ${{ matrix.native }}
with:
version: 9

- name: Install Node 20
if: ${{ matrix.native }}
Expand Down Expand Up @@ -147,8 +145,7 @@ jobs:
- name: Build Native Windows 32
if: ${{ matrix.os == 'windows-2019' && matrix.node_arch == 'ia32' }}
run:
node ./node_modules/cmake-ts/build/main.js named-configs
windows-x86
node ./node_modules/cmake-ts/build/main.js named-configs windows-x86

- name: Use Node 20
if: ${{ matrix.native }}
Expand Down Expand Up @@ -245,30 +242,55 @@ jobs:
runs-on: ubuntu-latest
needs: Build
steps:
- name: Merge Artifacts
uses: actions/upload-artifact/merge@v4
with:
name: build
pattern: build-*
delete-merged: true

- uses: actions/checkout@v4

- name: Place build
uses: actions/download-artifact@v4
with:
name: build
path: ./build

- name: Install Node
uses: actions/setup-node@v4
with:
node-version-file: "./.nvmrc"

- name: Install Pnpm
uses: pnpm/action-setup@v4

- name: Download Artifacts
uses: actions/download-artifact@v4
with:
version: 9
name: build
pattern: build-*
path: ./build-artifacts

- name: Create build directory
shell: bash
run: mkdir -p ./build

- name: Merge Manifests
shell: python
run: |
import json
import os
import sys

# Get the list of files in the build-artifacts directory
build_artifacts_dir = os.path.join(os.getcwd(), 'build-artifacts')
manifest_files = [os.path.join(build_artifacts_dir, f) for f in os.listdir(build_artifacts_dir) if f.endswith('.json')]
merged_manifest = {}
for file in manifest_files:
with open(file, 'r') as f:
manifest = json.load(f)
for key, value in manifest.items():
if key not in merged_manifest:
merged_manifest[key] = value
else:
merged_manifest[key] += value
Comment thread
aminya marked this conversation as resolved.
Outdated
with open('./build/manifest.json', 'w') as f:
json.dump(merged_manifest, f)

- name: Merge Artifacts
shell: bash
run: |
for folder in ./build-artifacts/*; do
mv "$folder" ./build/
done

- name: Pack Zeromq
run: |
Expand Down Expand Up @@ -324,8 +346,6 @@ jobs:
- name: Install Pnpm 9
if: matrix.node-version == 22
uses: pnpm/action-setup@v4
with:
version: 9

- uses: actions/checkout@v4

Expand Down
44 changes: 40 additions & 4 deletions lib/load-addon.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/load-addon.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
},
"homepage": "http://zeromq.github.io/zeromq.js/",
"dependencies": {
"cmake-ts": "^0.5.3",
"cmake-ts": "^0.6.0",
"node-addon-api": "^8.3.0"
},
"devDependencies": {
Expand Down Expand Up @@ -67,9 +67,9 @@
"which": "^5.0.0"
},
"engines": {
"node": ">= 12",
"pnpm": ">= 9"
"node": ">= 12"
},
"packageManager": "[email protected]",
"overrides": {
"typescript": "~4.9.5",
"node-gyp": "10.0.1"
Expand Down
10 changes: 5 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

84 changes: 71 additions & 13 deletions src/load-addon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,43 @@ function devWarn(message: string) {
function findAddon(): any | undefined {
let addon: undefined | any = undefined
try {
const addonParentDir = path.resolve(
path.join(
__dirname,
"..",
"build",
process.platform,
process.arch,
"node",
),
)
const addOnAbiDirs = fs.readdirSync(addonParentDir).sort((a, b) => {
const buildDir = path.resolve(__dirname, "..", "build")

const manifest = JSON.parse(
fs.readFileSync(path.resolve(buildDir, "manifest.json"), "utf-8"),
) as Record<string, string>

// compatible addons (abi -> addon path)
const compatibleAddons: Record<string, string> = {}

const configs = Object.keys(manifest)
for (const configStr of configs) {
const config = JSON.parse(configStr) as BuildConfiguration

// check if the config is compatible with the current runtime
if (config.os !== process.platform || config.arch !== process.arch) {
continue
}
const libc = detectLibc()
if (config.libc !== libc) {
continue
}

const addonRelativePath = manifest[configStr]
compatibleAddons[config.abi ?? 0] = path.resolve(
buildDir,
addonRelativePath,
)
Comment thread
aminya marked this conversation as resolved.
Outdated
}

// sort the compatible abis in descending order
const compatibleAbis = Object.keys(compatibleAddons).sort((a, b) => {
return Number.parseInt(b, 10) - Number.parseInt(a, 10)
})

// try each available addon ABI
for (const addOnAbiDir of addOnAbiDirs) {
const addonPath = path.join(addonParentDir, addOnAbiDir, "addon.node")
for (const abi of compatibleAbis) {
const addonPath = compatibleAddons[abi]
try {
addon = require(addonPath)
break
Expand All @@ -57,5 +77,43 @@ function findAddon(): any | undefined {
return addon
}

/**
* Build configuration (from cmake-ts)
*/
type BuildConfiguration = {
name: string
dev: boolean
os: typeof process.platform
arch: typeof process.arch
runtime: string
runtimeVersion: string
toolchainFile: string | null
CMakeOptions?: {name: string; value: string}[]
addonSubdirectory: string
// list of additional definitions to fixup node quirks for some specific versions
additionalDefines: string[]
/** The ABI number that is used by the runtime. */
abi?: number
/** The libc that is used by the runtime. */
libc?: string
}

/**
* Detect the libc used by the runtime (from cmake-ts)
*/
function detectLibc() {
if (process.platform === "linux") {
if (fs.existsSync("/etc/alpine-release")) {
return "musl"
}
return "glibc"
} else if (process.platform === "darwin") {
return "libc"
} else if (process.platform === "win32") {
return "msvc"
}
return "unknown"
}

const addon = findAddon()
export default addon
Loading