Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MSBuild rebuilds project when custom .target, .props files are modified #23388

Open
manojsitapara opened this issue Jan 12, 2022 · 21 comments
Open
Assignees
Milestone

Comments

@manojsitapara
Copy link

When I build .net core solution file using MSBuild, it keep rebuilding even if there is no code changes in c# files

Input file "h:\MyCustomTarget.Targets" is newer than output file "obj\Release\myproject.dll".

If I made any changes either in my custom .targets or .props file, it always rebuild it, which I really don't want.

Is there any way to not to consider .targets & .props file when compiling solution?

@dotnet-issue-labeler dotnet-issue-labeler bot added Area-NetSDK untriaged Request triage from a team member labels Jan 12, 2022
@manojsitapara manojsitapara changed the title MSBuild rebuild project when my custom .target, .pros file modified MSBuild rebuild project when custom .target, .pros file modified Jan 12, 2022
@KalleOlaviNiemitalo
Copy link

Perhaps caused by the fix of dotnet/msbuild#1299. If so, I think this would need an MSBuild change, perhaps an IgnoreModificationTime attribute on the Import element.

Alternatively, you could set an old timestamp on the file after each time you save it.

@manojsitapara
Copy link
Author

@KalleOlaviNiemitalo can you please give example how to specify IgnoreModificationTime on import element?

@KalleOlaviNiemitalo
Copy link

@manojsitapara I meant MSBuild would first have to be changed to support the attribute, and then you would be able to use it in your project.

@KalleOlaviNiemitalo
Copy link

My reasoning:

  • MSBuild nowadays checks the modification times of all imported projects and adds the path of the last-modified project to the MSBuildAllProjects property. In your case, it would be "h:\MyCustomTarget.Targets".
  • Maybe .NET SDK uses $(MSBuildAllProjects) as an input of some target. That would explain why MSBuild rebuilds the DLL when "h:\MyCustomTarget.Targets" is newer.
  • If you added a target that removes "h:\MyCustomTarget.Targets" from MSBuildAllProjects before MSBuild checks whether the DLL needs to be rebuilt, you could avoid the rebuild. But this would also prevent MSBuild from noticing that some other imported file has changed and requires the DLL to be rebuilt, if the modification time of the other file is earlier than that of "h:\MyCustomTarget.Targets", because MSBuild won't add both files to MSBuildAllProjects. So this is not a good solution.
  • If MSBuild supported an attribute to prevent it from considering "h:\MyCustomTarget.Targets" when it decides what to add to MSBuildAllProjects, that would let you edit the file without triggering a rebuild, but also without preventing other modified files from triggering a rebuild.

@baronfel
Copy link
Member

@manojsitapara can you expand on why you wouldn't want your changes to be represented in the build? what kinds of changes/processes are happening to these files that you'd like to ignore?

@baronfel baronfel added waiting-on-feedback and removed untriaged Request triage from a team member labels Jan 18, 2022
@manojsitapara
Copy link
Author

manojsitapara commented Jan 31, 2022

Let's say if I add new copy or delete command MSBuild script file which copy certain file, in this case my assembly should not be rebuild (which is right now rebuilding it), because there is no really code change in my C# files, but only changed MSBuild script.

@KalleOlaviNiemitalo
Copy link

Maybe .NET SDK uses $(MSBuildAllProjects) as an input of some target.

Yes, $(MSBuildAllProjects) is an input of the CoreCompile target. https://github.com/dotnet/roslyn/blob/15b43b33901c88f68ef43f8314b5a2457716780d/src/Compilers/Core/MSBuildTask/Microsoft.CSharp.Core.targets#L6-L7

@manojsitapara
Copy link
Author

Maybe .NET SDK uses $(MSBuildAllProjects) as an input of some target.

Yes, $(MSBuildAllProjects) is an input of the CoreCompile target. https://github.com/dotnet/roslyn/blob/15b43b33901c88f68ef43f8314b5a2457716780d/src/Compilers/Core/MSBuildTask/Microsoft.CSharp.Core.targets#L6-L7

Thanks !! is this mean do Microsoft has to change?

@geetmenon
Copy link

@baronfel: We are also facing the same issue. We notice the following:

a) BeforeCompile target (because of input param MSBuildAllProjects itemgroup ) - is checking the timestamp of our custom .props files and custom .target files to see if it is later than our dll/exe timestamp to decide if the dll/exe needs to be rebuilt

b) CoreCompile target - is checking the timestamp of our custom .target files to see if it is later than our dll/exe timestamp to decide if the dll/exe needs to be rebuilt

