nodejs / node

Node.js JavaScript runtime ✨🐢🚀✨
https://nodejs.org
Other
107.43k stars 29.53k forks source link

Cannot build static dll on windows v12.7.0 #28845

Closed KevinEady closed 4 years ago

KevinEady commented 5 years ago

Checking out the v12.7.0 tag and attempting to build via

./vcbuild.bat dll openssl-no-asm

Provides the following linking error:

node.obj : error LNK2019: unresolved external symbol "public: static class std::vector<unsigned __int64,class std ::allocator<unsigned __int64> > const * __cdecl node::NodeMainInstance::GetIsolateDataIndexes(void)" (?GetIsolate DataIndexes@NodeMainInstance@node@@SAPEBV?$vector@_KV?$allocator@_K@std@@@std@@XZ) referenced in function "int __ cdecl node::Start(int,char * * const)" (?Start@node@@YAHHQEAPEAD@Z) [H:\vs_workspace\node\libnode.vcxproj]
node.obj : error LNK2019: unresolved external symbol "public: static class v8::StartupData * __cdecl node::NodeMa inInstance::GetEmbeddedSnapshotBlob(void)" (?GetEmbeddedSnapshotBlob@NodeMainInstance@node@@SAPEAVStartupData@v8@ @XZ) referenced in function "int __cdecl node::Start(int,char * * const)" (?Start@node@@YAHHQEAPEAD@Z) [H:\vs_wor kspace\node\libnode.vcxproj]
node.obj : error LNK2019: unresolved external symbol "public: static void __cdecl node::native_module::NativeModu leEnv::InitializeCodeCache(void)" (?InitializeCodeCache@NativeModuleEnv@native_module@node@@SAXXZ) referenced in
function "int __cdecl node::InitializeNodeWithArgs(class std::vector<class std::basic_string<char,struct std::cha r_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_tr aits<char>,class std::allocator<char> > > > *,class std::vector<class std::basic_string<char,struct std::char_tra its<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits< char>,class std::allocator<char> > > > *,class std::vector<class std::basic_string<char,struct std::char_traits<c har>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char> ,class std::allocator<char> > > > *)" (?InitializeNodeWithArgs@node@@YAHPEAV?$vector@V?$basic_string@DU?$char_tra its@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@ std@@00@Z) [H:\vs_workspace\node\libnode.vcxproj]
node_config.obj : error LNK2001: unresolved external symbol "bool const node::native_module::has_code_cache" (?ha s_code_cache@native_module@node@@3_NB) [H:\vs_workspace\node\libnode.vcxproj]
v8_libbase.lib(time.obj) : error LNK2019: unresolved external symbol __imp_timeGetTime referenced in function "un signed long __cdecl v8::base::`anonymous namespace'::timeGetTimeWrapper(void)" (?timeGetTimeWrapper@?A0x02a379f9@ base@v8@@YAKXZ) [H:\vs_workspace\node\libnode.vcxproj]
v8_libbase.lib(platform-win32.obj) : error LNK2001: unresolved external symbol __imp_timeGetTime [H:\vs_workspace \node\libnode.vcxproj]
out\Release\libnode.dll : fatal error LNK1120: 5 unresolved externals [H:\vs_workspace\node\libnode.vcxproj]

This does not happen when building the normal executable target.

targos commented 5 years ago

Cc @nodejs/platform-windows @addaleax, @JoyeeCheung does it ring a bell?

addaleax commented 5 years ago

I guess this might be (at least partially) the snapshot/code cache creator binaries requiring dllimport/dllexport specifiers along the lines of NODE_EXTERN when they are being linked against Node as a DLL? For the V8 ones I’m less sure without having looked at it in detail – I think that means that we’re not linking against winmm.lib somewhere where we should (which would be a gyp issue and I’m less knowledgeable how to address that).

I can try to look into fixing this when I’m in front of a Windows machine.

KevinEady commented 5 years ago

Just for some additional info, I was last able to successfully build a shared library on all platforms last on v11.12.0 ... I've never tried on any 12 version.

QuLogic commented 5 years ago

The missing reference to node::native_module::NativeModuleEnv::InitializeCodeCache is also #27431 (except it's !Windows), which has been open for a while now.

davidhouweling commented 4 years ago

hi @targos / @addaleax , I was wondering if any further investigation had been done for this issue?

targos commented 4 years ago

Not from my end. It's not really my area of expertise, though I can help if there's something to do in our gyp configuration.

davidhouweling commented 4 years ago

I've tried to manually add winmm.lib to libnode.vcxproj in an attempt to resolve that specific issue, but it still is occurring. I've tried this on a completely clean windows + boxstarter so i'll see if i can find out where exactly the issue is, though C++ isn't really my area of expertise either.

