Unresolve external symbols when using v8.dll in my project - c++

I'm new to making C++ project. I may be not sure prerequisite knowledge of C++ project.
[My environment]
Windows 10
Python 2.7.18
Developer Command Prompt for VS 2022
Visual Studio 2022 Community
I'm currently straggling with making V8 engine as a DLL and using it.
I've built V8 engine as a DLL successfly but using it I'm facing "Unresolve exteranl symbols" error.
Details:
error LNK2019: unresolved external symbol "class std::unique_ptr<class v8::Platform,struct std::default_delete<class v8::Platform> > __cdecl v8::platform::NewDefaultPlatform(int,enum v8::platform::IdleTaskSupport,enum v8::platform::InProcessStackDumping,class std::unique_ptr<class v8::TracingController,struct std::default_delete<class v8::TracingController> >)" (?NewDefaultPlatform#platform#v8##YA?AV?$unique_ptr#VPlatform#v8##U?$default_delete#VPlatform#v8###std###std##HW4IdleTaskSupport#12#W4InProcessStackDumping#12#V?$unique_ptr#VTracingController#v8##U?$default_delete#VTracingController#v8###std###4##Z) referenced in function "public: __cdecl ezv8::Platform::Impl::Impl(void)" (??0Impl#Platform#ezv8##QEAA#XZ)
I've researched some thing that C++ mangling and compailer behaviours are.
I've noticed that the v8_libplatform.dll.lib file contains other type of mangled symbols like below.
?NewDefaultPlatform#platform#v8##YA?AV?$unique_ptr#VPlatform#v8##U?$default_delete#VPlatform#v8###__1#std###__1#std##HW4IdleTaskSupport#12#W4InProcessStackDumping#12#V?$unique_ptr#VTracingController#v8##U?$default_delete#VTracingController#v8###__1#std###45##Z = ?NewDefaultPlatform#platform#v8##YA?AV?$unique_ptr#VPlatform#v8##U?$default_delete#VPlatform#v8###__1#std###__1#std##HW4IdleTaskSupport#12#W4InProcessStackDumping#12#V?$unique_ptr#VTracingController#v8##U?$default_delete#VTracingController#v8###__1#std###45##Z (class std::__1::unique_ptr<class v8::Platform,struct std::__1::default_delete<class v8::Platform> > __cdecl v8::platform::NewDefaultPlatform(int,enum v8::platform::IdleTaskSupport,enum v8::platform::InProcessStackDumping,class std::__1::unique_ptr<class v8::TracingController,struct std::__1::default_delete<class v8::TracingController> >))
As you can see, the .lib file contains the symbol with __1 namespace.
I found out why the file contains that. A bundled clang compiler compiles std namespace with inline namespace __1 but I'm not sure that how I can change compililng without __1 inline namespace.
Does anyone know how to change the compiler behaviour?

I resolved this problem myself. (But I get still other erros in building.)
What the problem is that I have to add a flag "is_clang = false" to gn args because the clang that is bound v8 will compile other type of manglings to MSVS.
If I added the flag then v8 tools will compile these code with cl.exe you installed.

I had exactly the same linking issue with v8::platform::NewDefaultPlatform() function, as well as some other methods like v8::Context::Scope::Scope(), v8::Context::Scope::~Scope() and so on. And the cause wasn't related with name mangling, it looks like clang-cl (used in v8/chromium by default on Windows platforms) uses the same name mangling as cl does. All these methods are defined in header files so they're effectively inlines, and clang-cl uses /Zc:DllexportInlines- compiler option which doesn't export inlines from DLLs (see https://reviews.llvm.org/D51340?id=172304 for details).
A request for adding /Zc:DllexportInlines option to cl compiler was raised a long time ago: https://developercommunity.visualstudio.com/t/implement-zcdllexportinlines-aka-fvisibility-inlin/374754 , but as of now, cl version 19.34.31937 still doesn't support it.
So I can see no way using v8 DLLs with Microsoft's cl compiler without modifying v8/chromium header files (which is never good). One can build v8 as static libraries, or use clang-cl as a custom build tool.
As for building v8 without clang using is_clang=false gn argument, I wonder if it's actually possible. There are many compiler options like -Wno-unused-const-variable or -Wno-unused-function which aren't supported by cl but added unconditionally in gn build files. I remember years ago it was possible to build chromium using cl, but is it now?

Related

How to fix linker error unresolved external std::locale::id::id in C++ Builder

When compiling a C++ Builder 10.4 project, I get the following linker error:
[ilink32 Error] Error: Unresolved external 'std::locale::id::id(unsigned int)' referenced from C:\USERS\PUBLIC\DOCUMENTS\EMBARCADERO\STUDIO\21.0\DCP\SCREEN2VIDEO.LIB|Screen2Video
This linker error happens when 'Link with dynamic RTL', and 'Link with run-time packages' are turned off. When linking with dynamic RTL, the linker error does not occur, but I want to link statically.
The SCREEN2VIDEO.LIB is from a package containing an imported ActiveX control.
Recompile all dependent packages (including the screen2video.bpl) with dynamic RTL turned off. This fixed the linker error.
Same issue here, with C++ Builder 11 though. It turned out to be a problem of the optimizer. Try disabling all optimizations.
Also check out one of the related bug reports at Embarcadero:
https://quality.embarcadero.com/browse/RSP-29221
Edit: I experimented a bit more and found the problematic compiler flag. It is -finline-functions which is implicitely added when using -O2 or higher.
Therefore, as a workaround, you can add -fno-inline-functions to C++ compiler > Advanced > Additional Options to make it work without too much of a performance impact at least.
I also added this info to the above bug-report.

What / where is __scrt_common_main_seh?

A third party library in my program is trying to call __scrt_common_main_seh by way of the Microsoft library msvcrt.lib, but is defined by some unknown library and therefore gives a linker error. I don't know what this function is supposed to do or where it is defined.
I looked online for this function, but did not find any clues except for general descriptions of what linker errors are.
I believe it might be doing some setup for win32 GUI applications. The library which defines it might be configured as project dependency by Visual Studio but my project is using Bazel.
Summary
For non-console applications having error error LNK2019: unresolved external symbol main referenced in function "int __cdecl __scrt_common_main_seh(void)" try adding linker flag /ENTRY:wWinMainCRTStartup or /ENTRY:WinMainCRTStartup
For console applications having that error, make sure to implement a main() function.
Details
This answer shows that __scrt_common_main_seh is normally called during mainCRTStartup which is the default entry point for windows console applications. __scrt_common_main_seh is then (indirectly) responsible for calling main().
My program did not have a main() function, which might have prevented the compiler from generating __scrt_common_main_seh (Just speculating. I am totally clueless about who defines __scrt_common_main_seh)
I did find, however, that the library I was linking against defined a wWinMain() function. So I tried adding the linker flag /ENTRY:wWinMainCRTStartup and the linker error went away.

'TypeInfo<char>(char *)' isn't defined but worked pre-C++11; what changed, and how can I fix the error?

I am trying to build a DLL from source-code from the Crysis Wars SDK, and have successfully done so in the past on previous versions of Visual Studio (namely 2005, 2008, and 2010).
My specific problem is this:
Error 4 error LNK2019: unresolved external symbol "struct CTypeInfo const & __cdecl
TypeInfo<char>(char *)" (??$TypeInfo#D##YAABUCTypeInfo##PAD#Z) referenced in function
"void __cdecl SwapEndian<char>(char *,unsigned int)" (??$SwapEndian#D##YAXPADI#Z)
G:\Noctis\Mods\Noctis\Code\GameCVars.obj GameDll
I have attempted to clean the code in Visual Studio and rebuild it on the off-chance this'll work, but this has not changed anything.
Am I missing something here, or has something changed from C++03 to C++11 that means that this code is no longer compilable without reverting to an older version of C++?
I have successfully compiled this code on Visual Studio 2010 in both 64 bit and 32 bit, so it must be some issue related to migrating the project to Visual Studio 2015.
Compilation on 2012, 2013, and 2015 versions of Visual Studio reproduce this error but not 2010, so it seems that the change to trigger this problem was introduced in C++11.
What am I doing wrong?
Reading the answer to mem-fun is not a member of std, it could just be that I need to include a standard library that I didn't need to include in earlier versions of Visual Studio.
If this is true, which library would I need to #include?
I have also created a GitHub repository containing only the original unmodified code provided from the SDK, for testing purposes (in the event I myself made a typo, which doesn't seem to be the case here but I've put the link here as it may be helpful).
If it matters, I'm using Visual Studio 2015 Enterprise edition on Windows 10 Professional x64.
What does the error mean?
The error message hints towards a classic "declared but not defined" scenario.
TypeInfo<char>(char*) is declared in TypeInfo.h (through some macros) and declared in AutoTypeInfo.cpp in project CryCommon.
Usually you would just make sure the CryCommon project is built correctly and linked into your final GameDll project properly and that's it.
But it turns out here that the CryCommon project has not been built for a long time - it references many other Crytek libraries etc. So the problem must be that something now needs these TypeInfo<> definitions and previously it did not.
What is referencing the TypeInfo<> code?
In your project it's function CmdHelp() in Aurora/Code/GameCVars.cpp, precisely this line:
nRead = gEnv->pCryPak->FRead( buf, BUFSZ, f );
The implementation of the FRead() method is in CryCommon/ICryPak.h:
template<class T>
size_t FRead(T *data, size_t elems, FILE *handle, bool bSwap = true)
{
size_t count = FReadRaw(data, sizeof(T), elems, handle);
if (bSwap)
SwapEndian(data, count);
return count;
}
As you can see, if bSwap is true (the default), SwapEndian() is invoked there.
Why hasn't this manifested before?
Perhaps the compiler was indeed behaving differently.
Or, more likely, you have been always compiling the project as Release before. The whole byte-swapping functionality is enabled only on big-endian systems (and your target is most probably not one of those) or during debug - then the bytes are actually swapped twice to test the related code (see CryCommon/Endian.h).
What can be done to fix it?
You have several options now:
Keep compiling as release only (probably as before). Perhaps you will never be debugging the code in a debugger anyway.
Just comment the swap call in FRead() code out. You are using it to load a text file anyway, no point in swapping the characters around.
...
FWIW, other things I had to do to make your code compile:
Check out the earlier commit before "Broken"
Load Mods\Aurora\Code\Aurora.sln
Remove non-existing .vcprojx projects
Add all 3 .vcproj files again, let them be converted to VS2015 ones
For GameDll project, add preprocessor definition _SILENCE_STDEXT_HASH_DEPRECATION_WARNING
For GameDll project, set enabled C++ exception handling /EHsc
Comment out the code above

Unresolved Externals Nightmare

Hello industry veterans,
I am a junior in college embarking on my first summer programming internship, and I am in way over my head. The company I'm working for has purchased a colossal application from another company that has slowly been expanding and modifying it since the early 90's. The solution contains over 200,000 lines of code which are spread across more than 300 files. The entire solution has purportedly been written to ANSI-C++ standards. The code is almost entirely undocumented, and most of it looks like hieroglyphs to me. Ultimately, my job is to port this code to embedded Linux. At the moment, my job is simply to get it compiling using Visual Studio 2008 on Windows XP.
Today, I'm running into linker errors such as this one:
libcmtd.lib(sprintf.obj) : error LNK2005: _sprintf already defined in msvcrtd.lib(MSVCR90D.dll)
My understanding is that this often happens when different projects within a solution are compiled using different runtime libraries. There are 6 projects in my solution. 4 of them were set to compile using the multi-threaded debug DLL runtime library (/MDd), one of them was set to compile using the multi-threaded debug library (/MTd), and one of them was set to compile using the multi-threaded dll runtime library (/MD). The first thing I tried after receiving this error message was to change the /MTd and /MD switches to /MDd so that everything would have compiled with the same runtime libraries. Unfortunately, this led to the following error in afx.h:
fatal error C1189: #error : Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version. Please #define _AFXDLL or do not use /MD[d]
After some digging around, I discovered that it had already told me what I needed to do. I went ahead and changed the "Use of MFC" option under Project Properties->Configuration Properties->General to "Use MFC in a Shared DLL". At this point I started receiving dozens of unresolved external errors such as these:
dataPropertySheet.obj : error LNK2019: unresolved external symbol "public: __thiscall CResizableSheet::CResizableSheet(unsigned short const *,class CWnd *,unsigned int)" (??0CResizableSheet##QAE#PBGPAVCWnd##I#Z) referenced in function "public: __thiscall CdataPropertySheet::CdataPropertySheet(unsigned short const *,class CWnd *,unsigned int)" (??0CdataPropertySheet##QAE#PBGPAVCWnd##I#Z)
ResizableLib.lib(ResizablePage.obj) : error LNK2001: unresolved external symbol "public: virtual int __thiscall CWnd::Create(char const *,char const *,unsigned long,struct tagRECT const &,class CWnd *,unsigned int,struct CCreateContext *)" (?Create#CWnd##UAEHPBD0KABUtagRECT##PAV1#IPAUCCreateContext###Z)
After reading through the MSDN pages on LNK2001 and LNK2019, I've realized I have no idea what's going on. These are not the sort of issues they've taught us how to deal with in school. I know my data structures, and that's about it. How I ended up where I am now is beyond me!
From my limited knowledge, it seems that the various debug and release versions of these modules are all tangled up in a web of preprocessor directives and #includes. There are a number of nested #ifdef checks and #define statements done in nearly every header and source file throughout the solution for environment variables, file names, macros, and possibly more. By making even small changes to my compiler settings, I seem to be redirecting large parts of the program to different libraries which have very different function definitions. This is my vague conceptual understanding of what's going on.
I feel as though I'm going to need a better understanding of how this code works before I stand any chance of troubleshooting these compiler errors. To that end, I've been trying to step through many of the files line by line to see where they lead, what objects and variables are in scope, and so on. Unfortunately, this doesn't get me very far, because every call to an external function is ambiguous, and I have no way of seeing through the preprocessor mess to know which version of any given function is supposed to be called.
I was looking around for magic solutions to map out the program and try to make sense of it. I tried one called Doxygen, but either I don't know how to use it properly or it's getting just as confused by the preprocessor stuff as I am.
My question is this:
What are my remaining options?
At this point it's a toss up between:
a.) Switch majors
b.) Jump off a bridge
Neither of these choices are going to help me better understand this code base and get it compiling. Does anybody have any better ideas? Similar experiences? Sage wisdom to share?
Thanks a ton,
-Alex
It appears you're using the CResizableSheet and CResizeablePage from CodeProject. If you're using the compiled static lib from that page, you could try downloading the source and compiling that with the matching /MDd setting and using the .lib it outputs in the linker input section of your project. I'd also suggest doing a clean all (go to build->batch build->select all then click clean) and then try building again to make sure everything is up to date.
I hear nursing is a great program ...
At the risk of being pedantic, what you are fighting with are linker errors, not compiler errors. My basic approach to this would be to create a new solution, and start adding projects one at a time, getting each one to build in turn.
I would also seriously consider trying to standardize the settings of each project as much as possible. The easiest way to do this is to create empty projects in your new solution, and copy the existing code into them.
To start with you should assume the following settings (related to MFC):
Debug: Use MFC in a shared DLL, /MDd
Release: Use MFC in a shared DLL, /MD
MDd and MD are the same mode, but one links against debug libraries with extra information for debugging.
Then all you can do is work on one project at a time. Note that if you create a new solution as suggested, you'll need to rebuild the dependency tree between projects. (Right click on a project and choose 'Dependencies', you'll see what I mean.)
When you run into problems doing this, you should make friends with a senior developer at your workplace =).
Compile everything with the same runtime libraries. End of story.

