diff --git a/rust/androidmk.go b/rust/androidmk.go index c51ba5148..7eb5dbdbd 100644 --- a/rust/androidmk.go +++ b/rust/androidmk.go @@ -50,7 +50,7 @@ func (mod *Module) AndroidMkEntries() []android.AndroidMkEntries { } ret := android.AndroidMkEntries{ - OutputFile: mod.unstrippedOutputFile, + OutputFile: android.OptionalPathForPath(mod.UnstrippedOutputFile()), Include: "$(BUILD_SYSTEM)/soong_rust_prebuilt.mk", ExtraEntries: []android.AndroidMkExtraEntriesFunc{ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { @@ -185,14 +185,13 @@ func (compiler *baseCompiler) AndroidMk(ctx AndroidMkContext, ret *android.Andro return } - var unstrippedOutputFile android.OptionalPath if compiler.strippedOutputFile.Valid() { - unstrippedOutputFile = ret.OutputFile ret.OutputFile = compiler.strippedOutputFile } + ret.ExtraEntries = append(ret.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { - entries.SetOptionalPath("LOCAL_SOONG_UNSTRIPPED_BINARY", unstrippedOutputFile) + entries.SetPath("LOCAL_SOONG_UNSTRIPPED_BINARY", compiler.unstrippedOutputFile) path, file := filepath.Split(compiler.path.ToMakePath().String()) stem, suffix, _ := android.SplitFileExt(file) entries.SetString("LOCAL_MODULE_SUFFIX", suffix) diff --git a/rust/binary.go b/rust/binary.go index 7c18730c6..cba2f7232 100644 --- a/rust/binary.go +++ b/rust/binary.go @@ -122,20 +122,24 @@ func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps Path fileName := binary.getStem(ctx) + ctx.toolchain().ExecutableSuffix() srcPath, _ := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs) outputFile := android.PathForModuleOut(ctx, fileName) + ret := outputFile flags.RustFlags = append(flags.RustFlags, deps.depFlags...) flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...) flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...) + if binary.stripper.NeedsStrip(ctx) { + strippedOutputFile := outputFile + outputFile = android.PathForModuleOut(ctx, "unstripped", fileName) + binary.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile) + + binary.baseCompiler.strippedOutputFile = android.OptionalPathForPath(strippedOutputFile) + } + binary.baseCompiler.unstrippedOutputFile = outputFile + TransformSrcToBinary(ctx, srcPath, deps, flags, outputFile) - if binary.stripper.NeedsStrip(ctx) { - strippedOutputFile := android.PathForModuleOut(ctx, "stripped", fileName) - binary.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile) - binary.strippedOutputFile = android.OptionalPathForPath(strippedOutputFile) - } - - return outputFile + return ret } func (binary *binaryDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep { diff --git a/rust/binary_test.go b/rust/binary_test.go index 968c0c1ff..7dac2490a 100644 --- a/rust/binary_test.go +++ b/rust/binary_test.go @@ -106,7 +106,7 @@ func TestBinaryFlags(t *testing.T) { srcs: ["foo.rs"], }`) - fizzBuzz := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Output("fizz-buzz") + fizzBuzz := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Rule("rustc") flags := fizzBuzz.Args["rustcFlags"] if strings.Contains(flags, "--test") { @@ -139,7 +139,7 @@ func TestStaticBinaryFlags(t *testing.T) { static_executable: true, }`) - fizzOut := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Output("fizz") + fizzOut := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Rule("rustc") fizzMod := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Module().(*Module) flags := fizzOut.Args["rustcFlags"] @@ -173,7 +173,7 @@ func TestLinkObjects(t *testing.T) { name: "libfoo", }`) - fizzBuzz := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Output("fizz-buzz") + fizzBuzz := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Rule("rustc") linkFlags := fizzBuzz.Args["linkFlags"] if !strings.Contains(linkFlags, "/libfoo.so") { t.Errorf("missing shared dependency 'libfoo.so' in linkFlags: %#v", linkFlags) @@ -197,15 +197,17 @@ func TestStrippedBinary(t *testing.T) { `) foo := ctx.ModuleForTests("foo", "android_arm64_armv8-a") - foo.Output("stripped/foo") + foo.Output("unstripped/foo") + foo.Output("foo") + // Check that the `cp` rules is using the stripped version as input. cp := foo.Rule("android.Cp") - if !strings.HasSuffix(cp.Input.String(), "stripped/foo") { + if strings.HasSuffix(cp.Input.String(), "unstripped/foo") { t.Errorf("installed binary not based on stripped version: %v", cp.Input) } - fizzBar := ctx.ModuleForTests("bar", "android_arm64_armv8-a").MaybeOutput("stripped/bar") + fizzBar := ctx.ModuleForTests("bar", "android_arm64_armv8-a").MaybeOutput("unstripped/bar") if fizzBar.Rule != nil { - t.Errorf("stripped version of bar has been generated") + t.Errorf("unstripped binary exists, so stripped binary has incorrectly been generated") } } diff --git a/rust/builder.go b/rust/builder.go index 6f203476e..60b5926e8 100644 --- a/rust/builder.go +++ b/rust/builder.go @@ -361,7 +361,7 @@ func Rustdoc(ctx ModuleContext, main android.Path, deps PathDeps, Description: "rustdoc " + main.Rel(), Output: docTimestampFile, Input: main, - Implicit: ctx.RustModule().unstrippedOutputFile.Path(), + Implicit: ctx.RustModule().UnstrippedOutputFile(), Args: map[string]string{ "rustdocFlags": strings.Join(rustdocFlags, " "), "outDir": docDir.String(), diff --git a/rust/compiler.go b/rust/compiler.go index cada9854a..293b17b50 100644 --- a/rust/compiler.go +++ b/rust/compiler.go @@ -181,7 +181,11 @@ type baseCompiler struct { sanitize *sanitize distFile android.OptionalPath - // Stripped output file. If Valid(), this file will be installed instead of outputFile. + + // unstripped output file. + unstrippedOutputFile android.Path + + // stripped output file. strippedOutputFile android.OptionalPath // If a crate has a source-generated dependency, a copy of the source file @@ -340,6 +344,10 @@ func (compiler *baseCompiler) CargoPkgVersion() string { return String(compiler.Properties.Cargo_pkg_version) } +func (compiler *baseCompiler) unstrippedOutputFilePath() android.Path { + return compiler.unstrippedOutputFile +} + func (compiler *baseCompiler) strippedOutputFilePath() android.OptionalPath { return compiler.strippedOutputFile } diff --git a/rust/fuzz.go b/rust/fuzz.go index a628b6158..c52f5f9e2 100644 --- a/rust/fuzz.go +++ b/rust/fuzz.go @@ -147,7 +147,7 @@ func (s *rustFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { files = s.PackageArtifacts(ctx, module, fuzzModule.fuzzPackagedModule, archDir, builder) // The executable. - files = append(files, fuzz.FileToZip{rustModule.unstrippedOutputFile.Path(), ""}) + files = append(files, fuzz.FileToZip{rustModule.UnstrippedOutputFile(), ""}) // Grab the list of required shared libraries. sharedLibraries := fuzz.CollectAllSharedDependencies(ctx, module, cc.UnstrippedOutputFile, cc.IsValidSharedDependency) diff --git a/rust/fuzz_test.go b/rust/fuzz_test.go index 2524f9176..98be7c20d 100644 --- a/rust/fuzz_test.go +++ b/rust/fuzz_test.go @@ -45,7 +45,7 @@ func TestRustFuzz(t *testing.T) { } // Check that compiler flags are set appropriately . - fuzz_libtest := ctx.ModuleForTests("fuzz_libtest", "android_arm64_armv8-a_fuzzer").Output("fuzz_libtest") + fuzz_libtest := ctx.ModuleForTests("fuzz_libtest", "android_arm64_armv8-a_fuzzer").Rule("rustc") if !strings.Contains(fuzz_libtest.Args["rustcFlags"], "-Z sanitizer=hwaddress") || !strings.Contains(fuzz_libtest.Args["rustcFlags"], "-C passes='sancov'") || !strings.Contains(fuzz_libtest.Args["rustcFlags"], "--cfg fuzzing") { diff --git a/rust/library.go b/rust/library.go index ea14e6d48..07843fe32 100644 --- a/rust/library.go +++ b/rust/library.go @@ -469,7 +469,7 @@ func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) F } func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path { - var outputFile android.ModuleOutPath + var outputFile, ret android.ModuleOutPath var fileName string srcPath := library.srcPath(ctx, deps) @@ -477,6 +477,34 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa deps.srcProviderFiles = append(deps.srcProviderFiles, library.sourceProvider.Srcs()...) } + // Calculate output filename + if library.rlib() { + fileName = library.getStem(ctx) + ctx.toolchain().RlibSuffix() + outputFile = android.PathForModuleOut(ctx, fileName) + ret = outputFile + } else if library.dylib() { + fileName = library.getStem(ctx) + ctx.toolchain().DylibSuffix() + outputFile = android.PathForModuleOut(ctx, fileName) + ret = outputFile + } else if library.static() { + fileName = library.getStem(ctx) + ctx.toolchain().StaticLibSuffix() + outputFile = android.PathForModuleOut(ctx, fileName) + ret = outputFile + } else if library.shared() { + fileName = library.sharedLibFilename(ctx) + outputFile = android.PathForModuleOut(ctx, fileName) + ret = outputFile + } + + if !library.rlib() && !library.static() && library.stripper.NeedsStrip(ctx) { + strippedOutputFile := outputFile + outputFile = android.PathForModuleOut(ctx, "unstripped", fileName) + library.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile) + + library.baseCompiler.strippedOutputFile = android.OptionalPathForPath(strippedOutputFile) + } + library.baseCompiler.unstrippedOutputFile = outputFile + flags.RustFlags = append(flags.RustFlags, deps.depFlags...) flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...) flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...) @@ -488,34 +516,17 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa flags.RustFlags = append(flags.RustFlags, "-C prefer-dynamic") } + // Call the appropriate builder for this library type if library.rlib() { - fileName = library.getStem(ctx) + ctx.toolchain().RlibSuffix() - outputFile = android.PathForModuleOut(ctx, fileName) - TransformSrctoRlib(ctx, srcPath, deps, flags, outputFile) } else if library.dylib() { - fileName = library.getStem(ctx) + ctx.toolchain().DylibSuffix() - outputFile = android.PathForModuleOut(ctx, fileName) - TransformSrctoDylib(ctx, srcPath, deps, flags, outputFile) } else if library.static() { - fileName = library.getStem(ctx) + ctx.toolchain().StaticLibSuffix() - outputFile = android.PathForModuleOut(ctx, fileName) - TransformSrctoStatic(ctx, srcPath, deps, flags, outputFile) } else if library.shared() { - fileName = library.sharedLibFilename(ctx) - outputFile = android.PathForModuleOut(ctx, fileName) - TransformSrctoShared(ctx, srcPath, deps, flags, outputFile) } - if !library.rlib() && !library.static() && library.stripper.NeedsStrip(ctx) { - strippedOutputFile := android.PathForModuleOut(ctx, "stripped", fileName) - library.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile) - library.strippedOutputFile = android.OptionalPathForPath(strippedOutputFile) - } - if library.rlib() || library.dylib() { library.flagExporter.exportLinkDirs(deps.linkDirs...) library.flagExporter.exportLinkObjects(deps.linkObjects...) @@ -552,7 +563,7 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa library.flagExporter.setProvider(ctx) - return outputFile + return ret } func (library *libraryDecorator) srcPath(ctx ModuleContext, deps PathDeps) android.Path { diff --git a/rust/library_test.go b/rust/library_test.go index edb9c89b6..d78dcdd97 100644 --- a/rust/library_test.go +++ b/rust/library_test.go @@ -37,10 +37,10 @@ func TestLibraryVariants(t *testing.T) { }`) // Test all variants are being built. - libfooRlib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_rlib_rlib-std").Output("libfoo.rlib") - libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Output("libfoo.dylib.so") - libfooStatic := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_static").Output("libfoo.ffi.a") - libfooShared := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_shared").Output("libfoo.ffi.so") + libfooRlib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc") + libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc") + libfooStatic := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_static").Rule("rustc") + libfooShared := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_shared").Rule("rustc") rlibCrateType := "rlib" dylibCrateType := "dylib" @@ -78,7 +78,7 @@ func TestDylibPreferDynamic(t *testing.T) { crate_name: "foo", }`) - libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Output("libfoo.dylib.so") + libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc") if !strings.Contains(libfooDylib.Args["rustcFlags"], "prefer-dynamic") { t.Errorf("missing prefer-dynamic flag for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"]) @@ -94,7 +94,7 @@ func TestAndroidDylib(t *testing.T) { crate_name: "foo", }`) - libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Output("libfoo.dylib.so") + libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc") if !strings.Contains(libfooDylib.Args["rustcFlags"], "--cfg 'android_dylib'") { t.Errorf("missing android_dylib cfg flag for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"]) @@ -148,7 +148,7 @@ func TestSharedLibrary(t *testing.T) { libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared") - libfooOutput := libfoo.Output("libfoo.so") + libfooOutput := libfoo.Rule("rustc") if !strings.Contains(libfooOutput.Args["linkFlags"], "-Wl,-soname=libfoo.so") { t.Errorf("missing expected -Wl,-soname linker flag for libfoo shared lib, linkFlags: %#v", libfooOutput.Args["linkFlags"]) @@ -262,16 +262,17 @@ func TestStrippedLibrary(t *testing.T) { `) foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib") - foo.Output("stripped/libfoo.dylib.so") + foo.Output("libfoo.dylib.so") + foo.Output("unstripped/libfoo.dylib.so") // Check that the `cp` rule is using the stripped version as input. cp := foo.Rule("android.Cp") - if !strings.HasSuffix(cp.Input.String(), "stripped/libfoo.dylib.so") { - t.Errorf("installed binary not based on stripped version: %v", cp.Input) + if strings.HasSuffix(cp.Input.String(), "unstripped/libfoo.dylib.so") { + t.Errorf("installed library not based on stripped version: %v", cp.Input) } - fizzBar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_dylib").MaybeOutput("stripped/libbar.dylib.so") + fizzBar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_dylib").MaybeOutput("unstripped/libbar.dylib.so") if fizzBar.Rule != nil { - t.Errorf("stripped version of bar has been generated") + t.Errorf("unstripped library exists, so stripped library has incorrectly been generated") } } diff --git a/rust/prebuilt.go b/rust/prebuilt.go index 49f3c0f79..6099eec4d 100644 --- a/rust/prebuilt.go +++ b/rust/prebuilt.go @@ -100,6 +100,7 @@ func (prebuilt *prebuiltLibraryDecorator) compile(ctx ModuleContext, flags Flags if len(paths) > 0 { ctx.PropertyErrorf("srcs", "prebuilt libraries can only have one entry in srcs (the prebuilt path)") } + prebuilt.baseCompiler.unstrippedOutputFile = srcPath return srcPath } diff --git a/rust/proc_macro.go b/rust/proc_macro.go index 804d79fe9..974c096c4 100644 --- a/rust/proc_macro.go +++ b/rust/proc_macro.go @@ -75,6 +75,7 @@ func (procMacro *procMacroDecorator) compile(ctx ModuleContext, flags Flags, dep srcPath, _ := srcPathFromModuleSrcs(ctx, procMacro.baseCompiler.Properties.Srcs) TransformSrctoProcMacro(ctx, srcPath, deps, flags, outputFile) + procMacro.baseCompiler.unstrippedOutputFile = outputFile return outputFile } diff --git a/rust/rust.go b/rust/rust.go index 4a43c3eb4..b3e543ee9 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -156,11 +156,10 @@ type Module struct { sourceProvider SourceProvider subAndroidMkOnce map[SubAndroidMkProvider]bool - // Unstripped output. This is usually used when this module is linked to another module - // as a library. The stripped output which is used for installation can be found via - // compiler.strippedOutputFile if it exists. - unstrippedOutputFile android.OptionalPath - docTimestampFile android.OptionalPath + // Output file to be installed, may be stripped or unstripped. + outputFile android.OptionalPath + + docTimestampFile android.OptionalPath hideApexVariantFromMake bool @@ -468,6 +467,7 @@ type compiler interface { stdLinkage(ctx *depsContext) RustLinkage + unstrippedOutputFilePath() android.Path strippedOutputFilePath() android.OptionalPath } @@ -596,8 +596,8 @@ func (mod *Module) CcLibraryInterface() bool { } func (mod *Module) UnstrippedOutputFile() android.Path { - if mod.unstrippedOutputFile.Valid() { - return mod.unstrippedOutputFile.Path() + if mod.compiler != nil { + return mod.compiler.unstrippedOutputFilePath() } return nil } @@ -654,10 +654,7 @@ func (mod *Module) Module() android.Module { } func (mod *Module) OutputFile() android.OptionalPath { - if mod.compiler != nil && mod.compiler.strippedOutputFilePath().Valid() { - return mod.compiler.strippedOutputFilePath() - } - return mod.unstrippedOutputFile + return mod.outputFile } func (mod *Module) CoverageFiles() android.Paths { @@ -892,9 +889,12 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { if mod.compiler != nil && !mod.compiler.Disabled() { mod.compiler.initialize(ctx) - unstrippedOutputFile := mod.compiler.compile(ctx, flags, deps) - mod.unstrippedOutputFile = android.OptionalPathForPath(unstrippedOutputFile) - bloaty.MeasureSizeForPaths(ctx, mod.compiler.strippedOutputFilePath(), mod.unstrippedOutputFile) + outputFile := mod.compiler.compile(ctx, flags, deps) + if ctx.Failed() { + return + } + mod.outputFile = android.OptionalPathForPath(outputFile) + bloaty.MeasureSizeForPaths(ctx, mod.compiler.strippedOutputFilePath(), android.OptionalPathForPath(mod.compiler.unstrippedOutputFilePath())) mod.docTimestampFile = mod.compiler.rustdoc(ctx, flags, deps) @@ -1104,13 +1104,8 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { } if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag { - linkFile := rustDep.unstrippedOutputFile - if !linkFile.Valid() { - ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", - depName, ctx.ModuleName()) - return - } - linkDir := linkPathFromFilePath(linkFile.Path()) + linkFile := rustDep.UnstrippedOutputFile() + linkDir := linkPathFromFilePath(linkFile) if lib, ok := mod.compiler.(exportedFlagsProducer); ok { lib.exportLinkDirs(linkDir) } @@ -1219,15 +1214,15 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { var rlibDepFiles RustLibraries for _, dep := range directRlibDeps { - rlibDepFiles = append(rlibDepFiles, RustLibrary{Path: dep.unstrippedOutputFile.Path(), CrateName: dep.CrateName()}) + rlibDepFiles = append(rlibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()}) } var dylibDepFiles RustLibraries for _, dep := range directDylibDeps { - dylibDepFiles = append(dylibDepFiles, RustLibrary{Path: dep.unstrippedOutputFile.Path(), CrateName: dep.CrateName()}) + dylibDepFiles = append(dylibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()}) } var procMacroDepFiles RustLibraries for _, dep := range directProcMacroDeps { - procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.unstrippedOutputFile.Path(), CrateName: dep.CrateName()}) + procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()}) } var staticLibDepFiles android.Paths diff --git a/rust/rust_test.go b/rust/rust_test.go index 80f693eb6..9b518c8c5 100644 --- a/rust/rust_test.go +++ b/rust/rust_test.go @@ -439,6 +439,6 @@ func TestLibrarySizes(t *testing.T) { }`) m := ctx.SingletonForTests("file_metrics") + m.Output("unstripped/libwaldo.dylib.so.bloaty.csv") m.Output("libwaldo.dylib.so.bloaty.csv") - m.Output("stripped/libwaldo.dylib.so.bloaty.csv") } diff --git a/rust/snapshot_prebuilt.go b/rust/snapshot_prebuilt.go index b4188eecf..dfbc1d1e7 100644 --- a/rust/snapshot_prebuilt.go +++ b/rust/snapshot_prebuilt.go @@ -87,8 +87,9 @@ func (library *snapshotLibraryDecorator) compile(ctx ModuleContext, flags Flags, if !library.MatchesWithDevice(ctx.DeviceConfig()) { return nil } - - return android.PathForModuleSrc(ctx, *library.properties.Src) + outputFile := android.PathForModuleSrc(ctx, *library.properties.Src) + library.unstrippedOutputFile = outputFile + return outputFile } func (library *snapshotLibraryDecorator) rustdoc(ctx ModuleContext, flags Flags, deps PathDeps) android.OptionalPath {