From bc5e1332b8f8ac8b353e95063f474ee429ecee43 Mon Sep 17 00:00:00 2001 From: RetricSu Date: Tue, 30 Dec 2025 08:25:40 +0800 Subject: [PATCH 1/5] use portable if cpu-feature build fails --- README.md | 2 ++ package.json | 6 +++--- src/node/install.ts | 17 +++++++++++------ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 71b7fb9..8ede0e4 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,8 @@ pnpm install -g @offckb/cli _Require Node version `>= v20.0.0`. We recommend using latest [LTS](https://nodejs.org/en/download/package-manager) version of Node to run `offckb`_ +**Note for Windows users:** If installation fails due to native module compilation issues, the CLI will still work but may use portable binaries instead of optimized ones. For better performance, consider installing Visual Studio Build Tools. + ## Usage ```sh diff --git a/package.json b/package.json index 8549c77..9124b80 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,6 @@ }, "pnpm": { "onlyBuiltDependencies": [ - "cpu-features", "secp256k1" ] }, @@ -55,7 +54,6 @@ }, "devDependencies": { "@types/adm-zip": "^0.5.5", - "@types/cpu-features": "^0.0.3", "@types/node": "^20.17.24", "@types/node-fetch": "^2.6.11", "@types/semver": "^7.5.7", @@ -80,12 +78,14 @@ "child_process": "^1.0.2", "ckb-transaction-dumper": "^0.4.2", "commander": "^12.0.0", - "cpu-features": "^0.0.10", "http-proxy": "^1.18.1", "https-proxy-agent": "^7.0.5", "node-fetch": "2", "semver": "^7.6.0", "tar": "^6.2.1", "winston": "^3.17.0" + }, + "optionalDependencies": { + "cpu-features": "^0.0.10" } } diff --git a/src/node/install.ts b/src/node/install.ts index 3fee4bb..fdc56cd 100644 --- a/src/node/install.ts +++ b/src/node/install.ts @@ -9,7 +9,6 @@ import { Request } from '../util/request'; import { getCKBBinaryInstallPath, getCKBBinaryPath, readSettings } from '../cfg/setting'; import { encodeBinPathForTerminal } from '../util/encoding'; import { logger } from '../util/logger'; -import CPUFeatures from 'cpu-features'; export async function installCKBBinary(version: string) { const ckbBinPath = getCKBBinaryPath(version); @@ -150,11 +149,17 @@ function getExtension(): 'tar.gz' | 'zip' { } function isPortable(): boolean { - const features = CPUFeatures(); - if (features.arch === 'x86') { - const flags = features.flags as CPUFeatures.X86CpuFlags; - // if lacks any of the following instruction, use portable binary - return !(flags.avx2 && flags.sse4_2 && flags.bmi2 && flags.pclmulqdq); + try { + const CPUFeatures = require('cpu-features'); + const features = CPUFeatures(); + if (features.arch === 'x86') { + const flags = features.flags as any; // CPUFeatures.X86CpuFlags + // if lacks any of the following instruction, use portable binary + return !(flags.avx2 && flags.sse4_2 && flags.bmi2 && flags.pclmulqdq); + } + } catch (error) { + // If cpu-features fails to load (e.g., on Windows without build tools), assume portable + logger.warn('Failed to detect CPU features, using portable binary'); } return false; } From 09caefecc171b76b3db9365160b09d96423938d6 Mon Sep 17 00:00:00 2001 From: RetricSu Date: Tue, 30 Dec 2025 09:44:22 +0800 Subject: [PATCH 2/5] fix pnpm-lock --- pnpm-lock.yaml | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9e4a9dc..9e0c747 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,9 +35,6 @@ importers: commander: specifier: ^12.0.0 version: 12.1.0 - cpu-features: - specifier: ^0.0.10 - version: 0.0.10 http-proxy: specifier: ^1.18.1 version: 1.18.1 @@ -60,9 +57,6 @@ importers: '@types/adm-zip': specifier: ^0.5.5 version: 0.5.7 - '@types/cpu-features': - specifier: ^0.0.3 - version: 0.0.3 '@types/node': specifier: ^20.17.24 version: 20.17.24 @@ -102,6 +96,10 @@ importers: typescript: specifier: ^5.3.3 version: 5.8.2 + optionalDependencies: + cpu-features: + specifier: ^0.0.10 + version: 0.0.10 packages: @@ -357,9 +355,6 @@ packages: '@types/adm-zip@0.5.7': resolution: {integrity: sha512-DNEs/QvmyRLurdQPChqq0Md4zGvPwHerAJYWk9l2jCbD1VPpnzRJorOdiq4zsw09NFbYnhfsoEhWtxIzXpn2yw==} - '@types/cpu-features@0.0.3': - resolution: {integrity: sha512-W/Ep+LDZoxMbCcH7LHRB3RN+TY4gbHl3u4uRq4XsxOh1gnpf5Lkwy5xWTBKSaJYQuMLW2XPAmRWA5Ucsy2EGVQ==} - '@types/http-proxy@1.17.16': resolution: {integrity: sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w==} @@ -1998,8 +1993,6 @@ snapshots: dependencies: '@types/node': 20.17.24 - '@types/cpu-features@0.0.3': {} - '@types/http-proxy@1.17.16': dependencies: '@types/node': 20.17.24 @@ -2268,7 +2261,8 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 - buildcheck@0.0.6: {} + buildcheck@0.0.6: + optional: true call-bind-apply-helpers@1.0.2: dependencies: @@ -2375,6 +2369,7 @@ snapshots: dependencies: buildcheck: 0.0.6 nan: 2.22.2 + optional: true create-hash@1.2.0: dependencies: From 8bad47086483300302546496bf24b13a29e97280 Mon Sep 17 00:00:00 2001 From: RetricSu Date: Tue, 30 Dec 2025 09:53:43 +0800 Subject: [PATCH 3/5] fix isPortable --- src/node/install.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/node/install.ts b/src/node/install.ts index fdc56cd..bc40997 100644 --- a/src/node/install.ts +++ b/src/node/install.ts @@ -157,11 +157,12 @@ function isPortable(): boolean { // if lacks any of the following instruction, use portable binary return !(flags.avx2 && flags.sse4_2 && flags.bmi2 && flags.pclmulqdq); } + return false; } catch (error) { - // If cpu-features fails to load (e.g., on Windows without build tools), assume portable + // If cpu-features fails to load (e.g., on Windows without build tools), use portable binary logger.warn('Failed to detect CPU features, using portable binary'); + return true; } - return false; } function buildCKBGithubReleasePackageName(version: string, opt: { os?: string; arch?: string } = {}) { From f091b5fb28bff5f3748ca9fb7e33c40e487e4435 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Dec 2025 10:49:29 +0800 Subject: [PATCH 4/5] Memoize isPortable() and add error logging (#345) * Initial plan * Apply review suggestions: add error logging and memoize isPortable Co-authored-by: RetricSu <23436060+RetricSu@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: RetricSu <23436060+RetricSu@users.noreply.github.com> --- src/node/install.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/node/install.ts b/src/node/install.ts index bc40997..3425669 100644 --- a/src/node/install.ts +++ b/src/node/install.ts @@ -148,21 +148,30 @@ function getExtension(): 'tar.gz' | 'zip' { return 'zip'; } +let cachedIsPortable: boolean | undefined = undefined; + function isPortable(): boolean { + if (cachedIsPortable !== undefined) { + return cachedIsPortable; + } + try { const CPUFeatures = require('cpu-features'); const features = CPUFeatures(); if (features.arch === 'x86') { const flags = features.flags as any; // CPUFeatures.X86CpuFlags // if lacks any of the following instruction, use portable binary - return !(flags.avx2 && flags.sse4_2 && flags.bmi2 && flags.pclmulqdq); + cachedIsPortable = !(flags.avx2 && flags.sse4_2 && flags.bmi2 && flags.pclmulqdq); + } else { + cachedIsPortable = false; } - return false; } catch (error) { // If cpu-features fails to load (e.g., on Windows without build tools), use portable binary - logger.warn('Failed to detect CPU features, using portable binary'); - return true; + logger.warn('Failed to detect CPU features, using portable binary', error); + cachedIsPortable = true; } + + return cachedIsPortable; } function buildCKBGithubReleasePackageName(version: string, opt: { os?: string; arch?: string } = {}) { From c2c6ed9259e3c8aa5ab1bdf61d684d0590778e79 Mon Sep 17 00:00:00 2001 From: RetricSu Date: Tue, 30 Dec 2025 10:50:49 +0800 Subject: [PATCH 5/5] chore: fmt --- src/node/install.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/install.ts b/src/node/install.ts index 3425669..dbb8136 100644 --- a/src/node/install.ts +++ b/src/node/install.ts @@ -170,7 +170,7 @@ function isPortable(): boolean { logger.warn('Failed to detect CPU features, using portable binary', error); cachedIsPortable = true; } - + return cachedIsPortable; }