davidhouweling commented 4 years ago

So it appears this part of v8.gyp isn't actually doing anything when ran (on Windows), and you check the v8_libbase.vcxproj file, <AdditionalDependencies> are still empty.

This part of node.gyp is also missing the winmm.lib definition. When added, it does allow libnode.dll to be successfully build.

However, shortly after that, I get the following:

cache_builder.obj : error LNK2019: unresolved external symbol "void __cdecl node::Assert(struct node::AssertionInfo const &)" (?Assert@node@@YAXABUAssertionInfo@1@@Z) referenced in function "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl node::native_module::GetDefName(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?GetDefName@native_module@node@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@ABV34@@Z) [C:\git\node\mkcodecache.vcxproj]
cache_builder.obj : error LNK2019: unresolved external symbol "private: static class node::native_module::NativeModuleLoader * __cdecl node::native_module::NativeModuleLoader::GetInstance(void)" (?GetInstance@NativeModuleLoader@native_module@node@@CAPAV123@XZ) referenced in function "public: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl node::native_module::CodeCacheBuilder::Generate(class v8::Local<class v8::Context>)" (?Generate@CodeCacheBuilder@native_module@node@@SA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$Local@VContext@v8@@@v8@@@Z) [C:\git\node\mkcodecache.vcxproj]
cache_builder.obj : error LNK2019: unresolved external symbol "private: class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > __thiscall node::native_module::NativeModuleLoader::GetModuleIds(void)" (?GetModuleIds@NativeModuleLoader@native_module@node@@AAE?AV?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@XZ) referenced in function "public: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl node::native_module::CodeCacheBuilder::Generate(class v8::Local<class v8::Context>)" (?Generate@CodeCacheBuilder@native_module@node@@SA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$Local@VContext@v8@@@v8@@@Z) [C:\git\node\mkcodecache.vcxproj]
cache_builder.obj : error LNK2019: unresolved external symbol "private: bool __thiscall node::native_module::NativeModuleLoader::CanBeRequired(char const *)" (?CanBeRequired@NativeModuleLoader@native_module@node@@AAE_NPBD@Z) referenced in function "public: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl node::native_module::CodeCacheBuilder::Generate(class v8::Local<class v8::Context>)" (?Generate@CodeCacheBuilder@native_module@node@@SA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$Local@VContext@v8@@@v8@@@Z) [C:\git\node\mkcodecache.vcxproj]
cache_builder.obj : error LNK2019: unresolved external symbol "private: struct v8::ScriptCompiler::CachedData * __thiscall node::native_module::NativeModuleLoader::GetCodeCache(char const *)const " (?GetCodeCache@NativeModuleLoader@native_module@node@@ABEPAUCachedData@ScriptCompiler@v8@@PBD@Z) referenced in function "public: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl node::native_module::CodeCacheBuilder::Generate(class v8::Local<class v8::Context>)" (?Generate@CodeCacheBuilder@native_module@node@@SA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$Local@VContext@v8@@@v8@@@Z) [C:\git\node\mkcodecache.vcxproj]
cache_builder.obj : error LNK2019: unresolved external symbol "private: class v8::MaybeLocal<class v8::Function> __thiscall node::native_module::NativeModuleLoader::CompileAsModule(class v8::Local<class v8::Context>,char const *,enum node::native_module::NativeModuleLoader::Result *)" (?CompileAsModule@NativeModuleLoader@native_module@node@@AAE?AV?$MaybeLocal@VFunction@v8@@@v8@@V?$Local@VContext@v8@@@5@PBDPAW4Result@123@@Z) referenced in function "public: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl node::native_module::CodeCacheBuilder::Generate(class v8::Local<class v8::Context>)" (?Generate@CodeCacheBuilder@native_module@node@@SA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$Local@VContext@v8@@@v8@@@Z) [C:\git\node\mkcodecache.vcxproj]
out\Release\mkcodecache.exe : fatal error LNK1120: 6 unresolved externals [C:\git\node\mkcodecache.vcxproj]
node_mksnapshot.obj : error LNK2019: unresolved external symbol "void __cdecl node::Assert(struct node::AssertionInfo const &)" (?Assert@node@@YAXABUAssertionInfo@1@@Z) referenced in function _wmain [C:\git\node\node_mksnapshot.vcxproj]
snapshot_builder.obj : error LNK2001: unresolved external symbol "void __cdecl node::Assert(struct node::AssertionInfo const &)" (?Assert@node@@YAXABUAssertionInfo@1@@Z) [C:\git\node\node_mksnapshot.vcxproj]
node_mksnapshot.obj : error LNK2019: unresolved external symbol "struct node::InitializationResult __cdecl node::InitializeOncePerProcess(int,char * *)" (?InitializeOncePerProcess@node@@YA?AUInitializationResult@1@HPAPAD@Z) referenced in function _wmain [C:\git\node\node_mksnapshot.vcxproj]
node_mksnapshot.obj : error LNK2019: unresolved external symbol "void __cdecl node::TearDownOncePerProcess(void)" (?TearDownOncePerProcess@node@@YAXXZ) referenced in function _wmain [C:\git\node\node_mksnapshot.vcxproj]
snapshot_builder.obj : error LNK2019: unresolved external symbol "public: static class std::unique_ptr<class node::NodeMainInstance,struct std::default_delete<class node::NodeMainInstance> > __cdecl node::NodeMainInstance::Create(class v8::Isolate *,struct uv_loop_s *,class node::MultiIsolatePlatform *,class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > const &,class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > const &)" (?Create@NodeMainInstance@node@@SA?AV?$unique_ptr@VNodeMainInstance@node@@U?$default_delete@VNodeMainInstance@node@@@std@@@std@@PAVIsolate@v8@@PAUuv_loop_s@@PAVMultiIsolatePlatform@2@ABV?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@4@3@Z) referenced in function "public: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl node::SnapshotBuilder::Generate(class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > >,class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > >)" (?Generate@SnapshotBuilder@node@@SA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@4@0@Z) [C:\git\node\node_mksnapshot.vcxproj]
snapshot_builder.obj : error LNK2019: unresolved external symbol "public: void __thiscall node::NodeMainInstance::Dispose(void)" (?Dispose@NodeMainInstance@node@@QAEXXZ) referenced in function "public: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl node::SnapshotBuilder::Generate(class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > >,class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > >)" (?Generate@SnapshotBuilder@node@@SA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@4@0@Z) [C:\git\node\node_mksnapshot.vcxproj]
snapshot_builder.obj : error LNK2019: unresolved external symbol "public: __thiscall node::NodeMainInstance::~NodeMainInstance(void)" (??1NodeMainInstance@node@@QAE@XZ) referenced in function "public: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl node::SnapshotBuilder::Generate(class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > >,class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > >)" (?Generate@SnapshotBuilder@node@@SA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@4@0@Z) [C:\git\node\node_mksnapshot.vcxproj]
snapshot_builder.obj : error LNK2019: unresolved external symbol "public: class std::vector<unsigned int,class std::allocator<unsigned int> > __thiscall node::IsolateData::Serialize(class v8::SnapshotCreator *)" (?Serialize@IsolateData@node@@QAE?AV?$vector@IV?$allocator@I@std@@@std@@PAVSnapshotCreator@v8@@@Z) referenced in function "public: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl node::SnapshotBuilder::Generate(class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > >,class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > >)" (?Generate@SnapshotBuilder@node@@SA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@4@0@Z) [C:\git\node\node_mksnapshot.vcxproj]
snapshot_builder.obj : error LNK2001: unresolved external symbol "struct node::V8Platform node::per_process::v8_platform" (?v8_platform@per_process@node@@3UV8Platform@2@A) [C:\git\node\node_mksnapshot.vcxproj]
out\Release\node_mksnapshot.exe : fatal error LNK1120: 8 unresolved externals [C:\git\node\node_mksnapshot.vcxproj]

