Posts Tagged MSBuild

MSBuild fails to compile WPF with: error MC2000: Unkown build error ‘…’ does not have an implementation

My initial solution in this post was WRONG, it just changed the compile order of our build which made the error occur later after other issues were resolved. I’ve updated the post accordingly. I’m sorry if anyone had to read this post twice.

We have been struggling with a build error lately, where the compilation works perfectly in Visual Studio, and in our case it also works in some MSBuild builds but not in this specific build. By that I mean that two builds are compiling the same code, with the same dependencies and compilation flags, yet one fails and the other doesn’t.

The error message given is:

D:\Invoicing\UQList.xaml(55,167): error MC2000: Unknown build error, 'Method 'add_PropertyChanged' in type 'UsageQuantityPresenter' from assembly 'ServiceManagementApplication' does not have an implementation. Line 55 Position 167.' 

If we look at the buildlog.txt produced by MSBuild in the failing build, we can find something similar to this:

  Input file 'D:\Invoicing\UQList.xaml' is resolved to new relative path 'Invoicing\UQList.xaml' at directory 'D:\'.
D:\Invoicing\UQList.xaml(55,167): error MC2000: Unknown build error, 'Method 'add_PropertyChanged' in type 'UsageQuantityPresenter' from assembly 'ServiceManagementApplication' does not have an implementation. Line 55 Position 167.'
  Input file 'D:\Trait\TraitsView.xaml' is resolved to new relative path 'Trait\TraitsView.xaml' at directory 'D:\'.
...
  Generated BAML file: 'D:\obj\Release\Themes\luna.normalcolor.baml'.
  Generated BAML file: 'D:\obj\Release\Trait\TraitsView.baml'.
  Markup compilation is done.
Done executing task "MarkupCompilePass2" -- FAILED.
Done building target "MarkupCompilePass2" in project "ServiceMangementApplication.csproj" -- FAILED.

In the XAML we are depending on the UsageQuantityPresenter to implement INotifyPropertyChanged, which it does. However it also implements other interfaces and does inheritance of a base-class.

This is what it looked for for us:

