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
andBar
depend onSimple
, and also produce static libs. - Project
Module
depends onFoo
and produces a DLL. - Project
Module2
depends onBar
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?
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:To
So, just add the ;ResolvedLinkLib part to that file. Then VS will link in dependencies of dependencies.