I'm noticing some solutions in Team Foundation Server 2008 won't build completely. As in, some number of the projects in the solution succeed but then one fails. The particular failing project says I’m missing an assembly reference. But I'm not - the project has the reference. It builds fine on my PC. I'm looking at the .csproj file that the build agent pulled down and it has the reference, too (it's line-for-line identical to the project I'm building).
The reference in question is to another project in the solution. At first I thought it wasn't building projects in the right order but the build log is telling me that it did (i.e., the project which the reference is in reference to built successfully). So my guess is that somehow on this project (and I’d say about 10-20% of the projects I’m having it build are failing) it’s looking at the wrong folder for assemblies, but I have no idea.
Has anyone ever seen this before?
I did have one Solution which was building things in the wrong order and some Googling seemed to indicate that this was an occasional side-effect of converting a VS2003 SLN file to a VS2008 SLN file (and it was happening in Visual Studio as well), so in that case I made a new SLN from scratch, checked that in "on top" of the problematic one, and it worked fine. But I tried that in the problem above and it didn’t make a difference.
I've seen it on multicore machines where the project dependencies haven't been setup correctly, meaning that tfs starts a project compiling before it's dependencies are finished compiling.
At first I thought it wasn't building projects in the right order but the build log is telling me that it did (i.e., the project which the reference is in reference to built successfully).
Define "built successfully." In particular, make sure the CoreCompile target was invoked and ran to completion. I've seen cases where a different target on the referenced project was built, but that target was insufficient to generate the output the dependent project needed. For example, a web project that includes a Silverlight control will call the GetXapOutputFile target on the Silverlight project -- which is fine & dandy, but it's no replacement for CoreCompile.
If this clue isn't enough to resolve your issue, you should probably post a link to the log and/or the msbuild makefiles.
Related
I'm struggling to get Azure Devops Server 2019 (on prem) to build a complicated project setup of mine.
I have multiple solutions that build various BizTalk apps. Some of these solutions references some of the projects in other solutions/repos. This works fine in Visual Studio (providing everybody names their repos as the default, which they do).
To automate this build, I've created a multi-stage build pipeline that builds each solution in order.
Whilst solution 1 will build successfully, when it comes to solution 2, the msbuild tasks will not reference the outputs for the projects that have been included as a project reference in the solution.
This seems to be because these referenced projects aren't marked for build - because they wouldn't be able to build themselves without them in turn referencing their other projects in the main solutions etc.
Bundling everything into one big super solution file is not feasible.
I'm wanting msbuild to /reference the projects that have already been built in the previous step, as per being included as project references. But msbuild is a complicated beast and I cannot figure out a way of achieving this.
Is what I'm trying to achieve even possible? Can anybody point me in the right direction?
TFS / msbuild, building project references
This is a known issue about project reference in different Repos, but unfortunately it doesn't have a best answer. Because the best solution is always to have a single repository.
Git thinks of files as the content of the whole repository, not as a collection of files. Therefore this is quite hard to do. As workaround, you can consider to use Git Submodules or Git Subtree:
Check the details info from here:
Git and Visual Studio project references
Besides, the solution we are using now is to put the shared code in the NuGet package. Then, you can use the package from any repository, and you don't have to perform any unstable git settings and keep access control as they should be.
Hope this helps.
It seems that msbuild was changed to only reference project references, and that you can revert that to reference all references by setting the property OnlyReferenceAndBuildProjectsEnabledInSolutionConfiguration to true when running msbuild.
Source: https://stackoverflow.com/a/25144169
Have confirmed this works.
I've finally revisited this and done some more experimentation.
The only way, that I can see, to get TFS/msbuild to /reference other projects outputs is to mark them in the solution build configuration to build.
Now if you do this in Visual Studio and try and build a solution that has projects from another solution then the build will fail if the previous solution hasn't been fully built yet (as the other chained dependencies won't have been built). This makes sense.
But with TFS/msbuild, the build will succeed. From what I can tell there is some magic going on that ensures the dependencies across all solutions are somehow resolved. This might be luck, it might be specific behaviour (it's working for me so far).
The problem of course is that it's incompatible with Visual Studio. So I have an extra "Build" definition setup in each Solution file that has all the projects set to build.
This seems the easiest way to manage lots of interrelated solutions without having one big one.
So I have a website
Website_RWD
That has three dependencies SRECLeads, InetLeads, and BusinessLayer
I am trying to improve the speeds of our builds and deployments. One thing I stumbled upon was that it seems the main website is building twice.
Poking around on the internet my understanding is that the .metaproj exist because there are project dependencies.
My question is, using TFS Builds or in the solution file is there a way so the project builds in this order.
BusinessLayer
SRECLeads
InetLeads
Website
As it would build on the local machines.
If the below log is in the correct order you can see that after it builds the website a second time, it builds each individual project. If that is correct what is the point of doing that and is there a setting to stop that.
In fact the Website_RWD project is not built twice, from what I can see in the log snippet.
The MSBuild log output is structured as tree view, and as you can see the Website_RWD.csproj.metaproj is one level above the Website_RWD.csproj. That means the Website_RWD.csproj.metaproj build somehow contains the Website_RWD.csproj build as a sub-step.
I have setup a build controller etc and the builds were failing, I have fixed these now and the build failed properly - as in because of an error.
I have fixed the error and checked the code back in but now the code is not being extracted, although sometimes one folder of many is.
I have deleted the code from the build machine and requeued a build but it keeps failing. It complains that it cannot find the solution that I specified as the build solution.
I have checked the check box to build even if nothing has changed.
Have I missed a setting somewhere for extracting the code?
TFS version is 2012 Express
Visual Studio version is 2010 Professional
I had this issue recently with TFS 2012. I think it boils down to this:
In the lastest build definition files, it appears that it performs a Clean task before updating the workspace. This means that if you do something that causes the Clean part of the build to fail, it will never download the new files in order to fix it.
Recently, I was making big changes to my build file and inevitably made a lot of mistakes, I found that if one of these mistakes caused the Clean to break, I had to go onto the Build server and change the file manually to get it working again.
Does this sound like it might be the same issue?
There are several properties in your build definition you can check. I would start with setting the "Clean Workspace" to All to ensure the correct code is being pulled down and built.
There are other checks you can look at as well like the agent set for the build and the "GetVersion" property. Check the below link out. It should be able to help you in more detail.
Define a Build Process that is Based on the Default Template
We Have a large VS solution using project references which is build by TFS Build like so:
Solution
- Project 1
- Project 2
- Project ...
- Project N
Because the solution is too large we have several smaller solutions which we use day to day:
SubSolution
- Project 1
- Project 19
The problem is that developers working on SubSolution find that it is not building because the project references could not be found, so they change the projects to use file references.
This then goes on to break the TFS Build which cannot find these file references because they have not been built yet (Even though the projects are in the same solution). Is there a way around this tug of war between the two types of references. What is the correct way of splitting out your solutions?
What is the correct way of splitting out your solutions?
Check out this chapter from the TFS guide by the Patterns & Practices team:
Chapter 3 - Structuring Projects and Solutions in Source Control
Pay special attention to this note to the "Partitioned Solution" scenario (which I believe you're actually trying to implement):
Unlike previous versions of Visual Studio, Visual Studio 2005 relies upon MSBuild. It is now possible to create solution structures that do not include all referenced projects and still build without errors. As long as the master solution has been built first, generating the binary output from each project, MSBuild is able to follow project references outside the bounds of your solution and build successfully. This only works if you use project references, not file references. You can successfully build solutions created this way from the Visual Studio build command line and from the IDE, but not with Team Build by default. In order to build successfully with Team Build use the master solution that includes all of the projects and dependencies.
Regardless of how you organise your build, developers should understand how references work, and be aware when they make changes to references that they shouldn't check those changes in unless they intended to make a change to the build process.
On the subject of organising your builds - as Dmytrol says, project references should work between solutions (As long as the target is already built, however that's also the case for file references anyway).
My advice would be to group your projects into small workable solutions and use project references within those solutions. Your main solution file / build can use project references too, however if you find project references between the smaller solutions too difficult to maintain you can use file references instead, and control the build order through project dependencies or the project build order (accessible within Visual Studio by right-clicking on a project in your solution).
I have a vcproj file that includes a simple pre-build event along the lines of:
Helpertask.exe $(ProjectDir)
This works fine on developer PCs, but when the solution is built on our TFS 2008 build server under MSBuild, $(ProjectDir) is either blank or points to an unrelated folder on the server!
So far the best workaround I have managed is to hard code the developer and server paths instead:
if exist C:\DeveloperCode\MyProject HelperTask.exe C:\DeveloperCode\MyProject
if exist D:\BuildServerCode\MyProject HelperTask.exe D:\BuildServerCode\MyProject
This hack works in post-build steps but it doesn't work for a pre-build step (the Pre-build task now does nothing at all under MSBuild!)
Do you have any ideas for a fix or workaround? I have very little hair left!
$(MSBuildProjectDirectory) worked for me
I think your problem may be related to how items are initalized. An items include attribute is evaluated at the begining of a build. So if you depend on files that are created in the build process you must declare these as dynamic items. Dynamic items are those defined inside of a target, or by using the CreateItem task. I've detailed this on my blog MSBuild: Item and Property Evaluation.
Sayed Ibrahim Hashimi
My Book: Inside the Microsoft Build Engine : Using MSBuild and Team Foundation Build
I think the problem is that build server's workspace probably isn't initialized properly.
I just kept getting problems with this - I tried many different approaches but they all failed in mysterious ways.
Once $(ProjectDir) started behaving properly again, the pre-build step stopped executing the command (I added echo commands above and below it - they were both executed, but the program in between them was not. No errors or output of any kind were generated to indicate why it failed).
I don't know if this is a dodgy server of if MSBuild is having a laugh.
I've given up now. I gave the build server a big kick and have changed tack: We now run this tool offline (manually) and check in the results for the build server to use. So much for an automated build :-( If only MSBuild would run solutions in the same way as Visual Studio does - it's maddening that it sets up the environment completely differently (different paths coming out of the solution variables, ouptus redirected into different folders so you can't find them where they're supposed to be, etc)
I branched an existing project and $(ProjectDir) kept the old directory in the newly branched code. But that's because I had some compiling errors. Once every project in the solution compiled without errors, $(ProjectDir) changed to the correct path.
Carlos A Merighe