Bug 5870 - Remove Resource.Designer.cs from .csproj files, auto-generate and auto-add instead.
Summary: Remove Resource.Designer.cs from .csproj files, auto-generate and auto-add in...
Status: ASSIGNED
Alias: None
Product: Android
Classification: Xamarin
Component: MSBuild ()
Version: 4.2.x
Hardware: PC Mac OS
: Highest enhancement
Target Milestone: master
Assignee: dean.ellis
URL:
: 6909 9493 19657 21323 ()
Depends on:
Blocks:
 
Reported: 2012-06-26 14:17 UTC by Jonathan Pryor
Modified: 2017-03-21 20:21 UTC (History)
18 users (show)

Tags: XATriaged
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report for Bug 5870 on Developer Community or GitHub if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: Developer Community HTML or GitHub Markdown
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:
Status:
ASSIGNED

Description Jonathan Pryor 2012-06-26 14:17:43 UTC
Mono for Android projects don't integrate very well with Team Foundation Server (TFS) because the build process updates the Resources.Designer.cs file, which may not be checked out (and not writable):

http://lists.ximian.com/pipermail/monodroid/2012-June/011012.html

A workaround would likely be to generate Resources.Designer.cs into the obj directory, so that it isn't as visible to the developer, and thus will be less likely to be added to version control.
Comment 1 Jonathan Pryor 2012-07-08 09:47:27 UTC

*** This bug has been marked as a duplicate of bug 2057 ***
Comment 2 Jonathan Pryor 2012-11-19 22:23:21 UTC
*** Bug 6909 has been marked as a duplicate of this bug. ***
Comment 3 Jonathan Pryor 2013-01-31 09:57:53 UTC
(Behold my lack of Reading Comprehension!)

Bug 2057 dealt with Properties\AndroidManifest.xml, not anything else, so this isn't a proper duplicate. Furthermore, the fix for 2057 only dealt with Properties\AndroidManifest.xml, so this is by no mean fixed (which was implied by marking this bug a duplicate of a bug that's been fixed!).

To restate things: we should remove the $(AndroidResgenFile) MSBuild property, remove the Resources\Resources.designer.cs file, and instead:

1. Generate Resources.Designer.cs into the obj directory
2 .Update the @(Compile) list with the generated file at build time.

I believe this will have the added benefit of implicitly "fixing" the addition of Resources into Library projects, as those are the two steps that need to manually be done to use resources in library projects:

    https://bugzilla.xamarin.com/show_bug.cgi?id=9493#c3

Finally, we should review other generated files and attempt to remove any other generated files from source control. They're _generated_, they shouldn't be in source control.
Comment 4 Jonathan Pryor 2013-01-31 10:00:56 UTC
Related, and returning to the original description: when using TFS, and Resources\Resources.Designer.cs is readonly and requires update, the build will fail with the following error:

> error MSB4018: The "CopyIfChanged" task failed unexpectedly.
> error MSB4018: System.UnauthorizedAccessException: Access to the path 'Resources\Resource.Designer.cs' is denied.
> error MSB4018:    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
> error MSB4018:    at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite)
> error MSB4018:    at System.IO.File.Copy(String sourceFileName, String destFileName, Boolean overwrite)
> error MSB4018:    at Xamarin.Android.Tasks.CopyIfChanged.Execute()
> error MSB4018:    at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
> error MSB4018:    at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask(ITaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask, Boolean& taskResult) Done executing task "CopyIfChanged" -- FAILED. (TaskId:1005)
Comment 5 Jonathan Pryor 2013-02-05 15:43:11 UTC
*** Bug 9493 has been marked as a duplicate of this bug. ***
Comment 6 Mikayla Hutchinson [MSFT] 2013-05-22 16:32:02 UTC
This problem with this is that you won't (easily) get code completion.
Comment 8 Mikayla Hutchinson [MSFT] 2013-10-03 13:26:13 UTC
@jonp: I'd originally wanted to do the generated resource files that way, but the VS addin team nixed it - apparently VS will not provide code completion for types in files that are injected into @(Compile) at build time. However, we would be able to special-case it to work in XS with a few days of work.
Comment 9 Chris Thorp 2013-12-04 04:32:21 UTC
Our team is using VisualSVN 4.x with VS2013
We are experiencing the same issue on building. If you touch a file in the project that is not locked, the normal behavior is for a window to be displayed to allow the lock to be obtained. However in building we get the same error 

