While working on building a project that includes a NodeJs
addon using N-API
for Windows
(and *nix), I found that binaries built on my machine work but the same binaries do not work on another machine.
But the file(s) are all present. What is happening? The same behaviour was observed on Linux and MacOS machines other than mine.
I would have switched to Linux and used strace
to see what was happening, but I wanted to see if Windows has any good alternatives. After some quick Google searching, I realized that I could use the built-in Visual Studio
debugger.
Note: I assume that you have the Visual Studio environment setup for C++ development on windows, along with the required SDKs installed
The commands I used to load and test the libtorrent
build are (in a NodeJs shell) -
const lib = require('./libtorrent.node');
So I tried to find a Debug target (using the CMake extension that populates Visual Studio with stuff)
No luck. Next, I opened Visual Studio and tried to start a NodeJs
process using the debugger -
But the "Start Debugging" option was greyed out. However, the "Attach to Process" option is available. Choosing that option opens the following menu -
The Module
window will be of interest to us
Notice the timestamp column. Lets sort the list by timestamp and focus on the rows with a timestamp -
This makes sense as we haven't loaded the addon yet. Let's load the addon through Node
and check the window again
We see a few more entries. On observing them, we see the following:
- libcrypto-3-x64.dll
- libssl-3-x64.dll
Going through the dependencies, we see that our project's main dependency libtorrent depends on OpenSSL
. Finally it clicked that I installed OpenSSL
through choco
Solution 1: Bundle and distribute required DLLs
Let's try to bundle the required DLLs with the project
And we see that libtorrent
is successfully loaded
But that's not a feasible solution. There might be scenarios where one cannot bundle multiple DLLs
due to some restriction. How do we proceed?
Solution 2: If it works, it ain't stupid
We know that the project depends on libcrypto
and libssl
, but probably uses a few functions or items from them. To test this theory out, I modified my project's CMakeLists.txt
file to fetch openssl
from Github
using CMake's built in (version 3.11
and later) FetchContent
The following is an extract of the CMakeLists.txt
file:
include(FetchContent)
FetchContent_Declare(
openssl
GIT_REPOSITORY https://github.com/janbar/openssl-cmake.git
SOURCE_DIR ${CMAKE_SOURCE_DIR}/lib/openssl
GIT_TAG 392d455cd0b0fe992b312c9648eb5ea87e3afcea
)
FetchContent_MakeAvailable(openssl)
set(OPENSSL_ROOT_DIR ${CMAKE_SOURCE_DIR}/lib/openssl/*)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(OPENSSL_CRYPTO_LIBRARY ${CMAKE_SOURCE_DIR}/build/_deps/openssl-build/crypto/Debug)
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
set(OPENSSL_CRYPTO_LIBRARY ${CMAKE_SOURCE_DIR}/build/_deps/openssl-build/crypto/Release)
endif()
The statement to set
OPENSSL_CRYPTO_LIBRARY
can be optimised further
This resulted in the following files being generated -
the
openssl
binary is built as default behaviour that can be customized
Shaky cam courtesy of a friend
Top comments (0)