Plan: remove app-build LLVM IR and the bundled binutils dependency
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 5/5
- 预计耗时
- 一周以上
- 新手友好度
- 30/100
- Issue 类型
- 重构
- 描述清晰度
- 基本清楚
- 活跃度
- 活跃
调研方向
Start by reading the numbered stages, the existing PoC, and src/native/clr/xamarin-app-stub/application_dso_stub.cc; then trace EnvironmentBuilder and the JavaInteropRuntime.cs startup path. The work is done when the staged PRs remove the specified Android-specific LLVM IR and app-build llc calls while preserving the documented startup, packaging, remapping, and ABI acceptance cases.
由索引模型根据 Issue 内容生成。
描述
Relationship and goal
Supersedes #10784. This is the implementation and follow-up plan for replacing app-build LLVM IR in CoreCLR and NativeAOT. Updated after the managed ELF writer, modern-task migration, and completed local native-toolchain removal on 2026-09-30.
PoC result: we were able to drop the bundled binutils dependency entirely. The workload no longer downloads or distributes the custom toolchain from dotnet/android-native-tools. Ordinary CoreCLR applications build without an Android NDK or native binutils, including Debug/FastDev, Release, compressed assembly stores, ReadyToRun, and APK/AAB packaging. NativeAOT uses the official Android NDK. The opt-in AndroidStripNativeLibraries=true feature remains supported and also requires the NDK; it defaults to false.
This is implemented and exercised locally, not merely a proposed direction. It is not yet landed in the product.
Engineering goals: Simplify the total code-generation, application-build, and startup-runtime implementation; remove unnecessary toolchain dependencies and subprocesses; reduce overhead while preserving supported behavior and startup performance. Do not merely replace LLVM IR with a large custom native-configuration parser. Judge the result by deleted machinery, build overhead, package size, memory, and runtime behavior, not only by the absence of .ll files.
The supported paths must cut over unconditionally. This is not a feature-switched alternative to LLVM IR. Do not keep a native-codegen fallback or silently ignore unsupported inputs. Small, independently buildable PRs remain the intended review shape, but the backup branch below is a combined WIP PoC, not a proposed single PR.
Preserve per-RID delivery: Assembly stores must remain valid ELF shared objects at lib/<abi>/libassembly-store.so so Play can split an AAB by ABI. Moving them to ordinary assets is not equivalent: those assets do not receive the same automatic ABI splitting. The existing native host continues to use dlopen/dlsym; do not reintroduce APK ZIP scanning or change the store's internal format as part of this work.
Current PoC and backup
The complete PoC is backed up on simonrozsival-llvm-codegen-replacement:
8d308ebc42: unconditional Java/binary bootstrap cutover and LLVM-IR removal.99caaf09fe: managed assembly-store ELF writer, single-symbol contract, documentation, and regression coverage.1a74166477: modern-task migration, unconditional official-NDK NativeAOT/opt-in stripping, and bundled-binutils/runtime-pack cleanup.
The latest binutils-removal and modern-task migration are now committed and pushed in that backup. No PR has been opened for the combined PoC. A separate, narrowly scoped assembly-store ELF-writer PR is being extracted onto current main; it does not require #12895 and does not include the broader bootstrap or toolchain-distribution cleanup. Local functional coverage does not mean full CI or the final performance gate is complete.
Implemented design
1. Shared Java bootstrap for CoreCLR and NativeAOT
AppBootstrapConfig.java replaces app-specific native environment/configuration tables. It carries environment and bundled-property pairs, CoreCLR runtime properties, package settings, and native-library classification/preload metadata.
Java establishes default process environment values before app overrides and before loading the native runtime library. CoreCLR still receives hosting properties before coreclr_initialize. Bundled "system properties" are not Java System.setProperty: both hosts read the shared Java data through JNI early enough for native property consumers.
R8 must retain the bootstrap fields and methods accessed by JNI, including SystemProperties and readRemappingAsset(String).
2. Native loading without generated DSO caches
Build-time JNI_OnLoad classification and always/never-preload policy are retained, but the generated native DSO-cache tables and hashed alias arrays are gone. Small runtime-owned state handles name normalization, JNI-aware loading, and cached native library handles.
The native P/Invoke boundary remains necessary: Java's library loading API does not itself return the native function pointers CoreCLR needs. Preserve eager/lazy loading behavior and startup ordering rather than blindly loading every JNI library earlier.
3. Runtime-owned assembly-store state; no app stub
Mutable per-assembly slots and decompression descriptors/buffers are allocated from the store's counts, indices, and compressed-assembly headers. The mapped payload remains read-only.
The remaining assembly_store global now belongs to the prebuilt CoreCLR host. This removed its dependency on libxamarin-app.so, so the proposed intermediate plan to stage/copy a generic app stub is no longer needed. The PoC neither builds nor packages that library.
A small prebuilt native host is still required. NativeAOT still compiles managed IL and links its normal application .so.
4. Pointer-free JNI remapping asset and managed lookup
Versioned XAJR v1 binary assets replace native remapping tables. The format uses offsets/lengths, not process pointers, and contains the type, reverse-type, method, and field records needed by managed lookup.
The pipeline runs after R8:
- CoreCLR generates one common binary payload and packages it under the per-RID asset names expected by the loader.
- NativeAOT filters post-ILC and generates a distinct payload for each RID.
- Java reads
assets/xa-internal/jni-remap.<rid>.bin; JNI hands bytes to managed initialization before lookups. The managed reader validates its private copy and pins the storage used by stable UTF-8 pointers. - The current implementation always packages an asset, including a valid 64-byte empty asset when no mappings are present. There is no silent missing-asset fallback.
JNI-remapping asset bounds/version validation remains in place; it is separate from the assembly-store bounds decision below.
5. NativeAOT JNI initialization and explicit unsupported modes
NativeAOT directly calls AndroidCryptoNative_InitLibraryOnLoad from its handwritten managed JNI_OnLoad path, with the direct P/Invoke/linker reference needed to retain the initializer. No generated jni_init_funcs.<abi>.ll remains.
Unsupported configurations fail explicitly:
AndroidStaticJniInitFunction: XA1051.- Experimental unified native-runtime linking: XA1052.
- Removed
llvm-irtypemap selection: XA4267.
The old LLVM-IR emitters, CompileNativeAssembly/llc task path, native app stub, unified-linking implementation, and obsolete consumers have been removed. Compression metadata collection was retained and renamed CollectCompressedAssemblyInfo; it must not disappear merely because it no longer emits native source.
6. Assembly-store ELF written directly in C#
AssemblyStoreElfWriter, now under src/Microsoft.Android.Build.Tasks/Utilities/, replaces the former .S -> llvm-mc -> .o -> ld wrapping step. The initial backed-up implementation predates that move. This is a narrowly scoped serializer for a data-only shared object, not a general ELF linker or a serializer of pointer-bearing native configuration structs.
- Little-endian ELF32 for ARM; ELF64 for ARM64/x64. The encoder also retains the former wrapper's x86 capability.
- One read-only, non-executable
PT_LOADcontaining fixed metadata and the unchanged assembly-store bytes. - A small dynamic table, dynamic string/symbol tables, and a one-bucket SysV hash table.
- Exactly one exported payload symbol:
_assembly_store. Its standard ELF symbol-size field is populated for inspection tools. - No executable code, relocations, constructors, library dependencies, writable load segments, compiler, assembler, or linker invocation.
- 16 KiB segment/payload alignment on 64-bit ABIs and 4 KiB on 32-bit ABIs. ZIP-entry alignment and uncompressed
.sopackaging remain separate packaging responsibilities. - Non-allocated section names and section headers follow the payload outside
PT_LOAD. This is important for strip/objcopy compatibility; the earlier prefix-only layout exposed a section-name rewriting problem during stripping.
The PoC ended with only _assembly_store, removing its intermediate _assembly_store_end export and the runtime checks that depended on an external payload length. The store header has not gained a size field. The PoC runtime treats it as trusted build-generated application data and retains format, overflow, index, and compressed-descriptor checks. There is no replacement end symbol or ELF-header walk at startup. Current main already uses the single-symbol configure_from_payload(pointer, path) contract, so the standalone writer PR does not need an end-symbol/API removal or unrelated runtime validation changes.
The obsolete llvm-objcopy-based discrete-file wrapper and its native archive stub have now been removed too. Embedded CoreCLR assemblies use stores; FastDev does not require that wrapping path.
7. Modern build tasks and minimal runtime packs
All newly introduced managed build-side PoC code and its unit tests now live in Microsoft.Android.Build.Tasks and its standalone test project, rather than the legacy netstandard2.0 task assembly. This includes the Java bootstrap generators, compression metadata/collection, managed store writer/wrapper, NDK resolver, and NativeAOT linker task. The producer/consumer compression tasks remain together so their assembly-local metadata registry and incremental descriptor assignments stay consistent.
Runtime packs now distribute only the Android native host assets actually consumed by app builds:
| Runtime | Required Android host assets |
|---|---|
| CoreCLR | libnet-android.debug.so, libnet-android.release.so |
| NativeAOT | libnaot-android.release-static-release.a |
The .NET runtime/BCL assets remain necessary and are resolved separately. NDK system-library stubs, CRT objects, compiler-rt archives, archive-wrapper stubs, and unused Android host/support archives are no longer redistributed. Internal static archives needed to build the native host itself are retained; they are no longer shipped as app linker inputs.
Local pack refresh removes explicitly known obsolete filenames even on an otherwise up-to-date copy and preserves unrelated files and optional symbol sidecars. RuntimeList.xml must also be regenerated alongside the refresh to avoid stale publish entries; all six local manifests were refreshed for the integration runs.
8. Incremental-build corrections
The PoC includes corrections uncovered while exercising the new Java/resource paths:
- Generate/record remapping assets before
IncrementalClean, so they appear inFileWrites. - Exclude stale R8 remaps when obfuscation is disabled.
- Report missing/malformed existing remap XML as XA4329 instead of silently skipping it.
- Re-emit AAPT2's manifest/layout keep rules even when the base APK is up to date. Otherwise a Java-only change could cause R8 to strip
androidx.startup.InitializationProvider. - Regenerate missing AAPT2 keep rules when upgrading a previously affected
objtree, rather than requiring users to clean manually. - Include native stripping in the build-properties cache so incrementally toggling it off/on repackages the correct original/stripped bytes.
- Track NativeAOT's real linker inputs, response/script files, and debug-symbol sidecar. Remove incomplete
.so/.dbg.sooutputs after a failed link/debug-info operation so a subsequent incremental build retries it.
Completed: binutils is no longer a workload dependency
The removed archive came from dotnet/android-native-tools, not the similarly named dotnet/android-tools repository. The PoC removes the entire custom native-tool distribution, rather than keeping a smaller set of bundled executables.
The implemented app-build model is:
| Build | Native toolchain requirement |
|---|---|
| Ordinary CoreCLR Debug/Release, APK/AAB | None: Android SDK/JDK, .NET tooling, prebuilt runtime, and managed store writer suffice |
CoreCLR with AndroidStripNativeLibraries=true |
Official NDK's llvm-strip |
| NativeAOT | Official NDK's ld.lld, llvm-objcopy, CRT/sysroot, and compiler runtime |
| Former bundled component | Final disposition |
|---|---|
llc, llvm-mc, as, prefixed assembler wrappers |
No supported app-build use; removed from the workload |
ld/LLD |
No bundled linker; NativeAOT invokes NDK ld.lld |
llvm-objcopy |
No bundled copy; NativeAOT uses the NDK for debug extraction/stripping/debuglink and ARM32 EHABI symbol promotion |
llvm-strip, prefixed strip wrappers |
No bundled copies; opt-in native-library stripping uses NDK llvm-strip |
libLLVM*/liblld* support libraries |
Removed with the executable distribution |
NativeAOT's NDK path is unconditional. _AndroidUseWorkloadNativeLinker and the workload-linker fallback are gone. The task links ILC's .o directly, so an intermediate llvm-ar step is not needed. The ARM32 workaround still globalizes/weakens the existing EHABI personality symbols in a copied libRuntime.WorkstationGC.a; it does not add a second NDK libunwind.
Resolved stripping policy: preserve AndroidStripNativeLibraries=true, but require the official NDK when requested. This supersedes the earlier recommendation to retire CoreCLR stripping. Ordinary apps package native dependencies as supplied and need no NDK; applications opting into stripping accept the NDK dependency. Stripping writes intermediate copies, leaves inputs unchanged, and fails rather than silently packaging the original after a tool failure. No managed general-purpose ELF stripper was added.
NDK requirements are based on the effective runtime and requested features, not just the presence of PublishAot. Missing NDKs produce XA5104, missing required toolchain directories XA5101, and missing tools XA5105. Dependency discovery requests an NDK for NativeAOT, opt-in stripping, or internal checked builds; ordinary CoreCLR does not validate or require one.
Removed machinery includes:
src/binutils, its solution/project references, archive version/hash pins, installer/signing manifests, CI cache/artifact plumbing, and bundled LLVM/LLD libraries.- The old multi-version
NdkToolshierarchy and bundled-tool resolution fallbacks; the general native linker helper is replaced by a focused modern NativeAOT task. - Discrete assembly wrapping, the archive DSO stub and generated layout configuration, unused runtime mmap/ELF-section helpers, and obsolete strip/runtime-pack-directory tasks.
- NDK linker-only asset redistribution and unused native archives in runtime packs.
- The unused
termux-elf-cleanersubmodule and the obsolete GNU/binutils notice; unrelated ELFSharp/LLVM notices remain.
This does not remove the NDK/CMake requirement for building the .NET for Android runtime itself, Android SDK tools such as AAPT2, R8/D8, zipalign or apksigner, or unrelated tooling from dotnet/android-tools. Independent ELF tests also use NDK inspection tools; those are not customer CoreCLR app-build dependencies.
Functional evidence and remaining coverage
Completed locally:
- Earlier bootstrap/runtime validation: CoreCLR Release compressed-store, Debug FastDev without a store, and NativeAOT Release apps launched on Android; both runtime remapping paths were exercised with R8. These device runs predate the latest task/distribution cleanup.
- APK/AAB, NativeAOT multi-RID, incremental changes, and the four CoreCLR Release-SDK size references were exercised during the bootstrap PoC.
- 103 focused modern-task cases passed, zero skips, covering the migrated bootstrap/configuration/compression tasks, managed ELF writer, NDK resolution, and native-link/debug-info failure cleanup. The ELF coverage includes 24 independent native-tool extraction cases across ARM/ARM64/x64 and multiple payload sizes, before and after
llvm-strip --strip-all. - The external-tool cases get
_assembly_store's address/size fromllvm-nm, get its load-segment mapping fromllvm-readobj, calculate the corresponding file range, and compare arbitrary bytes exactly. Extraction does not depend on thepayloadsection name or the writer's own layout calculations. - 32 full-workload integration cases passed, zero skips, with both Debug and Release SDKs' entire bundled native-tool directories unavailable. Coverage includes CoreCLR Debug on all three ABIs, three-ABI CoreCLR Release APK/AAB stores, NativeAOT NDK builds on all three ABIs and multi-RID, missing-NDK diagnostics, dependency discovery, runtime-pack contents, and safe incremental stale-asset cleanup.
- Opt-in stripping succeeded for CoreCLR Debug APK/FastDev and Release APK/AAB, preserved dynamic exports and original inputs, and repackaged the correct bytes when toggled off/on incrementally. Missing-NDK and invalid-library/tool-failure cases failed explicitly. The final optional symbol-sidecar preservation cases were also rebuilt and rerun successfully.
- Both native host flavors were rebuilt for ARM/ARM64/x64, and all six local Debug runtime-pack manifests were regenerated after cleanup.
- A real Darwin SDK NuGet package was produced and inspected: no bundled binutils executables or LLVM/LLD support libraries, no stale binutils permission/target entries, and the relocated modern task DLLs/dependencies are present. Installer item evaluation also covered Darwin/Linux/Windows. This verifies removal from the actual distribution, not just absence of subprocesses during app builds.
- Managed-writer runtime evidence, collected before the latest task/distribution cleanup: a real compressed-store APK launched on an Android 35 ARM64 emulator with 4 KiB pages. Native ELF tools, zipalign, and the existing assembly-store reader also accepted the output, including a stripped store.
Still required before landing/claiming broad compatibility:
- Actual 16 KiB Android loading, plus ARM32/x64 runtime coverage. Structural/page-boundary coverage is not a substitute for these runs.
- Full CI and the relevant device matrix, including split-APK installation, extraction modes, JNI preload edge cases, crypto/TLS and additional processes where supported.
- The existing NativeAOT size-golden fixture remains skipped because it assumes an ILLink
linked/directory that NativeAOT does not produce. - Final build-time, package-size, memory and representative startup comparisons after the final set of changes. The inspected SDK package confirms toolchain removal, but does not establish a matched size/build-time delta.
- Further minimize managed task dependencies:
GenerateJavaApplicationConfigcurrently references the TypeNameMappings assembly only forPackageNamingPolicy, bringing its Cecil/Diagnostics dependency closure. Sharing that small policy definition separately is a review simplification opportunity. ELFSharp remains useful for build-timeJNI_OnLoadinspection; the ELF writer itself uses framework APIs only.
Startup performance: close, but parity is not proven
Comparisons used an unmodified-main baseline at 7a170b185aa8e78fc18908834ada19b578668d39, matched Debug-built local SDK/runtime packs, Release applications, and a Samsung A16 (Android 16). Launches were process-cold with warm filesystem caches, balanced ordering and app-ID crossover. These compare complete configurations, not an isolated serializer instruction.
- HelloWorld: two 36-pair app-ID assignments gave opposite-signed paired effects of -33 ms and +7 ms. Do not claim the apparent gain as an optimization win.
- XForms/R8, 240 KB remapping asset: the original PoC trended +8.5 ms slower across 120 pairs on roughly 0.6-second launches. Separate batches and installation orders showed material variability.
- Pre-sized Java asset-read buffer: the final 60-pair comparison was +6.5 ms, with a bootstrap 95% interval of 0 to +26 ms and markedly different app-ID phases (-5 ms versus +26.5 ms). Reduced allocation has not established a reliable startup speedup or exact parity.
- The representative pre-writer XForms APK was 139,279 bytes (about 0.85%) larger than clean main.
These performance/package-size figures predate the managed ELF writer, end-symbol removal, modern-task migration, and full toolchain cleanup. They must not be reported as final measurements of the current branch. Repeat representative comparisons before accepting the complete replacement.
The first XForms pilot crashed because the old fixture used android.support.* toolbar/tab tags. Both generated benchmark projects were corrected identically to AndroidX/Material before the usable measurements. Crashed pilots and known contaminated batches are excluded.
Review and landing
Split the WIP into cohesive, independently buildable changes; do not land an intermediate state that loses still-required metadata or introduces a permanent feature-switched fallback. Use current main and the current prerequisite PR versions, not a mechanical replay of the combined PoC's historical merge/cherry-pick commits.
Existing prerequisites and already-merged work
| Existing work | Status on 2026-09-30 | Relationship to the new PRs |
|---|---|---|
| #12887: default trimmable typemaps, associated post-trim/packaging and additional-process provider fixes | Merged | Reuse from main; do not include another default/typemap-enablement layer |
| #12950: preserve AAPT2 keep rules across incremental R8 builds | Merged | Prefer the upstream fix over the PoC's separate rule-collection implementation; missing-file recovery for an already-damaged obj tree is a distinct change |
| #12847 -> #12848: JNI remapping runtime and R8 remapping generation | Open | Prerequisites for replacing that feature's native tables with the binary asset; preserve later review/diagnostic/fail-closed fixes |
| #12889 -> #12890: legacy LLVM typemap build/runtime removal | Open | Existing typemap/marshal cleanup, not a new bootstrap PR; use this foundation for the complete remaining LLVM-IR cutover |
| #12895: simplify LLVM native source generation | Open | Overlapping work, not a prerequisite for the managed ELF writer or full removal; see supersession below |
#12824/#12825 (linked/NativeAOT typemap readers) and #12911 (runtimeconfig-parser removal) are already in the original PoC base, so they are not new work for this stack.
Refresh the existing chains before building on them. In the inspected snapshot, #12890's head is already an exact ancestor of the PoC, but does not include the current #12889 parent head and therefore needs restacking. Also retain newer main changes such as FastTiming removal (#12854), managed GC-bridge ownership (#12861), test restructuring (#12931/#12930), and updated debugging/AOT-property behavior (#12916/#12956).
Planned new PR sequence
| Layer | New PR scope | Dependencies and landing boundary |
|---|---|---|
| 1 | Write assembly-store ELF libraries directly in managed code | Standalone against main; does not wait for #12895 or either open prerequisite chain. Include modern store task/wiring, coverage and store-specific documentation; preserve main's existing single-symbol native contract. No end-symbol/API removal is needed. Exclude Java bootstrap, general NDK policy, and bundled-tool distribution cleanup |
| 2 | Replace native JNI remapping tables with binary assets | Requires the runtime/R8 feature from #12847 -> #12848. Move the XAJR producer, managed parser/lookup, Java/native handoff, per-RID packaging, diagnostics and FileWrites together |
| 3 | Replace generated bootstrap data with Java and runtime-owned state; remove remaining LLVM-IR generation | Build on layers 1/2 and the typemap-removal foundation #12889 -> #12890. Switch environment/runtime/system properties, native-library preload/cache metadata, mutable assembly/decompression state, and NativeAOT initialization. Remove app-specific libxamarin-app.so generation and coupled LLVM emitter/task code |
| 4 | Use the official NDK for NativeAOT and opt-in native stripping | After the generated-data consumers are gone. Keep ARM EHABI/debug-symbol behavior; switch tool resolution, dependency discovery and strip policy with their task/target/diagnostic changes. Keep bundled-tool distribution until its last callers have switched |
| 5 | Remove bundled binutils and obsolete runtime-pack assets | After layers 1-4 eliminate all remaining bundled-tool callers. Delete downloads/pins/installer/signing/CI/notices machinery; remove unused archive-stub generation and linker-only pack assets. Change pack producers, obsolete publish-list filters, stale-file cleanup and runtime manifests together |
Layer 1 is being extracted now as a separate main-based PR. Record its PR number here when opened. It replaces .S -> llvm-mc -> .o -> ld for assembly stores; that step uses assembly source, not LLVM IR. The writer alone does not remove the remaining environment/configuration/DSO/remapping LLVM-IR generation or the entire tool distribution.
Layer 1 preserves main's existing single-symbol/trusted-store contract; the earlier end-symbol removal belongs to the PoC's development history, not a new change against main. Keep any actual producer/consumer format and native initialization ABI changes in subsequent layers atomic. New managed tasks and tests should start in Microsoft.Android.Build.Tasks, rather than adding a later bulk migration PR. Keep the compressed-assembly metadata producer/consumer in the same task assembly.
Layer 3's large source deletion can be reviewed as separate commits within the functional cutover PR. A separate deletion-only sixth PR is optional only if the intermediate source tree still compiles without duplicated compatibility helpers or broken consumers.
Possible supersession of #12895
We may be able to supersede #12895 by removing the remaining LLVM-IR generation outright, rather than refactoring emitters immediately before deleting them. The full Java/binary bootstrap replacement removes our app-build LLVM-IR infrastructure: composers, emitters, generation tasks, and the llc invocation path. #12895 is not needed to make the managed store writer independent or to enable that removal.
#12895 also contains useful overlapping removal of obsolete unified-runtime-linking plumbing, not just emitter formatting/simplification. Preserve or incorporate those cleanup portions in the relevant removal PR; do not lose them when superseding the emitter refactor. Its underlying JVM-only test cleanup (#12894) remains a separate workstream and should not become an artificial dependency of this stack.
This is a planned possible supersession, not a request to close #12895 now. Coordinate it when the replacement removal PR is ready. The intended outcome removes app-generated LLVM IR, not the official NDK's Clang/LLD or NativeAOT's necessary native linking.
Track follow-up PRs, managed-dependency simplification, compatibility coverage, and the performance gate here, not in parallel replacement issues. The binutils-removal implementation and stripping policy are resolved; broad compatibility/performance validation and landing remain outstanding. Keep this issue open until those gates are complete.
- 主要语言
- C#
- 星标
- 2.1k
- 派生
- 581
- 平均合并
- 2 天 2 小时
- 30 天内合并 PR
- 228
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 没有贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
dotnet/android 的其他 Issue
-
Area: App+Library Build
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复
-
Area: Debugger enhancement needs-triage
难度 2/5 1-3 小时 新手友好度 85/100
维护者通常 1 天内回复
-
Area: Mono.Android
难度 2/5 1-3 小时 新手友好度 65/100
dotnet/android#9192 · 4 条评论 · 1 个 reaction ·
维护者通常 1 天内回复
-
Area: App+Library Build need-info
难度 4/5 3-5 天 新手友好度 48/100
dotnet/android#12942 · 3 条评论 ·
维护者通常 1 天内回复
相似的 Issue
-
bug
难度 2/5 1-3 小时 新手友好度 88/100
ClickHouse/clickhouse-cs#639 ·
维护者通常 1 天内回复
-
难度 1/5 1 小时以内 新手友好度 92/100
ifpebj-ti/controle-acesso-veiculos#377 ·
维护者通常 1 天内回复
-
bug
难度 2/5 1-3 小时 新手友好度 82/100
维护者通常 1 天内回复
-
Money Exploits未关闭S: Untriaged
难度 2/5 1-3 小时 新手友好度 62/100
project-wayfarer/wayfarer-14#1628 ·
维护者通常 3 天内回复
-
:watch: Not Triaged dotnet-target-version
难度 1/5 1 小时以内 新手友好度 85/100
维护者通常 1 天内回复