(x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(785,2): error MSB4018: The "CopyIfChanged" task failed unexpectedly.
C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(785,2): error MSB4018: System.UnauthorizedAccessException: Access to the path 'Resources\Resource.designer.cs' is denied.

We have .cs files marked as exclusive lock. If we change that, then we get the problem, that compiling the program then flags up the need to commit changes.
Is there any progress on this issue
Comment 11 Jonathan Pryor 2014-01-02 17:03:55 UTC
> apparently VS will not provide code completion for
> types in files that are injected into @(Compile) at build time.

Understandable. However, what prevents @(Compile) from referencing a generated file?

    <Compile Include="$(IntermediateOutputPath)\Resource.Designer.cs" />

This shouldn't actually require any build-system changes either; we'd "just" need to update the default templates, and also update the templates to set $(AndroidResgenFile) accordingly:

    <AndroidResgenFile>$(IntermediateOutputPath)\Resource.Designer.cs</AndroidResgenFile>

The one downside to this (I assume -- untested) is that it'll create/be shown in an e.g. obj\Debug folder within the Solution panel, which is (presumably) not ideal. Though maybe <Link/> can be used to fix that?
Comment 12 Mikayla Hutchinson [MSFT] 2014-01-02 17:18:36 UTC
Not sure how Link would help with that. You probably want the Visible item metadata.

I guess you could put something like this in the Targets file:

<PropertyGroup Condition="'$(AndroidResgenFile)' == '' && '$(AndroidAutoResgenFile)' != 'False'">
    <AndroidResgenFile>$(IntermediateOutputPath)\Resource.Designer.cs</AndroidResgenFile>
    <AndroidAutoResgenFile>true</AndroidAutoResgenFile>
<PropertyGroup>

<ItemGroup Condition="'$(AndroidAutoResgenFile)' != 'False'">
    <Compile Include="$(IntermediateOutputPath)\Resource.Designer.cs">
        <Visible>False</Visible>
        <AutoGen>True</AutoGen>
    </Compile>
</ItemGroup>

It would probably work in VS, but we'd have to special case it in XS.

I'd really rather work out how VS does this for xaml.g.cs files though so we can do it the "proper" way.
Comment 14 Mikayla Hutchinson [MSFT] 2014-02-10 23:50:09 UTC
One possible solution would be to reproduce the resource name generation logic and inject "fake" version of the generated classes (with dummy int values) directly into the type system. It would be easy to update them efficiently on the fly as when individual files were removed/added/renamed/changed. This would probably fix the perf issues we have using aapt to update the actual resource file on the fly - instead, it would only need to be updated at build time and injected into the build.

I can do this is XS, but I don't how easy it is to do in VS.
Comment 15 Jonathan Pryor 2014-05-09 16:30:17 UTC
*** Bug 19657 has been marked as a duplicate of this bug. ***
Comment 16 David Kean 2014-06-20 12:56:06 UTC
Here's a couple of suggestions:

1) It's considered bad practice to overwrite files that are part of the source tree as part of the build, regardless of whether you are using a source control system that sets the files to read-only.

2) Instead, as has already been suggested, you should be generating these files into the intermediate path and then add them to the list of things to compile.

You could do something like this:

 <Target Name="GenerateResourceDesignerFile"

        <GenerateResourceDesignerFile
                OutputPath="$(IntermediateOutputPath)"
            >

            <Output ItemName="Compile"   TaskParameter="GeneratedCodeFiles" />
            <Output ItemName="FileWrites" TaskParameter="GeneratedCodeFiles" />  <!-- For clean build -->

        </GenerateResourceDesignerFile>

 </Target>


This assumes a Task called GenerateResourceDesignerFile with two properties string OutputPath (get/set) and ITaskItem[] GeneratedCodeFiles (set). The generated code files automatically get added to the Compile item, which is then passed onto csc.exe.

Regards

David Kean
Microsoft
Comment 17 Mikayla Hutchinson [MSFT] 2014-06-20 14:36:34 UTC
Yes, the problem is that GenerateResourceDesignerFile is prohibitively expensive to add as a dependency of the VS background compiler, since it involves calling aapt. My suggestion with the dummy items was to fix this, the issue there is how to patch in the real values.
Comment 18 Jonathan Pryor 2014-06-20 15:09:00 UTC
When `aapt` needs to execute, yes, it's prohibitively expensive, but it only needs to execute if:

1. Resources.designer.cs doesn't exist, OR
2. An @(AndroidResource) file has been updated.

If Resources.designer.cs exists (which will be true most of the time) and @(AndroidResource) hasn't changed (which will be true most of the time), then <GenerateResourceDesignerFile/> could be a no-op.

That said, Xamarin Studio currently calls <GenerateResourceDesignerFile/> every time a Resource is updated, and this has been known to take 15+ seconds on large projects.

This in turn is a variation of: https://bugzilla.xamarin.com/show_bug.cgi?id=18692#c6

Do we have any idea on how "fast" it would need to be to consider running this in CoreBuild?

If it does take several seconds and IS part of CoreBuild, what will the IDE do? Is CoreBuild run on a separate thread? (Please let it not be on the UI thread...)
Comment 19 David Kean 2014-06-20 15:21:25 UTC
You should be making use of up-to-date checks in MSBuild to only run the target when needed: http://msdn.microsoft.com/en-us/library/ee264087.aspx.
Comment 20 Jonathan Pryor 2014-06-20 15:34:00 UTC
@David: Which we do; see the _UpdateAndroidResgen target in Xamarin.Android.Common.targets, which is what Xamarin Studio executes whenever Android Resources are modified:

<Target Name="_UpdateAndroidResgen"
	Inputs="$(MSBuildAllProjects);@(ResolvedFiles);@(_AndroidResourceDest)"
	Outputs="$(_AndroidResgenFlagFile)"
	Condition="'$(AndroidResgenFile)' != ''"
	DependsOnTargets="_CheckForDeletedResourceFile;_ValidateAndroidPackageProperties;_ResolveMonoAndroidSdks;_GetLibraryImports;_CheckDuplicateJavaLibraries;_AddTrialSplashScreenResources;_GetAdditionalResourcesFromAssemblies">

A problem (Bug #18692) is that WHEN an Android resource is updated, generating the new Resource.designer.cs can be a SLOW (15+ second) operation, depending on the number of Android resources, the size of the project, the number of referenced projects, etc. When doing GUI work (e.g. editing a .axml file), that's a large part of what the developer is doing (editing Android resources), so this isn't a great experience. (To put it mildly.)

On Visual Studio, Resource.designer.cs is only checked-for-and-updated on Build, not on every keystroke, so if it takes extra time it's not _quite_ as noticeable.
Comment 21 Jonathan Pryor 2014-07-16 13:06:15 UTC
*** Bug 21323 has been marked as a duplicate of this bug. ***
Comment 22 dean.ellis 2015-05-05 11:36:03 UTC
With great pleasure I can say

fixed in monodroid/master/1da1bc91