node-datachannel
node-datachannel copied to clipboard
Compiling on windows on ARM64
Hey, I recently tried to download the webtorrent module and this dependency failed to build, after looking into it further it complained about openSSL, so i installed that, added it to the PATH and created the OPENSSL_ROOT_DIR env variable that cmake was complaining about, but now i'm getting tons of errors about function references.
I know github doesn't have WoA64 build servers yet so i'm gonna need your help to walk me through how to get it compiling.
Here's an extract of the build logs: https://pastebin.com/nkUUupcm
Looks like linker can not find OpenSSL static libs. You need to either install OpenSSL static libs or link dynamically.
Could you please replace this line and re-build? https://github.com/murat-dogan/node-datachannel/blob/5eb81072bc729a403a6148b656d6b88bce52463e/CMakeLists.txt#L23
set(OPENSSL_USE_STATIC_LIBS FALSE)
Installation fails again, here are the logs: https://pastebin.com/j0Ka3hZb sorry for the wait i was on vacation
Thanks for the Log. It still tries to link static. Could you also please comment this line; https://github.com/murat-dogan/node-datachannel/blob/431e160d1e40427c47c8547a3acaba7359ceb34f/CMakeLists.txt#L15
here's the logs https://pastebin.com/vTx3vWnG
It still tries to link statically. And I don't know why.
I have checked GitHub runners now, but unfortunately, there is no win arm64 yet to find a solution or better have prebuilt binaries.
I believe I managed to cross compile for ARM64 on Windows using VCPKG successfully. The steps I used are as follows. I do not have a windows on arm based machine, so I can't test if it actually works.
- Install Visual Studio Build Tools with the following "individual components" enabled.
- C++ Modules for v143 build tools (ARM64 -- experimental)
- C++ Universal Windows Platform support for v143 build tools (ARV64/ARM64EC)
- MSVC v143 - VS 2022 C++ ARM64/ARM64EC build tools (Latest)
- MSVC v143 - VS 2022 C++ ARM64/ARM64EC Spectre-mitigated libs (Latest)
- Initialize command prompt for cross compile using
"C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" amd64_arm64- If the host is an ARM64 machine, then you'd replace
amd64_arm64with justarm64
- If the host is an ARM64 machine, then you'd replace
- Install VCPKG and
set VCPKG_ROOT=<VCPKG install directory> - Install openssl with vcpkg using
%VCPKG_ROOT%\vcpkg install openssl:arm64-windows-static - To compile, run
npx cmake-js build -A ARM64 -a ARM64 --CDCMAKE_TOOLCHAIN_FILE=%VCPKG_ROOT%\scripts\buildsystems\vcpkg.cmake --CDVCPKG_TARGET_TRIPLET=arm64-windows-static
Hey there,
I tested this in parallels on my mac mini and I found that it almost immediately crashes when running in Release mode, however Debug builds work fine. I suspect it's due to this bug in openssl. I'll see if I'm able to find a workaround.
Hello @funniray,
Thank you for sharing this. By using the info that you have provided and some others, I could build it here; https://github.com/murat-dogan/node-datachannel/actions/runs/13737250799
@ShyneTurtle Could you please try this binary if it works? https://github.com/murat-dogan/node-datachannel/releases/download/v0.26.0/node-datachannel-v0.26.0-napi-v8-win32-arm64.tar.gz
Hey, i've never worked with precompiled libraries with node, could you walk me through installing it ? tried to look it up but didn't find any ressources. and thanks for the help @funniray
@murat-dogan
I tested that prebuilt binary on my m4 mac mini via a windows arm64 vm and found it to have the same behavior as my earlier attempts that almost immediately crashed due to access violations.
After a few hours of reading and testing, I was able to successfully compile openssl statically for windows on arm using clangcl and vcpkg. It worked almost the same as the prior instructions, but needed a custom triplet/toolchain for vcpkg installed. You would most likely include this file as an overlay triplet. Part of the triplet was recycled from https://github.com/Neumann-A/my-vcpkg-triplets/. Some things used may be un-necessary, I didn't want to push my luck too far, especially as compile times were much longer than expected.
ClangCL (in my case) was installed via the visual studio installer via the C++ Clang Compiler for Windows and MSBuild support for LLVM (clang-cl) toolset options. I was only able to get openssl itself statically compiled via clangcl, with node-datachannel itself being compiled via MSVC.
@ShyneTurtle
could you walk me through installing it
It should be as simple as copying the build folder to the root directory of the node-datachannel folder.
https://github.com/openssl/openssl/issues/26239#issuecomment-2561590370
With OpenSSL 3.2, there are no reported errors. What do you think?
With OpenSSL 3.2, there are no reported errors.
Two comments down he said
Please ignore both of my comments. I see now. Its the debug build that is not affected. Both ARM configs were affected for me.
Personally, trying to get openssl to work on windows on arm, I've tried openssl 3.4.1 (latest) openssl 3.0.8#2 (closest to nodejs's built in version, just in case) openssl 1.1.1n (in case it was a regression in openssl 3)
so far, every release build I've tried that was built with msvc will result in an access violation, crashing the nodejs thread with no output. The only ways I've actually got it to run successfully was to use a clang built binary or to run a debug binary. I was unable to get a working binary with msvc using the -DNO_INTERLOCKEDOR64 flag as suggested, but I might've done it wrong.
Running npx jest with the file you sent failed all tests.
I can install clang, what are the steps you used to build successfuly @funniray ?
I have to say the downer is that the laptop can run x64 apps through emulation (this is my dev machine) but because of node runtime checks it won't even try the binary.
I did some testing and I came to the conclusion that -DNO_INTERLOCKEDOR64 is able to successfully create a binary with msvc that compiles and passes the test.
With that being said, after a few hours of trial and error, I was unable to make vcpkg correctly use the cflag. You can see my attempt here.
I did make another branch that just compiles openssl directly without using vcpkg. I was able to get it to successfully compile a binary using msvc and it successfully passed all tests on my m4 mac mini. @ShyneTurtle You can try the build from here.
A few notable things about this branch
- OpenSSL is configured for
VC-WIN64-CLANGASM-ARM. This is what vcpkg does by default for arm64. Essentially, MSVC is used for C compilation/linking and clang is only used as the ARM64 assembler. - the CFLAGS environment variable is set for both the configure and make step. This probably is only required during the configure step, but I haven't checked
- I am using Jom instead of nmake for building openssl, as nmake isn't parallelized.
- I'd love to use either ninja or even jom to build node-datachannel itself, but if I attempt to change the generator to either nmake or ninja, cmake tells me that it's unavailable for arm64. I'm unsure why this is the case
Super @funniray
Thanks for your work.
I think we can use vcpkg + your suggestions to build the all versions of Windows (x64, x86, arm64) Like
jobs:
build-windows:
runs-on: windows-2022
strategy:
matrix:
node-version: [18]
arch: [x64, x86, arm64]
include:
- arch: x64
vcpkg_triplet: x64-windows-static-custom
msvc_arch: amd64
- arch: x86
vcpkg_triplet: x86-windows-static-custom
msvc_arch: amd64_x86
- arch: arm64
vcpkg_triplet: arm64-windows-static-custom
msvc_arch: amd64_arm64
steps:
- uses: actions/checkout@v4
......
I have tried to make it with prebuild, with no success.
What you think and could you please create a PR for this?
I spent a bit more time trying to get vcpkg to compile with -DNO_INTERLOCKEDOR64 and I was able to check the logs and I confirmed it was indeed compiling with the -DNO_INTERLOCKEDOR64 flag.
With that being said, the vcpkg binaries are still somehow crashing with the same exception on the same line as binaries built without -DNO_INTERLOCKEDOR64.
I'm really not sure where to go with vcpkg from here, especially as -DNO_INTERLOCKEDOR64 fixes the exceptions when building openssl directly without vcpkg.
@ShyneTurtle Did you have any chance to try the binary that was generated by @funniray?
@funniray How can we continue? It will be good to have win arm64 prebuilt binaries.
And also, if we can merge all windows build jobs and use vcpkg, it will be very nice. https://github.com/murat-dogan/node-datachannel/issues/330#issuecomment-2724148848
But not sure where to continue.
Sorry, i was busy for the last few weeks.
@funniray 's build passed all the tests on my Snapdragon X1 laptop !
I posted this on another thread, but it may be of use.
The /Od disabled flag resolves the vcpkg issue here.
We didn't try the various /Ox options, but they may offer more insight into the problem.
https://learn.microsoft.com/en-us/cpp/build/reference/o-options-optimize-code?view=msvc-170
@murat-dogan
How can we continue?
I'm honestly not sure, I know that it is possible to adapt my solution that builds openssl from source to other windows platforms (x86/x64). VCPKG is really annoying to test locally, as the package cache is in odd locations, and I don't have an amazing setup to run cross compiled code on my test machine.
@Nick7K
The /Od disabled flag resolves the vcpkg issue here.
That sounds about right as the debug version of openssl works fine. However, I don't believe it's an acceptable solution, especially as arm64 devices are already relatively underpowered
It appears to be fixed with VS 17.14. This may be the relevant update.
I tried making a new build with vs 17.14 and I can confirm that the build passes tests successfully
The currently windows-2025 image only has visual studio 17.13, but I'm sure they'll update eventually
I've also noticed that there are native arm images for both windows and ubuntu via github actions partner images. I'm unsure if you should use them for building, but they might be useful for testing
Hello, any updates on this ? will there be a new npm release i can use to include in my project, or another way i could manually include it ?
The windows server 2022 and 2025 images both are on 17.14, so they should now build OpenSSL via VCPKG without an issue.
Hello @ShyneTurtle
Could you please test this binary? https://github.com/murat-dogan/node-datachannel/releases/download/v0.29.0/node-datachannel-v0.29.0-napi-v8-win32-arm64.tar.gz
Built with github actions with latest MSVC & VCPKG
Sure thing, how can i use the .node file ? i'm not familiar with the inner workings of node modules
https://github.com/murat-dogan/node-datachannel/issues/330#issuecomment-2708604203
Please check here
Here's the tests:
PASS test/jest-tests/basic.test.ts
PASS test/jest-tests/p2p.test.ts
PASS test/jest-tests/streams.test.ts
PASS test/jest-tests/polyfill.test.ts
PASS test/jest-tests/websocket.test.ts (5.326 s)
A worker process has failed to exit gracefully and has been force exited. This is likely caused by tests leaking due to improper teardown. Try running with --detectOpenHandles to find leaks. Active timers can also cause this, ensure that .unref() was called on them.
Test Suites: 5 passed, 5 total
Tests: 11 passed, 11 total
Snapshots: 0 total
Time: 6.187 s
and the result of the detectOpenHandles:
Jest has detected the following 4 open handles potentially keeping Jest from exiting:
● ThreadSafeCallback callback
64 | });
65 |
> 66 | dc1 = peer1.createDataChannel('test-p2p');
| ^
67 | dc1.onOpen(() => {
68 | p1DCMock();
69 | dc1.sendMessage('Hello From Peer1');
at test/jest-tests/p2p.test.ts:66:19
at Object.<anonymous> (test/jest-tests/p2p.test.ts:9:12)
● ThreadSafeCallback callback
65 |
66 | dc1 = peer1.createDataChannel('test-p2p');
> 67 | dc1.onOpen(() => {
| ^
68 | p1DCMock();
69 | dc1.sendMessage('Hello From Peer1');
70 | });
at test/jest-tests/p2p.test.ts:67:11
at Object.<anonymous> (test/jest-tests/p2p.test.ts:9:12)
● ThreadSafeCallback callback
69 | dc1.sendMessage('Hello From Peer1');
70 | });
> 71 | dc1.onMessage((msg) => {
| ^
72 | p1DCMessageMock(msg);
73 | peer1.close();
74 | peer2.close();
at test/jest-tests/p2p.test.ts:71:11
at Object.<anonymous> (test/jest-tests/p2p.test.ts:9:12)
● ThreadSafeCallback callback
55 | peer1.addRemoteCandidate(candidate, mid);
56 | });
> 57 | peer2.onDataChannel((dc) => {
| ^
58 | p2DCMock();
59 | dc2 = dc;
60 | dc2.onMessage((msg) => {
at test/jest-tests/p2p.test.ts:57:13
at Object.<anonymous> (test/jest-tests/p2p.test.ts:9:12)
The main point, then, is that it is ok for Windows ARM64. From this version on, it will also generate a binary for Windows ARM64. Thank you all.
For open handles, please follow here; https://github.com/murat-dogan/node-datachannel/issues/366