Skip to content
Merged
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
35 changes: 35 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,38 @@ jobs:
- name: Prebuild
shell: bash
run: npm run prebuild

test-mingw:
name: Test MinGW (MSYS2 MINGW64) on Windows
runs-on: windows-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up MSYS2 with MINGW64
uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
update: true
install: >-
mingw-w64-x86_64-nodejs
mingw-w64-x86_64-python
mingw-w64-x86_64-gcc
make

- name: Verify MinGW Node.js is active
shell: msys2 {0}
run: node -e "const os = require('os'); console.log('os.type():', os.type()); if (!os.type().startsWith('MINGW')) process.exit(1)"

- name: Install dependencies
shell: msys2 {0}
run: npm install

- name: Build native tests
shell: msys2 {0}
run: npm run build

- name: Run tests
shell: msys2 {0}
run: npm test
49 changes: 33 additions & 16 deletions deps/libffi/libffi.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@
{
'variables': {
'target_arch%': 'ia32', # built for a 32-bit CPU by default
# Distinguish MSVC from MinGW/MSYS2 on Windows. MinGW-compiled Node reports
# an OS type starting with "MINGW", but MSYS2 subsystems like UCRT64 ship a
# Windows-native Node where os.type() returns "Windows_NT". Real MSYS2 sets
# MSYSTEM_PREFIX (e.g. /mingw64, /ucrt64); Git for Windows also sets MSYSTEM
# but does NOT set MSYSTEM_PREFIX, so we use that to avoid false positives
# in Git Bash environments. Either signal means GCC is the toolchain, so .S
# files compile directly without the MSVC preprocess_asm.cmd step.
'target_platform%': '<!(node -p "require(\'os\').type().startsWith(\'MINGW\') || process.env.MSYSTEM_PREFIX ? \'mingw\' : (process.platform === \'win32\' ? \'msvc\' : \'\')")',
},
'target_defaults': {
'default_configuration': 'Debug',
Expand Down Expand Up @@ -50,9 +58,10 @@
],
},

# Compile .S files on Windows
# MSVC-specific rules for preprocessing .preasm -> .asm -> .obj.
# MinGW uses GCC and compiles .S files directly without these rules.
'conditions': [
['OS=="win"', {
['OS=="win" and target_platform=="msvc"', {
'target_defaults': {
'conditions': [
['target_arch=="ia32"', {
Expand Down Expand Up @@ -151,38 +160,51 @@
['OS=="linux" or OS=="mac"', {
'sources': [ 'src/aarch64/sysv.S' ]
}],
['OS=="win"', {
['OS=="win" and target_platform=="msvc"', {
'sources': [ 'src/aarch64/win64_armasm.preasm' ]
}],
['OS=="win" and target_platform=="mingw"', {
'sources': [ 'src/aarch64/sysv.S' ]
}],
]
}, { # ia32 or x64
'conditions': [
['target_arch=="ia32"', {
'sources': [ 'src/x86/ffi.c' ],
'conditions': [
['OS=="win"', {
['OS=="win" and target_platform=="msvc"', {
'sources': [ 'src/x86/sysv_intel.preasm' ],
}, {
}],
['OS=="win" and target_platform=="mingw"', {
'sources': [ 'src/x86/sysv.S' ],
}],
['OS!="win"', {
'sources': [ 'src/x86/sysv.S' ],
}],
],
}],
['target_arch=="x64"', {
'sources': [
'src/x86/ffiw64.c',
],
'conditions': [
['OS=="win"', {
['OS=="win" and target_platform=="msvc"', {
'sources': [
'src/x86/ffiw64.c',
'src/x86/win64_intel.preasm',
],
}, {
'msvs_disabled_warnings': [ 4267 ],
}],
['OS=="win" and target_platform=="mingw"', {
'sources': [
'src/x86/ffiw64.c',
'src/x86/win64.S',
],
}],
['OS!="win"', {
'sources': [
'src/x86/ffi64.c',
'src/x86/unix64.S',
'src/x86/win64.S',
],
}]
}],
],
}],
['target_arch=="s390x"', {
Expand All @@ -191,11 +213,6 @@
'src/s390/sysv.S',
],
}],
['OS=="win"', {
# the libffi dlmalloc.c file has a bunch of implicit conversion
# warnings, and the main ffi.c file contains one, so silence them
'msvs_disabled_warnings': [ 4267 ],
}],
]
}],
]
Expand Down
12 changes: 6 additions & 6 deletions package-lock.json

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

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@napi-ffi/ffi-napi",
"version": "4.0.4",
"version": "4.0.5",
"license": "MIT",
"author": "Anna Henningsen <anna@addaleax.net>",
"contributors": [
Expand Down Expand Up @@ -33,7 +33,7 @@
"@napi-ffi/get-uv-event-loop-napi-h": "^1.0.6",
"node-addon-api": "^8.2.1",
"node-gyp-build": "^4.8.2",
"@napi-ffi/ref-napi": "^3.0.6",
"@napi-ffi/ref-napi": "^3.0.7",
"@napi-ffi/ref-struct-di": "^1.1.1"
},
"devDependencies": {
Expand Down
21 changes: 12 additions & 9 deletions test/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,22 @@ describe('Library', function () {
});

it('should accept `null` as a first argument', function () {
if (process.platform == 'win32') {
// On Windows, null refers to just the main executable (e.g. node.exe).
// Windows never searches for symbols across multiple DLL's.
// Note: Exporting symbols from an executable is unusual on Windows.
// Normally you only see exports from DLL's. It happens that node.exe
// does export symbols, so null as a first argument can be tested.
// This is an implementation detail of node, and could potentially
// change in the future (e.g. if node gets broken up into DLL's
// rather than being one large static linked executable).
if (process.platform == 'win32' && !process.env.MSYSTEM_PREFIX) {
// On Windows (MSVC builds), null refers to just the main executable
// (e.g. node.exe). Windows never searches for symbols across DLLs.
// node.exe happens to export uv_fs_open, so null can be tested here.
// This is an implementation detail of node that does not hold for
// MSYS2/MinGW builds where libuv may be a separate DLL or symbols
// are not re-exported from the node binary.
const winFuncs = new Library(null, {
'uv_fs_open': [ 'void', [ charPtr ] ]
});
assert(typeof winFuncs.uv_fs_open === 'function');
} else if (process.platform == 'win32') {
// MinGW/MSYS2: null is supported but uv_fs_open is not guaranteed
// to be exported from the node binary, skip the symbol check.
const l = new Library(null, {});
assert(typeof l === 'object');
} else {
// On POSIX, null refers to the global symbol table, and lets you use
// symbols in the main executable and loaded shared libaries.
Expand Down
Loading