Closed dotMorten closed 2 years ago
It looks like it's caused by this part of the build:
Confirmed that if I redeclare the target, the problem goes away:
<Target Name="_CleanMacBuild" />
This file seems to be the culprit:
c:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\iOS\Xamarin.iOS.Windows.After.targets
<Target Name="_CleanMacBuild" DependsOnTargets="_SayHello">
<RemoveDir SessionId="$(BuildSessionId)"
Condition="'$(MtouchTargetsEnabled)' == 'true'"
Directories="$(OutputPath);$(IntermediateOutputPath)"
RemoveAppDir="$(RemoveAppDir)"
ContinueOnError="true" />
I'm not sure why it is triggering even when it's not a clean, but in any case, I don't think a clean should blow away the entire folder, but only the artifacts that single project is responsible for.
@dotMorten I have tested the provided test case on VS for Mac and I have not been able to reproduce the issue with the following version.
I have added the appropriate tag for the VS for Windows eng to take a look at the issue and investigate further.
Thanks for the bug report.
Removing tag since I did a second run and confirmed it does happen on Mac too.
Just to clarify, the compilation does complete on VSfM and the output is as follows:
. ├── ./ClassLibrary3 │ ├── ./ClassLibrary3/Class1.cs │ ├── ./ClassLibrary3/ClassLibrary3.csproj │ ├── ./ClassLibrary3/ClassLibrary3.csproj.user │ ├── ./ClassLibrary3/Properties │ │ └── ./ClassLibrary3/Properties/AssemblyInfo.cs │ ├── ./ClassLibrary3/Resources │ └── ./ClassLibrary3/obj │ └── ./ClassLibrary3/obj/Debug │ ├── ./ClassLibrary3/obj/Debug/ClassLibrary1.dll │ ├── ./ClassLibrary3/obj/Debug/ClassLibrary1.pdb │ ├── ./ClassLibrary3/obj/Debug/ClassLibrary3.csproj.CoreCompileInputs.cache │ └── ./ClassLibrary3/obj/Debug/ClassLibrary3.csproj.FileListAbsolute.txt ├── ./ClassLibrary3.sln ├── ./ClassLibrary4 │ ├── ./ClassLibrary4/Class1.cs │ ├── ./ClassLibrary4/ClassLibrary4.csproj │ ├── ./ClassLibrary4/Properties │ │ └── ./ClassLibrary4/Properties/AssemblyInfo.cs │ ├── ./ClassLibrary4/Resources │ └── ./ClassLibrary4/obj │ └── ./ClassLibrary4/obj/Debug │ ├── ./ClassLibrary4/obj/Debug/ClassLibrary1.dll │ ├── ./ClassLibrary4/obj/Debug/ClassLibrary1.pdb │ ├── ./ClassLibrary4/obj/Debug/ClassLibrary4.csproj.CopyComplete │ ├── ./ClassLibrary4/obj/Debug/ClassLibrary4.csproj.CoreCompileInputs.cache │ ├── ./ClassLibrary4/obj/Debug/ClassLibrary4.csproj.FileListAbsolute.txt │ └── ./ClassLibrary4/obj/Debug/ClassLibrary4.csprojResolveAssemblyReference.cache └── ./SharedOutput ├── ./SharedOutput/ClassLibrary1.dll └── ./SharedOutput/ClassLibrary1.pdb
which means works as expected. This is a Windows only issues as per comment https://github.com/xamarin/xamarin-macios/issues/4574#issuecomment-410402020
Any progress on this? This is a MAJOR showstopper for our entire team. Having multiple class libraries in a single solution is NOT an uncommon thing. Workaround no longer works in the latest VS Update.
Here's a good explanation how clean is supposed to be done: https://github.com/Microsoft/msbuild/issues/2408#issuecomment-321082997
@dotMorten what IS an uncommon thing is for teams to set a single output folder. I understand this is important to you, we're investigating ways to improve it. Still, it is not, IMO, a MAJOR showstopper since all you need to do to fix it is to use VS defaults for output folders. With Mac build host having to sync files across two machines, there are a number of things to consider including checks on out of date output on both sides and so on that are non-trivial.
what IS an uncommon thing is for teams to set a single output folder
Absolutely not uncommon to have all your artifacts go to the same output. This is quite a typical build server setup, and we're not changing the entire build system setup because Xamarin.iOS decides a build should also do a clean, and in addition the clean is incorrectly implemented.
Second having artifacts (and intermediates) go into the source controlled folder (gitignore or not) is a really bad practice. Especially in larger solution setups. I get why it's the default for VS as it's a simple starting point for a single contained project, but it quickly falls apart once you start going bigger, or you're dealing with larger complex build systems with artifacts in many places.
Third, this is a regression. It' had been working fine for years.
...could we perhaps start with not cleaning on a regular build? On an actual clean or rebuild I don't think the damage is so bad. But cleaning the same folder over and over again as each project builds is, obviously, not good.
Absolutely not uncommon to have all your artifacts go to the same output.
Well, I guess without some telemetry or data, there's no way to decide that ;-). Ditto for what is considered a "typical build server setup" or what is "really bad practice". No point in arguing either way.
Xamarin.iOS decides a build should also do a clean
As I mentioned, you can think of it in those simple terms if that helps you, but if you want to really understand the complexities around a XI build, I'd suggest reading http://www.cazzulino.com/how-vs-builds-on-mac-with-xamarin.html at least. If we never cleaned anything on the Windows side in between builds, rest assured that there would be a host of other issues with incremental builds on the remote build host. We need to carefully balance speed of builds vs incremental build and clean.
Third, this is a regression. It' had been working fine for years.
I've checked the commits for that particular target and it hasn't changed in years. So I wouldn't consider it a regression up-front.
Could you try the following workaround?
<Target Name="_DisableMtouchTargets" Condition="'$(DisableMacClean)' == 'true'" BeforeTargets="_CleanMacBuild" DependsOnTargets="_SayHello">
<PropertyGroup>
<!-- save original value to restore after the original clean -->
<_MtouchTargetsEnabled>$(MtouchTargetsEnabled)</_MtouchTargetsEnabled>
<MtouchTargetsEnabled>false</MtouchTargetsEnabled>
</PropertyGroup>
</Target>
<Target Name="_RestoreMtouchTargets" Condition="'$(DisableMacClean)' == 'true'" AfterTargets="_CleanMacBuild">
<PropertyGroup>
<MtouchTargetsEnabled>$(_MtouchTargetsEnabled)</MtouchTargetsEnabled>
</PropertyGroup>
</Target>
You can place that in an import for the XI projects.
Then just set DisableMacClean=true
for your CI build.
Let me know how that goes.
Thanks!
This is still an issue for us as well. We have made it work with the mentioned workaround.
`
</Target>
<Target Name="_RestoreMtouchTargets" Condition="'true' == 'true'" AfterTargets="_CleanMacBuild">
<PropertyGroup>
<MtouchTargetsEnabled>$(_MtouchTargetsEnabled)</MtouchTargetsEnabled>
</PropertyGroup>
</Target> `
However as you also state, it can give complications when building. So at times we need to delete the cache on the mac when in bridge mode.
As @CSkoubo mentions above, then we have this issue as well.
I agree that only telemetry can say what is the most common setup, so I an not sure how @kzu concludes that this is an uncommon setup. However this behavior is at least different from other project types, so in that sense it is not following standards and makes us having to handle a Xamarin.iOS project different from Xamarin.Android or C#.
For the clean on every build I fully agree with @dotMorten that this seems like an obvious mistake.
It doesn't really matter how common it is (apart from priority). No other project type does this, so what's the argument that this project type needs to be the only one doing it?
Is this resolved? If so which version? @vs-mobiletools-engineering-service2
Sorry, looks like automation closed this by mistake.
This item has been open for a while and we weren’t able to prioritize it over other higher impact issues we received, based on the votes and comments from others in the community and our understanding of the issue. Based on that, our current and future priorities in this area and others, I’m closing it since the chances of it becoming high enough in priority for a fix in the future are very low. I understand that may be disappointing, but I don’t want to create false hopes.
Late to the party :). @dotMorten
No other project type does this, so what's the argument that this project type needs to be the only one doing it?
No other project type does remote builds like XI does, so, there's that.
Steps to Reproduce
ClassLibrary1
ClassLibrary2
Expected Behavior
ClassLibrary2 shouldn't delete the output of ClassLibrary1.
Actual Behavior
ClassLibrary2 deletes the output of ClassLibrary1 when it begins compiling.
Environment
Build Logs
ClassLibrary4_Debug_AnyCPU_Build_2018-08-03T16_14_39.3297140-07_00.zip
Example Project (If Possible)
ClassLibrary3.zip