Errors trying to call GetAsyncKeyState() in C++/CLI project

I'm working on a fairly convoluted project in which I'm accessing classes written in plain-old-C++ from a project using C++/CLI. It's a Windows Forms GUI project that uses a lot of the same functions as its (non-CLI) C++ sister project.
In one of my classes that I'm trying to adjustment to work in both environments, I'm polling keypresses with this function:
inline bool IsKeyDown(unsigned char ch) const {
return (GetAsyncKeyState(ch) & (1u << 15)) != 0;
}
I'm getting both Unresolved Token and Unresolved External Symbol errors on
"extern "C" short __stdcall GetAsyncKeyState(int)" (?GetAsyncKeyState##$$J14YGFH#Z) referenced in function "public: bool __clrcall Engine::InputManager::IsKeyDown(unsigned char)const " (?IsKeyDown#InputManager#Engine##$$FQBM_NE#Z)
Obviously, the issue is related to GetAsyncKeyState() but I'm not sure what needs to be different for a CLI-friendly implementation. Can anyone direct me how to fix this? The function works properly in my non-CLI environment (and has for months). I'm very new to this CLI stuff so any help would be wonderful and no help could be too-specific.
If it helps, I'm using Visual Studio 2010 and compiling with the /clr parameter (not :pure or :safe).
The MSDN library provides the details of which header files and libraries need to be included for any particular function.
In this case, you need windows.h (which you must already have) and user32.lib (which is probably missing). So add
#pragma comment(lib, "user32.lib")
at the top of your code and all should be well. Alternatively, you could add user32.lib to the list of libraries in the project properties pages, remembering to do this for each configuration, e.g., debug as well as release.
Just got the same issue. The solution is to link against a .lib which has a respective symbol, which in this case is user32.lib.
I fixed a problem in Visual Studio by making a project use inherited values. Check this checkbox in your project properties and it should fix it: