diff --git a/android/androidmk.go b/android/androidmk.go index 493ba97e4..62243618d 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -40,6 +40,7 @@ type AndroidMkDataProvider interface { type AndroidMkData struct { Class string SubName string + DistFile OptionalPath OutputFile OptionalPath Disabled bool Include string @@ -220,6 +221,45 @@ func translateAndroidModule(ctx SingletonContext, w io.Writer, mod blueprint.Mod } } + if len(amod.commonProperties.Dist.Targets) > 0 { + distFile := data.DistFile + if !distFile.Valid() { + distFile = data.OutputFile + } + if distFile.Valid() { + dest := filepath.Base(distFile.String()) + + if amod.commonProperties.Dist.Dest != nil { + var err error + dest, err = validateSafePath(*amod.commonProperties.Dist.Dest) + if err != nil { + // This was checked in ModuleBase.GenerateBuildActions + panic(err) + } + } + + if amod.commonProperties.Dist.Suffix != nil { + ext := filepath.Ext(dest) + suffix := *amod.commonProperties.Dist.Suffix + dest = strings.TrimSuffix(dest, ext) + suffix + ext + } + + if amod.commonProperties.Dist.Dir != nil { + var err error + dest, err = validateSafePath(*amod.commonProperties.Dist.Dir, dest) + if err != nil { + // This was checked in ModuleBase.GenerateBuildActions + panic(err) + } + } + + goals := strings.Join(amod.commonProperties.Dist.Targets, " ") + fmt.Fprintln(&data.preamble, ".PHONY:", goals) + fmt.Fprintf(&data.preamble, "$(call dist-for-goals,%s,%s:%s)\n", + goals, distFile.String(), dest) + } + } + fmt.Fprintln(&data.preamble, "\ninclude $(CLEAR_VARS)") fmt.Fprintln(&data.preamble, "LOCAL_PATH :=", filepath.Dir(ctx.BlueprintFile(mod))) fmt.Fprintln(&data.preamble, "LOCAL_MODULE :=", name+data.SubName) diff --git a/android/module.go b/android/module.go index bf49ca29b..bbe7d3646 100644 --- a/android/module.go +++ b/android/module.go @@ -265,6 +265,24 @@ type commonProperties struct { // relative path to a file to include in the list of notices for the device Notice *string + Dist struct { + // copy the output of this module to the $DIST_DIR when `dist` is specified on the + // command line and any of these targets are also on the command line, or otherwise + // built + Targets []string `android:"arch_variant"` + + // The name of the output artifact. This defaults to the basename of the output of + // the module. + Dest *string `android:"arch_variant"` + + // The directory within the dist directory to store the artifact. Defaults to the + // top level directory (""). + Dir *string `android:"arch_variant"` + + // A suffix to add to the artifact file name (before any extension). + Suffix *string `android:"arch_variant"` + } `android:"arch_variant"` + // Set by TargetMutator CompileTarget Target `blueprint:"mutated"` CompileMultiTargets []Target `blueprint:"mutated"` @@ -781,6 +799,25 @@ func (a *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) } ctx.Variable(pctx, "moduleDescSuffix", s) + // Some common property checks for properties that will be used later in androidmk.go + if a.commonProperties.Dist.Dest != nil { + _, err := validateSafePath(*a.commonProperties.Dist.Dest) + if err != nil { + ctx.PropertyErrorf("dist.dest", "%s", err.Error()) + } + } + if a.commonProperties.Dist.Dir != nil { + _, err := validateSafePath(*a.commonProperties.Dist.Dir) + if err != nil { + ctx.PropertyErrorf("dist.dir", "%s", err.Error()) + } + } + if a.commonProperties.Dist.Suffix != nil { + if strings.Contains(*a.commonProperties.Dist.Suffix, "/") { + ctx.PropertyErrorf("dist.suffix", "Suffix may not contain a '/' character.") + } + } + if a.Enabled() { a.module.GenerateAndroidBuildActions(ctx) if ctx.Failed() { diff --git a/cc/androidmk.go b/cc/androidmk.go index 5e3897392..f5e04bb02 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -151,6 +151,7 @@ func (library *libraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.An ret.Class = "HEADER_LIBRARIES" } + ret.DistFile = library.distFile ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { library.androidMkWriteExportedFlags(w) fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES := ") @@ -194,6 +195,7 @@ func (binary *binaryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.Andr ctx.subAndroidMk(ret, binary.baseInstaller) ret.Class = "EXECUTABLES" + ret.DistFile = binary.distFile ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", binary.unstrippedOutputFile.String()) if len(binary.symlinks) > 0 { diff --git a/cc/binary.go b/cc/binary.go index 15db2ad6e..6923f2b84 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -88,6 +88,9 @@ type binaryDecorator struct { // Output archive of gcno coverage information coverageOutputFile android.OptionalPath + + // Location of the file that should be copied to dist dir when requested + distFile android.OptionalPath } var _ linker = (*binaryDecorator)(nil) @@ -330,10 +333,23 @@ func (binary *binaryDecorator) link(ctx ModuleContext, flagsToBuilderFlags(flags), afterPrefixSymbols) } - if Bool(binary.baseLinker.Properties.Use_version_lib) && ctx.Host() { - versionedOutputFile := outputFile - outputFile = android.PathForModuleOut(ctx, "unversioned", fileName) - binary.injectVersionSymbol(ctx, outputFile, versionedOutputFile) + if Bool(binary.baseLinker.Properties.Use_version_lib) { + if ctx.Host() { + versionedOutputFile := outputFile + outputFile = android.PathForModuleOut(ctx, "unversioned", fileName) + binary.injectVersionSymbol(ctx, outputFile, versionedOutputFile) + } else { + versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName) + binary.distFile = android.OptionalPathForPath(versionedOutputFile) + + if binary.stripper.needsStrip(ctx) { + out := android.PathForModuleOut(ctx, "versioned-stripped", fileName) + binary.distFile = android.OptionalPathForPath(out) + binary.stripper.strip(ctx, versionedOutputFile, out, builderFlags) + } + + binary.injectVersionSymbol(ctx, outputFile, versionedOutputFile) + } } if ctx.Os() == android.LinuxBionic && !binary.static() { diff --git a/cc/libbuildversion/libbuildversion.cpp b/cc/libbuildversion/libbuildversion.cpp index d80d587cd..5242025eb 100644 --- a/cc/libbuildversion/libbuildversion.cpp +++ b/cc/libbuildversion/libbuildversion.cpp @@ -23,9 +23,19 @@ namespace android { namespace build { +#define PLACEHOLDER "SOONG BUILD NUMBER PLACEHOLDER" + +extern "C" { + char soong_build_number[128] = PLACEHOLDER; +} + #ifdef __ANDROID__ std::string GetBuildNumber() { + if (strcmp(PLACEHOLDER, soong_build_number) != 0) { + return soong_build_number; + } + const prop_info* pi = __system_property_find("ro.build.version.incremental"); if (pi == nullptr) return ""; @@ -42,10 +52,6 @@ std::string GetBuildNumber() { #else -extern "C" { - char soong_build_number[128] = "SOONG BUILD NUMBER PLACEHOLDER"; -} - std::string GetBuildNumber() { return soong_build_number; } diff --git a/cc/libbuildversion/tests/Android.bp b/cc/libbuildversion/tests/Android.bp index a18bc6cc7..b3b206159 100644 --- a/cc/libbuildversion/tests/Android.bp +++ b/cc/libbuildversion/tests/Android.bp @@ -2,10 +2,53 @@ cc_defaults { name: "build_version_test_defaults", use_version_lib: true, host_supported: true, + dist: { + targets: ["test_build_version_test"], + }, target: { + android_arm: { + dist: { + dir: "android/arm", + }, + }, + android_arm64: { + dist: { + dir: "android/arm64", + }, + }, + android_x86: { + dist: { + dir: "android/x86", + }, + }, + android_x86_64: { + dist: { + dir: "android/x86_64", + }, + }, + darwin: { + dist: { + dir: "host/", + }, + }, + linux_glibc_x86: { + dist: { + dir: "host32/", + }, + }, + linux_glibc_x86_64: { + dist: { + dir: "host/", + }, + }, windows: { enabled: true, }, + windows_x86_64: { + dist: { + dest: "win64/build_ver_test.exe", + }, + }, }, } @@ -20,6 +63,11 @@ cc_test { not_windows: { shared_libs: ["libbuild_version_test"], }, + host: { + dist: { + suffix: "_host", + }, + }, }, } diff --git a/cc/library.go b/cc/library.go index abaa6c49d..a9d63f921 100644 --- a/cc/library.go +++ b/cc/library.go @@ -267,6 +267,9 @@ type libraryDecorator struct { // Location of the linked, unstripped library for shared libraries unstrippedOutputFile android.Path + // Location of the file that should be copied to dist dir when requested + distFile android.OptionalPath + versionScriptPath android.ModuleGenPath // Decorated interafaces @@ -542,10 +545,16 @@ func (library *libraryDecorator) linkStatic(ctx ModuleContext, outputFile := android.PathForModuleOut(ctx, fileName) builderFlags := flagsToBuilderFlags(flags) - if Bool(library.baseLinker.Properties.Use_version_lib) && ctx.Host() { - versionedOutputFile := outputFile - outputFile = android.PathForModuleOut(ctx, "unversioned", fileName) - library.injectVersionSymbol(ctx, outputFile, versionedOutputFile) + if Bool(library.baseLinker.Properties.Use_version_lib) { + if ctx.Host() { + versionedOutputFile := outputFile + outputFile = android.PathForModuleOut(ctx, "unversioned", fileName) + library.injectVersionSymbol(ctx, outputFile, versionedOutputFile) + } else { + versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName) + library.distFile = android.OptionalPathForPath(versionedOutputFile) + library.injectVersionSymbol(ctx, outputFile, versionedOutputFile) + } } TransformObjToStaticLib(ctx, library.objects.objFiles, builderFlags, outputFile, objs.tidyFiles) @@ -619,10 +628,23 @@ func (library *libraryDecorator) linkShared(ctx ModuleContext, library.unstrippedOutputFile = outputFile - if Bool(library.baseLinker.Properties.Use_version_lib) && ctx.Host() { - versionedOutputFile := outputFile - outputFile = android.PathForModuleOut(ctx, "unversioned", fileName) - library.injectVersionSymbol(ctx, outputFile, versionedOutputFile) + if Bool(library.baseLinker.Properties.Use_version_lib) { + if ctx.Host() { + versionedOutputFile := outputFile + outputFile = android.PathForModuleOut(ctx, "unversioned", fileName) + library.injectVersionSymbol(ctx, outputFile, versionedOutputFile) + } else { + versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName) + library.distFile = android.OptionalPathForPath(versionedOutputFile) + + if library.stripper.needsStrip(ctx) { + out := android.PathForModuleOut(ctx, "versioned-stripped", fileName) + library.distFile = android.OptionalPathForPath(out) + library.stripper.strip(ctx, versionedOutputFile, out, builderFlags) + } + + library.injectVersionSymbol(ctx, outputFile, versionedOutputFile) + } } sharedLibs := deps.SharedLibs