which library contains _is_c_termination_complete

Viewed 2167

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?

2 Answers

We ran into the exact same problem. Through making a simple console project in visual studio we found that this code:

#include <stdio.h>
extern "C" {
    int _is_c_termination_complete(...);
    int __acrt_initialize(...);
    int __acrt_uninitialize(...);
}


int main()
{
    if(_is_c_termination_complete())
    { 
        __acrt_initialize();
    }
    fprintf(stdout, "Hello world\n");
    return 0;
}

Became this in disassembly.

main:
<snip>
00007FF68B44194A  call        __scrt_stub_for_is_c_termination_complete (07FF68B441140h)  
00007FF68B44194F  test        eax,eax  
00007FF68B441951  je          main+38h (07FF68B441958h)  
00007FF68B441953  call        __acrt_initialize (07FF68B441393h)  
00007FF68B441958  mov         ecx,1  
00007FF68B44195D  call        qword ptr [__imp___acrt_iob_func (07FF68B4502F0h)]  
00007FF68B441963  lea         rdx,[string "Hello world\n" (07FF68B449C28h)]  
00007FF68B44196A  mov         rcx,rax  
00007FF68B44196D  call        fprintf (07FF68B44119Ah)  
00007FF68B441972  xor         eax,eax  
00007FF68B441974  lea         rsp,[rbp+0C8h]  
00007FF68B44197B  pop         rdi  
00007FF68B44197C  pop         rbp  

The linker apparently rewrites _is_c_termination_complete to be __scrt_stub_for_is_c_termination_complete. As best as we can tell, the function _is_c_termination_complete doesn't exist in any particular crt. Different crts appear to have different implementations that the linker appears to rewrite depending on the crt you are linking against.

For us, removing the /NOENTRY option from the link line fixed the 6 errors. Apparently, /NOENTRY stops the linker from pulling in the crt's implementation.

Apparently, /NOENTRY actually means no code, which we definitely had.

https://docs.microsoft.com/en-us/cpp/build/reference/noentry-no-entry-point?view=vs-2019

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.

Related