4

I am getting LNK2019 error from linking C++ code with the standard library C++ library. I need to know which libraries contain the functions:

  • is_c_termination_complete,
  • __acrt_initialize,
  • __acrt_uninitialize,
  • __acrt_uninitialize_critical,
  • __acrt_thread_attach,
  • __acrt_thread_detach

to include it in the linking process.

I am writing code in C++ with MS Visual Studio community 2017 and Intel Parallel studio xe 2019 update 1 to be integrated in 3rd party software. The 3rd party software provides a "make" option to compile the object files and link them together.

Compilation works fine, linking provides an issue.

The 3rd party software provides an entry to provide basic linker options in the form of a variable. The default options are as follows:

link_sl='LINK', '/nologo', '/NOENTRY', '/INCREMENTAL:NO', '/subsystem:console', '/machine:AMD64', 
' /NODEFAULTLIB:LIBC.LIB', '/NODEFAULTLIB:LIBCMT.LIB','/DEFAULTLIB:OLDNAMES.LIB', '/DEFAULTLIB:LIBIFCOREMD.LIB', '/DEFAULTLIB:LIBIFPORTMD.LIB', '/DEFAULTLIB:LIBMMD.LIB', '/DEFAULTLIB:kernel32.lib', '/DEFAULTLIB:user32.lib', '/DEFAULTLIB:advapi32.lib','/FIXED:NO', '/dll','/def:%E', '/out:%U', '%F', '%A', '%L', '%B', 
'oldnames.lib', 'user32.lib', 'ws2_32.lib', 'netapi32.lib','advapi32.lib', 
'msvcrt.lib', 'vcruntime.lib', 'ucrt.lib']

This gives the following 11 errors when linking:

msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol __vcrt_initialize referenced in function __scrt_initialize_crt
msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol __vcrt_uninitialize referenced in function __scrt_initialize_crt
msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol __vcrt_uninitialize_critical referenced in function __scrt_dllmain_uninitialize_critical
msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol __vcrt_thread_attach referenced in function __scrt_dllmain_crt_thread_attach
msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol __vcrt_thread_detach referenced in function __scrt_dllmain_crt_thread_attach
msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol _is_c_termination_complete referenced in function __scrt_dllmain_uninitialize_c
msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol __acrt_initialize referenced in function __scrt_initialize_crt
msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol __acrt_uninitialize referenced in function __scrt_uninitialize_crt
msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol __acrt_uninitialize_critical referenced in function __scrt_dllmain_uninitialize_critical
msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol __acrt_thread_attach referenced in function __scrt_dllmain_crt_thread_attach
msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol __acrt_thread_detach referenced in function __scrt_dllmain_crt_thread_detach

Which basically means that I am not including all the necessary libraries. I already found out that including the library 'libvcruntime.lib' in the options reduces the errors to 6. So, using:

link_sl='LINK', '/nologo', '/NOENTRY', '/INCREMENTAL:NO', '/subsystem:console', '/machine:AMD64', 
' /NODEFAULTLIB:LIBC.LIB', '/NODEFAULTLIB:LIBCMT.LIB','/DEFAULTLIB:OLDNAMES.LIB', '/DEFAULTLIB:LIBIFCOREMD.LIB', '/DEFAULTLIB:LIBIFPORTMD.LIB', '/DEFAULTLIB:LIBMMD.LIB', '/DEFAULTLIB:kernel32.lib', '/DEFAULTLIB:user32.lib', '/DEFAULTLIB:advapi32.lib','/FIXED:NO', '/dll','/def:%E', '/out:%U', '%F', '%A', '%L', '%B', 
'oldnames.lib', 'user32.lib', 'ws2_32.lib', 'netapi32.lib','advapi32.lib', 
'msvcrt.lib', 'vcruntime.lib', 'ucrt.lib',**'libvcruntime.lib'**]

Results in:

msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol _is_c_termination_complete referenced in function __scrt_dllmain_uninitialize_c
msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol __acrt_initialize referenced in function __scrt_initialize_crt
msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol __acrt_uninitialize referenced in function __scrt_uninitialize_crt
msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol __acrt_uninitialize_critical referenced in function __scrt_dllmain_uninitialize_critical
msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol __acrt_thread_attach referenced in function __scrt_dllmain_crt_thread_attach
msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol __acrt_thread_detach referenced in function __scrt_dllmain_crt_thread_detach

Which other libraries do I need to include in the linking process to resolve these?

