I've had to use msbuild.exe calls within my build script instead of the MSBuild Task and I've noticed that some assemblies only appear in Debug.
What determines that the configuration is Debug first and maybe only Debug from what I can see.
I'm using the DefaultTemplate.11.1.xaml.
(I'm guessing theres something in the xaml that dictates what Configuration is run first).
Also is the ConfigurationToBuild still used? I carried it over from TFS2010.
<ConfigurationToBuild Include="Release|Any CPU">
<FlavorToBuild>Release</FlavorToBuild>
<PlatformToBuild>Any CPU</PlatformToBuild>
</ConfigurationToBuild>
<ConfigurationToBuild Include="Debug|Any CPU">
<FlavorToBuild>Debug</FlavorToBuild>
<PlatformToBuild>Any CPU</PlatformToBuild>
</ConfigurationToBuild>
Related
Okay guys i am new here so i need a little help.I made automation test in c# for Nunit and i use it for CruiseControl
the CCnet.config:
<msbuild>
<executable>C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe</executable>
<projectFile>ClassParseMicroData.sln</projectFile>
<buildArgs> /t:Build </buildArgs>
<targets>Build</targets>
<timeout>600</timeout>
<logger>C:\Program Files (x86)\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
</msbuild>
<nunit>
<path>C:\Program Files (x86)\NUnit 2.6.2\bin\nunit-console.exe</path>
<assemblies>
<assembly>D:\SeleniumProject\microdata-csharp\test-class\ClassParseMicroData\ClassParseMicroData\bin\Debug\ClassParseMicroData.dll</assembly>
</assemblies>
<timeout>180000</timeout>
</nunit>
I want to send to MSbuild property for App.config from my test, something like this <buildArgs> /t:Build /p:link=test </buildArgs> it will be used in test, the problem is i don't know how to write App.config correctly to send this value. In test i will use like that ConfigurationManager.AppSettings["link"];
You might have to rewrite the ccnet.config to call a custom MSBuild script. In the custom MSBuild script you can use MSBuild Community Task using the XMLQuery or XMLUpdate task to get the value from the app.config file. Once the value from the app.config is acquired, it can then be passed in the call of the MSBuild to compile the solution file.
For more info on creating custom MSBuild scripts, the book Inside the Microsoft Build Engine: Using MSBuild and Team Foundation Build is a good guide. Alternatively you can use MSDN MSBuild reference.
I have a basic MSBuild script which includes a step for project compilation/build. Looks like this:
....
<ItemGroup>
<ProjectReferences Include="loc1\Project1.csproj"/>
<ProjectReferences Include="loc2\Project2.csproj"/>
<ProjectReferences Include="loc3\Project3.csproj"/>
</ItemGroup>
....
<Target Name="BuildProjects">
<Message Text="Beginning main project build"/>
<MSBuild Projects="#(ProjectReferences)" Targets="Build" Properties="Configuration=$(Configuration);ProjectBuild=$(ProjectBuild);AppDir=$(AppDir)">
<Output TaskParameter="TargetOutputs" ItemName="AssembliesBuilt"/>
</MSBuild>
<!--<CallTarget Targets="BuildToolkit"/>-->
</Target>
Project3.csproj is a .NET 3.5 Web Services project. The configuration is passed in on the command line.
First was a problem with System.Linq not being able to be resolved; I remedied this by creating a reference to System.Core directly in the project file (apparently this happens often and requires this fix).
Now, when I build this project in debug mode, all is well. However, when trying to build in release mode, it fails like this, with may of these messages pertaining to all kinds of assemblies:
Considered "c:\Program Files (x86)\Reference Assemblies\Microsoft\VST040\v8.0\MyReferencedProjectAssembly.dll", but it didn't exist.
This happens many times over for a number of references. Oddly, after this happens, I switch back to debug mode and it fails to build again after the release mode happens. I have to remove the offending Project3 from the MSBuild file, run again (which works), and re-add the offending Project3 back into the file before it works again in debug mode.
I'm stumped. Any ideas?
It seems to me like your project references are not set up correctly. Your projects are build in the wrong build order and build failed "sometimes". It has nothing to do with debug/release mode, I guess.
Check your csproj files if it contains correct project references to other projects. For example if Project2 is depending on Project1:
project2.csproj:
<ProjectReference Include="..\loc1\Project1.csproj">
<Project>{79FB10A6-6CD9-46D4-9463-319B8CBD82FE}</Project>
<Name>Project1</Name>
</ProjectReference>
Where Project is ProjectGuid of project1 (from project1.csproj)
I want to inhibit the building of certain projects within a solution from building (within a TeamCity Build Configuration in order to optimize the speed of my Commit Build feedback if you must know).
I'm aware of the Solution Configurations mechanism but don't want to have to force lots of .sln files to end up with every permutation of things I want to be able to switch off. I have Convention based rule where I want to say "If I'm doing the Commit Build, I dont want to do the final installer packaging". (And I don't want to break it out into a separate solution).
I'd prefer not to use a solution involving find and replace in the .sln file or in a .proj file created via [MsBuildEmitSolution][1]. I'm aware of questions here which cover the out of the box solution and this slightly related question.
I see MSBuild /v:diag is saying:
2>Target "Build" in file "Z.sln.metaproj" from project "Z.sln" (entry point):
Using "MSBuild" task from assembly "Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
Task "MSBuild"
Global Properties:
BuildingSolutionFile=true
CurrentSolutionConfigurationContents=<SolutionConfiguration>
<ProjectConfiguration Project="{C83D035D-169B-4023-9BEE-1790C9FE22AB}" AbsolutePath="X.csproj" BuildProjectInSolution="True">Debug|AnyCPU</ProjectConfiguration>
<ProjectConfiguration Project="{15E7887D-F1DB-4D85-8454-E4EF5CBDE6D5}" AbsolutePath="Y.csproj" BuildProjectInSolution="True">Debug|AnyCPU</ProjectConfiguration>
</SolutionConfiguration>
So the question is:
Is there a neat way of me getting to do an XPath replace or similar to have the effect of changing BuildProjectInSolution="True" to BuildProjectInSolution="False" for Project Y above
Failing that, is there a relatively simple edit I can do within a .ccproj (An Azure 1.4 Package) or a .csproj (a general project) file to cause the effects (including triggering of dependent projects) of the project being enabled within a commandline msbuild Z.sln solution build to be nullified?
Not sure it qualifies as neat, but you can set CustomAfterMicrosoftCommonTargets to import an msbuild file to over-ride the BuildDependsOn property, pointing it to your own custom build task. Basically, by setting CustomAfterMicrosoftCommonTargets you get msbuild to import an msbuild file containing the following:
<PropertyGroup>
<OldBuildDependsOn>$(BuildDependsOn)</OldBuildDependsOn>
<BuildDependsOn>MyBuild</BuildDependsOn>
</PropertyGroup>
<Target Name="OldBuild" DependsOnTargets="$(OldBuildDependsOn)" />
<Target Name="MyBuild">
<CallTarget Targets="OldBuild" Condition="<IfIWantThis>" />
</Target>
Edit
You can use the following MyBuild target to Include/Exclude projects based on regular expressions passed in as IncludeInBuild and ExcludeFromBuild properties. (If you want complex regexes, you may fall foul of MSBuild special character escaping, but this works well enough for simple matching)
> msbuild /p:ExcludeFromBuild="Tests|Install|Azure"
<Target Name="MyBuild">
<CallTarget Targets="OldBuild" Condition="('$(IncludeInBuild)'=='' OR
'$([System.Text.RegularExpressions.Regex]::IsMatch($(MSBuildProjectFullPath),
$(IncludeInBuild),
System.Text.RegularExpressions.RegexOptions.IgnoreCase))'=='True') AND
('$(ExcludeFromBuild)'=='' OR
'$([System.Text.RegularExpressions.Regex]::IsMatch($(MSBuildProjectFullPath),
$(ExcludeFromBuild),
System.Text.RegularExpressions.RegexOptions.IgnoreCase))'=='False')" />
</Target>
You could always pass the particular projects you want to build as parameters to the MSBuild.
The MSBuild command line would look like this:
MSBuild /t:<Project Name>:Rebuild;<Another Project Name>:Rebuild
In TeamCity, you would put <Project Name>:<Target Action> in the target field in the MSBuild runner.
I add a system parameter under Parameters
Name: system.ExcludeFromBuild
Kind: System property (system.)
Value: path to your csproj
I need a set of tasks that need to be executed exactly once for the entire solution. This will run tasks that will modify each project to run a separate set of tasks for each project. We had done this earlier using a separate project to the solution which had the solution level tasks, but we want to move away from that. Has anyone done this or does anyone have any suggestions on how to implement this?
Since Solution files are not in MSBuild format they are not easily extended or customized. If you want more control over the build process you would have to create a "driver" msbuild file which would replace your solution file. Inside this driver file you would build all the projects that you needed and perform some additional tasks. You would do this using the MSBuild task. Here is a sample showing how to build more than 1 project.
<Project ...>
<ItemGroup>
<Projects Include="proj01.csproj"/>
<Projects Include="proj02.csproj"/>
<Projects Include="proj03.csproj"/>
</ItemGroup>
<Target Name="BuildAll">
<MSBuild Projects="#(Projects)" BuildInParallel="true" />
</Target>
</Project>
So in your case you would just execute the tasks before you build the projects. Also note that I specified the value true for the BuildInParallel indicating that MSBuild can try and build more than one project at once.
An alternative solution is to have a single target that dispatches to an MSBuild invoked target with as many Global properties removed as possible. My team have a target in the InitialTargets of a Directory.Build.props Import'ed props file - something like:
<Target Name="Prebuild">
<MSBuild Projects="$(MSBuildThisFileFullPath)"
Targets="PrebuildWorker"
RemoveProperties="Configuration;Platform;TargetFramework;BuildProjectReferences" />
</Target>
Since MSBuild appears to synchronize parallel builds on the {project file, global properties, target} set, then by removing all of the properties you can synchronize the build and run it once for all projects being built. The downside: you have to maintain the RemoveProperties attribute - MSBuild doesn't have a way to remove all global properties. If something in the build issues a new MSBuild task with a custom property specified, then you'll get a second instance of the Target invoked.
And - of course - your build will be synchronized on this target. You could try hooking the target up by setting, say, CompileDependsOn to depend on the Prebuild target, to allow independent progress in the build. But to have the target run early and ubiquitously using InitialTargets seems like the better option.
To an earlier question of mine, invovling VBC and NAnt with WinForms, I have since come up with a better way of stating this.
Within vbproj file, you have the following:
<ItemGroup>
<None Include="My Project\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<CustomToolNamespace>My</CustomToolNamespace>
<LastGenOutput>Settings.Designer.vb</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<Content Include="My Project\Application.myapp">
<Generator>MyApplicationCodeGenerator</Generator>
<LastGenOutput>Application.Designer.vb</LastGenOutput>
</Content>
</ItemGroup>
When one runs build from within Visual Studio (Debug Verbosity set to Normal), one of the lines produces is:
Target CoreCompile:
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Vbc.exe ...
Which includes all of the settings required for vbc.exe to run. However, taking that string from Visual Studio, and running it directly on the command line yields:
... My Project\Settings.Designer.vb(67) : error BC30002: Type 'My.MySettings' is not defined.
Friend ReadOnly Property Settings() As Global.My.MySettings
...\My Project\Settings.Designer.vb(69) : error BC30456: 'My' is not a member of '<Default>'.
Return Global.My.MySettings.Default
How does one get the above Generators to run from a command line, or is there a call somewhere that will generate the correct temp files that are needed for vbc.exe to run the command string correctly?
The problem with looking at the build string within visual studio is that it's not actually calling vbc.exe to build from visual studio. All builds in visual studio happen with the in-memory compiler instead of the command line compiler (true for C# as well).
The command that looks like vbc.exe ... is a generated string that isn't actually executed. If you want to find out the correct string to build your project run the following code from a visual studio command prompt.
msbuild /v:diag myproject.vbproj
This will produce an msbuild log file (it will be quite long so I suggest piping to a file). Once the build is completed search for vbc.exe within that file. It will have the actual command line needed to build your project.
I spent a while working on this today. I'd like to know a proper answer as to how to get the vbc compiler to work properly in regard to the "My" namespace, but I managed to get my NAnt script working using NAnt contrib (http://nantcontrib.sourceforge.net/).
NAnt contrib allows you to build using the .NET msbuild, which at least allowed me to set up automated builds, notifications, etc. It does not give quite the granular control I would like, but it serves its purpose.
The reference on this task is:
http://nantcontrib.sourceforge.net/release/latest/help/tasks/msbuild.html
And the pertinent snippet from my build script:
<target name="build" depends="clean">
<msbuild project="ProjectName.vbproj" />
</target>
I've used NAnt quite a bit for CS applications, but this is the first for a VB.NET application.