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

In projects configured to use AAPT2, invalid Android resource elements added after an initial successful design-time build do not produce errors during subsequent incremental builds #3336

Closed
brendanzagaeski opened this issue Jul 9, 2019 · 2 comments · Fixed by #3355
Assignees
Labels
Area: App+Library Build Issues when building Library projects or Application projects. bug Component does not function as intended.

Comments

@brendanzagaeski
Copy link
Contributor

Steps to reproduce

  1. Create a new Android App (Xamarin) > Single View App project.
  2. Add a new XML file Resources\values\ids.xml that has an intentionally invalid element:
    <?xml version="1.0" encoding="utf-8" ?>
    <resources>
      <item/>
    </resources>
  3. Build > Build Solution. If this build fails with no error due to Build fails first time after layout file changed and saved #2427, then repeat the build again. If the build succeeds, then you can stop at this step. If the build instead fails correctly with the expected APT0000 error, then complete the additional steps 4–7 to see the problem.
  4. Exclude ids.xml from the solution by highlighting the file in the Solution Explorer and then selecting Project > Exclude From Project.
  5. Build > Build Solution. (Note: This build might fail with no error on the first attempt due to Build fails first time after layout file changed and saved #2427. If so, repeat the build again until it succeeds.)
  6. Re-include ids.xml into the project.
  7. Build > Build Solution. (Again, repeat the build if needed to work around Build fails first time after layout file changed and saved #2427.)

If it's more convenient, you can also use command line builds to reproduce the issue:

  1. After creating the project and adding the ids.xml file, delete the .vs directory, the obj and bin directories, and the Resources\Resource.designer.cs file. Then build the project on the command line:

    msbuild -restore .\AndroidApp1.sln
  2. Edit the .csproj file in a text editor to remove the <AndroidResource Include="Resources\values\ids.xml" /> item.

  3. Build the solution again.

  4. Edit the .csproj file to add back the ids.xml item.

  5. Build the solution again.

Expected behavior

The build should fail at both step 3 and step 7 with the following error:

1>C:\Temp\AndroidApp1\AndroidApp1\Resources\values\ids.xml(2): error APT0000: <item> must have a 'type' attribute.
1>C:\Temp\AndroidApp1\AndroidApp1\Resources\values\ids.xml : error APT0000: file failed to compile.

Rebuilding the solution with Build > Rebuild Solution after either step 3 or step 7 produces this correct result.

Setting $(AndroidUseAapt2) to false also leads to the correct result.

Actual behavior

The build succeeds.

Out of curiosity, I tried a quick experiment where I set $(AndroidUseManagedDesignTimeResourceGenerator) to false and repeated the steps. That did not change this particular behavior.

Version information

Xamarin.Android SDK 9.4.0.34 (d16-2/7cce305)

Microsoft Visual Studio Enterprise 2019 Int Preview
Version 16.2.0 Preview 4.0 [29027.242.d16.2stg]
VisualStudio.16.IntPreview/16.2.0-pre.4.0+29027.242.d16.2stg
Microsoft .NET Framework
Version 4.8.03752

Log file

MSBuildBinlogs.zip

@brendanzagaeski brendanzagaeski added bug Component does not function as intended. Area: App+Library Build Issues when building Library projects or Application projects. labels Jul 9, 2019
@brendanzagaeski brendanzagaeski added this to the Under Consideration milestone Jul 9, 2019
@jonathanpeppers
Copy link
Member

jonathanpeppers commented Jul 16, 2019

Ugh, I could only repro this in a test with 3 steps...

[Test]
public void InvalidAndroidResource ([Values (true, false)] bool useAapt2)
{
	var invalidXml = new AndroidItem.AndroidResource (@"Resources\values\ids.xml") {
		TextContent = () => "<?xml version=\"1.0\" encoding=\"utf-8\" ?><resources><item/></resources>"
	};

	var proj = new XamarinAndroidApplicationProject ();
	proj.SetProperty ("AndroidUseAapt2", useAapt2.ToString ());
	using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) {
		b.ThrowOnBuildFailure = false;

		proj.OtherBuildItems.Add (invalidXml);
		Assert.IsFalse (b.Build (proj), "Build should *not* have succeeded.");

		proj.OtherBuildItems.Remove (invalidXml);
		Assert.IsTrue (b.Build (proj), "Build should have succeeded.");

		proj.OtherBuildItems.Add (invalidXml);
		Assert.IsFalse (b.Build (proj), "Build should *not* have succeeded.");
	}
}

aapt1 works, and I had to specifically do things in this order to see the problem...

The issue seems to be:

Skipping target "_CompileResources" because all output files are up-to-date with respect to the input files.
Input files: Resources\values\ids.xml;Resources\drawable-hdpi\Icon.png;Resources\drawable-mdpi\Icon.png;Resources\drawable-xhdpi\Icon.png;Resources\drawable-xxhdpi\Icon.png;Resources\drawable-xxxhdpi\Icon.png;Resources\layout\Main.axml;Resources\values\Strings.xml
Output files: obj\Debug\flata\\_CompileResources.stamp

But _UpdateAndroidResgen runs:

Building target "_UpdateAndroidResgen" completely.
Input file "C:\src\xamarin-android\bin\TestDebug\temp\InvalidAndroidResourceTrue\obj\Debug\res\values\ids.xml" is newer than output file "obj\Debug\R.cs.flag".

jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Jul 16, 2019
Fixes: dotnet#3336

@brendanzagaeski found a really weird bug:

1. Build a project with aapt2 with an invalid XML file.
2. Remove the file from the project, build again.
3. Add the file back, build a third time.

On step 3 & beyond, no build error is given--meaning *something* must
be out of date.

I was able to reproduce the problem in a test, and saw it only occurs
with aapt2.

The `_CompileResources` MSBuild target was skipped:

    Skipping target "_CompileResources" because all output files are up-to-date with respect to the input files.
    Input files: Resources\values\ids.xml;Resources\drawable-hdpi\Icon.png;Resources\drawable-mdpi\Icon.png;Resources\drawable-xhdpi\Icon.png;Resources\drawable-xxhdpi\Icon.png;Resources\drawable-xxxhdpi\Icon.png;Resources\layout\Main.axml;Resources\values\Strings.xml
    Output files: obj\Debug\flata\\_CompileResources.stamp

But `_UpdateAndroidResgen` was *not* skipped:

    Building target "_UpdateAndroidResgen" completely.
    Input file "C:\src\xamarin-android\bin\TestDebug\temp\InvalidAndroidResourceTrue\obj\Debug\res\values\ids.xml" is newer than output file "obj\Debug\R.cs.flag".

Reviewing the `Inputs` of `_CompileResources`, it seems like we need
to include the following files to better match `_UpdateAndroidResgen`:

* `$(MSBuildAllProjects)` - so if the `.csproj` changes.
* `$(_AndroidBuildPropertiesCache)` - so if any of the important
  Xamarin.Android MSBuild properties change.

After adding these `Inputs`, I also had to add a `Condition` to skip
the `_CompileResources` target entirely if `@(AndroidResource)` was
blank. Otherwise projects like `Xamarin.Android.NUnitLite` did not
build. This was skipping before because the `Inputs` were empty.
jonathanpeppers added a commit that referenced this issue Jul 17, 2019
Fixes: #3336

@brendanzagaeski found a really weird bug:

1. Build a project with aapt2 with an invalid XML file.
2. Remove the file from the project, build again.
3. Add the file back, build a third time.

On step 3 & beyond, no build error is given--meaning *something* must
be out of date.

I was able to reproduce the problem in a test, and saw it only occurs
with aapt2.

The `_CompileResources` MSBuild target was skipped:

    Skipping target "_CompileResources" because all output files are up-to-date with respect to the input files.
    Input files: Resources\values\ids.xml;Resources\drawable-hdpi\Icon.png;Resources\drawable-mdpi\Icon.png;Resources\drawable-xhdpi\Icon.png;Resources\drawable-xxhdpi\Icon.png;Resources\drawable-xxxhdpi\Icon.png;Resources\layout\Main.axml;Resources\values\Strings.xml
    Output files: obj\Debug\flata\\_CompileResources.stamp

But `_UpdateAndroidResgen` was *not* skipped:

    Building target "_UpdateAndroidResgen" completely.
    Input file "C:\src\xamarin-android\bin\TestDebug\temp\InvalidAndroidResourceTrue\obj\Debug\res\values\ids.xml" is newer than output file "obj\Debug\R.cs.flag".

Reviewing the `Inputs` of `_CompileResources`, it seems like we need
to include the following files to better match `_UpdateAndroidResgen`:

* `$(MSBuildAllProjects)` - so if the `.csproj` changes.
* `$(_AndroidBuildPropertiesCache)` - so if any of the important
  Xamarin.Android MSBuild properties change.

After adding these `Inputs`, I also had to add a `Condition` to skip
the `_CompileResources` target entirely if `@(AndroidResource)` was
blank. Otherwise projects like `Xamarin.Android.NUnitLite` did not
build. This was skipping before because the `Inputs` were empty.
jonpryor pushed a commit that referenced this issue Jul 22, 2019
Fixes: #3336

@brendanzagaeski found a really weird bug:

1. Build a project with aapt2 with an invalid XML file.
2. Remove the file from the project, build again.
3. Add the file back, build a third time.

On step 3 & beyond, no build error is given--meaning *something* must
be out of date.

I was able to reproduce the problem in a test, and saw it only occurs
with aapt2.

The `_CompileResources` MSBuild target was skipped:

    Skipping target "_CompileResources" because all output files are up-to-date with respect to the input files.
    Input files: Resources\values\ids.xml;Resources\drawable-hdpi\Icon.png;Resources\drawable-mdpi\Icon.png;Resources\drawable-xhdpi\Icon.png;Resources\drawable-xxhdpi\Icon.png;Resources\drawable-xxxhdpi\Icon.png;Resources\layout\Main.axml;Resources\values\Strings.xml
    Output files: obj\Debug\flata\\_CompileResources.stamp

But `_UpdateAndroidResgen` was *not* skipped:

    Building target "_UpdateAndroidResgen" completely.
    Input file "C:\src\xamarin-android\bin\TestDebug\temp\InvalidAndroidResourceTrue\obj\Debug\res\values\ids.xml" is newer than output file "obj\Debug\R.cs.flag".

Reviewing the `Inputs` of `_CompileResources`, it seems like we need
to include the following files to better match `_UpdateAndroidResgen`:

* `$(MSBuildAllProjects)` - so if the `.csproj` changes.
* `$(_AndroidBuildPropertiesCache)` - so if any of the important
  Xamarin.Android MSBuild properties change.

After adding these `Inputs`, I also had to add a `Condition` to skip
the `_CompileResources` target entirely if `@(AndroidResource)` was
blank. Otherwise projects like `Xamarin.Android.NUnitLite` did not
build. This was skipping before because the `Inputs` were empty.
jonpryor pushed a commit that referenced this issue Jul 22, 2019
Fixes: #3336

@brendanzagaeski found a really weird bug:

1. Build a project with aapt2 with an invalid XML file.
2. Remove the file from the project, build again.
3. Add the file back, build a third time.

On step 3 & beyond, no build error is given--meaning *something* must
be out of date.

I was able to reproduce the problem in a test, and saw it only occurs
with aapt2.

The `_CompileResources` MSBuild target was skipped:

    Skipping target "_CompileResources" because all output files are up-to-date with respect to the input files.
    Input files: Resources\values\ids.xml;Resources\drawable-hdpi\Icon.png;Resources\drawable-mdpi\Icon.png;Resources\drawable-xhdpi\Icon.png;Resources\drawable-xxhdpi\Icon.png;Resources\drawable-xxxhdpi\Icon.png;Resources\layout\Main.axml;Resources\values\Strings.xml
    Output files: obj\Debug\flata\\_CompileResources.stamp

But `_UpdateAndroidResgen` was *not* skipped:

    Building target "_UpdateAndroidResgen" completely.
    Input file "C:\src\xamarin-android\bin\TestDebug\temp\InvalidAndroidResourceTrue\obj\Debug\res\values\ids.xml" is newer than output file "obj\Debug\R.cs.flag".

Reviewing the `Inputs` of `_CompileResources`, it seems like we need
to include the following files to better match `_UpdateAndroidResgen`:

* `$(MSBuildAllProjects)` - so if the `.csproj` changes.
* `$(_AndroidBuildPropertiesCache)` - so if any of the important
  Xamarin.Android MSBuild properties change.

After adding these `Inputs`, I also had to add a `Condition` to skip
the `_CompileResources` target entirely if `@(AndroidResource)` was
blank. Otherwise projects like `Xamarin.Android.NUnitLite` did not
build. This was skipping before because the `Inputs` were empty.
@brendanzagaeski
Copy link
Contributor Author

Release status update

A new Release version has now been published that includes the fix for this item.

Fix included in Xamarin.Android 10.0.0.43

Fix included on Windows in Visual Studio 2019 version 16.3. To get the new version that includes the fix, check for the latest updates or install the latest version from https://visualstudio.microsoft.com/downloads/.

Fix included on macOS in Visual Studio 2019 for Mac version 8.3. To get the new version that includes the fix, check for the latest updates on the Stable updater channel.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Area: App+Library Build Issues when building Library projects or Application projects. bug Component does not function as intended.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants