Skip to content

Commit

Permalink
feat: support rebuild and build for cross-compiling Node-API modu…
Browse files Browse the repository at this point in the history
…le to wasm on Windows (#2974)
  • Loading branch information
toyobayashi committed Jun 28, 2024
1 parent ea99fea commit 6318d2b
Show file tree
Hide file tree
Showing 9 changed files with 392 additions and 17 deletions.
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'])
}
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

0 comments on commit 6318d2b

Please sign in to comment.