TFS Build: projects rebuilt even if not changed - c++

I'm trying to automate our main project build (C++) via Team Build system (TFS 2013).
However, I see that a couple of projects are always built, even if no code change has occurred, while this does not happen using VS2013 on my development machine. This would cause some headache since binaries would always be generated and sent to test team even if not really modified.
Enabling "diagnostic" verbosity in build output, I see that the two project exhibit different behavior.
In the first project the log says that all .cpp files are rebuilt because the .PCH file has been modified (although no change happened). I could try disabling the PCH but would really avoid it if possible. Besides, not going to the root cause of the error would leave an open door to the error representing again and again.
In the second project, we have a pre build step that generates a .h file. However, prebuild steps should not run if no change in the code has been detected (https://msdn.microsoft.com/en-us/library/42x5kfw4.aspx), so happens indeed on my development machine. On the build machine, instead, the prebuild step is executed, the .h is generated and this forces a complete rebuild.
In the team build settings I have "Clean workspace=false", "Clean build=false". I also tried "/p:IncrementalBuild=True" in MSBuild settings, but this did not fix the issue.
Note - I already looked at Visual Studio Rebuilds unmodified projects and VS2010 always rebuilds solution? before posting.

According to your info about project2, the pre build step executed on the build agent and not executed on your local machine. There must be something different with your local build environment and build agent environment. This may be the root cause.
Suggest you to double check it and make sure the environment is the same with each other. And try it again.

Related

Visual Studio 2015 - Pre build event to determine which projects to compile

Motivation
PreBuild to disable compilation of redundant projects for faster compilation cycle.
Background
I have a VS15 ALL solution that contains many projects.
I have a single project, PreBuild, that all the other projects are dependent on, meaning, this PreBuild compiles first.
In addition, we also have a PostBuild project that do some more work once binaries are ready.
All projects are configured to build in Release mode (which is desired).
When a team member wants to release some binaries, he hits F7, Build Solution.
Now, the PreBuild, activates a separate dedicated process that calculates which projects should be released. The nature of the calculation is irrelevant to this discussion.
Problem
Out of the many many projects, it is often the case that only a few projects needs to be released. However, once the PreBuild process is done, ALL the projects are will compile which is very time consuming.
Question
Is it possible, after a solution build had started, to change the released projects?
Suggested unwanted approaches
A developer handpicks only the relevant projects and only build those.
PreBuild Kill & Revive. Once desired projects are calculated, PreBuild kills the VS15 process and activate a cmd compiling only the relevant projects.
Suggested approach
Change file ALL.sln and remove the the unwanted projects.
This would work had I changed that file prior to the process start but I'm not sure it would work if this change occurs during the process.
The simplest way I can think of, while still keeping most of the current infrastructure in place: have a dedicated project which invokes the release build (by calculating dependencies and invoking msbuild) and configure VS so it can be select just that project for a build. All from within your ALL.sln so the rest of the features remain. Steps:
Get rid of the PreBuild/PostBuild projects. I assume the PostBuild you mention is also meant for the actual release builds; if not just leave it there. Note by not requiring all projects to depend on the PreBuild project you already got rid of one maintainance burden.
Add one single project which will do the release building, say ReleaseBuild. Such name is also better than having PreBuild/PostBuild projects since it clearly states the intent of the project. A Makefile project is suitable, though technically it could be as simple as an msbuild file with just one Build target. Configure the build command line to do whatever is needed, i.e. figuring out what to build then build. For the sake of an example: say you use Powershell to do this you would configure the build commandline to be
Powershell -NoProfile -File BuildRelease.ps1 $(Platform)
and BuildRelease.ps1 contains something like
$projectsToRelease = CalculateMyProjectsForRelease()
$platform = $Args[0]
$projectsToRelease | %{& msbuild $_ "/p:Configuration=Release;Platform=$platform"}
In Configuration Manager add an extra Configuration called Deploy or so. This will be used to select what to build: you probably have Debug and Release configurations now already. Those stay in place, and are simply used to build everything. The idea is this extra configuration will take care of building the actual release. This is fairly consistent with the standard way of working in VS and easy to discover and understand for newcomers. Using the checkboxes, make it so that when the Deploy configuration is selected only the ReleaseBuild is built and none of the others whereas when Debug or Release is selected the ReleaseBuild project is not built. Looks like this:
To build a release, select Deploy from the configuration drop down menu in the VS toolbar and hit F7 (or whatever way you use to invoke Build Solution). Any build errors/warnings will be parsed and shown as usual in the Error List.
This is also easy to extend: suppose you only have a couple of release build versions just add more configurations like DeployA DeployB DeployC and adjust the build command line for them.

Visual Studio Team Services No Build Artifacts Created

I use an onsite build agent to perform my VSTS builds. This is working fine, sort of. I have 2 build definitions, one of which is a clone of the other and the only difference between the 2 is the solution that is built, all other parameters are exactly the same.
One of my builds completes without error and creates build artifacts and compiled code zip files in the 'build/1/a' artifacts folder. My other build completes without error BUT there are no build artifacts and compiled zip files created, my 'build/3/a' directory for this build is empty and I cannot see anywhere in the logs where the tasks to create this was executed, if at all. This did used to work before I cloned the build definition though. These are the MSBuild arguments that I have defined for both build definitions;
/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactstagingdirectory)\\" /p:PackageTempRootDir="D:\Build\SiteManagerDev"
The only difference between them is the last parameter '/p:PackageTempRootDir'.
I have tried switching between the 2 directories for both build definitions to make sure it is not a permission error and the definition that finishes correctly works against either directory. I am starting to tear my hair out now and I have even tried creating a completely new build definition for the solution that creates an incomplete build and it is the same result, it is almost as if it is the solution itself that is causing the issue?
Any help would be greatly appreciated.
UPDATE: 05/02/2017
I think I finally understand what is going on! Question, if a build is manually triggered, not by a check-in trigger, if there have been no changes made to the code, and even though the build is executed, does this prevent the build artifacts from being created again because nothing has changed? The reason I ask is because I have found a strange in-house housekeeping routine that goes and deletes the contents of the 'D:\Build\1\a' directory on our build machine on a regular basis (I have no idea why!) and this results in there being nothing to publish UNTIL there is a code change checked in and then they are generated again! What a waste of everyone time this has been, my apologies and thank you for your help.

