I'm working on optimizing my build process. When I go to build my solution, it's always rebuilding a few projects - namely one named ManagedToNativeInterface.
Taking information from other questions, I enabled Diagnostic level build information.
This project is showing as up-to-date
Why is this project still being build? It's worth noting that we do have other processes in our solution that always run (be design).
Project that shouldn't build but is getting built:
> 22>------ Up-To-Date check: Project: VisualStudio\ManagedToNativeInterface\ManagedToNativeInterface.vcxproj, Configuration: Release x64 ------
22>All outputs are up-to-date.
22>Time Elapsed 0 ms
22>------ Build started: Project: ManagedToNativeInterface, Configuration: Release x64 ------
22>Search paths being used for $(MSBuildExtensionsPath) are C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild;$(MSBuildProgramFiles32)\MSBuild
22>Trying to import C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\$(MSBuildToolsVersion)\Microsoft.Common.props using extensions path C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild
22>Property reassignment: $(TagMajorVersion)="" (previous value: "6") at P:\standard\TagVersion.props (19,3)
...
In the past, I faced this exact situation. It's very frustrating wondering why the project insists on rebuilding even though I have not touched any code since the last compile and run.
The usual culprit in my experience is that a header file was deleted or renamed but it was not removed from the Project under the header file list. So, the compiler thinks that it is a generated file and insists on re-running the compile in hopes that the file will be created in a pre-build step or some other process. So, visually look through the .h and .cpp file list in Solution Explorer and make sure all of the files are current and exist on disk.
I have used the editbin /LARGEADDRESSAWARE command to change my .NET C# exe so that it can address memory > 2 GB. This works fine and I can run the dumpbin command to verify that it's been modified successfully.
I then proceed to create a .msi package that includes this exe. When I run this .msi on a windows 7 target machine it successfully installs the exe. But now if I run dumpbin on the same exe that got installed on the target machine is shows that it is no longer supporting memory > 2 GB.
What is causing this? Is is the process of building .msi or the running of .msi on the target machine?
Whatever is going wrong here, it surely has something to do with you doing this by hand. Let the build system do this for you. Project + Properties, Build Events tab. Paste this into the "Post-build event command line" box:
set pathsave=%path%
set path=$(devenvdir);$(devenvdir)..\..\vc\bin
editbin.exe /nologo /largeaddressaware "$(targetfilename)"
set path=%pathsave%
There are several issues with editbin to set the LARGEADDRESSAWARE flag in an msbuild post build step.
EditBin x32 does not run outside of VS command prompt because mspdb100.dll is not found. Why should you care? Well if you run a TFS build workflow msbuild is NOT called from a VS command prompt. This will cause issues ...
You can fix this one by using the one in bin\amd64\editbin.exe but then you can build your exe only on a x64 build machine.
If you patch the final file at $(TargetPath) then it will work but if you rebuild your project and you have set Inputs and Outputs for your task then it will not run again.
This is an issue because during a rebuild the exe from the intermediate folder is copied again to the final location which was not patched.
This is still not it. Because if you did strong name your exe you need to re-sign it to make the strong name valid again. It will run on you dev machine because most of the time dev machines have disabled strong name verification but it will fail to run on customer machines.
Finally your task will look like this:
<Target Name="AfterBuild" BeforeTargets="CopyFilesToOutputDirectory" Inputs="$(IntermediateOutputPath)$(TargetFileName)" Outputs="$(IntermediateOutputPath)largaddessaware.tmp">
<Exec Command="xxxxxbin\amd64\EditBin.exe /LARGEADDRESSAWARE "$(IntermediateOutputPath)$(TargetFileName)""/>
<Exec Command="sn -Ra "$(IntermediateOutputPath)$(TargetFileName)" "$(AssemblyOriginatorKeyFile)""/>
<Touch AlwaysCreate="true" Files="$(IntermediateOutputPath)largaddessaware.tmp"/>
</Target>
We need to patch the executable before CopyFiletoOutputDirectory has run otherwise we will patch the intermediate file after the unpatched file has already been copied to the ouptut folder. The final file cannot be patched because this target will not run when the exe has not changed to prevent breaking the incremental build.
This is a classic example of a simple task (set one bit in the PE header) which is quite difficult to get right. It is (nearly) never as easy as it might look like at the beginning.
I thinks in the end I found that the Installer was picking my exe from a different path than the one I was using to update using editbin post build command. I added this line in my post build command of my exe
copy "$(targetpath)" "$(ProjectDir)\obj\x86\release"
So the entire post build command looks like this
set pathsave=%path%
set path=$(devenvdir);$(devenvdir)..\..\vc\bin
editbin.exe /nologo /largeaddressaware "$(targetpath)"
copy "$(targetpath)" "$(ProjectDir)\obj\x86\release"
set path=%pathsave%
Thanks
While including the multiple project where the dll of project 1 is being referred in another ,Is it mandatory to build the sub-project's in release mode and refers its dll in "main" project's reference.
For example if I have this Solution :
Solution- Master
- Project 1
- Project 2
- Project 3
- Project 4
- Project 5
Project 5 is the Main project.While making the Release setup.exe is it mandatory to build each project(1,2,3 and 4) in release mode (selecting the Release from the drop down options) and include the reference of each from /bin/Release of each projects into Project5.
Also where can I set the path of output dll for each project?
No, it's not mandatory to have outputs be built to the same underlying configuration - that is, you could define a configuration named "Obscure" and have one project build to release, another to debug and another to staging and whatever.
You can set the output path for projects in the Properties -> Build page (see Output Path).
Basically if a project built in release mode is capable of running independently on the target hardware. Its not really mandatory but good.
Its very easy to set up the output directory for each project, from project properties.
Right click on the project, select Properties
For C#, it is one of the Build property page, under Output, Output directory.
In VB.Net projects, it is on the Compile tab, in the textbox at the top.
Hope it will help
If you add a reference in the Reference Manager, under Solution > Projects, you can browse to .csproj file and it will make the build type equivalent to the build type of the main project.
So, as the title reads, I have a VS2010 solution with ~50 projects in it right now. If I make a change to a "top level" project that nothing references then VS still rebuilds all 50 projects. I'm running Visual Studio 2010 Ultimate without any add-ons. I am using ILMerge to consolidate all of the projects into a single file.
I have verified this by checking the time stamps of the lower level dlls and see that they are indeed rebuilt even though their code wasn't touched.
I've read all responses and comments for:
Visual Studio 2008 keeps rebuilding
Visual studio keeps building everything
Strange VS2010 build glitch occurs in my solution
Reasons for C# projects to rebuild in Visual Studio
But most of them just offer suggestions on unloading projects to speed up build times but nothing concrete as to a fix. I'm trying to figure out why VS thinks these dependent projects need to be rebuilt when they don't and fix it.
I've turned on 'Tools > Options > Projects and Solutions > Build and Run > Only build startup projects and dependencies on run' but with no effect.
Also, if I just rebuild a "mid-level" project that only has 8 (in)direct dependencies then it still builds all 8 projects even though ILMerge isn't invoked and none of the dependent projects have been modified.
Thank you everyone for any insight you may be able to provide.
Added
To test some of the suggestions I created a new WinForms project from scratch. I then created two new projects inside that solution. I copied all of the code and resources (not project file) from my two 'lowest level' projects into the two brand new projects (I did this by dropping the files and folders from Explorer onto the project in Visual Studio).
The lowest project, let's call it B, did not reference any other project. The next project, A, referenced B only. So once I added the required .NET and external assembly references to the projects then the solution would build.
I then had my new WinForm project reference A and did a full build. So the ref chain is:
WinForm -> A -> B
I then modified WinForm only and did a standard build (F6). As before, Visual Studio rebuilt all three projects.
After some systematic eleminiation of source files in project B I found that if I removed my Resources.Designer.cs and Resources.resx (and commented out the code that made use of the .Properties.Resources object of those resources) then a modification of WinForm would no longer rebuild the entire solution and would only rebuild WinForm.
Adding the Resources.resx and Resources.Designer.cs back to project B (but leaving the referenced code commented out so that nothing was making use of the resources) would re-introduce the full build behavior.
To see if perhaps my resource files were corrupted, I deleted them again and then created a new one (via Project Properties -> Resources) and re-added the same resource as before, which was a single Excel file. With this setup the full rebuild would still occur.
I then removed the single resource, but left the resource file in project B. Even with no resources added, but the resource file still in the project, the full (unneeded) rebuild would occur.
It appears that just having a resource file added to a (.NET 3.5) project will cause Visual Studio 2010 to always rebuild that project. Is this a bug or intended/expected behavior?
Thanks all again!
Open Tools - Options, select Projects and Solutions - Build and Run in tree, then set "MSBuild project build output verbosity" to Diagnostic.
This will output the reason for building a project, i.e.
Project 'ReferencedProject' is not up to date. Project item
'c:\some.xml' has 'Copy to Output Directory' attribute set to 'Copy
always'.
or
Project 'MyProject' is not up to date. Input file
'c:\ReferencedProject.dll' is modified after output file
'c:\MyProject.pdb'.
In this case the fix is to copy some.xml only if newer.
Pre and post build events can trigger build as well.
While I don't think this is a fix, it is a workaround that has worked for my situation...
I originally had about 5 projects out of 50 that contained a Resources section. These projects would always be rebuilt and thus anything that they depended on would also be rebuilt. One of those 5 projects was a "base" level library that 48 of the other projects referenced, thus 96% of my project would be rebuilt every time even if it didn't need it.
My workaround was to use dependency injection, interfaces, and a dedicated "Resources" project. Instead of having those 5 projects reference their own Resources object, I created an interface in each project that would supply the desired resources. Then, the classes that needed those resources would require that interface be passed in during their creation in the constructor (constructor injection).
I then created a separate "Resources" project that had an actual Resources section like normal. This project only contained the resources themselves, and a class for each interface that was needed to provide those resources via an interface. This project would reference every other project that had a resource dependency and implement the interface that the project needed.
Finally, in my "Top Level" project which nothing referenced (and where the exe was actually built and my composition root lives) I referenced the "Resources" project, wired up the DI, and away we went.
This means that only two projects (the "Resources" and the "Top Level") will be rebuilt every time, and if I do a partial build (Shift-F6) then they won't get rebuilt at all.
Again, not a great work around, but with 48 projects being built every time a build would take about 3 minutes, so I was losing 30 to 90 minutes a day with needless rebuilds. It took awhile to refactor, but I think it was a good investment.
Here is a simplified diagram. Note that the dependencies from Main.exe to Proj1 and Proj2 are not shown in order to reduce clutter.
With this design, I can do a build of Proj1 or Proj2 without triggering a full rebuild, since they don't have any dependencies on a Resources section. Only Main knows about the Resources implementation.
This happens when a project has a file that doesn't really exist.
The project can't determine if the file was changed (because it's not there) so it rebuilds.
Simply look at all the files in the project, and search for the one that doesn't have an expandable arrow near it.
I had the same issue in VS 2015.
What did the trick for me is:
One project was referencing itself copy in some other project bin (magic, yes). This kind of stuff could be found when switching to diagnostic build output (in build options) and then trying to build projects one by one from the top of projects hierarchy - if you see the project that rebuilds even if nothing has been changed then see it's references.
I've changed all "copy always" files in all projects to "copy if newer". Basically, in all .csproj files replace <CopyToOutputDirectory>Always</CopyToOutputDirectory>
to <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
Then I've disabled NTFS tunneling as described in this article with this powershell script:
New-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "MaximumTunnelEntries" -Value 0 -PropertyType "DWord"
After that I needed on rebuild and it seems working for now.
In my case the culprit was "Copy Local" setting of a referenced dll set to true and "Copy to Output Directory" setting a file set to Copy always.
For .Net Core Projects, all solutions above are not working.
I've found the solution. In case you are using Visual Studio 2019:
Build the solution twice
Turn on Tools -> Options -> Projects and Solutions -> SDK-Style Projects -> Logging Level -> Verbose
Clear the output window
Build your start project
Inspect the output window. All the string starting with FastUpToDate
You will find some project items that are making your project not up to date.
Fix these issues and try again from step 1. If your fixes are correct, you will achieve Build: 0 succeeded, 0 failed, {n} up-to-date, 0 skipped in the last string of build output.
The MSBuild team is collecting documentation about investigating build incrementality issues here:
https://github.com/Microsoft/MSBuild/wiki/Rebuilding%20when%20nothing%20changed
UPDATED LINK: https://github.com/dotnet/msbuild/blob/main/documentation/wiki/Rebuilding-when-nothing-changed.md
Based on your observations, it sounds like you have projects expressing dependencies to other projects in a way that isn't obvious. It is possible for orphaned dependencies to remain in project files without being apparent in the UI. Have you looked through a misbehaving project file after opening it in a text editor? Checked solution build dependencies?
If you're not able to spot anything, try recreating one of your projects from scratch to see if the new project exhibits the same problem. If the clean project builds correctly, you'll know that you have unwanted dependencies expressed somewhere. As far as I know, these would have to be in the project file(s) or the solution file, unless you have makefiles or other unusual build steps.
Another problem that frequently happens is when some item in your solution has a modified stamp that is in the future. This can happen if you set your clock forward, and then set your clock to the correct time. I had this happen while installing Linux.
In this case you can recursively touch all the files using git bash (yes, in Windows):
find . -exec touch {} \;
I've finally found one more culprit that I had hard time finding by increasing the build log verbosity.
In some cases, MSBuild looks for vc120.pdb in the output folder, and if this file doesn't exist, it will rebuild the entire project. This occurs even if you have disabled debug symbol generation.
The workaround here is to enable debug symbols and let this file get generated, then disable the setting again without deleting the PDB file.
I had this same problem and it turned out to be related to a couple of project that had a copy local reference to a dll in their own output directory.
The key to finding this was having diagnostic output set for the build output, but also knowing what to look for in the log. Searching for: 'not up to date' was the key.
Here is an answer from VS2010 always rebuilds solution?
This issue is solved by changing the project files, cleaning solution,
deleting all bin folders by hand, restarting Visual studio and
rebuilding everything.
I had the same issues with you.
I found that it came from some deleted files.
When I had removed the files from my project, the issues was gone.
Regards.
For this category of build problems setting MSBuild output verbosity to 'diagnostic' is indeed a necessary first step. Most of the time the stated reason for the re-builds would be enough to act upon, BUT occasionally MSBuild would erroneously claim that some files are modified and need to be copied.
If that is the case, you'd need to either disable NTFS tunneling or duplicate your output folder to a new location. Here it is in more words.
I had the problem of Visual Studio rebuilding projects when upgrading from Visual Studio 2015 to 2017 and I add this answer for the benefit of those who might experience similar problems, as it does not seem to be documented anywhere.
In my case, the problem was that all projects in the solution had the same intermediate Output path (obj). The file GeneratedInternalTypeHelper.cs gets generated by all projects containing XAML. Up to Visual Studio 2015, the build process apparently did not check for the file date of this file and thus no problem with it occurred. With VS2017 the file date of this file is checked and because a later project in the build process will overwrite it (with the same content), the earlier project will re-build, re-triggering the later build, ad infinitum.
The solution in this case is to ensure that all projects have differing intermediate output directories, which will make the problem go away.
In my case (mixed C#, C++/CLI and native C++ solution) , some C++ projects were being re-linked even if nothing had changed. I spent ages trying to work out what was happening. In the end I worked out from the "Command Line" option that the PDB output path (option /Fd) could not handle the folder setting $(IntDir). I removed that - an empty value will do the default correctly - and my issue went away.
As others have noticed, a likely reason is that CopyToOutputDirectory is set to Always. This can be fixed simultaneously in all project files by applying the powershell script below:
$folder = "C:\My\Solution\Folder"
$csvFiles = Get-ChildItem $folder *.csproj -rec
foreach ($file in $csvFiles)
{
(Get-Content $file.PSPath -Encoding UTF8 -Raw) |
Foreach-Object { $_ -replace "<CopyToOutputDirectory>Always</CopyToOutputDirectory>", "<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>" } |
Set-Content $file.PSPath -Encoding UTF8 -NoNewline
}
Files that do not exist are a problem and obviously files producing no output as well. That can happen, wenn you have a resource file in a static library. (C++)
I'm using VS2008 to compile my C# Console App. When I release my app, I have to delete lots of what appear to me to be superfluous files. For example,
MyApp.vshost.exe.manifest
MyApp.vshost.exe.config
MyApp.vshost.exe
MyApp.pdb
How do I prevent these files being copied into my Release directory? Oh, I'm using Reshaper also - if that makes any difference.
To remove the PDB file, just turn off PDB generation in the project settings. (Go to the Build tab, Advanced, and set "debug info" to "none" - if you're really sure you don't want the debug info...)
The VSHOST files are to allow Visual Studio to host the executable in a reusable process - basically this is a way of restarting the app quickly within Visual Studio. To stop them from being produced, again go into the project properties, this time in the "Debug" tab, untick "Enable the Visual Studio Hosting Process" option.
I suggest not to remove those files from your Release directory. Instead, create a separate folder (let's call it Deploy) for the files you really want to deploy, and make a script fillDeploy.bat which copies exactly the needed files from Release to Deploy. This script can do some additional things for your deployment (for example, put the documentation files there, provide a different config file etc). If you want this script to be called every time you make a Release build, add a postbuild event to your project like this one:
if $(ConfigurationName)==Release call $(ProjectDir)fillDeploy.bat
Inside the Properties of the project you are building you can configure these things. The exact place of the options varies from version to version of Visual Studio. Start in the "Build" tab and then look in the "Advanced" area.