Add command-line arguments to visual Studio Project in TeamCity - visual-studio

If I run a c++ project/solution, in Visual Studio, with a command line option "--xx", how can I do the exact same thing from TeamCity ?
I have searched and have been unable to find any option.
The one thing that looks like "Command line parameters" is actually designated for MSBuild.
I have to run the solution - and not just the executable generated by the solution.
Thank you.

Your Visual Studio build is executed using MSBuild on the server, the name may be a little confusing, but the parameters should function in the same way using that MSBuild parameter box as passing them to visual studio would be.
if there are issues getting this to work using that parameters box, we will need some more information about the commands you need to run and the behaviour you need.
Edit following questioner's comment
The problem in actuality here is that Visual Studio builds don't really exist in TeamCity, visual studio build is actually just going to run MsBuild against your visual studio solution, which, in terms of Google Test, is sufficiently different to cause your problems.
To resolve this, you are probably going to have to change your build runner to just be an MsBuild script which builds your solution and runs the Google tests. thankfully, the internet provides:
http://code.google.com/p/msbuildteamcitytasks/wiki/RunGoogleTests
The above is some MsBuild tasks which claim to integrate GoogleTest results completely with TeamCity, doing all the leg work for you in that regard. The result of this is that you only need a very brief build script calling MsBuild on your solution, followed by calling that MsBuild Task as required. I cant confirm how well they work or how easy they are to set up as I haven't used them, but the documentation on the page implies it should be reasonably easy to put together.
below is a snippet of MsBuild that will build your solution(s)
<MSBuild Projects="#(BuildProjects)" Targets="Rebuild" BuildInParallel="true" Properties="Configuration=Debug;Platform=$(Platform)">
<Output ItemName="DebugOutputs" TaskParameter="TargetOutputs"/>
</MSBuild>
where each $() variable is a system property in your TeamCity configuration #(BuildProjects) is a list of solutions generated using this:
<ItemGroup>
<BuildProjects Include="$(WorkingArea)\**\*.sln" />
</ItemGroup>
you can of course hard code any and all of these variables, or change parameters as required, but this example will give you some freedom to reuse the script on other projects (its not a full script, there's some extra structure stuff to go around the outside).
you can of course build in further functionality to the script as required, or leave it as simple as possible to make it easy to understand.
there is further documentation on MsBuild scripts are available from these locations:
http://www.universalthread.com/ViewPageArticle.aspx?ID=61
http://codingcockerel.co.uk/2008/04/15/automating-the-build-with-msbuild/
http://www.codeproject.com/Articles/12985/Practical-NET2-and-C-2-An-introduction-to-MSBuild
I'm sure there's plenty more out there if you need it.

Well, In TeamCity (I am using version 6.5.x), When you add a new Build Step, select the Build runner as Visual Studio (sln) or Visual Studio 2003 as per your requirement and there you'll get the option to pass command line parameters.
What Version of TeamCity do you use?

Related

How do I do a deterministic build locally (ContinuousIntegrationBuild flag)?

When I attempt to publish my package using NuGet Package Explorer, I see the following warning:
Deterministic (dll/exe): Non deterministic
Ensure that the following property is enabled for CI builds
and you're using at least the 2.1.300 SDK:
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
However, when I add that property to the PropertyGroup (as described here), VS 2019 freaks out so badly I literally need to ctrl+alt+delete to close it.
According to this page the property name is <Deterministic>, but that doesn't seem to do anything at all.
So how do I get deterministic builds to work?
Visual Studio 2019, v16.7.1
.Net SDK 3.1.401 (LTS)
An easier answer is to not mess with .csproj files (urgh!) and do this via the command line, in your CI script.
add the /p:ContinuousIntegrationBuild=true argument to the dotnet pack command.
dotnet pack
-c $env:CONFIGURATION
/p:ContinuousIntegrationBuild=true
-p:PackageVersion=$env:APPVEYOR_BUILD_VERSION
(make this all one line. I've multi-lined it, for readability)
NOTE: the --no-build argument is NOT here. We need to build this again. Or you add that param to the build step, before this.
This is taken from an example CI file I use. So when I'm in release mode, I pack the library into a nuget and publish it.
Keeps things clean and out of your .csproj file (which is very hard to grok and maintain).
I basically just found the answer in this blogpost:
While deterministic builds are enabled by default in .NET SDK projects, there is an extra property, ContinuousIntegrationBuild, to set on the build server to normalize stored file paths. These should not be enabled during local dev or the debugger won’t be able to find the local source files.
<PropertyGroup Condition="'$(TF_BUILD)' == 'true'">
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>

Cppcheck doesn't expand Visual Studio project macros

To automate C++ code quality analysis in our company, I've been asked to integrate Cppcheck tool with our SonarQube server (through the C++ Community plugin).
For the C++ part of our main product, in Visual Studio, we have a dozen of solutions, with almost a hundred of projects within each solution.
We use standard inherited property page macros like $(SolutionDir) and $(ProjectDir), and define our own custom (user-defined) macros as well (via Property Manager).
I'm currently writing Windows command line batch scripts to perform static code analysis separately on each solution. The idea is to run Cppcheck with an option like --project="solution_name.sln" and then run SonarQube Scanner to parse the generated XML output.
But there's a problem. It seems that Cppcheck doesn't recognize these $(SolutionDir) macros during include path resolution. (When run with --check-config option, it complains about missing include files.)
Unfortunately it turns out I even cannot supply additional include paths for a solution because the -I and --includes-file options are ignored when --project is specified.
How is Cppcheck supposed to be used with Visual Studio projects in an automated environment? I'm talking about command line interface (to be used on server side), not about interactive plugins (as used locally on developers' machines).
One possible way would be to create a Python script to preprocess the hundreds of project (*.vcxproj) files, replacing all these macros with real paths (each time after checking out from SVN and before executing Cppcheck). Or is there a proper way to make Cppcheck recognize Visual Studio macros?
Yes the --project is supposed to work. It's just that --project is a very new feature.
I would like to have a simple solution so I can reproduce easily.. Could you create some simple solution with such configuration? no real code is needed. I think a cpp file with just a #include and then an empty header might be enough. Configure it so that Visual Studio finds the header but Cppcheck doesn't.
Please attach it to the ticket orbitcowboy created.

Using IncrediBuild with DevEnv.exe vs MSBuild.exe

I use Xorax IncrediBuild to build Visual Studio 2013 (or later) solutions and projects, they're mostly .vcxproj with a bunch of .csproj ones.
It took me a little bit of digging, but I've learned that:
When IncrediBuild is used with the regular Visual Studio, it uses the Devenv.exe by default.
Since version 5.0, BuildConsole.exe supports a new switch: /UseMSBuild to specifically instruct IncrediBuild to use MSBuild's build engine instead of the default Visual Studio's DevEnv.
So, in case of Visual Studio projects, there are two modes available:
BuildConsole.exe MyProj.vcxproj which uses DevEnv.exe
BuildConsole.exe MyProj.vcxproj /usemsbuild which uses MSBuild.exe
I'd like to learn if there are any differences between using the two engines.
I have made some tests and observed that:
IncrediBuild "Initializing..." phase takes slightly longer in case of DevEnv.exe.
BuildConsole.exe generates different output, obviously.
No (or insignificant) difference in build performance.
In case of building individual C/C++ native projects (.vcxproj) as well as whole solutions (.sln), what are advantages and disadvantages of using DevEnv.exe versus MSBuild.exe?
** disclaimer: I work at IncrediBuild **
We've determined together with Microsoft that in order to get builds that behave in the same manner as building from within Visual Studio (without IncrediBuild), DevEnv should be used. MSBuild executes builds in a slightly different manner than VS both in the build output it produces and in the way it behaves when executing custom steps and some other minor things. If a user wants IncrediBuild builds to behave in the same manner as he is used to when building from Visual Studio, the default way should be used (IncrediBuild executing DevEnv). If a user is used to execute his builds using MSBuild, whether from the command line or through TFS, the UseMSBuild switch should be used. We wanted to allow users to choose the way they would like IncrediBuild to work depending on the way they are used to do that, same as Microsoft supporting both DevEnv and MSBuild.
Additional comments:
The initialization stage is indeed longer when using Devenv, since devenv loads and parses the solution and .vcxproj files in a different manner than msbuild. The more Projects a solution has – the longer this phase should take. The increase of time it takes this phase to complete usually greatly offset by the speed increase in the actual build time – when building several projects at the same time.
Devenv is highly recommended for our Predicted Execution feature which can provide up to 20% of additional build acceleration due to the above way of work which would be not possible using MSBuild.
Microsoft is pretty explicit about it:
For build-related tasks, it is now recommended that you use MSBuild instead of devenv. For more information, see MSBuild Command Line Reference.
A note in the Devenv documentation since VS2010, the first version of VS that started supporting building C++ projects with MSBuild and also changed the default project file extension from .vcproj to vcxproj.
The wisdom of this kind of advice can only be inferred when they are not explicit about it. One you ready saw, Devenv.exe is a pretty heavy process with many DLL dependencies, it takes a while to get going. Another you could fret about with the way you are doing it now, original guidance was to use Devenv.com instead of Devenv.exe. Those dependencies are also troublemakers, the kind that tend to get in the way or just plain fall over when Devenv.exe runs in an unusual runtime environment like a service. Sample story-from-hell is this Q+A, three answers and none look correct. There are others.
Plain advice is to use the recommended way.

Building MSI from TFS Build

I am trying to build MSIs in a TFS Build by shelling out to DEVENV.exe (since MSBUILD does not support VSPROJs). In any case, my first installer project builds fine, the second one fails. If I reverse the order, same thing happends (i.e. the error does not follow the project). Looking at the output, I get the following errors:
Deserializing the project state for project '[MyProject].dbproj'
[MyProject].dbproj : error : Error HRESULT E_FAIL has been returned from a call to a COM component.
Also, I get:
Package 'Microsoft.VisualStudio.TestTools.TestCaseManagement.QualityToolsPackage, Microsoft.VisualStudio.QualityTools.TestCaseManagement, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' failed to load
It looks as though the first build tries to serialize the DB project (and it says it succeeds, but there is no DBML file anywhere). Then the second build tries to deserialize the DB project and fails.
I've tried resetting env settings (using the /resetusersettings flag) as well as using the /resetskippkgs flag. Nothing works.
Any ideas?
When you shell out to DevEnv, are you building that specific project (.vdproj file), or are you building the solution? It sounds like VS is trying to open the solution on the build machine and the database and test project systems aren't present.
Have you considered porting your setup project to WiX?
Start simple. Unless you're well versed in the problem you're trying to solve it's usually best to try it "by hand" before getting it running as part of a TFS build. RDP into the build server and try running the necessary commands at the command line and see what happens. You can even go simpler than that and RDP into the build machine and load Visual Studio and build it.
Bottom line is that if you can't get it to build within Visual Studio or at the command line by calling devenv.exe it won't work as part of the team build.
I am using the below Exec task to do precisely what you are doing as part of a TFS build. So I know this works. Your platform and configuration may vary depending on what you're building. The nice thing about this is that you'll have a log file at C:\Temp\MSIBuildOutputLog.txt that you can analyze for additional errors and information.
<Exec Command=""C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe" "$(PathToSolution)\solution.sln" /Build "Release|Mixed Platforms" /out "C:\Temp\MSIBuildOutputLog.txt"" />
One important thing to note... There is a bug in VS2010 which causes MSI generation to fail when you try to run it at the command line using devenv.exe. This took me days to find and figure out, but you need this hotfix. Worked like a charm...
http://archive.msdn.microsoft.com/KB2286556
Actually it's the deployment projects that don't support msbuild. FWIW, this is all deprecated in the next release of Visual Studio so you might want to start looking at InstallShield Limited Edition and/or Windows Installer XML now before spending too much time on dead end, broken technology. Both of these alternatives have proper MSBuild support aswell as many other improvements.
It would be perhaps better and quicker to adopt WIX (Windows Installer XML) which is the technology MS now recommends to use within VS/MSBuild/TFSBuild environment to crate MSIs.
It is relatively easy to setup and integrate within your VS Solutions. It uses XML based files to describe your MSIs and uses these files to create your MSIs when you compile.
I would start by downloading Wix from http://wix.codeplex.com/
Once installed you would be able to use the VS2010 integration of Wix based projects to create MSIs. To get started quickly simply add a new Wix project to your solution and reference the projects whose output you wish to combine into an MSI. Next you can run a tool called "Heat" which is included with Wix toolkit to generate the XML files by scanning your projects.
Once you have these XML files, add them to your Wix project and compile.

Make Visual Studio (Express) stop compiling when something doesn't compile

If one project can't build, Visual Studio, by default, keeps right on trying to build all the other projects that depend on that project, and therefore gets stupid errors because those other projects are now building against a stale version of the binary.
How can I change this behavior, and get it to stop on failure?
For example, suppose I have a library project called MyApp.Core, and an executable project called MyApp. MyApp calls a method in MyApp.Core. Suppose I add a new parameter to that method and then try to build, but I've inadvertently introduced an unrelated compiler error in MyApp.Core. When I build, Visual Studio will:
Try to build MyApp.Core, and fail because of the compiler error. The MyApp.Core.dll on disk is left unchanged because the build failed.
Go on to try to build MyApp against that older version of MyApp.Core.dll, and report compiler errors because it's passing more parameters than the method in the old DLL expects.
Report the second batch of errors at the top of the Errors window, thus making it very difficult to find the actual problem.
Make has had this problem solved since 1977: when it realizes that it can't build, it stops building. Every other build system and IDE that I've used is also clever enough to stop on a lost cause. But Visual Studio hasn't quite caught up to the technological sophistication of 1977.
The book "Visual Studio Hacks", in its section on macros, has a workaround: you can write a macro that fires when a project is done building; if the project's build status was "failed", the macro can issue a Cancel Build command. I regularly install this hack on every computer I use that has Visual Studio. However, at home I use Visual C# Express, which doesn't support macros.
Is there any way to get Visual Studio 2010 (including the Express editions) to stop building on a build failure?
As much as I like MSBuild, there isn't a built-in way to do this when using the solution file to build (as you've already discovered). With Resharper's analysis enabled I find that compiler errors are very rare for me these days, so I rarely have the problem of overwhelming error messages.
At my previous shop, someone routinely gacked-up the build so that one of the root projects in a solution of over 60 projects and because of that, many people took to running projects individually from the command line similar to running individual Make files.
If you really wanted to handle this problem in a different way than the macro you mentioned, you could construct an external msbuild file that executes the projects individually and checks for errors in-between runs. You'll have to keep the build ordering correct, and you'll need to run it from the command line and/or add a shortcut to the Tools menu option.
Here's an example:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Build">
<MSBuild ContinueOnError="false" Projects="log4net\log4net.csproj" Targets="Build">
<Output TaskParameter="TargetOutputs" ItemName="BuildOutput"/>
</MSBuild>
<MSBuild ContinueOnError="false" Projects="Project1\Project1.csproj" Targets="Build">
<Output TaskParameter="TargetOutputs" ItemName="BuildOutput"/>
</MSBuild>
<MSBuild ContinueOnError="false" Projects="Project3\Project3.csproj" Targets="Build">
<Output TaskParameter="TargetOutputs" ItemName="BuildOutput"/>
</MSBuild>
</Target>
<!-- <OnError ExecuteTargets="ErrorTarget" /> //-->
</Project>
Replace the projects with your projects, and the group will need to be mimicked for the Clean target.
I wish there was a better solution and I don't know why the MSBuild team won't add this feature into the product. Like you said, Make figured it out decades ago. FWIW, I don't know how well this works with complicated build dependencies and build parallelism.
My problems with MSBuild center around the ResolveAssemblyReferences, and ResolveComReferences Tasks which are the slowest part of a build in a big solution with a large/complicated project dependency tree (large being relative ~30 projects at a minimum).
I hope this helps.
There is also this free extension for Visual Studio 2010/2012/2013 that does this.
StopOnFirstBuildError (Download)
http://visualstudiogallery.msdn.microsoft.com/91aaa139-5d3c-43a7-b39f-369196a84fa5
Stop Build on first error in Visual Studio 2010 (Write-up)
http://einaregilsson.com/stop-build-on-first-error-in-visual-studio-2010/
You can also kill the process called cl.exe using the task manager. There might be multiple cl.exe processes - killing just one of them should be enough.
This will stop the build process immediately.
I always just hold down the "Pause / Break" key when I see it happening and it cancels the build.

Resources