Based on my couple of days understanding, running .\vcbuild.bat dll means libnode is produced as a dll, but this causes the subsequent dependents to fail because the lib isn't being produced like in the normal executable mode.

joyeecheung commented 4 years ago

One idea that may work is to just disable code cache and snapshot for shared builds on Windows until we actually fix https://github.com/nodejs/node/issues/27431#issuecomment-515976858 (to disable snapshot, use --without-node-snapshot in configure. However it seems the code cache option was lost at some point)

joyeecheung commented 4 years ago

To fix the node lib it self, I guess we could add winmm.lib in node.gyp as suggested in https://github.com/nodejs/node/issues/28845#issuecomment-558438817 ...however why would actually we need this lib? I don't know that much about Windows but this appears to be the lib for the Windows Multimedia API? Do the server options of Windows have them?

joyeecheung commented 4 years ago

I guess this might be (at least partially) the snapshot/code cache creator binaries requiring dllimport/dllexport specifiers along the lines of NODE_EXTERN when they are being linked against Node as a DLL?

@addaleax To build mkcodecache and mksnapshot (they are executables), we currently build libnode with unresolved symbols, then build the two exectuables with src/node_snapshot_stub.cc and src/node_code_cache_stub.cc. Each of them write a C++ file to disk when being run. We then use the generated C++ files + libnode (with unresolved symbols) to build the final Node executable.

