|
1 | 1 | # Copilot Instructions for .NET Android Libraries Repository |
2 | 2 |
|
3 | | -**Note**: Always update `copilot-instructions.md` with new/relevant information to keep GitHub Copilot suggestions current and accurate. |
| 3 | +**Note**: Update this file with new learnings to keep suggestions accurate. |
4 | 4 |
|
5 | 5 | ## Repository Overview |
6 | 6 |
|
7 | | -This repository creates and maintains .NET for Android bindings for Google's Java/Kotlin Android libraries, including: |
8 | | -- AndroidX libraries (600+ packages) |
9 | | -- Google Play Services |
10 | | -- Firebase |
11 | | -- ML Kit |
12 | | -- Various third-party dependencies |
| 7 | +Creates .NET for Android bindings for Google's Java/Kotlin libraries (AndroidX, Play Services, Firebase, ML Kit, etc.) using a **config-driven approach** with `config.json` and the "binderator" tool. |
13 | 8 |
|
14 | | -The repository uses a **config-driven approach** where all bindings are defined in `config.json` and automatically generated using the "binderator" tool. |
| 9 | +## Key Files & Directories |
| 10 | +- **`config.json`**: Master config for 600+ Maven artifacts → NuGet packages. Update via `dotnet cake --target=update-config` or `bump-config`, not manually. |
| 11 | +- **`build.cake`**: Main Cake build script |
| 12 | +- **`source/{groupId}/{artifactId}/`**: Binding customizations (Additions/, Transforms/, Metadata.xml) |
| 13 | +- **`generated/`**: Auto-generated projects (not in source control) |
| 14 | +- **`source/AssemblyInfo.cs`**: **DO NOT EDIT** - contains placeholder tokens |
15 | 15 |
|
16 | | -## Key Architecture Components |
17 | | - |
18 | | -### Core Files |
19 | | -- **`config.json`**: Master configuration containing all 600+ Maven artifacts to bind, their versions, and NuGet package information |
20 | | -- **`build.cake`**: Main Cake build script orchestrating the entire build process |
21 | | -- **`BUILDING.md`**: Comprehensive build instructions and prerequisites |
22 | | -- **`source/AssemblyInfo.cs`**: Contains build metadata placeholders that are replaced during the build process. **DO NOT EDIT** this file or modify the placeholder tokens - always revert any changes to maintain the original placeholder format. |
23 | | - |
24 | | - |
25 | | -### Directory Structure |
26 | | -- **`source/`**: Contains binding customizations organized by Maven groupId (e.g., `androidx.core`, `com.google.android.gms`) and Razor templates (`.cshtml` files) |
27 | | -- **`util/Xamarin.AndroidBinderator/`**: The "binderator" tool that generates binding projects from config |
28 | | -- **`generated/`**: Auto-generated binding projects (created during build, not in source control) |
29 | | -- **`docs/`**: Additional documentation including artifact lists and development tips |
30 | | - |
31 | | -## Build System |
32 | | - |
33 | | -### Prerequisites |
34 | | -- a recent .NET SDK |
35 | | -- Cake .NET Tool: `dotnet tool install -g cake.tool` |
36 | | -- Microsoft OpenJDK 21 |
37 | | -- Android SDK and `$ANDROID_SDK_ROOT` environment variable |
38 | | -- Optional: `api-tools` for API diffs: `dotnet tool install -g api-tools` |
| 16 | +## Target Frameworks |
| 17 | +- `net9.0-android` (API 35) and `net10.0-android` (API 36) |
| 18 | +- Legacy Xamarin.Android support ended May 1, 2024 |
39 | 19 |
|
40 | | -### Common Build Commands |
| 20 | +## Common Build Commands |
41 | 21 | ```bash |
42 | | -# Full build of all packages |
43 | | -dotnet cake |
44 | | - |
45 | | -# Clean build for CI |
46 | | -dotnet cake -t=ci |
47 | | - |
48 | | -# Build specific target |
49 | | -dotnet cake --target=libs |
50 | | -dotnet cake --target=nuget |
51 | | -dotnet cake --target=packages |
52 | | - |
53 | | -# Update config to latest Maven versions |
54 | | -dotnet cake --target=update-config |
55 | | - |
56 | | -# Bump NuGet package versions (4th component) |
57 | | -dotnet cake --target=bump-config |
58 | | - |
59 | | -# Generate API differences |
60 | | -dotnet cake nuget-diff.cake |
61 | | - |
62 | | -# Run utilities (governance, mappings, etc.) |
63 | | -dotnet cake utilities.cake |
| 22 | +dotnet cake # Full build |
| 23 | +dotnet cake -t=ci # CI build |
| 24 | +dotnet cake --target=libs # Build libraries only |
| 25 | +dotnet cake --target=binderate # Regenerate projects from config |
| 26 | +dotnet cake --target=update-config # Update to latest Maven versions |
| 27 | +dotnet cake --target=bump-config # Increment NuGet revision (4th component) |
64 | 28 | ``` |
65 | 29 |
|
66 | | -## Configuration System |
67 | | - |
68 | | -### config.json Structure |
69 | | -**Note**: This file is normally updated using Cake build targets (`update-config`, `bump-config`) rather than manual editing. |
70 | | - |
71 | | -Each artifact entry contains: |
| 30 | +## config.json Entry Structure |
72 | 31 | ```json |
73 | 32 | { |
74 | 33 | "groupId": "androidx.activity", |
75 | 34 | "artifactId": "activity", |
76 | | - "version": "1.10.1", |
77 | | - "nugetVersion": "1.10.1.2", |
| 35 | + "version": "1.10.1", // Maven version |
| 36 | + "nugetVersion": "1.10.1.2", // 4th component for NuGet-only changes |
78 | 37 | "nugetId": "Xamarin.AndroidX.Activity", |
79 | | - "dependencyOnly": false // true for transitive deps only |
| 38 | + "dependencyOnly": false // true = transitive dep, no standalone package |
80 | 39 | } |
81 | 40 | ``` |
82 | 41 |
|
83 | | -### Version Conventions |
84 | | -- **Major.Minor.Patch**: Mirrors the Maven artifact version |
85 | | -- **Revision (4th component)**: Used for NuGet-only updates without Maven changes |
86 | | -- **Pre-release suffixes**: Supported (e.g., "1.0.0.1-alpha05") |
87 | | - |
88 | | -## Development Workflow |
89 | | - |
90 | | -### Adding New Bindings |
91 | | -1. Add artifact entry to `config.json` |
92 | | -2. Run `dotnet cake --target=binderate` to generate projects |
93 | | -3. Add any necessary customizations in `source/{groupId}/{artifactId}/` |
94 | | -4. Build and test: `dotnet cake --target=libs` |
95 | | - |
96 | | -### Updating Existing Bindings |
97 | | -1. Use `dotnet cake --target=update-config` for automatic updates |
98 | | -2. Or manually edit versions in `config.json` |
99 | | -3. Run `dotnet cake --target=binderate-diff` to see changes |
100 | | -4. Build and validate |
101 | | - |
102 | | -### Version Bumping |
103 | | -- Use `dotnet cake --target=bump-config` to increment revision numbers |
104 | | -- This updates only non-dependency packages (where `dependencyOnly != true`) |
105 | | - |
106 | | -### Release Process |
107 | | -1. Tag commit: `git tag YYYYMMDD-weekly-stable-updates-YYYYMMDD` |
108 | | -2. Push tag: `git push upstream <tag>` |
109 | | -3. Use AndroidX Push NuGet.org pipeline in Azure DevOps |
110 | | - |
111 | | -## Binding Customizations |
112 | | - |
113 | | -### Per-Artifact Customizations |
114 | | -Located in `source/{groupId}/{artifactId}/`: |
115 | | -- **`Additions/`**: Additional C# code to add to generated bindings |
116 | | -- **`Transforms/`**: XML transforms to modify generated API |
117 | | -- **`Metadata.xml`**: Binding metadata and parameter names |
118 | | -- **`merge.targets`**: Custom MSBuild targets to include |
| 42 | +## Binding Customizations (in `source/{groupId}/{artifactId}/`) |
| 43 | +- **`Additions/*.cs`**: Extra C# code added to bindings |
| 44 | +- **`Metadata.xml`**: Fix parameter names, remove problematic APIs |
| 45 | +- **`Transforms/`**: XML transforms for generated API |
| 46 | +- **`merge.targets`**: Custom MSBuild targets |
119 | 47 |
|
120 | 48 | ### Common Metadata Patterns |
121 | | -For comprehensive guidance on troubleshooting binding issues, see: https://github.com/dotnet/java-interop/wiki/Troubleshooting-Android-Bindings-Issues |
122 | | - |
123 | | -```xml |
124 | | -<!-- Remove problematic APIs --> |
125 | | -<remove-node path="/api/package[@name='com.example']/class[@name='ProblematicClass']" /> |
126 | | - |
127 | | -<!-- Fix parameter names --> |
128 | | -<attr path="/api/package[@name='com.example']/class[@name='Example']/method[@name='example']/parameter[@name='p0']" name="name">properName</attr> |
129 | | - |
130 | | -<!-- Add managed wrapper --> |
131 | | -<add-node path="/api/package[@name='com.example']"> |
132 | | - <class abstract="false" deprecated="not deprecated" final="false" name="ManagedWrapper" static="false" visibility="public"> |
133 | | - </class> |
134 | | -</add-node> |
135 | | -``` |
136 | | - |
137 | | -### Changing Package/Namespace Names |
138 | | - |
139 | | -To change the C# namespace for a Java package (e.g., fixing casing issues), use `Metadata.xml` with the `managedName` attribute. **Do NOT use `rootNamespace` metadata in config.json** - it does not work for namespace changes. |
140 | | - |
141 | | -Create `source/{groupId}/{artifactId}/Transforms/Metadata.xml`: |
142 | | - |
143 | 49 | ```xml |
144 | | -<metadata> |
145 | | - <!-- Fix namespace casing: androidx.navigationevent -> AndroidX.NavigationEvent --> |
146 | | - <attr |
147 | | - path="/api/package[@name='androidx.navigationevent']" |
148 | | - name="managedName" |
149 | | - > |
150 | | - AndroidX.NavigationEvent |
151 | | - </attr> |
152 | | -</metadata> |
153 | | -``` |
154 | | - |
155 | | -This approach: |
156 | | -1. Uses the binding generator's transform system |
157 | | -2. Properly renames the managed namespace during code generation |
158 | | -3. Is applied at build time when the bindings are generated |
159 | | - |
160 | | -## Target Frameworks |
161 | | - |
162 | | -### Current Support |
163 | | -- **Primary**: `net9.0-android` (API 21+) |
164 | | -- **Migration**: `net10.0-android` (API 35+) - migration capability exists but not currently enabled |
165 | | -- **Legacy**: Xamarin.Android support ended May 1, 2024 |
166 | | - |
167 | | -## Code Organization Patterns |
168 | | - |
169 | | -### Generated Projects |
170 | | -- Follow pattern: `{groupId}.{artifactId}.csproj` |
171 | | -- Located in `generated/` directory |
172 | | -- Include auto-generated targets files: `{nugetId}.targets` |
173 | | - |
174 | | -### NuGet Package Structure |
175 | | -``` |
176 | | -lib/ |
177 | | - net9.0-android35.0/ |
178 | | - {assembly}.dll |
179 | | - net10.0-android36.0/ |
180 | | - {assembly}.dll |
181 | | -build/ |
182 | | - net9.0-android35.0/ |
183 | | - {package}.targets |
184 | | - net10.0-android36.0/ |
185 | | - {package}.targets |
186 | | -``` |
187 | | - |
188 | | -## Testing and Validation |
189 | | - |
190 | | -### Available Test Targets |
191 | | -- **`all-packages-tests`**: Run test suite on built packages |
192 | | -- **`build-run-all-packages-tests`**: Build then test all packages |
193 | | -- **`api-diff`**: Generate API difference reports |
194 | | -- **`binderate-config-verify`**: Validate config.json format |
195 | | -- **`metadata-verify`**: Check binding metadata |
| 50 | +<!-- Remove problematic API --> |
| 51 | +<remove-node path="/api/package[@name='com.example']/class[@name='Problematic']" /> |
196 | 52 |
|
197 | | -### Quality Checks |
198 | | -- **Namespace verification**: `dotnet cake utilities.cake -t=namespace-check` |
199 | | -- **Spell checking**: `dotnet cake utilities.cake -t=spell-check` |
200 | | -- **Target SDK verification**: `dotnet cake utilities.cake -t=target-sdk-version-check` |
| 53 | +<!-- Fix parameter name --> |
| 54 | +<attr path="//method[@name='example']/parameter[@name='p0']" name="name">properName</attr> |
201 | 55 |
|
202 | | -## Documentation Resources |
203 | | - |
204 | | -### Internal Documentation |
205 | | -- **`BUILDING.md`**: Comprehensive build instructions |
206 | | -- **`docs/development-tips.md`**: Workflow tips and release procedures |
207 | | -- **`docs/artifact-list.md`**: Complete Maven-to-NuGet mappings |
208 | | -- **`.github/CONTRIBUTING.md`**: Contribution guidelines |
209 | | - |
210 | | -### External Resources |
211 | | -- [.NET for Android Documentation](https://learn.microsoft.com/en-us/dotnet/android/) |
212 | | -- [AndroidX Release Notes](https://developer.android.com/jetpack/androidx/versions/stable-channel) |
213 | | -- [Google Play Services Release Notes](https://developers.google.com/android/guides/releases) |
214 | | - |
215 | | -## Common Binding Issues and Solutions |
216 | | - |
217 | | -### Interface Implementation Issues |
218 | | -When a generated class doesn't implement interface methods with the correct signature, typically showing errors like: |
219 | | -``` |
220 | | -error CS0535: 'ClassName' does not implement interface member 'IInterface.Method(IEncoder, Object?)' |
| 56 | +<!-- Change managed namespace --> |
| 57 | +<attr path="/api/package[@name='androidx.example']" name="managedName">AndroidX.Example</attr> |
221 | 58 | ``` |
222 | 59 |
|
223 | | -This occurs when Java allows method overloading with different parameter types, but C# requires exact interface implementation. |
| 60 | +Reference: https://github.com/dotnet/java-interop/wiki/Troubleshooting-Android-Bindings-Issues |
224 | 61 |
|
225 | | -**Solution**: Create an Additions file with a method that matches the interface signature and calls the strongly-typed method: |
| 62 | +## Common Issues and Fixes |
226 | 63 |
|
| 64 | +### CS0535: Interface Implementation Mismatch |
| 65 | +When Java method overloading doesn't map to C# interface requirements: |
227 | 66 | ```csharp |
| 67 | +// Add in source/{groupId}/{artifactId}/Additions/ClassName.cs |
228 | 68 | namespace PackageName; |
229 | | - |
230 | 69 | public partial class ClassName |
231 | 70 | { |
232 | 71 | public unsafe void Method(IEncoder encoder, Java.Lang.Object? value) |
233 | | - { |
234 | | - this.Method(encoder, (SpecificType?) value); |
235 | | - } |
| 72 | + => this.Method(encoder, (SpecificType?) value); |
236 | 73 | } |
237 | 74 | ``` |
238 | 75 |
|
239 | | -Place this in `source/{groupId}/{artifactId}/Additions/ClassName.cs`. |
| 76 | +### Build File Locking Errors (XARLP7024) |
| 77 | +Transient parallel build issue. Usually resolves on retry. If persistent, may need to reduce build parallelism in `build/cake/build-and-package.cake`. |
240 | 78 |
|
241 | | -### Reference Documentation |
242 | | -- **`docs/development-tips.md`**: Contains detailed examples of common binding fixes |
243 | | -- [Java Interop Troubleshooting Guide](https://github.com/dotnet/java-interop/wiki/Troubleshooting-Android-Bindings-Issues): Comprehensive binding issue resolution |
| 79 | +### Identifying Failing Package from Build Logs |
| 80 | +Look for the `.csproj` path in error messages: |
| 81 | +``` |
| 82 | +[C:\...\generated\{groupId}.{artifactId}\{groupId}.{artifactId}.csproj::TargetFramework=net10.0-android36.0] |
| 83 | +``` |
| 84 | +The `{groupId}.{artifactId}` maps to the Maven coordinates and customization folder. |
244 | 85 |
|
245 | | -## Best Practices for Contributors |
| 86 | +## Validation Commands |
| 87 | +```bash |
| 88 | +dotnet cake utilities.cake -t=namespace-check |
| 89 | +dotnet cake utilities.cake -t=spell-check |
| 90 | +dotnet cake --target=metadata-verify |
| 91 | +dotnet cake --target=binderate-config-verify |
| 92 | +``` |
246 | 93 |
|
247 | | -### Before Making Changes |
248 | | -1. Read `BUILDING.md` for full setup instructions |
249 | | -2. Ensure all prerequisites are installed |
250 | | -3. Run `dotnet cake -t=ci` to verify clean build |
251 | | -4. Check existing issues and PRs for related work |
| 94 | +## Internal Documentation |
| 95 | +- **`BUILDING.md`**: Full build prerequisites and setup |
| 96 | +- **`docs/development-tips.md`**: Workflow tips, release procedures |
| 97 | +- **`docs/artifact-list.md`**: Complete Maven → NuGet mappings |
252 | 98 |
|
253 | | -This repository represents a critical piece of the .NET ecosystem for Android development, enabling C# developers to use the full range of modern Android libraries through automatically maintained bindings. |
| 99 | +## External Resources |
| 100 | +- [.NET for Android Docs](https://learn.microsoft.com/en-us/dotnet/android/) |
| 101 | +- [AndroidX Release Notes](https://developer.android.com/jetpack/androidx/versions/stable-channel) |
| 102 | +- [Google Play Services Release Notes](https://developers.google.com/android/guides/releases) |
| 103 | +- [Java Interop Troubleshooting](https://github.com/dotnet/java-interop/wiki/Troubleshooting-Android-Bindings-Issues) |
0 commit comments