Module did not self-register only for Windows platform
Related but different from #2695
We have a Go library with JS bindings, see https://github.com/tdewolff/minify/tree/master/bindings/js which builds a Go library (using MingW) to a C archive, then we use that together with the C file to build the NAPI binary. I use GitHub actions to build on each platform, see https://github.com/tdewolff/minify/blob/master/.github/workflows/nodejs.yml.
The native addon builds and runs for Ubuntu and MacOS, but for Windows it keeps giving the error "Module did not self-register" at https://github.com/tdewolff/minify/runs/7293618101?check_suite_focus=true#step:6:94. Is there anyway to get a more specific error or debug message what is going on?
The Node and NPM version is the same which usually seems to cause this issue. Perhaps is using the MSVC compiler with GYP together with the MingW compiler for Go causing the problem. Since Go must use MingW, can I configure GYP to use MingW?
I figured out that on Windows you can only compile a node-gyp module using MSVC, while Go only supports compiling with GCC. I don't think you can load a non-MSVC module in Windows for a Node native module. Apparently, neither node-gyp wants to support GCC, and Go doesn't want to support MSVC, so I'm stuck in the middle I'm afraid.
@StefanStojanovic Any ideas on this one or #2695?
Unfortunately, I do not have any experience with this type of issue, but from what I saw here and in https://github.com/nodejs/node-gyp/issues/2855 I have a suggestion - @tdewolff did you try using Node.js FFI and would that be feasible for your use case?
This issue seems no longer relevant as it has been stale for a long time. If there are no objections, I will close this issue next Mon-Tue. In case something similar happens again please open a new issue.
The problem is that Go only supports compiling with MingW, and node-gyp (or some third-party library) only supports compiling with Microsoft's compiler. Neither side budges so there isn't really a solution. I've given up on it at least, and you may close both issues if you wish. Thanks anyways!
Can this be reproduced when NOT using the unmaintained node-pre-gyp?
I don't think I used node-pre-gyp, I seem to be using https://github.com/prebuild/prebuildify. But as I said, this more of a platform issue...you could argue that the Go team needs to add support for MSVC, but you could also argue that we should be able to use the MingW compiler for pre-build binaries with node-gyp...
Can you please rerun the GitHub Action error so we can see the output. The one in the run above has aged out.
Yes, here is the new run: https://github.com/tdewolff/minify/actions/runs/8745650432/job/24001045387
Relevant part:
Building Go library...
mingw32-make: Entering directory 'D:/a/minify/minify/bindings/js'
go build -buildmode=c-archive -o minify.a minify.go
go: downloading github.com/tdewolff/minify/v2 v2.12.5
go: downloading github.com/tdewolff/parse/v2 v2.6.5
mingw32-make: Leaving directory 'D:/a/minify/minify/bindings/js'
win_delay_load_hook.cc
Generating code
Previous IPDB not found, fall back to full compilation.
All 1 functions were compiled because no usable IPDB/IOBJ from previous compilation was found.
Finished generating code
minify.vcxproj -> D:\a\minify\minify\bindings\js\build\Release\\minify.node
gyp info ok
added 103 packages, and audited 104 packages in 3m
14 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
> @tdewolff/[email protected] test
> node test/index.js
node:internal/modules/cjs/loader:1465
return process.dlopen(module, path.toNamespacedPath(filename));
^
Error: Module did not self-register: '\\?\D:\a\minify\minify\bindings\js\build\Release\minify.node'.
at Module._extensions..node (node:internal/modules/cjs/loader:1465:18)
at Module.load (node:internal/modules/cjs/loader:1206:32)
at Module._load (node:internal/modules/cjs/loader:1022:12)
at Module.require (node:internal/modules/cjs/loader:1231:19)
at require (node:internal/modules/helpers:179:18)
at load (D:\a\minify\minify\bindings\js\node_modules\node-gyp-build\node-gyp-build.js:22:10)
at file:///D:/a/minify/minify/bindings/js/index.js:9:66
at ModuleJob.run (node:internal/modules/esm/module_job:222:25)
at async ModuleLoader.import (node:internal/modules/esm/loader:323:24)
at async loadESM (node:internal/process/esm_loader:28:7) {
code: 'ERR_DLOPEN_FAILED'
}
Node.js v20.12.2
The error is really unhelpful, but I'm fairly sure this is due to using a MinW compiled archive while node-gyp seems to use MSVC. This would cause the symbols be mixed up (both compilers use a different naming scheme for their linker symbols) and thus doesn't load. I'm not sure why the linker allows them to be linked at all, shouldn't the linker throw an error? I'm not an expert though, but I've noticed this issue from 5 years back that might be relevant: https://github.com/nodejs/node-gyp/issues/1240. Thanks a lot for looking into this @cclauss ! Your time is highly appreciated.