Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support rebuild and build for cross-compiling Node-API module to wasm on Windows #2974

Merged
merged 15 commits into from
Jun 28, 2024
Merged
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ jobs:
FULL_TEST: ${{ (matrix.node == '20.x' && matrix.python == '3.12') && '1' || '0' }}
- name: Run Tests (Windows)
if: startsWith(matrix.os, 'windows')
shell: pwsh
run: npm run test --python="${env:pythonLocation}\\python.exe"
shell: bash # Building wasm on Windows requires using make generator, it only works in bash
run: npm run test --python="${pythonLocation}\\python.exe"
env:
FULL_TEST: ${{ (matrix.node == '20.x' && matrix.python == '3.12') && '1' || '0' }}
33 changes: 20 additions & 13 deletions lib/build.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict'

const fs = require('graceful-fs').promises
const gracefulFs = require('graceful-fs')
const fs = gracefulFs.promises
const path = require('path')
const { glob } = require('glob')
const log = require('./log')
Expand Down Expand Up @@ -85,59 +86,65 @@ async function build (gyp, argv) {
async function findSolutionFile () {
const files = await glob('build/*.sln')
if (files.length === 0) {
throw new Error('Could not find *.sln file. Did you run "configure"?')
if (gracefulFs.existsSync('build/Makefile') || (await glob('build/*.mk')).length !== 0) {
command = makeCommand
await doWhich(false)
return
} else {
throw new Error('Could not find *.sln file or Makefile. Did you run "configure"?')
}
}
guessedSolution = files[0]
log.verbose('found first Solution file', guessedSolution)
await doWhich()
await doWhich(true)
}

/**
* Uses node-which to locate the msbuild / make executable.
*/

async function doWhich () {
async function doWhich (msvs) {
// On Windows use msbuild provided by node-gyp configure
if (win) {
if (msvs) {
if (!config.variables.msbuild_path) {
throw new Error('MSBuild is not set, please run `node-gyp configure`.')
}
command = config.variables.msbuild_path
log.verbose('using MSBuild:', command)
await doBuild()
await doBuild(msvs)
return
}

// First make sure we have the build command in the PATH
const execPath = await which(command)
log.verbose('`which` succeeded for `' + command + '`', execPath)
await doBuild()
await doBuild(msvs)
}

/**
* Actually spawn the process and compile the module.
*/

async function doBuild () {
async function doBuild (msvs) {
// Enable Verbose build
const verbose = log.logger.isVisible('verbose')
let j

if (!win && verbose) {
if (!msvs && verbose) {
argv.push('V=1')
}

if (win && !verbose) {
if (msvs && !verbose) {
argv.push('/clp:Verbosity=minimal')
}

if (win) {
if (msvs) {
// Turn off the Microsoft logo on Windows
argv.push('/nologo')
}

// Specify the build type, Release by default
if (win) {
if (msvs) {
// Convert .gypi config target_arch to MSBuild /Platform
// Since there are many ways to state '32-bit Intel', default to it.
// N.B. msbuild's Condition string equality tests are case-insensitive.
Expand Down Expand Up @@ -173,7 +180,7 @@ async function build (gyp, argv) {
}
}

if (win) {
if (msvs) {
// did the user specify their own .sln file?
const hasSln = argv.some(function (arg) {
return path.extname(arg) === '.sln'
Expand Down
24 changes: 22 additions & 2 deletions lib/configure.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,28 @@ async function configure (gyp, argv) {
log.verbose(
'build dir', '"build" dir needed to be created?', isNew ? 'Yes' : 'No'
)
const vsInfo = win ? await findVisualStudio(release.semver, gyp.opts['msvs-version']) : null
return createConfigFile(vsInfo)
if (win) {
let usingMakeGenerator = false
for (let i = argv.length - 1; i >= 0; --i) {
const arg = argv[i]
if (arg === '-f' || arg === '--format') {
const format = argv[i + 1]
if (typeof format === 'string' && format.startsWith('make')) {
usingMakeGenerator = true
break
}
} else if (arg.startsWith('--format=make')) {
usingMakeGenerator = true
break
}
}
let vsInfo = {}
if (!usingMakeGenerator) {
vsInfo = await findVisualStudio(release.semver, gyp.opts['msvs-version'])
toyobayashi marked this conversation as resolved.
Show resolved Hide resolved
}
return createConfigFile(vsInfo)
}
return createConfigFile(null)
}

async function createConfigFile (vsInfo) {
Expand Down
8 changes: 8 additions & 0 deletions test/node_modules/hello_napi/binding.gyp

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

110 changes: 110 additions & 0 deletions test/node_modules/hello_napi/common.gypi

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

54 changes: 54 additions & 0 deletions test/node_modules/hello_napi/hello.c

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

57 changes: 57 additions & 0 deletions test/node_modules/hello_napi/hello.js

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

11 changes: 11 additions & 0 deletions test/node_modules/hello_napi/package.json

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

Loading
Loading