Skip to content

Commit 5ed6afb

Browse files
committed
Merge branch 'main' into dev/grendel/blazor-hang
* main: [ci] Use managed identity for ApiScan (#8823) [Xamarin.Android.Build.Tasks] DTBs should not rm generator output (#8706) [Xamarin.Android.Build.Tasks] Bump to NuGet 6.7.1 (#8833) $(AndroidPackVersionSuffix)=preview.4; net9 is 34.99.0.preview.4 (#8831) Localized file check-in by OneLocBuild Task (#8824) [Xamarin.Android.Build.Tasks] Enable POM verification features. (#8649) [runtime] Optionally disable inlining (#8798) Fix assembly count when satellite assemblies are present (#8790) [One .NET] new "greenfield" projects are trimmed by default (#8805) Localized file check-in by OneLocBuild Task (#8819) LEGO: Merge pull request 8820 LEGO: Merge pull request 8818 Bump to dotnet/installer@b40c44502d 9.0.100-preview.3.24165.20 (#8817) Bump com.android.tools:r8 from 8.2.47 to 8.3.37 (#8816) [Mono.Android] Prevent NullPointerException in TranslateStackTrace (#8795) Localized file check-in by OneLocBuild Task (#8815) [Xamarin.Android.Build.Tasks] Make all assemblies RID-specific (#8478) Localized file check-in by OneLocBuild Task (#8813)
2 parents bad8d15 + 9884bd0 commit 5ed6afb

File tree

241 files changed

+9314
-3671
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

241 files changed

+9314
-3671
lines changed

Directory.Build.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
* Bump first digit of the patch version for feature releases (and reset the first two digits to 0)
3737
-->
3838
<AndroidPackVersion>34.99.0</AndroidPackVersion>
39-
<AndroidPackVersionSuffix>preview.3</AndroidPackVersionSuffix>
39+
<AndroidPackVersionSuffix>preview.4</AndroidPackVersionSuffix>
4040
</PropertyGroup>
4141

4242
<!-- Common <PackageReference/> versions -->
@@ -48,7 +48,7 @@
4848
<NuGetApiPackageVersion>5.4.0</NuGetApiPackageVersion>
4949
<LZ4PackageVersion>1.1.11</LZ4PackageVersion>
5050
<MonoOptionsVersion>6.12.0.148</MonoOptionsVersion>
51-
<SystemCollectionsImmutableVersion>6.0.0</SystemCollectionsImmutableVersion>
51+
<SystemCollectionsImmutableVersion>8.0.0</SystemCollectionsImmutableVersion>
5252
<SystemRuntimeCompilerServicesUnsafeVersion>6.0.0</SystemRuntimeCompilerServicesUnsafeVersion>
5353
<ELFSharpVersion>2.13.1</ELFSharpVersion>
5454
<HumanizerVersion>2.14.1</HumanizerVersion>

Documentation/building/configuration.md

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
<!--toc:start-->
2+
- [Build Configuration](#build-configuration)
3+
- [Options suitable to use in builds for public use](#options-suitable-to-use-in-builds-for-public-use)
4+
- [Options suitable for local development](#options-suitable-for-local-development)
5+
- [Native runtime (`src/monodroid`)](#native-runtime-srcmonodroid)
6+
- [Disable function inlining](#disable-function-inlining)
7+
- [Don't strip the runtime shared libraries](#dont-strip-the-runtime-shared-libraries)
8+
<!--toc:end-->
9+
110
# Build Configuration
211

312
The Xamarin.Android build is heavily dependent on MSBuild, with the *intention*
@@ -10,6 +19,8 @@ However, some properties may need to be altered in order to suit your
1019
requirements, such as the location of a cache directory to store
1120
the Android SDK and NDK.
1221

22+
## Options suitable to use in builds for public use
23+
1324
To modify the build process, copy
1425
[`Configuration.Override.props.in`](../../Configuration.Override.props.in)
1526
to `Configuration.Override.props`, and edit the file as appropriate.
@@ -93,7 +104,7 @@ Overridable MSBuild properties include:
93104

94105
* `$(IgnoreMaxMonoVersion)`: Skip the enforcement of the `$(MonoRequiredMaximumVersion)`
95106
property. This is so that developers can run against the latest
96-
and greatest. But the build system can enforce the min and max
107+
and greatest. But the build system can enforce the min and max
97108
versions. The default is `true`, however on CI we use:
98109

99110
/p:IgnoreMaxMonoVersion=False
@@ -129,6 +140,43 @@ Overridable MSBuild properties include:
129140
* `4`: Mono 4.6 support.
130141
* `5`: Mono 4.8 and above support. This is the default.
131142

132-
* `$(AndroidEnableAssemblyCompression)`: Defaults to `True`. When enabled, all the
143+
* `$(AndroidEnableAssemblyCompression)`: Defaults to `True`. When enabled, all the
133144
assemblies placed in the APK will be compressed in `Release` builds. `Debug`
134145
builds are not affected.
146+
147+
## Options suitable for local development
148+
149+
### Native runtime (`src/monodroid`)
150+
151+
Note that in order for the native build settings to have full effect, one needs to make sure that
152+
the entire native runtime is rebuilt **and** that all `cmake` files are regenerated. This is true
153+
on the very first build, but rebuilds may require forcing the entire runtime to be rebuilt.
154+
155+
The simplest way to do it is to remove `src/monodroid/obj` and run the usual build from the
156+
repository's root directory.
157+
158+
#### Disable function inlining
159+
160+
The native runtime by default builds with function inlining enabled, making heavy use of
161+
the feature in order to generate faster code. However, when debugging a native crash inlining
162+
causes stack traces to point to unlikely locations, reporting the outer function as the crash
163+
location instead of the inlined function where crash actually happened. There are two ways to
164+
enable this mode of operation:
165+
166+
1. Export the `XA_NO_INLINE` environment variable before building either the entire repository
167+
or just `src/monodroid/`
168+
2. Set the MSBuild property `DoNotInlineMonodroid` to `true`, when building `src/monodroid/monodroid.csproj`
169+
170+
Doing either will force all normally inlined functions to be strictly preserved and kept
171+
separate. The generated code will be slower, but crash stack traces should be much more precise.
172+
173+
#### Don't strip the runtime shared libraries
174+
175+
Similar to the previous section, this option makes crash stack traces more informative. In normal
176+
builds, all the debugging information is stripped from the runtime shared libraries, thus making
177+
stack traces rarely point to anything more than the surrounding function name (which may sometimes
178+
be misleading, too). Just as for inlining, the no-strip mode can be enabled with one of two ways:
179+
180+
1. Export the `XA_NO_STRIP` environment variable before building either the entire repository
181+
or just `src/monodroid/`
182+
2. Set the MSBuild property `DoNotStripMonodroid` to `true`, when building `src/monodroid/monodroid.csproj`

Documentation/guides/AndroidMavenLibrary.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ Note: This feature is only available in .NET 9+.
1717
</ItemGroup>
1818
```
1919

20-
This will do two things at build time:
20+
This will do several things at build time:
2121
- Download the Java [artifact](https://central.sonatype.com/artifact/com.squareup.okhttp3/okhttp/4.9.3) with group id `com.squareup.okhttp3`, artifact id `okhttp`, and version `4.9.3` from [Maven Central](https://central.sonatype.com/) to a local cache (if not already cached).
2222
- Add the cached package to the .NET Android bindings build as an [`<AndroidLibrary>`](https://github.com/xamarin/xamarin-android/blob/main/Documentation/guides/building-apps/build-items.md#androidlibrary).
23+
- Download the Java artifact's POM file (and any needed parent/imported POM files) to enable [Java Dependency Verification](JavaDependencyVerification.md). To opt out of this feature, add `VerifyDependencies="false"` to the `<AndroidMavenLibrary>` item.
2324

2425
Note that only the requested Java artifact is added to the .NET Android bindings build. Any artifact dependencies are not added. If the requested artifact has dependencies, they must be fulfilled individually.
2526

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# Java Dependency Verification
2+
3+
Note: This feature is only available in .NET 9+.
4+
5+
## Description
6+
7+
A common problem when creating Java binding libraries for .NET Android is not providing the required Java dependencies. The binding process ignores API that requires missing dependencies, so this can result in large portions of desired API not being bound.
8+
9+
Unlike .NET assemblies, a Java library does not specify its dependencies in the package. The dependency information is stored in external files called POM files. In order to consume this information to ensure correct dependencies an additional layer of files must be added to a binding project.
10+
11+
Note: the preferred way of interacting with this system is to use [`<AndroidMavenLibrary>`](AndroidMavenLibrary.md) which will automatically download any needed POM files.
12+
13+
For example:
14+
15+
```xml
16+
<AndroidMavenLibrary Include="com.squareup.okio:okio" Version="1.17.4" />
17+
```
18+
19+
automatically gets expanded to:
20+
21+
```xml
22+
<AndroidLibrary
23+
Include="<MavenCacheDir>/Central/com.squareup.okio/okio/1.17.4/com.squareup.okio_okio.jar"
24+
Manifest="<MavenCacheDir>/Central/com.squareup.okio/okio/1.17.4/com.squareup.okio_okio.pom"
25+
JavaArtifact="com.squareup.okio:okio"
26+
JavaVersion="1.17.4" />
27+
28+
<AndroidAdditionalJavaManifest
29+
Include="<MavenCacheDir>/Central/com.squareup.okio/okio-parent/1.17.4/okio-parent-1.17.4.pom"
30+
JavaArtifact="com.squareup.okio:okio-parent"
31+
JavaVersion="1.17.4" />
32+
33+
etc.
34+
```
35+
36+
However it is also possible to manually opt in to Java dependency verification using the build items documented here.
37+
38+
## Specification
39+
40+
To manually opt in to Java dependency verification, add the `Manifest`, `JavaArtifact`, and `JavaVersion` attributes to an `<AndroidLibrary>` item:
41+
42+
```xml
43+
<!-- JavaArtifact format is {GroupId}:{ArtifactId} -->
44+
<ItemGroup>
45+
<AndroidLibrary
46+
Include="my_binding_library.jar"
47+
Manifest="my_binding_library.pom"
48+
JavaArtifact="com.example:mybinding"
49+
JavaVersion="1.0.0" />
50+
</ItemGroup>
51+
```
52+
53+
Building the binding project now should result in verification errors if `my_binding_library.pom` specifies dependencies that are not met.
54+
55+
For example:
56+
57+
```
58+
error : Java dependency 'androidx.collection:collection' version '1.0.0' is not satisfied.
59+
```
60+
61+
Seeing these error(s) or no errors should indicate that the Java dependency verification is working. Follow the [Resolving Java Dependencies](ResolvingJavaDependencies.md) guide to fix any missing dependency errors.
62+
63+
## Additional POM Files
64+
65+
POM files can sometimes have some optional features in use that make them more complicated than the above example.
66+
67+
That is, a POM file can depend on a "parent" POM file:
68+
69+
```xml
70+
<parent>
71+
<groupId>com.squareup.okio</groupId>
72+
<artifactId>okio-parent</artifactId>
73+
<version>1.17.4</version>
74+
</parent>
75+
```
76+
77+
Additionally, a POM file can "import" dependency information from another POM file:
78+
79+
```xml
80+
<dependencyManagement>
81+
<dependencies>
82+
<dependency>
83+
<groupId>com.squareup.okio</groupId>
84+
<artifactId>okio-bom</artifactId>
85+
<version>3.0.0</version>
86+
<type>pom</type>
87+
<scope>import</scope>
88+
</dependency>
89+
</dependencies>
90+
</dependencyManagement>
91+
```
92+
93+
Dependency information cannot be accurately determined without also having access to these additional POM files, and will results in an error like:
94+
95+
```
96+
error : Unable to resolve POM for artifact 'com.squareup.okio:okio-parent:1.17.4'.
97+
```
98+
99+
In this case, we need to provide the POM file for `com.squareup.okio:okio-parent:1.17.4`:
100+
101+
```xml
102+
<!-- JavaArtifact format is {GroupId}:{ArtifactId} -->
103+
<ItemGroup>
104+
<AndroidAdditionalJavaManifest
105+
Include="com.square.okio.okio-parent.1.17.4.pom"
106+
JavaArtifact="com.squareup.okio:okio-parent"
107+
JavaVersion="1.17.4" />
108+
</ItemGroup>
109+
```
110+
111+
Note that as "Parent" and "Import" POMs can themselves have parent and imported POMs, this step may need to be repeated until all POM files can be resolved.
112+
113+
Note also that if using `<AndroidMavenLibrary>` this should all be handled automatically.
114+
115+
At this point, if there are dependency errors, follow the [Resolving Java Dependencies](ResolvingJavaDependencies.md) guide to fix any missing dependency errors.
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Resolving Java Dependencies
2+
3+
Note: This feature is only available in .NET 9+.
4+
5+
## Description
6+
7+
Once Java dependency verification has been enabled for a bindings project, either automatically via `<AndroidMavenLibrary>` or manually via `<AndroidLibrary>`, there may be errors to resolve, such as:
8+
9+
```
10+
error : Java dependency 'androidx.collection:collection' version '1.0.0' is not satisfied.
11+
```
12+
13+
These dependencies can be fulfilled in many different ways.
14+
15+
## `<PackageReference>`
16+
17+
In the best case scenario, there is already an existing binding of the Java dependency available on NuGet.org. This package may be provided by Microsoft or the .NET community. Packages maintained by Microsoft may be surfaced in the error message like this:
18+
19+
```
20+
error : Java dependency 'androidx.collection:collection' version '1.0.0' is not satisfied. Microsoft maintains the NuGet package 'Xamarin.AndroidX.Collection' that could fulfill this dependency.
21+
```
22+
23+
Adding the `Xamarin.AndroidX.Collection` package to the project should automatically resolve this error, as the package provides metadata to advertise that it provides the `androidx.collection:collection` dependency. This is done by looking for a specially crafted NuGet tag. For example, for the AndroidX Collection library, the tag looks like this:
24+
25+
```xml
26+
<!-- artifact={GroupId}:{ArtifactId}:{Java Library Version} -->
27+
<PackageTags>artifact=androidx.collection:collection:1.0.0</PackageTags>
28+
```
29+
30+
However there may be NuGet packages which fulfill a dependency but have not had this metadata added to it. In this case, you will need to explicitly specify which dependency the package contains with `JavaArtifact` and `JavaVersion`:
31+
32+
```xml
33+
<PackageReference
34+
Include="Xamarin.Kotlin.StdLib"
35+
Version="1.7.10"
36+
JavaArtifact="org.jetbrains.kotlin:kotlin-stdlib"
37+
JavaVersion="1.7.10" />
38+
```
39+
40+
With this, the binding process knows the Java dependency is satisfied by the NuGet package.
41+
42+
> Note: NuGet packages specify their own dependencies, so you will not need to worry about transitive dependencies.
43+
44+
## `<ProjectReference>`
45+
46+
If the needed Java dependency is provided by another project in your solution, you can annotate the `<ProjectReference>` to specify the dependency it fulfills:
47+
48+
```xml
49+
<ProjectReference
50+
Include="..\My.Other.Binding\My.Other.Binding.csproj"
51+
JavaArtifact="my.other.binding:helperlib"
52+
JavaVersion="1.0.0" />
53+
```
54+
55+
With this, the binding process knows the Java dependency is satisfied by the referenced project.
56+
57+
> Note: Each project specifies their own dependencies, so you will not need to worry about transitive dependencies.
58+
59+
## `<AndroidLibrary>`
60+
61+
If you are creating a public NuGet package, you will want to follow NuGet's "one library per package" policy so that the NuGet dependency graph works. However, if creating a binding for private use, you may want to include your Java dependencies directly inside the parent binding.
62+
63+
This can be done by adding additional `<AndroidLibrary>` items to the project:
64+
65+
```xml
66+
<ItemGroup>
67+
<AndroidLibrary Include="mydependency.jar" JavaArtifact="my.library:dependency-library" JavaVersion="1.0.0" />
68+
</ItemGroup>
69+
```
70+
71+
To include the Java library but not produce C# bindings for it, mark it with `Bind="false"`:
72+
73+
```xml
74+
<ItemGroup>
75+
<AndroidLibrary Include="mydependency.jar" JavaArtifact="my.library:dependency-library" JavaVersion="1.0.0" Bind="false" />
76+
</ItemGroup>
77+
```
78+
79+
Alternatively, `<AndroidMavenLibrary>` can be used to retrieve a Java library from a Maven repository:
80+
81+
```xml
82+
<ItemGroup>
83+
<AndroidMavenLibrary Include="my.library:dependency-library" Version="1.0.0" />
84+
<!-- or, if the Java library doesn't need to be bound -->
85+
<AndroidMavenLibrary Include="my.library:dependency-library" Version="1.0.0" Bind="false" />
86+
</ItemGroup>
87+
```
88+
89+
> Note: If the dependency library has its own dependencies, you will be required to ensure they are fulfilled.
90+
91+
## `<AndroidIgnoredJavaDependency>`
92+
93+
As a last resort, a needed Java dependency can be ignored. An example of when this is useful is if the dependency library is a collection of Java annotations that are only used at compile type and not runtime.
94+
95+
Note that while the error message will go away, it does not mean the package will magically work. If the dependency is actually needed at runtime and not provided the Android application will crash with a `Java.Lang.NoClassDefFoundError` error.
96+
97+
```xml
98+
<ItemGroup>
99+
<AndroidIgnoredJavaDependency Include="com.google.errorprone:error_prone_annotations" Version="2.15.0" />
100+
</ItemGroup>
101+
```

0 commit comments

Comments
 (0)