Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
11 changes: 11 additions & 0 deletions lib/create-config-gypi.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,17 @@ async function getCurrentConfigGypi ({ gyp, nodeDir, vsInfo, python }) {
const defaults = config.target_defaults
const variables = config.variables

// When node itself is an Android build (e.g. Termux), process.config
// reports OS "android". gyp then enables Android-only branches (like the
// one referencing android_ndk_path in node's common.gypi) that only exist
// for NDK cross-compiles. Building a local addon on Android is a native
// build, not an NDK one, so normalize OS to linux. Honor custom headers
// (--nodedir/--dist-url): those may intentionally target Android via NDK.
if (process.platform === 'android' && variables.OS === 'android' &&
!(gyp.opts.nodedir || gyp.opts.disturl || gyp.opts['dist-url'])) {
variables.OS = 'linux'
}

// don't inherit the "defaults" from the base config.gypi.
// doing so could cause problems in cases where the `node` executable was
// compiled on a different machine (with different lib/include paths) than
Expand Down
49 changes: 49 additions & 0 deletions test/test-create-config-gypi.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,55 @@ describe('create-config-gypi', function () {
}
})

it('config.gypi normalizes OS to linux when running on Android (e.g. Termux)', async function () {
const prog = gyp()
prog.parseArgv([])

const originalPlatform = process.platform
const originalOS = process.config.variables.OS
Object.defineProperty(process, 'platform', { value: 'android' })
// node built for Android reports OS "android" in process.config
let canStubOS = true
try {
Object.defineProperty(process.config.variables, 'OS', { value: 'android', configurable: true })
} catch {
// process.config.variables is not extensible on some node builds
canStubOS = false
}
try {
const config = await getCurrentConfigGypi({ gyp: prog, vsInfo: {} })
// a local addon build on Android is native, not an NDK cross-compile
if (canStubOS) {
assert.strictEqual(config.variables.OS, 'linux')
} else {
assert.ok(config.variables)
}
} finally {
if (canStubOS) {
Object.defineProperty(process.config.variables, 'OS', { value: originalOS, configurable: true })
}
Object.defineProperty(process, 'platform', { value: originalPlatform })
}
})

it('config.gypi keeps OS from custom headers when using --nodedir on Android', async function () {
const nodeDir = path.join(__dirname, 'fixtures', 'nodedir')

const prog = gyp()
prog.parseArgv(['_', '_', `--nodedir=${nodeDir}`])

const originalPlatform = process.platform
Object.defineProperty(process, 'platform', { value: 'android' })
try {
const config = await getCurrentConfigGypi({ gyp: prog, nodeDir, vsInfo: {} })
// explicit custom headers may intentionally target Android via NDK:
// OS must come from the custom config.gypi, not process.config
assert.strictEqual(config.variables.OS, undefined)
} finally {
Object.defineProperty(process, 'platform', { value: originalPlatform })
}
})

it('config.gypi parsing', function () {
const str = "# Some comments\n{'variables': {'multiline': 'A'\n'B'}}"
const config = parseConfigGypi(str)
Expand Down
Loading