We are investigating why a project is getting an error about a weird C++/CX symbol, and we thought we had figured it out, but our attempt to replicate the problem with a minimal example failed. So we must have removed something important from the example.
Since the problem occurred when the project involved C++/CX, let’s add C++/CX to our minimal example. Maybe that will tell us something.
rem create a minimal fuzzer library >lib.cpp echo void fuzzme(); int __cdecl main(int, char**) { fuzzme(); return 42; } cl /c lib.cpp lib /out:lib.lib lib.obj rem create our fuzzer plugin >fuzzer.cpp echo void fuzzme() {} cl /c fuzzer.cpp rem new! Add a superfluous C++/CX component >cx.cpp echo ref class Dummy {}; cl /c /EHsc /ZW cx.cpp rem Try to link them all together link /out:fuzzer.exe /subsystem:console fuzzer.obj cx.obj lib.lib
Output:
vccorlib.lib(climain.obj) : error LNK2019: unresolved external symbol "?main@@YAHP$01E$AAV?$Array@PE$AAVString@ Platform@@ $00@Platform@@@Z" (?main@@YAHP$01E$AAV?$Array@ PE$AAVString@ Platform@@ $00@Platform@@@Z) referenced in function "int __cdecl _main(void)" (?_main@@YAHXZ)
Okay, now we get the error.
So the presence of cx.obj
introduces the problem.
Let’s go back to the verbose log to see where cx.obj
enters the picture.
Actually, something interesting jumps out right at the start.
Starting pass 1 Processed /DEFAULTLIB:LIBCMT Processed /DEFAULTLIB:OLDNAMES Processed /DEFAULTLIB:vccorlib.lib Processed /DEFAULTLIB:MSVCRT
These two libraries got added as default libraries, and that’s how vccorlib.lib
became one of the libraries participating in the module.
If we dig into cx.obj
, we can see where it requests those libraries.
link /dump /all cx.obj | findstr /i defaultlib
Output:
/DEFAULTLIB:vccorlib.lib /DEFAULTLIB:MSVCRT /DEFAULTLIB:OLDNAMES
The compiler injects requests for three default libraries into cx.obj
, so that’s how vccorlib.lib
joins the set of default libraries.
This explains why cx.obj
is essential to the repro: It is cx.obj
that pulls in vccorlib.lib
, which means that a search for main
finds the version in vccorlib.lib
before it finds the one we want in lib.lib
.
Now that we understand the source of the problem, we’ll look at trying to fix it. Next time.
0 comments
Be the first to start the discussion.