What setting controls whether Visual Studio builds a solution when running tests or not?

We have two distinct team projects, both running in TFS 2013 / VS 2013. One of them always builds the whole solution when asked to run all tests in the Test Explorer window, while the other one does not build anything and just tries to run the tests again.
Sometimes we would like to prevent VS from building the whole solution, since we know it did not change or we just don't want to test against the modified changes, for instance.
What setting controls this behavior? I can't really see any differences between both projects to warrant different test behavior. I'm not using any settings file in neither of them, and this was tested with both projects completely cleaned (like deleting the .suo file for example).
I'm aware of two things that may help.
Set files in your solution to Do not copy or Copy if newer
In Tools -> Options -> Projects and Solutions -> Build and Run check the checkbox: Only build startup projects and dependencies on Run
I'm working with these settings and I don't have the issue thought I cannot guarantee it will help in your case.
To build only few projects, you can create a sub solution - meaning the solution will have only few projects and their dependencies.
To stop building every time, use the tools-options-Projects and solutions->Build and run
check, build only the Startup projects and dependencies
and select "never build" in the drop down "On run, when projects are out of date"

What does Visual Studio 2010 do before invoking msbuild?

I'm having a problem with Visual Studio not invoking msbuild to actually build my solution. Invoking msbuild from the commandline results in a proper build, but in Visual Studio starting build results in an "everything is up to date" message. Manually compiling a .cpp file seems to partially or fully fix the problem.
Restarting VS2010 does not correct the problem, so I feel like VS2010 must be writing its own dependency information somewhere. By dependency information I mean what files actually require building, AKA which files have been altered since the last successful build.
Does VS2010 perform it's own dependency checking before invoking msbuild? Where does it store this information?
To force a build to occur from the Visual Studio GUI you can select "Rebuild All". That will trigger compilation of all your source files.
The problem with regular builds not working could be related to incorrect clock settings in your PC. Make sure your system clock is correct, including the time zone. Then do a project 'clean' and try to build again.
My Dad says to check your "obj folder" and clean it out. VS2010 is seeing that there are things on there so it assumes there's nothing new to build.
I've seen this kind of behavior occasionally, though I can't explain how it gets corrupted.
Try deleting all the intermediate files: everything in the Debug and Release directories, plus the project name files of types .suo, .ncb, and .aps. Then rebuild all.
If you are experiencing the same behavior as I do, this tends to make VS work properly for awhile—a few weeks or 50-100 builds (whichever comes first).

