Page 1 of 1

Tracking Down Linker Errors

Posted: Sun Jul 11, 2021 10:56 am
by jussij
When compiling some throw away C++ code found in a c:\temp\test.cpp file I ran into this strange linking error:

Code: Select all

Microsoft (R) C/C++ Optimizing Compiler Version 19.29.30037 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

TEST.CPP
Microsoft (R) Incremental Linker Version 14.29.30037.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:TEST.exe
TEST.obj
comctl32.lib
kernel32.lib
user32.lib
gdi32.lib
winspool.lib
comdlg32.lib
advapi32.lib
shell32.lib
ole32.lib
shlwapi.lib
wtsapi32.lib
libcpmt.lib(syserror.obj) : error LNK2019: unresolved external symbol __imp__FormatMessageA@28 referenced in function "unsigned long __cdecl std::_Winerror_message(unsigned long,char *,unsigned long)" (?_Winerror_message@std@@YAKKPADK@Z)
libcpmt.lib(syserror_import_lib.obj) : error LNK2001: unresolved external symbol __imp__FormatMessageA@28
libcpmt.lib(xwctomb.obj) : error LNK2019: unresolved external symbol __imp__WideCharToMultiByte@32 referenced in function __Wcrtomb
libcpmt.lib(StlLCMapStringA.obj) : error LNK2001: unresolved external symbol __imp__WideCharToMultiByte@32
libucrt.lib(widechartomultibyte.obj) : error LNK2001: unresolved external symbol __imp__WideCharToMultiByte@32
libucrt.lib(osfinfo.obj) : error LNK2001: unresolved external symbol __imp__EnterCriticalSection@4
libcpmt.lib(xmtx.obj) : error LNK2001: unresolved external symbol __imp__EnterCriticalSection@4
libvcruntime.lib(locks.obj) : error LNK2001: unresolved external symbol __imp__EnterCriticalSection@4
libucrt.lib(locks.obj) : error LNK2001: unresolved external symbol __imp__EnterCriticalSection@4
libucrt.lib(_file.obj) : error LNK2001: unresolved external symbol __imp__EnterCriticalSection@4
libucrt.lib(osfinfo.obj) : error LNK2001: unresolved external symbol __imp__LeaveCriticalSection@4
..
To produce this error I was just running this simple command line:

Code: Select all

cl.exe test.cpp
Now that error output clearly shows the issue was happening in the linker phase so it is no suprise I could reproduce the error using these individual compile and link steps:

Code: Select all

cl.exe -c test.cpp
link.exe test.obj
This then helps as I was then able to reproduce just the linker error by running this command:

Code: Select all

link.exe test.obj
Finally I was able to solve the issue by running this special linker command:

Code: Select all

link.exe test.obj /VERBOSE:LIB
Running that command produced this output:

Code: Select all

Microsoft (R) Incremental Linker Version 14.29.30037.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Searching libraries
    Searching C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\lib\x86\libcpmt.lib:
    Searching C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\lib\x86\LIBCMT.lib:
    Searching C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\lib\x86\OLDNAMES.lib:
    Searching kernel32.lib:
    Searching C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\lib\x86\libvcruntime.lib:
    Searching C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\ucrt\x86\libucrt.lib:
    Searching C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\um\x86\uuid.lib:
    Searching C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\lib\x86\libcpmt.lib:
    Searching C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\lib\x86\LIBCMT.lib:
    Searching C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\lib\x86\OLDNAMES.lib:
    Searching kernel32.lib:
    Searching C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\lib\x86\libvcruntime.lib:
    Searching C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\ucrt\x86\libucrt.lib:
    Searching C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\um\x86\uuid.lib:
    Searching C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\lib\x86\libcpmt.lib:
    Searching C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\lib\x86\LIBCMT.lib:
    Searching C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\lib\x86\OLDNAMES.lib:
    Searching kernel32.lib:
    ...
If you look at that output you can see the kernel32.lib stands out like a sore thumb as it has a totally different path to the other LIB files.

Surely enough somehow a kernel32.lib had found it's way into that c:\temp\ folder and the linker was using that file in the link process.

I use that temp folder to test code I find on the web and I suspect that lib file had been added to the folder as one such download.

Deleting that errant file fixed the issue :)

Cheers Jussi