These are breaking changes in MSBuild 16.11.1. This was not the case with older versions of MSBuild. This is a bug. In our custom targets, we do a lot of other steps like copying files, moving files, include additional logging, changing a folder name etc. These changes should not force our c# assemblies or executables to be rebuilt. Also, we do not want to be setting an older timestamp to our custom scripts to workaround this issue (it will become a maintenance nightmare for us if we start doing this).

Our builds are currently broken now as a result. Please have this issue fixed at the earliest or at least provide us a patch for this issue or a flag which can turn off to let MSBuild know to not consider our custom .props files and custom .target files in BeforeCompile and in CoreCompile targets.

@KalleOlaviNiemitalo
Copy link

If the MSBuild team agrees to add a feature that lets developers hide some project files from MSBuildAllProjects, then I think it would be best to control that feature with a new attribute on the Project element, in each imported file. This way, the feature could also be used on Directory.Build.props or other files that are imported by the .NET SDK. MSBuild appears to ignore unrecognized attributes on the Project element, so project files with the new attribute would still be compatible with older versions of MSBuild that did not automatically set MSBuildAllProjects.

@baronfel
Copy link
Member

baronfel commented Feb 2, 2022

These are breaking changes in MSBuild 16.11.1. This was not the case with older versions of MSBuild

What makes you think this is the case, @geetmenon? From what I can see, $(MSBuildAllProjects) has been an input parameter to the CoreCompile task in the C# targets for at least 6 years, so this behavior shouldn't be emergent. I also don't see anything related to this in the documented MSBuild Change Waves.

@KalleOlaviNiemitalo
Copy link

@baronfel, the MSBuild behavior was changed in dotnet/msbuild#3605, which was merged before MSBuild v16.0.461.62831. It is not listed in change waves because you cannot opt out by setting MSBuildDisableFeaturesFromVersion.

#2853 made .NET SDK assume that MSBuild automatically sets MSBuildAllProjects. If the MSBuild change were retroactively added to a change wave, then that assumption would no longer hold, and the .NET SDK files that were modified in that PR would have to conditionally append themselves to MSBuildAllProjects if the user configured MSBuild not to do that. I don't think that would be a good fix here.

@baronfel
Copy link
Member

baronfel commented Feb 2, 2022

Thank you for this linkages as always, @KalleOlaviNiemitalo. You're on top of things 👍

@manojsitapara
Copy link
Author

@baronfel any update on this?

@geetmenon
Copy link

@baronfel, when can we expect a fix for this?

@baronfel
Copy link
Member

Hi folks, we haven't had the team dig into the impacts and decided on a priority yet. When we do, the issue will be moved into a milestone matching the expected release. Then, based on the team's workload they'll triage this issue against the others in the milestone before implementing a fix.

@baronfel baronfel added needs team triage Requires a full team discussion and removed waiting-on-feedback labels Feb 10, 2022
@marcpopMSFT
Copy link
Contributor

@rainersigwald Can you think of a way to work around this by forcing the specific props/targets to be covered in the rebuild checks?

@marcpopMSFT marcpopMSFT added this to the Discussion milestone Feb 16, 2022
@marcpopMSFT marcpopMSFT removed the needs team triage Requires a full team discussion label Feb 16, 2022
@rainersigwald
Copy link
Contributor

The long-term tracking issue is dotnet/msbuild#701, but it's very difficult to implement because it's a fundamental redesign of MSBuild's incrementality model.

There's no way to guarantee that an imported file doesn't have impact on the build. It would be possible to add an IgnoreModificationTime attribute but that's not something that has been requested before.

@manojsitapara
Copy link
Author

Any update on this?

1 similar comment
@manojsitapara
Copy link
Author

Any update on this?

@manojsitapara manojsitapara changed the title MSBuild rebuild project when custom .target, .pros file modified MSBuild rebuild project when custom .target, .props file modified Sep 13, 2022
@manojsitapara manojsitapara changed the title MSBuild rebuild project when custom .target, .props file modified MSBuild rebuilds project when custom .target, .props file modified Sep 13, 2022
@manojsitapara manojsitapara changed the title MSBuild rebuilds project when custom .target, .props file modified MSBuild rebuilds project when custom .target, .props files are modified Sep 13, 2022
@geetmenon
Copy link

We are facing the same issue. If your design needs to be changed, please change it and provide a resolution for this asap. We have been waiting for a fix for this issue for more than a year now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants