diff --git a/cli/src/api/templates/js-binding.ts b/cli/src/api/templates/js-binding.ts index f3d14d10..5061e7e3 100644 --- a/cli/src/api/templates/js-binding.ts +++ b/cli/src/api/templates/js-binding.ts @@ -16,18 +16,52 @@ let nativeBinding = null let localFileExisted = false let loadError = null -function isMusl() { - // For Node 10 - if (!process.report || typeof process.report.getReport !== 'function') { - try { - const lddPath = require('child_process').execSync('which ldd').toString().trim() - return readFileSync(lddPath, 'utf8').includes('musl') - } catch (e) { - return true +const isMusl = () => { + let musl = false; + if (process.platform === 'linux') { + musl = isMuslFromFilesystem(); + if (musl === null) { + musl = isMuslFromReport(); } - } else { - const { glibcVersionRuntime } = process.report.getReport().header - return !glibcVersionRuntime + if (musl === null) { + musl = isMuslFromChildProcess(); + } + } + return musl; +}; + +const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-'); + +const isMuslFromFilesystem = () => { + try { + return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl'); + } catch { + return null; + } +} + +const isMuslFromReport = () => { + const report = typeof process.report.getReport === 'function' ? process.report.getReport() : null; + if (!report) { + return null; + } + if (report.header && report.header.glibcVersionRuntime) { + return false; + } + if (Array.isArray(report.sharedObjects)) { + if (report.sharedObjects.some(isFileMusl)) { + return true; + } + } + return false; +}; + +const isMuslFromChildProcess = () => { + try { + return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl'); + } catch (e) { + // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false + return false; } }