Thursday, March 06, 2008

Solving pesky LNK4204 warnings...

So today I finally thought I had the entire build process worked out for the upgrade to VS 2008. Turns out I had one final little hurdle to overcome. After experiencing the mess of trying to integrate third-party libraries into my main base library, I decided to try creating a build hierarchy to significantly reduce build times and my base library project size.

Let me clarify what a build hierarchy is: Basically, I have a base library that I integrate with every software application I write. I've actually got pre-made projects set up that allow me to quickly roll out a new piece of software without wasting 30 minutes each time I go to write a quick little program. Occasionally I have need for a third-party library. Instead of dragging those VC++ projects into each and every solution so that the base library didn't break, I merged the solutions into one project. Yeah, after the fact, it turned out to be not one of my brighter ideas (it generally worked fine though but rebuilds were a huge pain). A build hierarchy is a separate solution where I build a static library or DLL of whatever it is that needs building. Then I just use the output libs in my main library's build process. The idea here is to keep the library layer completely separate from the application layer. I don't ever want to have to edit project settings for the application layer or the library layer.

Basically, I added the path and filename to the .lib file to Properties->Librarian->General->Additional Dependencies and then went and built the project. The test application built but then, for every last .obj file in the third-party .lib, the linker issued a LNK4204 warning despite the .pdb files clearly being in the same directory as the third-party .lib file was. The solution to this was pretty obscure. Apparently all .pdb files generated outside the current solution have to have completely unique names to be used within another solution. This is obscure because you would think that the output .pdb filename from each solution being unique would be sufficient as it contains all the .objs and .pdb data within the .lib and library .pdb. Apparently the linker gets confused if two .pdb names conflict at any level in the hierarchy. VC++ gives a default name to each .pdb, making it somewhat painful to go through each project and override it. Anyway, making all .pdbs have unique names (not just the top-level ones) made all the LNK4204 errors go away and build cleanly (did a Rebuild Solution just to make sure).

I still have quite a ways to go before my development environment is stabilized again but the major hurdles are out of the way. I've basically stalled all development effort until this gets done. I've put in countless hours getting this to work and probably lost some sleep too.

Sleep? What's that?

2 comments:

  1. Nice post, I'm currently working on the same issue but within own build engine. So no visual studio environment present. My problem is that I got many .objs and one some.pdb from cl.exe /Zi and after that I produce library some.lib with LIB.EXE. But I got the LNK4204 when I'm linking that some.lib to other project. Any suggestions? Thanks

    ReplyDelete
    Replies
    1. As per this post, did you check and make sure that your PDB files are uniquely named? The IDE uses the same VC++ compiler and linker as your build engine, so the same rules apply.

      Delete