How to supress Warning LNK4099 – PDB ‘XXX’ was not found

When a library is compiled in MSVC with PDB support, but later distributed without the correct PDBs, anyone attempting to link with the library will get many warnings of the form:

warning LNK4099: PDB 'XXX' was not found with 'YYY' or at 'ZZZ';
linking object as if no debug info

You might think that it’s not a big deal: recompile the library to not use PDB files, or disable the warning. The former option isn’t available if it’s a 3rd party SDK without source code, and the latter option isn’t possible (more on that in a second).

At least in Visual Studio 2003 (7.1) and Visual Studio 2005 (8.0), 4099 is on a ‘non-ignorable’ warning list. This means that you can’t use /ignore in the linker command line options to get rid of it, brilliant! This is by design [1] and they don’t care enough to provide any other mechanism right now [2]. To be fair, both the /ignore switch and which warnings are non-ignorable seem to be undocumented, but someone else has made a handy list of them [3].

Now, you could probably live with it if there was just one warning per-library and you don’t really care about compiling with 0 warnings, but it’s typically hundreds of warnings, and we all know how slow VC80 gets when you spam the output window. So, since there is no sanctioned workaround, let’s do this the hard way.

How to disable the warning by patching your linker

The following are instructions that I wrote up for some friends in this situation, only tested on VC8, but it should apply to VC7.1 or VC9 as well. Yes, I really am proposing that you patch your linker to ensure a clean build. If it helps you sleep at night, think of it as correcting a profound oversight by Microsoft. There just isn’t any other solution if you want to compile in debug mode against libraries you don’t have source for that were incorrectly configured.

You could go after the code that generates a 4099 and prevent it from ever getting generated, or the code that prevents it from being ignored. The second path is quite easy, there is a whole list of non-ignorable warnings which makes it trivial to correctly identify the list within the linker executable.

Fire up your favorite hex editor on link.exe (likely the one in “C:\Program Files\Microsoft Visual Studio 8\VC\bin”) and look for 4099 at 32 bits wide. The very first hit also has 4088 before it, and 4105 after it, bingo! I set it to 65535; pick your poison, but you probably want to avoid the 4xxx range. Hooray for no more annoying PDB warnings, at least until the next VS SP or VC9.

The usual caveats apply when modifying executables (Make a backup copy, validate what you’re attempting to change, no warranty express or implied, etc…). If you have a newer or older link.exe, the list of unignorable warnings may be different, or stored differently, so verify that the value you’re replacing is sane:

... F8 0F 00 00 - 03 10 00 00 - 09 10 00 00 ... (4088, 4099, 4105)

Once done, you can add /ignore:4099 to your linker options and it will actually work.

Thanks. I can confirm that making this change confused the crap out of my coworkers who then spent time trying to track down the presence of the warning on THEIR unpatched machines to configuration problems on their end. A better solution is perhaps #pragma message(“Please ignore LNK4099, it is not an issue.”) then leaving it be.