edit: I finally was able to resolve all unresolved symbols - see my answer below. However the behavior of the MS tools remains mysterious and not like documented.
I have an ANT project, that uses the Visual Studio (C++) 2022 toolchain on Win 10 to build.
So there is no VS project - every setting is done via ANT.
I want an exe and a dll sharing the same CRT. So therefore I use the /MD compiler switch.
Currently I struggle with the dll.
Unfortunately, at the end I get many unresolved externals, i.e. _floor, _memset, _memcpy,
and also _terminate, which is referenced by LIBCMT.LIB (is this a hint already?).
With the /VERBOSE:LIB linker switch I analysed the libs that are used, which are the following:
Searching C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\\um\x86\kernel32.lib:
Searching C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\\um\x86\rpcns4.lib:
Searching C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\\um\x86\rpcrt4.lib:
Searching C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\\um\x86\oleaut32.lib:
Searching C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\\um\x86\uuid.lib:
Searching C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\\um\x86\user32.lib:
Searching C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\\um\x86\gdi32.lib:
Searching C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\\um\x86\winspool.lib:
Searching C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\\um\x86\comdlg32.lib:
Searching C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\\um\x86\advapi32.lib:
Searching C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\\um\x86\shell32.lib:
Searching C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\\um\x86\ole32.lib:
Searching C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\\um\x86\odbc32.lib:
Searching C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\\um\x86\odbccp32.lib:
Searching C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\\um\x86\Ws2_32.lib:
Searching C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\\um\x86\Psapi.lib:
Searching C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\\um\x86\IPHlpApi.Lib:
Searching C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.32.31326\lib\x86\delayimp.lib:
Searching C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.32.31326\lib\x86\LIBCMT.lib:
Searching C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.32.31326\lib\x86\OLDNAMES.lib:
Searching C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.32.31326\lib\x86\msvcprt.lib:
Searching C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.32.31326\lib\x86\MSVCRT.lib:
msvcrt.lib seems to be the suitable one according to this MS doc. And it obviously was picked by the linker automatically.
However I don't understand under which circumstances the other mentioned libs should be picked: ucrt.lib and vcruntime.lib.
Using dumpbin /symbols "..." | find /i " _memset" I can see, that neither
C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\ucrt\x86\ucrt.lib nor
C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.32.31326\lib\x86\vcruntime.lib contain it.
But I can find it in libvcruntime.lib:
> dumpbin /symbols "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.32.31326\lib\x86\libvcruntime.lib" | find /i " _memset"
011 00000000 SECT6 notype () External | _memset
But this should be the static one, so not suitable for me, right?
Any hint how to get the missing functions??
At first, the
LIBCMT.libyou see in my question resulted from an old object, that still was compiled with /MT. After I updated this object, theLIBCMT.libdisappeared from linker output.vcruntime.libindeed contained symbols like_memset, _memcpy.And
ucrt.libcontained symbols like__imp__calloc,_terminate&_floor.The exported symbols contained in the libs could finally be viewed by
dumpbin /linkermember:1.(
dumpbin /exportsdid not show e.g.__imp__callocinucrt.lib.)Although
msvcrt.libwas picked by the linker automatically, I had to specifyvcruntime.lib&ucrt.libmanually. (Does anyone know why?)After that I was left with the following 11 unresolved symbols:
This seems to be the same problem like in this SO question. It has no real good answer (currently), but a comment there refers to this MS community question. There the solution was to remove the
/ENTRY:myEntryPoint.Following this I end up with the unresolved external
_DllMainCRTStartup.I could not find this symbol in
vcruntime.libas the MS doc stated, however I found__DllMainCRTStartup@12inmsvcrt.lib.vcruntime.libwas already used; andmsvcrt.libwas also already used. The sticking point is:msvcrt.libcontains the__stdcallvariant of the function – what I need is the__cdeclvariant.So I decided to build a little bridge like this:
This linked without error, however I got a warning
which brought me to the solution to specify the
msvcrt.libfunction as entrypoint:/ENTRY:__DllMainCRTStartup@12I deleted my bridge and made an ordinary DllMain.
which finally linked fine.
So all that's left to do is to explain this unexpected behavior:
_DllMainCRTStartupas default entrypoint, but does not comply with its calling convention?(Remember: The unresolved external
_DllMainCRTStartupdisappears when I simply specify the (already existing) function__DllMainCRTStartup@12as entrypoint.)__DllMainCRTStartup@12) as entrypoint.