Why Build Fails with CruiseControl.NET but it builds fine manually with same settings?

I have a project that builds fine If I build it manually but it fails with CC.NET.
The error that shows up on CC.NET is basically related to an import that's failing because file was not found; one of the projects (C++ dll) tries to import a dll built by another project. Dll should be in the right place since there's a dependency between the projects - indeeed when I build manually everything works fine (Note that when I say manually I am getting everything fresh from source code repository then invoking a Rebuild from VS2005 to simulate CC.NET automation).
looks like dependencies are ignored when the build is automated through CC.NET.
I am building in Release MinDependency mode.
Any help would be highly appreciated!
Can you change CC to use msbuild instead of devenv? That seems like the optimal solution to me, as it means the build is the same in both situations.
After a long investigation - my understanding on this at current stage is that the problem is related to the fact that I am using devenv to build through CruiseControl.NET but when I build manually VisualStudio is using msbuild.
Basically this causes dependencies to be ignored (because of some msbuild command arg that I am not reproducing using devenv).
I think the fact that dependencies are set between C++ projects is relevant too to some extent, since I've been able in other occasions to build properly with CC.NET setting dependencies between .NET projects and C++ projects.
In order to figure out exactly what is generating this different
behavior I'd have to follow this lead.
I'd like to hear other people's opinions on this.
Try building it from the command line and see what happens.
My guess would be that the user that the service is configured has different permissions and/or environment variables as you do when actually running it. If you are on the same physical box and it compiles fine with visual studio and you are also using visual studio in CruiseControl (not MSBuild) then it is almost assuredly the user. If however you are using MSBuild in CruiseControl there is a huge set of diffrence when MSBuild (2.0) compiles a C++ sln and when Visual Studio compiles it. If you must use MSBuild on C++ solutions try v3.5 it has much more support for C++ solutions.
I wonder if CC.Net is building with different environment variables, such that the necessary library directories aren't properly added to the path.
Is there any specific error message in the CC.Net build log as to why that particular DLL import failed? Could not find file? Permissions? Look in the detailed CC.Net build log for the failure and see where it differs from a normal command-line build.
I've run into instances where my solution builds if I open it in the IDE and compile, but fails if I run from a command line (either msbuild or devenv.) In each case, the problem was due to a bad reference - likely from paths not matching between your local box and the build server. You see it compile in the IDE correctly because VisualStudio, when opening a solution, will attempt to auto-resolve broken paths. When it does this, it won't tell you about it and usually won't change your solution and project files (which is what you'd hope for.)
Try opening your solution file and/or project files in a text editor and make sure all relative paths are valid.
As Alex said, I think that your problem is that the CC.NET service runs as a local user account. Unfortunatly some of the C++ environment variables are per user and will not be carried over to the default build environment. In my case it was the lib and include files defined in Tools -> Options -> Projects and Solutions -> VC++ Directories. This same issue evidently causes other issues and is called out in this article as a yellow block.
My solution was to create a new user (BuildUser) on the build machine specifically for building. The key was to then log in as BuildUser and set up the environment. Finally, I changed the CC.NET service to login as BuildUser and restarted it.
(reposting as my initial post seems to have failed)
VC2003 seems to have an inconsistency between dependencies and input libraries.
An example:
ProjectA --> A.lib
ProjectB --> B.exe
In Properties-->Linker-->Additional Input Libraries, A.lib is specified.
In Project Dependencies, ProjectA is unchecked (why it is not automatic is still a mystery to me)
When cleaning ProjectB, A.lib is not deleted, nor is it rebuilt when ProjectB is compiled. So the build appears to succeed in your local machine.
CC.NET starts from scratch, and the build fails as A.lib is not found in the first place.