Question

I'm using Visual Studio 2010, with a lot of project and solution files. But now I find myself in a bit of dependency hell with ProjectReferences:

  • Project Simple produces a static lib.
  • Projects Foo and Bar depend on Simple, and also produce static libs.
  • Project Module depends on Foo and produces a DLL.
  • Project Module2 depends on Bar and produces a DLL.

So the dependency tree looks like this:

                Simple
                  |
     ____________/ \__________
     |                        |
    Foo                      Bar
     |                        |
   Module                   Module2

With ProjectReferences, I can make Module depend on Foo and automatically link Foo.lib. This works fine.

But, is there a way for Module to automatically link in Simple.lib?

It seems like that should be possible. Module depends on Foo, which depends on Simple, so it seems like it should be able to have an option for "link in the output of my references and my references' references". But I can't find anything that lets me do that.

The "Link Library Dependencies" option doesn't do it. It only links in Foo.lib, and then I get a linking error about unresolved external symbols (symbols which are defined in Simple.lib).

Setting "Link Library Dependencies" to true for the Foo->Simple and Bar->Simple references seems to work at first, until you have a project that uses both Foo and Bar. That setting actually embeds Simple.lib inside of Foo.lib and Bar.lib, and then you get "symbol is already defined" errors if you try to use both Foo.lib and Bar.lib. And that's the correct error - I don't actually want to put Simple.lib inside of any other lib.

I can add a ProjectReferece from Module to Simple, but that's tedious to set in every project that uses Foo, and it's violating the encapsulation of Foo. Module should not need to know about Simple. Obviously the linker needs to know about Simple, but it should be able to figure that out by following ProjectReferences.

Here's why this matters: Suppose, during maintenance, a new project is created: Basic, which creates a static lib, and Simple depends on Basic. Now we have to update every single project that has a ProjectReference to Simple directly or through another ProjectReference (in this example it's only two projects, Module and Module2, but in reality it's dozens). That's tedious.

tl;dr Is there a way to automatically link in the static libs of my dependencies?

Was it helpful?

Solution

Apparently, this is a bug in Visual Studio 2010: https://connect.microsoft.com/VisualStudio/feedback/details/638534/unresolved-externals-when-build-a-vc-project-with-chained-static-lib-dependencies#details

Unfortunately, Microsoft closed the bug as "fixed" -- which isn't quite true. It's more of a workaround, but it's not what I would consider a real fix. (A real fix would be a patch or a service pack, not something that needs to be manually tweaked on every machine).

The "fix" is to do the following:

Modify %ProgramFiles(x86)%\MSBuild\Microsoft.cpp\v4.0\Microsoft.CPPBuild.Targets And change the line:

<Target Name="GetResolvedLinkLibs" Returns="@(LibFullPath)"
 DependsOnTargets="$(CommonBuildOnlyTargets)">

To

<Target Name="GetResolvedLinkLibs" Returns="@(LibFullPath)"
 DependsOnTargets="$(CommonBuildOnlyTargets);ResolvedLinkLib">

So, just add the ;ResolvedLinkLib part to that file. Then VS will link in dependencies of dependencies.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top