You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am currently investigating why we get full builds on some of our larger solution files (500+ CSPROJ).
We are currently using Visual Studio 2017 15.9.6
Goals
Here is what we are trying to do:
We want to be able to invoke MSBuild from the Command Line to build our solutions (this way we can script this to happen in the morning before a developer comes in).
With NO changes we expect to be able to open the Solution File in Visual Studio and hit Build and have nothing build (since everything should be up to date).
In this way our Developers can be productive right when they get in instead of waiting on a build.
Unfortunately as it stands today Visual Studio feels like it needs to rebuild a significant amount of the code base.
Background
We have already encountered and corrected the following issues:
The State Files attempt to write to paths that were too long. We would constantly get MSB3101: Could not write state file errors. We had these as relative paths but unbeknown to us apparently MSBuild does not "expand" this path prior to passing it off; this actually resulted in paths that were even LONGER than we expected. We worked around that by setting our IntermediateOutputPath to be explicitly expanded by MSBuild prior to passing it off. Like so:
This seems to have resolved that issue and we no longer encounter the warnings and incremental builds seem to work. I have not seen any issues reported for this; but I did find this StackOverflow post which led me in the right direction: https://stackoverflow.com/questions/139964/msbuild-directory-structure-limit-workarounds/9635709#9635709 Its unclear if this is a known issue, an issue that will go away once we get Long Path Support, or an issue that should be reported as a new bug.
We then encountered Issue GenerateCompiledExpressionsTempFile does not clean up the files it creates #1648 wherein when Visual Studio would launch it would then create the 3 Temporary generated files in the \bin\obj\ folder even when we were not utilizing Workflow; this of course triggered a rebuild. We have worked around that by inserting into every single project a no-op like so:
<TargetName="GenerateCompiledExpressionsTempFile">
<!--This is a no-op to overwrite the existing target that ships with MSBuild. When we upgrade to Visual Studio 2019 (MSBuild 16.0) we can remove this. See https://github.com/Microsoft/msbuild/issues/1648-->
</Target>
With these changes we have been able to drive down our solution rebuilds from 900 projects down to 140 Projects; all of which are Xaml Projects or have an N-Order Dependency on a shared library which contains Xaml code.
Using the diagnostic verbosity level we can see the following from within Visual Studio:
Project 'CU.TestClient.Core' is not up to date. Input file 's:\timssvn\6x\trunk\bin\obj\{5b44a2e5-81f9-4d9d-9857-006b76d62f8c}\generatedinternaltypehelper.g.cs' is modified after output file ''.
When we build via the Command Line in MSBuild in MSBuild we see that the file is indeed created; however the file is empty. When we run this build in diagnostic verbosity we see the following:
InternalTypeHelper class is not required for this project, make file 'S:\TimsSVN\6x\Trunk\bin\obj\{5B44A2E5-81F9-4D9D-9857-006B76D62F8C}\GeneratedInternalTypeHelper.g.cs' empty.
//// If no any xaml file with local-types wants to reference an internal type from// current assembly and friend assembly, and InternalTypeHelperFile is set in the// cache file, now it is the time to remove the content of InternalTypeHelper File.//// We still keep the empty file to make other parts of the build system happy.//if(!String.IsNullOrEmpty(_internalTypeHelperFile)&&!compilerWrapper.HasInternals){if(TaskFileService.Exists(_internalTypeHelperFile)){// Make empty content for this file.MemoryStreammemStream=newMemoryStream();using(StreamWriterwriter=newStreamWriter(memStream,newUTF8Encoding(false))){writer.WriteLine(String.Empty);writer.Flush();TaskFileService.WriteFile(memStream.ToArray(),_internalTypeHelperFile);}Log.LogMessageFromResources(MessageImportance.Low,SRID.InternalTypeHelperNotRequired,_internalTypeHelperFile);}}
Therefore the file is indeed empty. HOWEVER when the solution is loaded up in Visual Studio (on launch; not even hitting Build or in any way interacting with the IDE beyond opening) we see:
generatedinternaltypehelper.g.cs get deleted
generatedinternaltypehelper.g.i.cs get created with content
generatedinternaltypehelper.g.cs get recreated with the same content as the i.cs
The Code within these files is:
//------------------------------------------------------------------------------// <auto-generated>// This code was generated by a tool.// Runtime Version:4.0.30319.42000//// Changes to this file may cause incorrect behavior and will be lost if// the code is regenerated.// </auto-generated>//------------------------------------------------------------------------------namespaceXamlGeneratedNamespace{/// <summary>/// GeneratedInternalTypeHelper/// </summary>[System.Diagnostics.DebuggerNonUserCodeAttribute()][System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks","4.0.0.0")][System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]publicsealedclassGeneratedInternalTypeHelper:System.Windows.Markup.InternalTypeHelper{/// <summary>/// CreateInstance/// </summary>protectedoverrideobjectCreateInstance(System.Typetype,System.Globalization.CultureInfoculture){returnSystem.Activator.CreateInstance(type,((System.Reflection.BindingFlags.Public|System.Reflection.BindingFlags.NonPublic)|(System.Reflection.BindingFlags.Instance|System.Reflection.BindingFlags.CreateInstance)),null,null,culture);}/// <summary>/// GetPropertyValue/// </summary>protectedoverrideobjectGetPropertyValue(System.Reflection.PropertyInfopropertyInfo,objecttarget,System.Globalization.CultureInfoculture){returnpropertyInfo.GetValue(target,System.Reflection.BindingFlags.Default,null,null,culture);}/// <summary>/// SetPropertyValue/// </summary>protectedoverridevoidSetPropertyValue(System.Reflection.PropertyInfopropertyInfo,objecttarget,objectvalue,System.Globalization.CultureInfoculture){propertyInfo.SetValue(target,value,System.Reflection.BindingFlags.Default,null,null,culture);}/// <summary>/// CreateDelegate/// </summary>protectedoverrideSystem.DelegateCreateDelegate(System.TypedelegateType,objecttarget,stringhandler){return((System.Delegate)(target.GetType().InvokeMember("_CreateDelegate",(System.Reflection.BindingFlags.InvokeMethod|(System.Reflection.BindingFlags.NonPublic|System.Reflection.BindingFlags.Instance)),null,target,newobject[]{delegateType,handler},null)));}/// <summary>/// AddEventHandler/// </summary>protectedoverridevoidAddEventHandler(System.Reflection.EventInfoeventInfo,objecttarget,System.Delegatehandler){eventInfo.AddEventHandler(target,handler);}}}
Reading the source to MarkupCompilePass2 it appears that the g.i.cs file is generated for use by Intellisense and is not put into play with the build (as is expected) but for some reason Visual Studio felt that it needed to regenerate the g.cs file.
This is where I am stuck; I am not smart enough to understand the scenarios in which the MarkupCompilePass2 will require itself to build the g.cs file. I have tried to narrow down if it is a project or solution file causing the issue (to try and get a smaller repo) but I have been unsuccessful.
When I have attempted to reduce it down to just this project I am unable to get the same behavior; with smaller solutions I will often get this behavior:
generatedinternaltypehelper.g.cs is left alone (still blank)
generatedinternaltypehelper.g.i.cs is created with the content listed above
In this cases the incremental build obviously works because g.cs was not touched.
Can anyone provide pointers as to where I can go to continue to debug this? I am currently stuck and unsure how to debug further.
Questions
What in the Visual Studio Startup Process is muxing the generatedinternaltypehelper files?
How can I debug that above process?
I am dedicated to identifying this issue and am pretty resourceful if pointed in the right direction.
Hi,
I am currently investigating why we get full builds on some of our larger solution files (500+ CSPROJ).
We are currently using Visual Studio 2017 15.9.6
Goals
Here is what we are trying to do:
In this way our Developers can be productive right when they get in instead of waiting on a build.
Unfortunately as it stands today Visual Studio feels like it needs to rebuild a significant amount of the code base.
Background
We have already encountered and corrected the following issues:
MSB3101: Could not write state fileerrors. We had these as relative paths but unbeknown to us apparently MSBuild does not "expand" this path prior to passing it off; this actually resulted in paths that were even LONGER than we expected. We worked around that by setting our IntermediateOutputPath to be explicitly expanded by MSBuild prior to passing it off. Like so:This seems to have resolved that issue and we no longer encounter the warnings and incremental builds seem to work. I have not seen any issues reported for this; but I did find this StackOverflow post which led me in the right direction: https://stackoverflow.com/questions/139964/msbuild-directory-structure-limit-workarounds/9635709#9635709 Its unclear if this is a known issue, an issue that will go away once we get Long Path Support, or an issue that should be reported as a new bug.
<CopyToOutputDirectory>Always</CopyToOutputDirectory>this seemed to trigger builds; we have converted all of these to<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>which again seems to have reduced the copying. This seems to have been documented in several places on the internet; one such place is https://blogs.msdn.microsoft.com/kirillosenkov/2014/08/04/how-to-investigate-rebuilding-in-visual-studio-when-nothing-has-changed/.Current Roadblock (This Report)
With these changes we have been able to drive down our solution rebuilds from 900 projects down to 140 Projects; all of which are Xaml Projects or have an N-Order Dependency on a shared library which contains Xaml code.
Using the diagnostic verbosity level we can see the following from within Visual Studio:
When we build via the Command Line in MSBuild in MSBuild we see that the file is indeed created; however the file is empty. When we run this build in diagnostic verbosity we see the following:
This traces back to this section of logic in MarkupCompilePass2.cs: https://referencesource.microsoft.com/#PresentationBuildTasks/BuildTasks/Microsoft/Build/Tasks/Windows/MarkupCompilePass2.cs,684
Therefore the file is indeed empty. HOWEVER when the solution is loaded up in Visual Studio (on launch; not even hitting Build or in any way interacting with the IDE beyond opening) we see:
The Code within these files is:
Reading the source to MarkupCompilePass2 it appears that the g.i.cs file is generated for use by Intellisense and is not put into play with the build (as is expected) but for some reason Visual Studio felt that it needed to regenerate the g.cs file.
This is where I am stuck; I am not smart enough to understand the scenarios in which the MarkupCompilePass2 will require itself to build the g.cs file. I have tried to narrow down if it is a project or solution file causing the issue (to try and get a smaller repo) but I have been unsuccessful.
When I have attempted to reduce it down to just this project I am unable to get the same behavior; with smaller solutions I will often get this behavior:
In this cases the incremental build obviously works because g.cs was not touched.
Can anyone provide pointers as to where I can go to continue to debug this? I am currently stuck and unsure how to debug further.
Questions
I am dedicated to identifying this issue and am pretty resourceful if pointed in the right direction.
Thank you