views:

763

answers:

4

I'm currently using msbuild for a solution of over 600 projects.

Imagine I change the code for 1 library that is used by 10 projects. Instead of providing all 600 projects to msbuild and let it compile all of them and figure out the dependencys. I was wondering if there was a program or library I could use that would analyse the dependencys of all 600 projects, and allow me to only compile the 11 that are necessary.

In other words given the input of all 600 projects to scan, and BaseLibrary.csproj as a project that has been modified parameter, provide me only the 11 projects I need to compile as output.

I'm experienced in writing custom tasks, I'd just rather use a third party library to do the dependency analysis if there is already one out there.

My company does incremental releases to production every 3-4 months. As an experiment I wrote a custom task that looks at the previous releases "Subversion tag" and evaluates all the compiled files that have changed since then and maps them to a project.

The only use case I can think of that doesn't work is the one I mentioned where a base library is changed and the system doesn't know about all the projects that depend on it.

A: 

MSBuild Tasks doesn't have what you're looking for, but it will give you an easy entry point for writing your own tasks.

Gavin Miller
+1  A: 

The project dependencies are a graph, where project P has a directed edge to project Q if P depends on Q. This means that Q has to be build before P.

In general a topological sort of the graph reveals the dependency order of the entire graph, but you're only interested in the graph from P to the root of the graph (or roots, if there are more).

A root in this graph is the project which depends on no other project but other projects depend on that project.

When you change P, all projects from P to the root(s) you're running into are to be compiled, in reverse order (root first). The easiest way to do that is to create a subgraph of that path (with subnodes) and use topological sorting to determine the right order.

That said, it's a complex problem, as changing code in a project must mark that project as 'changed' somehow, and also you've to manually parse the project files for dependencies.

If I'm not mistaken, MSBuild compiles only projects which are out of date. (although does process them but it has to, otherwise it can't determine which project is 'changed').

Frans Bouma
+1  A: 

Have you tried .NET assembly dependency analyser?.

It is open source, and the graph output in dot script might be what you need. An example from the site:

digraph G { 
      size="100,69"
      center=""
      ratio=All
      node[width=.25,hight=.375,fontsize=12,color=lightblue2,style=filled]
      1 -> 9;
      1 -> 11;
      9 -> 10;
      11 -> 10;
      1 [label="Drew.Controls.Map"];
      9 [label="Drew.Types"];
      10 [label="nunit.framework"];
      11 [label="Drew.Util"];
 }

With the list of projects and this script output, you can create your compilation list.

Alberto Sciessere
+1  A: 

I have some code that does exactly this; I use it in our bespoke build process to a: figure out the build order (without having to maintain it), and b: cascade changes upwards through a tree of random projects. Unfortunately I'm not in my usual office at the moment, and the code is too complex to reproduce "off the cuff" (it does lots of graph mapping and dependency tracking).

I should add that it currently works by having a custom marker (xml file) in the root of every project that tracks what needs building; our code promotion process sets the flag, and the build process clears it.

The way it works at the moment is you get to the root that contains all the projects (at any depth), and just type depends (with a few switches), and it emits all the project paths that need building, in the right order.

Let me know if it is of interest...

Marc Gravell