/// <summary>
/// UsageQuantityPresenter
/// </summary>
public class UsageQuantityPresenter : EntityViewPresenterBase, IUsageQuantity
{
...

The EntityViewPresenterBase (I hate that class name by the way) implements INotifyPropertyChanged.

The solution was found in the following forum tread: http://social.msdn.microsoft.com/Forums/en/wpf/thread/00907c94-c6b2-4bf1-98f9-113c5c4392d8

It states that you should add:

<AlwaysCompileMarkupFilesInSeparateDomain>true</AlwaysCompileMarkupFilesInSeparateDomain>

to the .csproj file with the XAML files. Doing this makes MSBuild happy again.

, ,

No Comments

Independent trunk and MSBuild

A while back I posted a post about a concept I call the Independent trunk.
The core concept is that everything required to build a distributable version of a software product is checked in under one branch in the source-control system. A build system should get everything it requires to build the system from the branch and shouldn’t need any more sources.

Ideally I would thus like to have custom buildtasks checked in under the branch so that the custom build processes for the product follow the evolution and version history of the product.

Now buildtasks for MSBuild doesn’t change very often, so we had a theory that we could have a compiled version of the checked in as a reference for the build system. Having the buildtask set up to be checked out and checked in as its recompiled.

Anyway we looked into this, this week. It turn out that such a setup is not valid for MSBuild. The reason is due to the order in which MSBuild does things.

See first MSBuild compiles and checks the project files and their structures. Then it goes to fetch the sources needed for the build.

This means that in order to have custom buildtasks they have to be avaliable from the same location that the TFSProj file is located or be avaliable before the sources are fetched from the server.

All in all, we cannot have the buildtargets checked in with the product under source-control.

If anyone have an idea on how to get around this constraint I’m all ears.

, ,

No Comments

Safe import of .target files

We’ve changed most of our projects to import other .target files. This means that we get allot of warnings about unsafe imports.

To eliminate these we can add a registry setting with the file name of the .targets file in HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\MSBuild\SafeImports.

However this needs to be the full path of the file, which makes it problematic for branching and for teams without common rules of where to put their work spaces.

Our initial idea was to create an .inf file that adds our project targets to the registry, but the full-path requirement spoils it for us as we use allot of branches.

For more information I found this how-to.

Along with this Forum entry in 2005, describing that this has been reported as a bug.

,

No Comments

error MSB3491: Could not write lines to file (Solution).(Configuration).vsprops

Just got this error message from MSBuild. I’ve gotten it before, but I couldn’t remember what the problem was.

Build FAILED.

“D:\Builds\*\BuildType\TFSBuild.proj” (EndToEndIteration target) (1) ->
“D:\Builds\*\BuildType\TFSBuild.proj” (CoreCompile target) (1:2) ->
“D:\Builds\*\BuildType\TFSBuild.proj” (CompileConfiguration target) (1:3) ->
“D:\Builds\*\BuildType\TFSBuild.proj” (CompileSolution target) (1:5) ->
(CoreCompileSolution target) ->
C:\Program Files\MSBuild\Microsoft\VisualStudio\TeamBuild\Microsoft.TeamFoundation.Build.targets(978,5): error MSB3491: Could not write lines to file “D:\Builds\*\*.sln.Release.vsprops”. Could not find a part of the path ‘D:\Builds\*\*.sln.Release.vsprops’.

0 Warning(s)
1 Error(s)

Turns out that I forgot to add the location of the solution I wanted to build to the builds workspace, defined in the build definition.

3 Comments

Balancing builds over several build servers

I always have a tendency to strive to find uses for the academic problem solving techniques I learned when I achieved my masters. This is something that is a bit fun, doesn’t take too long and gives a quick starting template for balancing builds over several build agents in TFS2008.

The problem:
Our build environment is set up by several small builds that build parts of the system independently. We have two build agents to balance the load of the building, and can do so by defining the default build agent to use in the build definition. Were of course using the built in Continues Integration in TFS2008. Now we want our builds to utilize these agents as much as possible. So when I do a check-in that will start more than one build I want the builds to be distributed across several build agents.

The solution:
First of Id like to start out by point out that this solution is, by far, not an optimal solution, it does not take into account the direction of dependencies nor the build time of each build. This does however provide a low cost, fast, starting point for deploying the builds across agents.

Now; the Continues Integration in TFS2008 uses the workspace mappings to trigger builds. For example; if you check in under the “Forms” folder in source control, all builds that have that folder under its workspace mapping will be triggered.

So say we have 5 builds; Rest Service, Domain Objects, Integration Service, Windows Client and Windows UI Components. These builds all depend on each other which means that parts of them have the same sources mapped in their workspace mappings.
Now for the fun part.

Let each build represent a node in a graph. Let each node be connected by a edge, based on the similarities in the workspace mappings. Lets call an edge a dependency. Using our 5 builds example we could get a graph that looks something like the following:

Now to balance the 5 builds across 2 build agents. To do this, we apply classic graph coloring. Let each build server be represented by a color. Now assign a color to a build in the graph. The nodes (builds) connected the colored node now has to be colored with a different color than the one used. Continue coloring the nodes so that no nodes are connected to each other and have the same color. The above graph above is colored with two colors green and blue, each representing a build agent.

What we achieve by this is that if we check-in in the Windows UI Components parts of the trunk the following builds will be triggered:

Build Agent 1
Build Agent 2
Windows UI components Windows Client

However; we can see that the Domain Objects build is highly centric, checking in in this part of the trunk will trigger 4 builds; Domain objects, Rest Service, Integration Service and the Windows Client builds. With a distribution that looks like:

Build Agent 1
Build Agent 2
Domain Objects Windows Client
Integration Service
Rest Service

This is due to two problems; the domain objects build is highly coupled and used in the other builds, and that this approach for balancing the builds does not take the build duration or weight into account.

The above graph is of course possible to color using two colors, it might not be the case that the graph of your build system is possible to color using two colors, then just cant efficiently load the builds across just two build agents.

The graph above was created using the Carya.Net tool.

No Comments

Running tests in DesktopBuild

This post is inspired by a problem we had in our TFS2008 build environment, I am not sure if it applies to the 2005 version of MSBuild.

The problem:

Say you are running tests in your team builds, and you have configured your build so they can run on a Developer desktop as well as on a build server.
By default, using Microsoft’s targets, tests are not run during a Desktop Build. This means that a build can pass when run locally but fail, or give partial success on the server, due to test errors. We had a scenario where some tests were “Not runnable” in our Test Container. Which resulted in failed builds.

The reason is that MSTest returns the error code 1 if there are tests that are not runnable.

To test the behaviour locally we wanted our tests to run during the Desktop Build, so we could have a faster debug cycle when working with this problem.

Solution:
So by looking in the Microsoft.TeamFoundation.Build.targets file, we see what dependencies the test targets have.

Here is a list starting from the Test target.
If a target has a dependency it is located above the target. If a target results in the execution of MSBuild on different targets it is represented by the content in the column to the right column.

BeforeTest;
CoreTest; (CoreTest starts the project file again but targets RunTest)
ComputeConfigurationList;
RunTest (RunTest starts the project file again but targets TestConfiguration)
BeforeTestConfiguration;
ResolveTestFilesForEndToEndIteration
CoreTestConfiguration;
AfterTestConfiguration;
TestConfiguration
AfterTest;

The target marked red in the above table is not run during Desktop Builds, and is the only one that doesn’t work in Desktop environments. This means that the entire suite of test targets stops at that target.
The CoreTestConfiguration target depends on the ResolveTestFilesForEndToEndIteration target, and the CoreTestConfiguration runs the actual tests.
The ResolveTestFilesForEndToEndIteration target looks like the following.

We can make our own version of this and add it to our TFSBuild.proj file that runs on Desktop Builds. What we do is simply pass on the TestContainer, without using the WorkspaceItemConverterTask.

With this target included in our TFSBuild.proj file, the build runs the tests both locally and on the server.

For our project, we have added this target to our common targets file that all builds refer to. So that all projects run tests when run on as a Desktop Build.

No Comments