I’m trying to create an API wrapper for Discord’s GameSDK using Node’s addon api and cmake-js. My code makes calls to Discord’s libraries using their provided header files. However, I keep getting LNK2019 errors when trying to compile, even though the correct .lib file for my architecture is passed to the linker.
I’m using:
-
Microsoft Visual Studio 2022 with Visual C++ toolset (v170)
-
CMake >= 3.15
-
CMake-js 7.30
What I’ve Tried:
-
Ensuring all project source and header files are built
-
Setting my
VCTargetsPath
env variable to the proper directory -
Reinstalling Visual Studio
Relevant files and outputs are below
cmake-js compile
output:
...
info CMD CLEAN
info RUN [
info RUN 'cmake',
info RUN '-E',
info RUN 'remove_directory',
info RUN 'C:\Users\Nick\Desktop\Projects\discord-gamesdk\build'
info RUN ]
info CMD CONFIGURE
info find VS using VS2022 (17.10.35013.160) found at:
info find VS "C:Program FilesMicrosoft Visual Studio2022Community"
info find VS run with --verbose for detailed information
info RUN [
info RUN 'cmake',
info RUN 'C:\Users\Nick\Desktop\Projects\discord-gamesdk',
info RUN '--no-warn-unused-cli',
info RUN '-G',
info RUN 'Visual Studio 17 2022',
info RUN '-A',
info RUN 'x64',
info RUN '-DCMAKE_JS_VERSION=7.3.0',
info RUN '-DCMAKE_BUILD_TYPE=Release',
info RUN '-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=C:\Users\Nick\Desktop\Projects\discord-gamesdk\build',
info RUN '-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded$<$<CONFIG:Debug>:Debug>',
info RUN '-DCMAKE_JS_INC=C:\Users\Nick\.cmake-js\node-x64\v20.15.0\include\node',
info RUN '-DCMAKE_JS_SRC=C:/Users/Nick/Desktop/Projects/discord-gamesdk/node_modules/.pnpm/[email protected]/node_modules/cmake-js/lib/cpp/win_delay_load_hook.cc',
info RUN '-DNODE_RUNTIME=node',
info RUN '-DNODE_RUNTIMEVERSION=20.15.0',
info RUN '-DNODE_ARCH=x64',
info RUN '-DCMAKE_JS_LIB=C:\Users\Nick\.cmake-js\node-x64\v20.15.0\win-x64\node.lib',
info RUN '-DCMAKE_SHARED_LINKER_FLAGS=/DELAYLOAD:NODE.EXE'
info RUN ]
Not searching for unused variables given on the command line.
-- Selecting Windows SDK version 10.0.22621.0 to target Windows 10.0.19045.
-- The C compiler identification is MSVC 19.40.33811.0
-- The CXX compiler identification is MSVC 19.40.33811.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.40.33807/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.40.33807/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Linked libraries: C:UsersNick.cmake-jsnode-x64v20.15.0win-x64node.libC:/Users/Nick/Desktop/Projects/discord-gamesdk/lib/discord_game_sdk.dll.lib
-- Configuring done (5.2s)
-- Generating done (0.1s)
-- Build files have been written to: C:/Users/Nick/Desktop/Projects/discord-gamesdk/build
info CMD BUILD
info RUN [
info RUN 'cmake',
info RUN '--build',
info RUN 'C:\Users\Nick\Desktop\Projects\discord-gamesdk\build',
info RUN '--config',
info RUN 'Release'
info RUN ]
MSBuild version 17.10.4+10fbfbf2e for .NET Framework
1>Checking Build System
Building Custom Rule C:/Users/Nick/Desktop/Projects/discord-gamesdk/CMakeLists.txt
activity.cpp
core.cpp
win_delay_load_hook.cc
Generating Code...
Creating library C:/Users/Nick/Desktop/Projects/discord-gamesdk/build/Release/discord_gamesdk.lib and object C:/Users/Nick/Desktop/Projects/discord-gamesdk/build/Release/discord_gamesdk.exp
activity.obj : error LNK2019: unresolved external symbol "public: void __cdecl discord::ActivityManager::UpdateActivity(class discord::Activity const &,class std::function<void __cdecl(enum discord::Res
ult)>)" (?UpdateActivity@ActivityManager@discord@@QEAAXAEBVActivity@2@V?$function@$$A6AXW4Result@discord@@@Z@std@@@Z) referenced in function "void __cdecl Activity::updateActivityWrapped(class Napi::Cal
lbackInfo const &)" (?updateActivityWrapped@Activity@@YAXAEBVCallbackInfo@Napi@@@Z) [C:UsersNickDesktopProjectsdiscord-gamesdkbuilddiscord_gamesdk.vcxproj]
activity.obj : error LNK2019: unresolved external symbol "public: class discord::ActivityManager & __cdecl discord::Core::ActivityManager(void)" (?ActivityManager@Core@discord@@QEAAAEAV02@XZ) referenced
in function "void __cdecl Activity::updateActivityWrapped(class Napi::CallbackInfo const &)" (?updateActivityWrapped@Activity@@YAXAEBVCallbackInfo@Napi@@@Z) [C:UsersNickDesktopProjectsdiscord-game
sdkbuilddiscord_gamesdk.vcxproj]
activity.obj : error LNK2019: unresolved external symbol "class discord::Activity __cdecl Activity::parseActivityFromObject(class Napi::Object)" (?parseActivityFromObject@Activity@@YA?AV1discord@@VObjec
t@Napi@@@Z) referenced in function "void __cdecl Activity::updateActivityWrapped(class Napi::CallbackInfo const &)" (?updateActivityWrapped@Activity@@YAXAEBVCallbackInfo@Napi@@@Z) [C:UsersNickDesktop
Projectsdiscord-gamesdkbuilddiscord_gamesdk.vcxproj]
core.obj : error LNK2019: unresolved external symbol "public: static enum discord::Result __cdecl discord::Core::Create(__int64,unsigned __int64,class discord::Core * *)" (?Create@Core@discord@@SA?AW4Re
sult@2@_J_KPEAPEAV12@@Z) referenced in function "class Napi::Number __cdecl Discord::createWrapped(class Napi::CallbackInfo const &)" (?createWrapped@Discord@@YA?AVNumber@Napi@@AEBVCallbackInfo@3@@Z) [C
:UsersNickDesktopProjectsdiscord-gamesdkbuilddiscord_gamesdk.vcxproj]
core.obj : error LNK2019: unresolved external symbol "public: enum discord::Result __cdecl discord::Core::RunCallbacks(void)" (?RunCallbacks@Core@discord@@QEAA?AW4Result@2@XZ) referenced in function "vo
id __cdecl Discord::runCallbacksWrapped(class Napi::CallbackInfo const &)" (?runCallbacksWrapped@Discord@@YAXAEBVCallbackInfo@Napi@@@Z) [C:UsersNickDesktopProjectsdiscord-gamesdkbuilddiscord_game
sdk.vcxproj]
C:UsersNickDesktopProjectsdiscord-gamesdkbuildReleasediscord_gamesdk.node : fatal error LNK1120: 5 unresolved externals [C:UsersNickDesktopProjectsdiscord-gamesdkbuilddiscord_gamesdk.vcxp
roj]
ERR! OMG Process terminated: 1
ELIFECYCLE Command failed with exit code 1.
CMakeLists.txt
:
cmake_minimum_required(VERSION 3.15)
project (discord_gamesdk)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
include_directories(${CMAKE_JS_INC} include "./")
file(GLOB SOURCE_FILES "src/backend/*.cpp" "src/backend/*.h")
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${CMAKE_JS_SRC})
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node")
find_library(DISCORD_GAME_SDK
NAMES discord_game_sdk discord_game_sdk.dll
HINTS ${CMAKE_SOURCE_DIR}
PATH_SUFFIXES lib
REQUIRED)
target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB})
target_link_libraries(${PROJECT_NAME} ${DISCORD_GAME_SDK})
get_target_property(OUT ${PROJECT_NAME} LINK_LIBRARIES)
message(STATUS "Linked libraries: " ${OUT})
# Output:
# -- Linked libraries: C:UsersNick.cmake-jsnode-x64v20.15.0win-x64node.libC:/Users/Nick/Desktop/Projects/discord-gamesdk/lib/discord_game_sdk.dll.lib
# Include N-API wrappers
execute_process(COMMAND node -p "require('node-addon-api').include"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE NODE_ADDON_API_DIR
)
string(REPLACE "n" "" NODE_ADDON_API_DIR ${NODE_ADDON_API_DIR})
string(REPLACE """ "" NODE_ADDON_API_DIR ${NODE_ADDON_API_DIR})
target_include_directories(${PROJECT_NAME} PRIVATE ${NODE_ADDON_API_DIR})
add_definitions(-DNAPI_VERSION=3)
core.h
:
#include <napi.h>
#include <assert.h>
#include <iostream>
#ifndef DISCORD
#define DISCORD
#include "include/discord.h"
#endif
using namespace std;
extern discord::Core *core;
namespace Discord
{
void runCallbacksWrapped(Napi::CallbackInfo const &);
Napi::Number createWrapped(Napi::CallbackInfo const &);
Napi::Number getVersionWrapped(Napi::CallbackInfo const &);
}
Napi::Object Init(Napi::Env env, Napi::Object exports);
core.cpp
:
#include "core.h"
extern discord::Core *core{};
void Discord::runCallbacksWrapped(Napi::CallbackInfo const &info)
{
::core->RunCallbacks();
}
/**
* @param info clientId: Number, createFlags: Number
*/
Napi::Number Discord::createWrapped(Napi::CallbackInfo const &info)
{
auto env = info.Env();
if (info.Length() < 2)
{
throw ERROR_BAD_ARGUMENTS;
}
assert(info[0].IsNumber());
assert(info[1].IsNumber());
auto clientId = (discord::ClientId)info[0].As<Napi::Number>().Int64Value();
auto createFlags = info[1].As<Napi::Number>().Int64Value();
return Napi::Number::New(env,
(double)discord::Core::Create(
clientId,
createFlags,
&core));
}
Napi::Number Discord::getVersionWrapped(Napi::CallbackInfo const &info)
{
return Napi::Number::New(info.Env(), DISCORD_VERSION);
}
Napi::Object Init(Napi::Env env, Napi::Object exports)
{
exports.Set("getVersion", Napi::Function::New(env, Discord::getVersionWrapped));
exports.Set("create", Napi::Function::New(env, Discord::createWrapped));
exports.Set("runCallbacks", Napi::Function::New(env, Discord::runCallbacksWrapped));
return exports;
}
NODE_API_MODULE(discordgamesdk, Init)