Duck Dodgers
  • 3,409
  • 8
  • 29
  • 43
  • 1
    Why are you using the `/NODEFAULTLIB:LIBC.LIB` and `/NODEFAULTLIB:LIBCMT.LIB` options? How did you configure your project? – Some programmer dude Jan 10 '19 at 08:28
  • Frankly, I don't know. They come as default options after installation of the 3rd party software. I guess they are required somehow. – Ruben Sevenois Jan 10 '19 at 08:51
  • Removing them does not change anything btw – Ruben Sevenois Jan 10 '19 at 08:52
  • Why are you linking with 2 [CRT's](https://learn.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=vs-2017)... vcruntime.lib, ucrt.lib – rustyx Jan 10 '19 at 09:03
  • This is obligatory as default values from the 3rd party software – Ruben Sevenois Jan 11 '19 at 11:15
  • See this on MSDN forums: [unresolved symbols moving C++ MFC-based application to VS2015 from VS2008](https://social.msdn.microsoft.com/Forums/vstudio/en-US/92ad53c5-22c1-4905-82a2-b0f1d68dbfc8/unresolved-symbols-moving-c-mfcbased-application-to-vs2015-from-vs2008?forum=vcgeneral). – jww Dec 14 '19 at 20:45

2 Answers2

0

One thing first: Since I compile with /MD, I use the DLL/shared variants of the CRT libs, not the lib... versions.


From within a DLL, when setting a breakpoint on ___vcrt_initialize, VS sets 2 underlying breakpoints, both in __scrt_stub_for_acrt_initialize() (here in C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.36.32532\crt\src\vcruntime\ucrt_stubs.cpp).

So this looks like vcruntime.lib or ucrt.lib, but it resides - surprise, surprise - in msvcrt.lib, as you can see from the following test:

T:>dumpbin /linkermember:1 "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.36.32532\lib\x86\vcruntime.lib"  | find /i "crt_initialize"
     441E ___vcrt_InitializeCriticalSectionEx
     441E __imp____vcrt_InitializeCriticalSectionEx

T:>dumpbin /linkermember:1 "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.36.32532\lib\x86\ucrt.lib"  | find /i "crt_initialize"

T:>dumpbin /linkermember:1 "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.36.32532\lib\x86\msvcrt.lib"  | find /i "crt_initialize"
   555AF0 ___scrt_initialize_mta
   555AF0 ___scrt_initialize_winrt
   5633F6 ___scrt_stub_for_vcrt_initialize
   564772 ___scrt_stub_for_acrt_initialize
   565DFE ___scrt_initialize_crt
   565DFE ___scrt_initialize_onexit_tables
   6DB504 ?__scrt_initialize_type_info@@YAXXZ
   70B59E ___scrt_initialize_default_local_stdio_options

Astonishingly, it does not help to explicitly put msvcrt.lib at the beginning AND at the end of the lib list passed to the linker.
And even more: The 11 unresolved externals are referenced by msvcrt.lib herself!

So I think, the solution is to find where the mapping between ___vcrt_initialize and __scrt_stub_for_acrt_initialize() is made.


The only way out of this I found was not to use an own DLL entrypoint, but explicitly specifying __DllMainCRTStartup@12 as entrypoint. See also my experiences in this SO post.

MattTT
  • 339
  • 3
  • 9
-1

I have encountered exactly the same problem when working within the framework provided by this 3rd party software. Although I cannot answer directly the question for finding the libraries containing _is_c_termination_complete, I realised it is still possible to make your code work: simply adding a /FORCE flag to your link_sl flag list.

According to MSVC official documentation:

The /FORCE option tells the linker to create a valid .exe file or DLL even if a symbol is referenced but not defined or is multiply defined.

Therefore, LNK2019 error messages will not stop the linker producing the dll library which is critical for the 3rd party software to run. The linker messages would look like:

msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol _is_c_termination_complete referenced in function __scrt_dllmain_uninitialize_c
msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol __acrt_initialize referenced in function __scrt_initialize_crt
msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol __acrt_uninitialize referenced in function __scrt_uninitialize_crt
msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol __acrt_uninitialize_critical referenced in function __scrt_dllmain_uninitialize_critical
msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol __acrt_thread_attach referenced in function __scrt_dllmain_crt_thread_attach
msvcrt.lib(utility.obj) : error LNK2019: unresolved external symbol __acrt_thread_detach referenced in function __scrt_dllmain_crt_thread_detach
 : warning LNK4088: image being generated due to /FORCE option; image may not run
msvcprt.lib(locale0_implib.obj) : warning LNK4210: .CRT section exists; there may be unhandled static initializers or terminators

This is certainly not a decant solution and is not guaranteed to be working in any case, however it worked for my codes at least.

Xi Zou
  • 1
  • 2
  • This Answer showed up in a quality queue. I don't think it is a good answer, but I don't have authority to move against it. In the future you should provide an answer that does not introduce additional errors. – jww Dec 14 '19 at 19:51
  • @jww I have to admit this is more a walkaround for the purpose of solving the owner's problem rather than a decent answer to his question. However, there is no addtional error introduced if one compares carefully the linker outputs listed in the question and the answer. – Xi Zou Dec 14 '19 at 20:07
  • The problem looks like it lies in the third party's linker flags. See this on MSDN forums: [unresolved symbols moving C++ MFC-based application to VS2015 from VS2008](https://social.msdn.microsoft.com/Forums/vstudio/en-US/92ad53c5-22c1-4905-82a2-b0f1d68dbfc8/unresolved-symbols-moving-c-mfcbased-application-to-vs2015-from-vs2008?forum=vcgeneral). – jww Dec 14 '19 at 20:45
  • @jww Exactly. Unfortunately the third party software is a commercial code, which only provides you some pre-built static libraries with poorly documented APIs. Apparently it is the user's work to link user-customised code to those libraries and make the program run. – Xi Zou Dec 14 '19 at 21:54