However, if libnode itself is the final product, then we should not build it with unresolved symbols. https://github.com/nodejs/node/pull/28897 added the two stubs for the libnode target when the --shared configure option is used, but it did not get rid of the actions to build and run mksnapshot and mkcodecache for --shared, so I think to get it working we also need a patch to make sure --shared imply --without-node-code-cache and --without-node-snapshot, until we actually fix the TODO so that mksnapshot and mkcodecache do not use the libnode that way.

joyeecheung commented 4 years ago

I added another commit in https://github.com/nodejs/node/pull/30647 to implement what I suggested in https://github.com/nodejs/node/issues/28845#issuecomment-558466684 as a temporary fix. Can you try with the two commits and see if it works?

davidhouweling commented 4 years ago

Just tried it with nosnapshot parameter to vcbuild but still failing because it is still attempting to compile. I'm gonna take a break for a few hours but when I'm back i'll try it out @joyeecheung

davidhouweling commented 4 years ago

@joyeecheung i took a look at your changes in the https://github.com/nodejs/node/pull/30647 and applied it to v12.x branch (as i'm needing the version 12 dll). it's a lot closer... but still not quite.

v8_base_without_compiler.lib(basic-block-profiler.obj) : error LNK2005: "public: static class v8::internal::BasicBlockProfiler * __cdecl v8::internal::BasicBlockProfiler::Get(void)" (?Get@BasicBlockProfiler@internal@v8@@SAPAV123@XZ) already defined in 
 libnode.lib(libnode.dll) [C:\git\node\node.vcxproj]
     Creating library out\Release\node.lib and object out\Release\node.exp
out\Release\node.exe : fatal error LNK1169: one or more multiply defined symbols found [C:\git\node\node.vcxproj]

I'll see what I can work out in a few hours and report back.

davidhouweling commented 4 years ago

@joyeecheung i didn't get any further on my local changes after cherry picking your changes so I decided to pull your PR https://github.com/nodejs/node/pull/30647 locally, but am getting the same error.

What I did:

  1. applied https://github.com/nodejs/node/issues/28845#issuecomment-558438817
  2. extend vcbuild.bat to add a nonodecache flag
  3. in console, call .\vcbuild.bat dll nonodecache

Resulting error:

v8_base_without_compiler.lib(basic-block-profiler.obj) : error LNK2005: "public: static class v8::internal::BasicBlockP
rofiler * __cdecl v8::internal::BasicBlockProfiler::Get(void)" (?Get@BasicBlockProfiler@internal@v8@@SAPEAV123@XZ) alre
ady defined in libnode.lib(libnode.dll) [C:\git\node\node.vcxproj]
v8_base_without_compiler.lib(machine-type.obj) : error LNK2005: "class std::basic_ostream<char,struct std::char_traits<
char> > & __cdecl v8::internal::operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class v8::in
ternal::MachineType)" (??6internal@v8@@YAAEAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AEAV23@VMachineType@01@@Z) al
ready defined in libnode.lib(libnode.dll) [C:\git\node\node.vcxproj]
v8_base_without_compiler.lib(machine-type.obj) : error LNK2005: "class std::basic_ostream<char,struct std::char_traits<
char> > & __cdecl v8::internal::operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,enum v8::int
ernal::MachineRepresentation)" (??6internal@v8@@YAAEAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AEAV23@W4MachineRepr
esentation@01@@Z) already defined in libnode.lib(libnode.dll) [C:\git\node\node.vcxproj]
v8_base_without_compiler.lib(machine-type.obj) : error LNK2005: "char const * __cdecl v8::internal::MachineReprToString
(enum v8::internal::MachineRepresentation)" (?MachineReprToString@internal@v8@@YAPEBDW4MachineRepresentation@12@@Z) alr
eady defined in libnode.lib(libnode.dll) [C:\git\node\node.vcxproj]
     Creating library out\Release\node.lib and object out\Release\node.exp
out\Release\node.exe : fatal error LNK1169: one or more multiply defined symbols found [C:\git\node\node.vcxproj]
joyeecheung commented 4 years ago

@davidhouweling step 2 should be unnecessary with https://github.com/nodejs/node/pull/30647 because --shared should imply --without-node-code-cache and --without-node-snapshot.

davidhouweling commented 4 years ago

Hi @targos , do you mind taking a look at https://github.com/nodejs/node/pull/30695?

KevinEady commented 4 years ago

Hi all,

As an update, I was able to compile my Windows dll using @davidhouweling 's updated node.gyp from #30695 on 13.5.0

davidhouweling commented 4 years ago

@KevinEady that's great to hear. Did you have any issues consuming it in your Windows application?

KevinEady commented 4 years ago

Hi @davidhouweling ,

Yep, just incorporated the new .lib/.dll in project build and .dll at application runtime and all seems well :+1:

jasnell commented 4 years ago

I don't believe this has anything left that is actionable. Closing but can reopen if necessary