As you figured out already yourself, both requirements (only project references + chained builds) contradict each other. At least I can't think of a way to get them to play togeher. So one of them will have to change somehow.
First idea: do you really need chained builds? It takes a while to set up, in the end you probably want to build everything anyway, so why not just build everything by default?
If the answer to the above is 'yes': suppose not using project references after all. Using dll references directly is a mess though, wouldn't recommend it. You could use NuGet in some way though. That would mean for instance CommonLibrary is built into a package, and other builds use that package through NuGet meaning it's still a dll reference but install is automatic. I've seen people do that with TeamCity (since it can act as package server) but I don't know the details of the setup, not how to deal with local dev builds. It does mean teaching your dev team to add references only using NuGet of course.
Another way: you keep project references (yay!), but for chained builds you run a script on all project files that removes the reference and replaces it with an assembly reference. Sound messy, but I'm usig something like this as well and once setup it's pretty much foolproof. In practice you'd add some build steps to TC so you get a build flow like this:
- checkout CommonLibrary, build and store artefacts
- checkout CoreProduct, run script, build and store artefacts
- checkout XYZ, run script, build and store artefacts
And the script would:
- look for
ProjectReference
items - store the value of the
Name
tag - remove the
ProjectReference
items - for every
Name
found above, add a plain reference like<Reference Include=name HintPath=/path/to/artefacts>
- save the project file
Writing such a program is relatively easy if you use C# and the classes from the Microsoft.Build.Construction
namespace since they can deal with project files. Or else you can use your favourite xml library.
edit
in response to your comment/answer: it seems your build environment is a bit crippled. You can either spend lots of time figuring out workarounds etc, or you could just fix it properly once and for all. From my experience the first option leads to more and more problems and in the end you're left with a monolithic block where even the slightest change results in a waterfall of problems requiring again more time to fix everything. The second option on the other hand (eg do not rely on SolutionDir and place targets in a common place accessible by all projects - don't have different projects output assemblies with the same name, ...) might take more time now, but it will be worth it in the end casue you'll be left with a fairly clean build system that is easy to extend and you won't be wasting more time in the future. Also if you fix said problems now, chances are you can simply use something like my last solution and you do not need Choose element/multiple projects/conditions/... etc: the script creates a whole new project file that is just used for the chained build and nothing else.