Skip to content

Commit

Permalink
Merge branch 'main' into native-code-classic-cleanup
Browse files Browse the repository at this point in the history
* main:
  [Xamarin.Android.Build.Tasks] Improve aapt2+file not found handling (dotnet#7644)
  [MSBuildDeviceIntegration] Fix duplicated test parameter (dotnet#7809)
  • Loading branch information
grendello committed Feb 21, 2023
2 parents c054a00 + 37a1758 commit 7ead601
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 4 deletions.
1 change: 1 addition & 0 deletions Documentation/guides/messages/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ ms.date: 01/24/2020
+ APT0002: Invalid file name: It must contain only \[^a-zA-Z0-9_.-\]+.
+ APT0003: Invalid file name: It must contain only \[^a-zA-Z0-9_.\]+.
+ APT0004: Invalid file name: It must start with either A-Z or a-z or an underscore.
+ [APT2264](apt2264.md): The system cannot find the file specified. (2).

## JAVAxxxx: Java Tool

Expand Down
58 changes: 58 additions & 0 deletions Documentation/guides/messages/apt2264.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
title: Xamarin.Android error APT2264
description: APT2264 error code
ms.date: 12/16/2022
---
# Xamarin.Android error APT2264

## Issue

The tool `aapt2` is unable to resolve one of the files it was passed.
This is generally caused by the path being longer than the Maximum Path
length allowed on windows.

## Solution

The best way to avoid this is to ensure that your project is not located
deep in the folder structure. For example if you create all of your
projects in folders such as

`C:\Users\shelly\Visual Studio\Android\MyProjects\Com.SomeReallyLongCompanyName.MyBrillantApplication\MyBrilliantApplicaiton.Android\`

you may well encounter problems with not only `aapt2` but also Ahead of Time
compilation. Keeping your project names and folder structures short and
concise will help work around these issues. For example instead of the above
you could use

`C:\Work\Android\MyBrilliantApp`

Which is much shorter and much less likely to encounter path issues.

However this is no always possible. Sometimes a project or a environment requires
deep folder structures. In this case enabling long path support in Windows *might*
be enough to get your project working. Details on how to do this can be found
[here](https://learn.microsoft.com/windows/win32/fileio/maximum-file-path-limitation?tabs=registry#enable-long-paths-in-windows-10-version-1607-and-later).


If long path support does not work changing the location of the
`$(BaseIntermediateOutputPath)` can help solve these problems. In order for this
to work the setting MUST be changed before ANY build or restore occurs. To do this
you can make use of the MSBuild `Directory.Build.props` support.

Creating a `Directory.Build.props` file in your solution or project directory which
redefines the `$(BaseIntermediateOutputPath)` to somewhere nearer the root of the drive
with solve these issues. Adding a file with the following contents will create the `obj`
directory in a different location of your choosing.

```
<Project>
<PropertyGroup>
<BaseIntermediateOutputPath Condition=" '$(OS)' == 'Windows_NT' ">C:\Intermediate\$(ProjectName)</BaseIntermediateOutputPath>
<BaseIntermediateOutputPath Condition=" '$(OS)' != 'Windows_NT' ">/tmp/Intermediate/$(ProjectName)</BaseIntermediateOutputPath>
</PropertyGroup>
</Project
```

Using this technique will reduce the lengths of the paths sent to the various tools like `aapt2`.
Note this is generally only a Windows issue. So there is no need to override the `$(BaseIntermediateOutputPath)`
on Mac or Linux based environments. However you might want to override everywhere to be consistent.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/Xamarin.Android.Build.Tasks/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,10 @@ Please change the value to an assembly-qualifed type name which inherits from '{
<comment>The following are literal names and should not be translated: Java.Interop.DoNotPackageAttribute
{0} - The assembly name</comment>
</data>
<data name="APT2264" xml:space="preserve">
<value>This is probably caused by the project exceeding the Windows maximum path length limitation. See https://learn.microsoft.com/xamarin/android/errors-and-warnings/apt2264 for details.</value>
<comment>The following are literal names and should not be translated:</comment>
</data>
<data name="XA3001" xml:space="preserve">
<value>Could not AOT the assembly: {0}</value>
<comment>The abbreviation "AOT" should not be translated.</comment>
Expand Down
22 changes: 19 additions & 3 deletions src/Xamarin.Android.Build.Tasks/Tasks/Aapt2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,23 +188,38 @@ protected bool LogAapt2EventsFromOutput (string singleLine, MessageImportance me
message = message.Substring ("error: ".Length);

if (level.Contains ("error") || (line != 0 && !string.IsNullOrEmpty (file))) {
var errorCode = GetErrorCode (message);
if (manifestError)
LogCodedError (GetErrorCode (message), string.Format (Xamarin.Android.Tasks.Properties.Resources.AAPTManifestError, message.TrimEnd('.')), AndroidManifestFile.ItemSpec, 0);
LogCodedError (errorCode, string.Format (Xamarin.Android.Tasks.Properties.Resources.AAPTManifestError, message.TrimEnd('.')), AndroidManifestFile.ItemSpec, 0);
else
LogCodedError (GetErrorCode (message), message, file, line);
LogCodedError (errorCode, AddAdditionalErrorText (errorCode, message), file, line);
return true;
}
}

if (!apptResult) {
var message = string.Format ("{0} \"{1}\".", singleLine.Trim (), singleLine.Substring (singleLine.LastIndexOfAny (new char [] { '\\', '/' }) + 1));
LogCodedError (GetErrorCode (message), message, ToolName);
var errorCode = GetErrorCode (message);
LogCodedError (errorCode, AddAdditionalErrorText (errorCode, message), ToolName);
} else {
LogCodedWarning (GetErrorCode (singleLine), singleLine);
}
return true;
}

static string AddAdditionalErrorText (string errorCode, string message)
{
var sb = new StringBuilder ();
sb.AppendLine (message);
switch (errorCode)
{
case "APT2264":
sb.AppendLine (Xamarin.Android.Tasks.Properties.Resources.APT2264);
break;
}
return sb.ToString ();
}

static string GetErrorCode (string message)
{
foreach (var tuple in error_codes)
Expand Down Expand Up @@ -478,6 +493,7 @@ static string GetErrorCode (string message)
Tuple.Create ("APT2261", "file failed to compile"),
Tuple.Create ("APT2262", "unexpected element <activity> found in <manifest>"),
Tuple.Create ("APT2263", "found in <manifest>"), // unexpected element <xxxxx> found in <manifest>
Tuple.Create ("APT2264", "The system cannot find the file specified. (2).") // Windows Long Path error from aapt2
};
}
}
2 changes: 1 addition & 1 deletion tests/MSBuildDeviceIntegration/Tests/XASdkDeployTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public class XASdkDeployTests : DeviceTest
new object[] {
/* isRelease */ true,
/* xamarinForms */ false,
/* targetFramework*/ "net8.0-android",
/* targetFramework*/ "net7.0-android",
},
new object[] {
/* isRelease */ false,
Expand Down

0 comments on commit 7ead601

Please sign in to comment.