Merge "Avoid creating APEX variant for sdk member"
diff --git a/android/Android.bp b/android/Android.bp
index 96f0983..50faa44 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -24,6 +24,7 @@
"filegroup.go",
"hooks.go",
"image.go",
+ "makefile_goal.go",
"makevars.go",
"metrics.go",
"module.go",
@@ -39,7 +40,6 @@
"paths.go",
"phony.go",
"prebuilt.go",
- "prebuilt_build_tool.go",
"proto.go",
"register.go",
"rule_builder.go",
diff --git a/android/androidmk.go b/android/androidmk.go
index 94b4b81..7e86140 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -126,6 +126,26 @@
}
}
+func (a *AndroidMkEntries) SetPaths(name string, paths Paths) {
+ if _, ok := a.EntryMap[name]; !ok {
+ a.entryOrder = append(a.entryOrder, name)
+ }
+ a.EntryMap[name] = paths.Strings()
+}
+
+func (a *AndroidMkEntries) SetOptionalPaths(name string, paths Paths) {
+ if len(paths) > 0 {
+ a.SetPaths(name, paths)
+ }
+}
+
+func (a *AndroidMkEntries) AddPaths(name string, paths Paths) {
+ if _, ok := a.EntryMap[name]; !ok {
+ a.entryOrder = append(a.entryOrder, name)
+ }
+ a.EntryMap[name] = append(a.EntryMap[name], paths.Strings()...)
+}
+
func (a *AndroidMkEntries) SetBoolIfTrue(name string, flag bool) {
if flag {
if _, ok := a.EntryMap[name]; !ok {
diff --git a/android/config.go b/android/config.go
index d680b65..aeed81d 100644
--- a/android/config.go
+++ b/android/config.go
@@ -337,8 +337,8 @@
config: config,
}
- // Sanity check the build and source directories. This won't catch strange
- // configurations with symlinks, but at least checks the obvious cases.
+ // Soundness check of the build and source directories. This won't catch strange
+ // configurations with symlinks, but at least checks the obvious case.
absBuildDir, err := filepath.Abs(buildDir)
if err != nil {
return Config{}, err
@@ -1252,10 +1252,6 @@
return c.productVariables.MissingUsesLibraries
}
-func (c *deviceConfig) BoardVndkRuntimeDisable() bool {
- return Bool(c.config.productVariables.BoardVndkRuntimeDisable)
-}
-
func (c *deviceConfig) DeviceArch() string {
return String(c.config.productVariables.DeviceArch)
}
diff --git a/android/defs.go b/android/defs.go
index 83daa03..4552224 100644
--- a/android/defs.go
+++ b/android/defs.go
@@ -69,7 +69,7 @@
// A symlink rule.
Symlink = pctx.AndroidStaticRule("Symlink",
blueprint.RuleParams{
- Command: "rm -f $out && ln -f -s $fromPath $out",
+ Command: "ln -f -s $fromPath $out",
Description: "symlink $out",
},
"fromPath")
diff --git a/android/makefile_goal.go b/android/makefile_goal.go
new file mode 100644
index 0000000..eae3976
--- /dev/null
+++ b/android/makefile_goal.go
@@ -0,0 +1,99 @@
+// Copyright 2020 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android
+
+import (
+ "fmt"
+ "io"
+ "path/filepath"
+
+ "github.com/google/blueprint/proptools"
+)
+
+func init() {
+ RegisterModuleType("makefile_goal", MakefileGoalFactory)
+}
+
+type makefileGoalProperties struct {
+ // Sources.
+
+ // Makefile goal output file path, relative to PRODUCT_OUT.
+ Product_out_path *string
+}
+
+type makefileGoal struct {
+ ModuleBase
+
+ properties makefileGoalProperties
+
+ // Destination. Output file path of this module.
+ outputFilePath OutputPath
+}
+
+var _ AndroidMkEntriesProvider = (*makefileGoal)(nil)
+var _ OutputFileProducer = (*makefileGoal)(nil)
+
+// Input file of this makefile_goal module. Nil if none specified. May use variable names in makefiles.
+func (p *makefileGoal) inputPath() *string {
+ if p.properties.Product_out_path != nil {
+ return proptools.StringPtr(filepath.Join("$(PRODUCT_OUT)", proptools.String(p.properties.Product_out_path)))
+ }
+ return nil
+}
+
+// OutputFileProducer
+func (p *makefileGoal) OutputFiles(tag string) (Paths, error) {
+ if tag != "" {
+ return nil, fmt.Errorf("unsupported tag %q", tag)
+ }
+ return Paths{p.outputFilePath}, nil
+}
+
+// AndroidMkEntriesProvider
+func (p *makefileGoal) DepsMutator(ctx BottomUpMutatorContext) {
+ if p.inputPath() == nil {
+ ctx.PropertyErrorf("product_out_path", "Path relative to PRODUCT_OUT required")
+ }
+}
+
+func (p *makefileGoal) GenerateAndroidBuildActions(ctx ModuleContext) {
+ filename := filepath.Base(proptools.String(p.inputPath()))
+ p.outputFilePath = PathForModuleOut(ctx, filename).OutputPath
+
+ ctx.InstallFile(PathForModuleInstall(ctx, "etc"), ctx.ModuleName(), p.outputFilePath)
+}
+
+func (p *makefileGoal) AndroidMkEntries() []AndroidMkEntries {
+ return []AndroidMkEntries{AndroidMkEntries{
+ Class: "ETC",
+ OutputFile: OptionalPathForPath(p.outputFilePath),
+ ExtraFooters: []AndroidMkExtraFootersFunc{
+ func(w io.Writer, name, prefix, moduleDir string, entries *AndroidMkEntries) {
+ // Can't use Cp because inputPath() is not a valid Path.
+ fmt.Fprintf(w, "$(eval $(call copy-one-file,%s,%s))\n", proptools.String(p.inputPath()), p.outputFilePath)
+ },
+ },
+ }}
+}
+
+// Import a Makefile goal to Soong by copying the file built by
+// the goal to a path visible to Soong. This rule only works on boot images.
+func MakefileGoalFactory() Module {
+ module := &makefileGoal{}
+ module.AddProperties(&module.properties)
+ // This module is device-only
+ InitAndroidArchModule(module, DeviceSupported, MultilibFirst)
+ return module
+}
diff --git a/android/neverallow.go b/android/neverallow.go
index 526d399..73829f1 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -56,6 +56,7 @@
AddNeverAllowRules(createJavaDeviceForHostRules()...)
AddNeverAllowRules(createCcSdkVariantRules()...)
AddNeverAllowRules(createUncompressDexRules()...)
+ AddNeverAllowRules(createMakefileGoalRules()...)
}
// Add a NeverAllow rule to the set of rules to apply.
@@ -231,6 +232,15 @@
}
}
+func createMakefileGoalRules() []Rule {
+ return []Rule{
+ NeverAllow().
+ ModuleType("makefile_goal").
+ WithoutMatcher("product_out_path", Regexp("^boot[0-9a-zA-Z.-]*[.]img$")).
+ Because("Only boot images may be imported as a makefile goal."),
+ }
+}
+
func neverallowMutator(ctx BottomUpMutatorContext) {
m, ok := ctx.Module().(Module)
if !ok {
diff --git a/android/neverallow_test.go b/android/neverallow_test.go
index 45d36a6..56a07dc 100644
--- a/android/neverallow_test.go
+++ b/android/neverallow_test.go
@@ -326,6 +326,20 @@
"module \"outside_art_libraries\": violates neverallow",
},
},
+ {
+ name: "disallowed makefile_goal",
+ fs: map[string][]byte{
+ "Android.bp": []byte(`
+ makefile_goal {
+ name: "foo",
+ product_out_path: "boot/trap.img"
+ }
+ `),
+ },
+ expectedErrors: []string{
+ "Only boot images may be imported as a makefile goal.",
+ },
+ },
}
func TestNeverallow(t *testing.T) {
@@ -350,6 +364,7 @@
ctx.RegisterModuleType("java_library", newMockJavaLibraryModule)
ctx.RegisterModuleType("java_library_host", newMockJavaLibraryModule)
ctx.RegisterModuleType("java_device_for_host", newMockJavaLibraryModule)
+ ctx.RegisterModuleType("makefile_goal", newMockMakefileGoalModule)
ctx.PostDepsMutators(RegisterNeverallowMutator)
ctx.Register(config)
@@ -438,3 +453,22 @@
func (p *mockJavaLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
}
+
+type mockMakefileGoalProperties struct {
+ Product_out_path *string
+}
+
+type mockMakefileGoalModule struct {
+ ModuleBase
+ properties mockMakefileGoalProperties
+}
+
+func newMockMakefileGoalModule() Module {
+ m := &mockMakefileGoalModule{}
+ m.AddProperties(&m.properties)
+ InitAndroidModule(m)
+ return m
+}
+
+func (p *mockMakefileGoalModule) GenerateAndroidBuildActions(ModuleContext) {
+}
diff --git a/android/prebuilt_build_tool.go b/android/prebuilt_build_tool.go
deleted file mode 100644
index d457da4..0000000
--- a/android/prebuilt_build_tool.go
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2020 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package android
-
-import (
- "path"
- "path/filepath"
-)
-
-func init() {
- RegisterModuleType("prebuilt_build_tool", prebuiltBuildToolFactory)
-}
-
-type prebuiltBuildToolProperties struct {
- // Source file to be executed for this build tool
- Src *string `android:"path,arch_variant"`
-
- // Extra files that should trigger rules using this tool to rebuild
- Deps []string `android:"path,arch_variant"`
-}
-
-type prebuiltBuildTool struct {
- ModuleBase
- prebuilt Prebuilt
-
- properties prebuiltBuildToolProperties
-
- toolPath OptionalPath
-}
-
-func (t *prebuiltBuildTool) Name() string {
- return t.prebuilt.Name(t.ModuleBase.Name())
-}
-
-func (t *prebuiltBuildTool) Prebuilt() *Prebuilt {
- return &t.prebuilt
-}
-
-func (t *prebuiltBuildTool) DepsMutator(ctx BottomUpMutatorContext) {
- if t.properties.Src == nil {
- ctx.PropertyErrorf("src", "missing prebuilt source file")
- }
-}
-
-func (t *prebuiltBuildTool) GenerateAndroidBuildActions(ctx ModuleContext) {
- sourcePath := t.prebuilt.SingleSourcePath(ctx)
- installedPath := PathForModuleOut(ctx, t.ModuleBase.Name())
- deps := PathsForModuleSrc(ctx, t.properties.Deps)
-
- var relPath string
- if filepath.IsAbs(installedPath.String()) {
- relPath = filepath.Join(absSrcDir, sourcePath.String())
- } else {
- var err error
- relPath, err = filepath.Rel(path.Dir(installedPath.String()), sourcePath.String())
- if err != nil {
- ctx.ModuleErrorf("Unable to generate symlink between %q and %q: %s", installedPath.String(), sourcePath.String(), err)
- }
- }
-
- ctx.Build(pctx, BuildParams{
- Rule: Symlink,
- Output: installedPath,
- Input: sourcePath,
- Implicits: deps,
- Args: map[string]string{
- "fromPath": relPath,
- },
- })
-
- t.toolPath = OptionalPathForPath(installedPath)
-}
-
-func (t *prebuiltBuildTool) HostToolPath() OptionalPath {
- return t.toolPath
-}
-
-var _ HostToolProvider = &prebuiltBuildTool{}
-
-// prebuilt_build_tool is to declare prebuilts to be used during the build, particularly for use
-// in genrules with the "tools" property.
-func prebuiltBuildToolFactory() Module {
- module := &prebuiltBuildTool{}
- module.AddProperties(&module.properties)
- InitSingleSourcePrebuiltModule(module, &module.properties, "Src")
- InitAndroidArchModule(module, HostSupportedNoCross, MultilibFirst)
- return module
-}
diff --git a/android/variable.go b/android/variable.go
index 2c8bd07..5826138 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -308,8 +308,6 @@
BoardPlatPrivateSepolicyDirs []string `json:",omitempty"`
BoardSepolicyM4Defs []string `json:",omitempty"`
- BoardVndkRuntimeDisable *bool `json:",omitempty"`
-
VendorVars map[string]map[string]string `json:",omitempty"`
Ndk_abis *bool `json:",omitempty"`
diff --git a/apex/androidmk.go b/apex/androidmk.go
index 10cc4b6..82a902b 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -82,9 +82,9 @@
var moduleName string
if linkToSystemLib {
- moduleName = fi.moduleName
+ moduleName = fi.androidMkModuleName
} else {
- moduleName = fi.moduleName + "." + apexBundleName + a.suffix
+ moduleName = fi.androidMkModuleName + "." + apexBundleName + a.suffix
}
if !android.InList(moduleName, moduleNames) {
@@ -250,9 +250,9 @@
}
// m <module_name> will build <module_name>.<apex_name> as well.
- if fi.moduleName != moduleName && a.primaryApexType {
- fmt.Fprintln(w, ".PHONY: "+fi.moduleName)
- fmt.Fprintln(w, fi.moduleName+": "+moduleName)
+ if fi.androidMkModuleName != moduleName && a.primaryApexType {
+ fmt.Fprintf(w, ".PHONY: %s\n", fi.androidMkModuleName)
+ fmt.Fprintf(w, "%s: %s\n", fi.androidMkModuleName, moduleName)
}
}
return moduleNames
@@ -353,6 +353,10 @@
if apexType == imageApex {
fmt.Fprintln(w, "ALL_MODULES.$(my_register_name).BUNDLE :=", a.bundleModuleFile.String())
}
+ if len(a.lintReports) > 0 {
+ fmt.Fprintln(w, "ALL_MODULES.$(my_register_name).LINT_REPORTS :=",
+ strings.Join(a.lintReports.Strings(), " "))
+ }
if a.installedFilesFile != nil {
goal := "checkbuild"
diff --git a/apex/apex.go b/apex/apex.go
index 86963fd..e3a95fa 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -691,6 +691,14 @@
MinSdkVersion: a.minSdkVersion(mctx),
Updatable: a.Updatable(),
}
+
+ useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
+ excludeVndkLibs := useVndk && proptools.Bool(a.properties.Use_vndk_as_stable)
+ if !useVndk && proptools.Bool(a.properties.Use_vndk_as_stable) {
+ mctx.PropertyErrorf("use_vndk_as_stable", "not supported for system/system_ext APEXes")
+ return
+ }
+
mctx.WalkDeps(func(child, parent android.Module) bool {
am, ok := child.(android.ApexModule)
if !ok || !am.CanHaveApexVariants() {
@@ -699,6 +707,11 @@
if !parent.(android.DepIsInSameApex).DepIsInSameApex(mctx, child) {
return false
}
+ if excludeVndkLibs {
+ if c, ok := child.(*cc.Module); ok && c.IsVndk() {
+ return false
+ }
+ }
depName := mctx.OtherModuleName(child)
// If the parent is apexBundle, this child is directly depended.
@@ -1009,6 +1022,11 @@
// The minimum SDK version that this apex must be compatibile with.
Min_sdk_version *string
+
+ // If set true, VNDK libs are considered as stable libs and are not included in this apex.
+ // Should be only used in non-system apexes (e.g. vendor: true).
+ // Default is false.
+ Use_vndk_as_stable *bool
}
type apexTargetBundleProperties struct {
@@ -1134,12 +1152,14 @@
// apexFile represents a file in an APEX bundle
type apexFile struct {
- builtFile android.Path
- stem string
- moduleName string
- installDir string
- class apexFileClass
- module android.Module
+ builtFile android.Path
+ stem string
+ // Module name of `module` in AndroidMk. Note the generated AndroidMk module for
+ // apexFile is named something like <AndroidMk module name>.<apex name>[<apex suffix>]
+ androidMkModuleName string
+ installDir string
+ class apexFileClass
+ module android.Module
// list of symlinks that will be created in installDir that point to this apexFile
symlinks []string
dataPaths []android.DataPath
@@ -1151,19 +1171,20 @@
hostRequiredModuleNames []string
jacocoReportClassesFile android.Path // only for javalibs and apps
+ lintDepSets java.LintDepSets // only for javalibs and apps
certificate java.Certificate // only for apps
overriddenPackageName string // only for apps
isJniLib bool
}
-func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, moduleName string, installDir string, class apexFileClass, module android.Module) apexFile {
+func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, installDir string, class apexFileClass, module android.Module) apexFile {
ret := apexFile{
- builtFile: builtFile,
- moduleName: moduleName,
- installDir: installDir,
- class: class,
- module: module,
+ builtFile: builtFile,
+ androidMkModuleName: androidMkModuleName,
+ installDir: installDir,
+ class: class,
+ module: module,
}
if module != nil {
ret.moduleDir = ctx.OtherModuleDir(module)
@@ -1275,6 +1296,9 @@
// Struct holding the merged notice file paths in different formats
mergedNotices android.NoticeOutputs
+
+ // Optional list of lint report zip files for apexes that contain java or app modules
+ lintReports android.Paths
}
func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext,
@@ -1617,7 +1641,8 @@
}
fileToCopy := ccMod.OutputFile().Path()
- return newApexFile(ctx, fileToCopy, ccMod.Name(), dirInApex, nativeSharedLib, ccMod)
+ androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName
+ return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod)
}
func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFile {
@@ -1627,7 +1652,8 @@
}
dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath())
fileToCopy := cc.OutputFile().Path()
- af := newApexFile(ctx, fileToCopy, cc.Name(), dirInApex, nativeExecutable, cc)
+ androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName
+ af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc)
af.symlinks = cc.Symlinks()
af.dataPaths = cc.DataPaths()
return af
@@ -1636,7 +1662,7 @@
func apexFileForPyBinary(ctx android.BaseModuleContext, py *python.Module) apexFile {
dirInApex := "bin"
fileToCopy := py.HostToolPath().Path()
- return newApexFile(ctx, fileToCopy, py.Name(), dirInApex, pyBinary, py)
+ return newApexFile(ctx, fileToCopy, py.BaseModuleName(), dirInApex, pyBinary, py)
}
func apexFileForGoBinary(ctx android.BaseModuleContext, depName string, gb bootstrap.GoBinaryTool) apexFile {
dirInApex := "bin"
@@ -1655,25 +1681,33 @@
func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile {
dirInApex := filepath.Join("bin", sh.SubDir())
fileToCopy := sh.OutputFile()
- af := newApexFile(ctx, fileToCopy, sh.Name(), dirInApex, shBinary, sh)
+ af := newApexFile(ctx, fileToCopy, sh.BaseModuleName(), dirInApex, shBinary, sh)
af.symlinks = sh.Symlinks()
return af
}
-type javaDependency interface {
+type javaModule interface {
+ android.Module
+ BaseModuleName() string
DexJarBuildPath() android.Path
JacocoReportClassesFile() android.Path
+ LintDepSets() java.LintDepSets
+
Stem() string
}
-func apexFileForJavaLibrary(ctx android.BaseModuleContext, lib javaDependency, module android.Module) apexFile {
+var _ javaModule = (*java.Library)(nil)
+var _ javaModule = (*java.SdkLibrary)(nil)
+var _ javaModule = (*java.DexImport)(nil)
+var _ javaModule = (*java.SdkLibraryImport)(nil)
+
+func apexFileForJavaLibrary(ctx android.BaseModuleContext, module javaModule) apexFile {
dirInApex := "javalib"
- fileToCopy := lib.DexJarBuildPath()
- // Remove prebuilt_ if necessary so the source and prebuilt modules have the same name.
- name := strings.TrimPrefix(module.Name(), "prebuilt_")
- af := newApexFile(ctx, fileToCopy, name, dirInApex, javaSharedLib, module)
- af.jacocoReportClassesFile = lib.JacocoReportClassesFile()
- af.stem = lib.Stem() + ".jar"
+ fileToCopy := module.DexJarBuildPath()
+ af := newApexFile(ctx, fileToCopy, module.BaseModuleName(), dirInApex, javaSharedLib, module)
+ af.jacocoReportClassesFile = module.JacocoReportClassesFile()
+ af.lintDepSets = module.LintDepSets()
+ af.stem = module.Stem() + ".jar"
return af
}
@@ -1696,6 +1730,7 @@
OutputFile() android.Path
JacocoReportClassesFile() android.Path
Certificate() java.Certificate
+ BaseModuleName() string
}) apexFile {
appDir := "app"
if aapp.Privileged() {
@@ -1703,7 +1738,7 @@
}
dirInApex := filepath.Join(appDir, aapp.InstallApkName())
fileToCopy := aapp.OutputFile()
- af := newApexFile(ctx, fileToCopy, aapp.Name(), dirInApex, app, aapp)
+ af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
af.certificate = aapp.Certificate()
@@ -1809,7 +1844,8 @@
// Because APEXes targeting other than system/system_ext partitions
// can't set apex_available, we skip checks for these APEXes
- if ctx.SocSpecific() || ctx.DeviceSpecific() || ctx.ProductSpecific() {
+ if a.SocSpecific() || a.DeviceSpecific() ||
+ (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
return
}
@@ -2028,7 +2064,7 @@
case javaLibTag:
switch child.(type) {
case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport:
- af := apexFileForJavaLibrary(ctx, child.(javaDependency), child.(android.Module))
+ af := apexFileForJavaLibrary(ctx, child.(javaModule))
if !af.Ok() {
ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
return false
@@ -2051,7 +2087,7 @@
if ap.Privileged() {
appDir = "priv-app"
}
- af := newApexFile(ctx, ap.OutputFile(), ap.Name(),
+ af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(),
filepath.Join(appDir, ap.BaseModuleName()), appSet, ap)
af.certificate = java.PresignedCertificate
filesInfo = append(filesInfo, af)
@@ -2125,6 +2161,13 @@
// don't include it in this APEX
return false
}
+ if cc.UseVndk() && proptools.Bool(a.properties.Use_vndk_as_stable) && cc.IsVndk() {
+ // For vendor APEX with use_vndk_as_stable: true, we don't include VNDK libs
+ // and use them from VNDK APEX.
+ // TODO(b/159576928): add "vndk" as requiredDeps so that linkerconfig can make "vndk"
+ // linker namespace avaiable to this apex.
+ return false
+ }
af := apexFileForNativeLibrary(ctx, cc, handleSpecialLibs)
af.transitiveDep = true
if !a.Host() && !android.DirectlyInApex(ctx.ModuleName(), depName) && (cc.IsStubs() || cc.HasStubsVariants()) {
@@ -2161,7 +2204,7 @@
// use the name of the generated test binary (`fileToCopy`) instead of the name
// of the original test module (`depName`, shared by all `test_per_src`
// variations of that module).
- af.moduleName = filepath.Base(af.builtFile.String())
+ af.androidMkModuleName = filepath.Base(af.builtFile.String())
// these are not considered transitive dep
af.transitiveDep = false
filesInfo = append(filesInfo, af)
@@ -2242,7 +2285,8 @@
// APEXes targeting other than system/system_ext partitions use vendor/product variants.
// So we can't link them to /system/lib libs which are core variants.
- if a.SocSpecific() || a.DeviceSpecific() || a.ProductSpecific() {
+ if a.SocSpecific() || a.DeviceSpecific() ||
+ (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
a.linkToSystemLib = false
}
@@ -2272,6 +2316,8 @@
a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx)
a.buildApexDependencyInfo(ctx)
+
+ a.buildLintReports(ctx)
}
// Enforce that Java deps of the apex are using stable SDKs to compile
diff --git a/apex/apex_test.go b/apex/apex_test.go
index f064338..7db61d5 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -2203,6 +2203,55 @@
ensureContains(t, androidMk, `LOCAL_MODULE_PATH := /tmp/target/product/test_device/vendor/apex`)
}
+func TestVendorApex_use_vndk_as_stable(t *testing.T) {
+ ctx, _ := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ binaries: ["mybin"],
+ vendor: true,
+ use_vndk_as_stable: true,
+ }
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+ cc_binary {
+ name: "mybin",
+ vendor: true,
+ shared_libs: ["libvndk", "libvendor"],
+ }
+ cc_library {
+ name: "libvndk",
+ vndk: {
+ enabled: true,
+ },
+ vendor_available: true,
+ }
+ cc_library {
+ name: "libvendor",
+ vendor: true,
+ }
+ `)
+
+ vendorVariant := "android_vendor.VER_arm64_armv8-a"
+
+ ldRule := ctx.ModuleForTests("mybin", vendorVariant+"_myapex").Rule("ld")
+ libs := names(ldRule.Args["libFlags"])
+ // VNDK libs(libvndk/libc++) as they are
+ ensureListContains(t, libs, buildDir+"/.intermediates/libvndk/"+vendorVariant+"_shared/libvndk.so")
+ ensureListContains(t, libs, buildDir+"/.intermediates/libc++/"+vendorVariant+"_shared/libc++.so")
+ // non-stable Vendor libs as APEX variants
+ ensureListContains(t, libs, buildDir+"/.intermediates/libvendor/"+vendorVariant+"_shared_myapex/libvendor.so")
+
+ // VNDK libs are not included when use_vndk_as_stable: true
+ ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
+ "bin/mybin",
+ "lib64/libvendor.so",
+ })
+}
+
func TestAndroidMk_UseVendorRequired(t *testing.T) {
ctx, config := testApex(t, `
apex {
@@ -5179,6 +5228,57 @@
ensureRealfileExists(t, files, "lib64/myotherlib.so") // this is a real file
}
+func TestSymlinksFromApexToSystemRequiredModuleNames(t *testing.T) {
+ ctx, config := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ native_shared_libs: ["mylib"],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library_shared {
+ name: "mylib",
+ srcs: ["mylib.cpp"],
+ shared_libs: ["myotherlib"],
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [
+ "myapex",
+ "//apex_available:platform",
+ ],
+ }
+
+ cc_prebuilt_library_shared {
+ name: "myotherlib",
+ srcs: ["prebuilt.so"],
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [
+ "myapex",
+ "//apex_available:platform",
+ ],
+ }
+ `)
+
+ apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
+ data := android.AndroidMkDataForTest(t, config, "", apexBundle)
+ var builder strings.Builder
+ data.Custom(&builder, apexBundle.BaseModuleName(), "TARGET_", "", data)
+ androidMk := builder.String()
+ // `myotherlib` is added to `myapex` as symlink
+ ensureContains(t, androidMk, "LOCAL_MODULE := mylib.myapex\n")
+ ensureNotContains(t, androidMk, "LOCAL_MODULE := prebuilt_myotherlib.myapex\n")
+ ensureNotContains(t, androidMk, "LOCAL_MODULE := myotherlib.myapex\n")
+ // `myapex` should have `myotherlib` in its required line, not `prebuilt_myotherlib`
+ ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += mylib.myapex myotherlib apex_manifest.pb.myapex apex_pubkey.myapex\n")
+}
+
func TestApexWithJniLibs(t *testing.T) {
ctx, _ := testApex(t, `
apex {
diff --git a/apex/builder.go b/apex/builder.go
index a70c767..0a1ec3e 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -815,3 +815,12 @@
},
})
}
+
+func (a *apexBundle) buildLintReports(ctx android.ModuleContext) {
+ depSetsBuilder := java.NewLintDepSetBuilder()
+ for _, fi := range a.filesInfo {
+ depSetsBuilder.Transitive(fi.lintDepSets)
+ }
+
+ a.lintReports = java.BuildModuleLintReportZips(ctx, depSetsBuilder.Build())
+}
diff --git a/cc/cc.go b/cc/cc.go
index bea851f..57fe9ba 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -116,8 +116,6 @@
// Used for host bionic
LinkerFlagsFile string
DynamicLinker string
-
- Tools []string
}
type PathDeps struct {
@@ -160,8 +158,6 @@
// Path to the dynamic linker binary
DynamicLinker android.OptionalPath
-
- Tools map[string]android.Path
}
// LocalOrGlobalFlags contains flags that need to have values set globally by the build system or locally by the module
@@ -429,12 +425,6 @@
XrefCcFiles() android.Paths
}
-type ToolDependencyTag struct {
- blueprint.BaseDependencyTag
-
- Name string
-}
-
var (
dataLibDepTag = DependencyTag{Name: "data_lib", Library: true, Shared: true}
sharedExportDepTag = DependencyTag{Name: "shared", Library: true, Shared: true, ReexportFlags: true}
@@ -1704,7 +1694,6 @@
deps.LateSharedLibs = android.LastUniqueStrings(deps.LateSharedLibs)
deps.HeaderLibs = android.LastUniqueStrings(deps.HeaderLibs)
deps.RuntimeLibs = android.LastUniqueStrings(deps.RuntimeLibs)
- deps.Tools = android.LastUniqueStrings(deps.Tools)
for _, lib := range deps.ReexportSharedLibHeaders {
if !inList(lib, deps.SharedLibs) {
@@ -2048,11 +2037,6 @@
}, vndkExtDepTag, vndkdep.getVndkExtendsModuleName())
}
}
-
- for _, tool := range deps.Tools {
- actx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(),
- ToolDependencyTag{Name: tool}, tool)
- }
}
func BeginMutator(ctx android.BottomUpMutatorContext) {
@@ -2248,21 +2232,6 @@
depName := ctx.OtherModuleName(dep)
depTag := ctx.OtherModuleDependencyTag(dep)
- if toolDep, ok := depTag.(ToolDependencyTag); ok {
- if toolMod, ok := dep.(android.HostToolProvider); ok {
- if depPaths.Tools == nil {
- depPaths.Tools = make(map[string]android.Path)
- }
- toolPath := toolMod.HostToolPath()
- if !toolPath.Valid() {
- ctx.ModuleErrorf("Failed to find path for host tool %q", toolDep.Name)
- }
- depPaths.Tools[toolDep.Name] = toolPath.Path()
- } else {
- ctx.ModuleErrorf("Found module, but not host tool for %q", toolDep.Name)
- }
- }
-
ccDep, ok := dep.(LinkableInterface)
if !ok {
diff --git a/cc/compiler.go b/cc/compiler.go
index ba14dd5..d5ea2c3 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -251,14 +251,6 @@
deps.StaticLibs = append(deps.StaticLibs, "libomp")
}
- if compiler.hasSrcExt(".y") || compiler.hasSrcExt(".yy") {
- deps.Tools = append(deps.Tools, "bison", "m4")
- }
-
- if compiler.hasSrcExt(".l") || compiler.hasSrcExt(".ll") {
- deps.Tools = append(deps.Tools, "flex", "m4")
- }
-
return deps
}
@@ -589,7 +581,7 @@
srcs := append(android.Paths(nil), compiler.srcsBeforeGen...)
- srcs, genDeps := genSources(ctx, srcs, buildFlags, deps.Tools)
+ srcs, genDeps := genSources(ctx, srcs, buildFlags)
pathDeps = append(pathDeps, genDeps...)
compiler.pathDeps = pathDeps
diff --git a/cc/config/integer_overflow_blacklist.txt b/cc/config/integer_overflow_blocklist.txt
similarity index 100%
rename from cc/config/integer_overflow_blacklist.txt
rename to cc/config/integer_overflow_blocklist.txt
diff --git a/cc/gen.go b/cc/gen.go
index 6f9036b..b0aadc6 100644
--- a/cc/gen.go
+++ b/cc/gen.go
@@ -24,6 +24,7 @@
)
func init() {
+ pctx.SourcePathVariable("lexCmd", "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/flex")
pctx.SourcePathVariable("m4Cmd", "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/m4")
pctx.HostBinToolVariable("aidlCmd", "aidl-cpp")
@@ -31,6 +32,12 @@
}
var (
+ lex = pctx.AndroidStaticRule("lex",
+ blueprint.RuleParams{
+ Command: "M4=$m4Cmd $lexCmd -o$out $in",
+ CommandDeps: []string{"$lexCmd", "$m4Cmd"},
+ })
+
sysprop = pctx.AndroidStaticRule("sysprop",
blueprint.RuleParams{
Command: "$syspropCmd --header-dir=$headerOutDir --public-header-dir=$publicOutDir " +
@@ -59,8 +66,7 @@
}
func genYacc(ctx android.ModuleContext, rule *android.RuleBuilder, yaccFile android.Path,
- outFile android.ModuleGenPath, props *YaccProperties,
- tools map[string]android.Path) (headerFiles android.Paths) {
+ outFile android.ModuleGenPath, props *YaccProperties) (headerFiles android.Paths) {
outDir := android.PathForModuleGen(ctx, "yacc")
headerFile := android.GenPathWithExt(ctx, "yacc", yaccFile, "h")
@@ -91,17 +97,9 @@
}
}
- bison, ok := tools["bison"]
- if !ok {
- ctx.ModuleErrorf("Unable to find bison")
- }
- m4, ok := tools["m4"]
- if !ok {
- ctx.ModuleErrorf("Unable to find m4")
- }
-
- cmd.FlagWithInput("M4=", m4).
- Tool(bison).
+ cmd.Text("BISON_PKGDATADIR=prebuilts/build-tools/common/bison").
+ FlagWithInput("M4=", ctx.Config().PrebuiltBuildTool(ctx, "m4")).
+ PrebuiltBuildTool(ctx, "bison").
Flag("-d").
Flags(flags).
FlagWithOutput("--defines=", headerFile).
@@ -155,23 +153,13 @@
}
}
-func genLex(ctx android.ModuleContext, rule *android.RuleBuilder, lexFile android.Path,
- outFile android.ModuleGenPath, tools map[string]android.Path) {
-
- flex, ok := tools["flex"]
- if !ok {
- ctx.ModuleErrorf("Unable to find flex")
- }
- m4, ok := tools["m4"]
- if !ok {
- ctx.ModuleErrorf("Unable to find m4")
- }
-
- rule.Command().
- FlagWithInput("M4=", m4).
- Tool(flex).
- FlagWithOutput("-o", outFile).
- Input(lexFile)
+func genLex(ctx android.ModuleContext, lexFile android.Path, outFile android.ModuleGenPath) {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: lex,
+ Description: "lex " + lexFile.Rel(),
+ Output: outFile,
+ Input: lexFile,
+ })
}
func genSysprop(ctx android.ModuleContext, syspropFile android.Path) (android.Path, android.Paths) {
@@ -218,22 +206,14 @@
return rcFile, headerFile
}
-func genSources(ctx android.ModuleContext, srcFiles android.Paths, buildFlags builderFlags,
- tools map[string]android.Path) (android.Paths, android.Paths) {
+func genSources(ctx android.ModuleContext, srcFiles android.Paths,
+ buildFlags builderFlags) (android.Paths, android.Paths) {
var deps android.Paths
var rsFiles android.Paths
var aidlRule *android.RuleBuilder
- var lexRule_ *android.RuleBuilder
- lexRule := func() *android.RuleBuilder {
- if lexRule_ == nil {
- lexRule_ = android.NewRuleBuilder().Sbox(android.PathForModuleGen(ctx, "lex"))
- }
- return lexRule_
- }
-
var yaccRule_ *android.RuleBuilder
yaccRule := func() *android.RuleBuilder {
if yaccRule_ == nil {
@@ -247,19 +227,19 @@
case ".y":
cFile := android.GenPathWithExt(ctx, "yacc", srcFile, "c")
srcFiles[i] = cFile
- deps = append(deps, genYacc(ctx, yaccRule(), srcFile, cFile, buildFlags.yacc, tools)...)
+ deps = append(deps, genYacc(ctx, yaccRule(), srcFile, cFile, buildFlags.yacc)...)
case ".yy":
cppFile := android.GenPathWithExt(ctx, "yacc", srcFile, "cpp")
srcFiles[i] = cppFile
- deps = append(deps, genYacc(ctx, yaccRule(), srcFile, cppFile, buildFlags.yacc, tools)...)
+ deps = append(deps, genYacc(ctx, yaccRule(), srcFile, cppFile, buildFlags.yacc)...)
case ".l":
cFile := android.GenPathWithExt(ctx, "lex", srcFile, "c")
srcFiles[i] = cFile
- genLex(ctx, lexRule(), srcFile, cFile, tools)
+ genLex(ctx, srcFile, cFile)
case ".ll":
cppFile := android.GenPathWithExt(ctx, "lex", srcFile, "cpp")
srcFiles[i] = cppFile
- genLex(ctx, lexRule(), srcFile, cppFile, tools)
+ genLex(ctx, srcFile, cppFile)
case ".proto":
ccFile, headerFile := genProto(ctx, srcFile, buildFlags)
srcFiles[i] = ccFile
@@ -291,10 +271,6 @@
aidlRule.Build(pctx, ctx, "aidl", "gen aidl")
}
- if lexRule_ != nil {
- lexRule_.Build(pctx, ctx, "lex", "gen lex")
- }
-
if yaccRule_ != nil {
yaccRule_.Build(pctx, ctx, "yacc", "gen yacc")
}
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 4578fd3..22e3ec3 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -396,8 +396,8 @@
return module
}
-// ndk_library creates a stub library that exposes dummy implementation
-// of functions and variables for use at build time only.
+// ndk_library creates a library that exposes a stub implementation of functions
+// and variables for use at build time only.
func NdkLibraryFactory() android.Module {
module := newStubLibrary()
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibBoth)
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 72ad6d7..300bc8f 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -51,7 +51,7 @@
}
cfiCflags = []string{"-flto", "-fsanitize-cfi-cross-dso",
- "-fsanitize-blacklist=external/compiler-rt/lib/cfi/cfi_blacklist.txt"}
+ "-fsanitize-blacklist=external/compiler-rt/lib/cfi/cfi_blocklist.txt"}
// -flto and -fvisibility are required by clang when -fsanitize=cfi is
// used, but have no effect on assembly files
cfiAsflags = []string{"-flto", "-fvisibility=default"}
@@ -61,7 +61,7 @@
cfiStaticLibsMutex sync.Mutex
hwasanStaticLibsMutex sync.Mutex
- intOverflowCflags = []string{"-fsanitize-blacklist=build/soong/cc/config/integer_overflow_blacklist.txt"}
+ intOverflowCflags = []string{"-fsanitize-blacklist=build/soong/cc/config/integer_overflow_blocklist.txt"}
minimalRuntimeFlags = []string{"-fsanitize-minimal-runtime", "-fno-sanitize-trap=integer,undefined",
"-fno-sanitize-recover=integer,undefined"}
@@ -174,6 +174,8 @@
// value to pass to -fsanitize-blacklist
Blacklist *string
+ // value to pass to -fsanitize-blacklist
+ Blocklist *string
} `android:"arch_variant"`
SanitizerEnabled bool `blueprint:"mutated"`
@@ -596,6 +598,12 @@
flags.CFlagsDeps = append(flags.CFlagsDeps, blacklist.Path())
}
+ blocklist := android.OptionalPathForModuleSrc(ctx, sanitize.Properties.Sanitize.Blocklist)
+ if blocklist.Valid() {
+ flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize-blacklist="+blocklist.String())
+ flags.CFlagsDeps = append(flags.CFlagsDeps, blocklist.Path())
+ }
+
return flags
}
diff --git a/cc/vndk.go b/cc/vndk.go
index 4adf9d2..f9adec7 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -340,7 +340,7 @@
}
}
-// Sanity check for modules that mustn't be VNDK
+// Check for modules that mustn't be VNDK
func shouldSkipVndkMutator(m *Module) bool {
if !m.Enabled() {
return true
@@ -559,10 +559,6 @@
return
}
- if ctx.DeviceConfig().BoardVndkRuntimeDisable() {
- return
- }
-
var snapshotOutputs android.Paths
/*
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index e485c60..69e4f69 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -35,14 +35,14 @@
// A command represents an operation to be executed in the soong build
// system.
type command struct {
- // the flag name (must have double dashes)
+ // The flag name (must have double dashes).
flag string
- // description for the flag (to display when running help)
+ // Description for the flag (to display when running help).
description string
- // Forces the status output into dumb terminal mode.
- forceDumbOutput bool
+ // Stream the build status output into the simple terminal mode.
+ simpleOutput bool
// Sets a prefix string to use for filenames of log files.
logsPrefix string
@@ -70,21 +70,21 @@
stdio: stdio,
run: make,
}, {
- flag: "--dumpvar-mode",
- description: "print the value of the legacy make variable VAR to stdout",
- forceDumbOutput: true,
- logsPrefix: "dumpvars-",
- config: dumpVarConfig,
- stdio: customStdio,
- run: dumpVar,
+ flag: "--dumpvar-mode",
+ description: "print the value of the legacy make variable VAR to stdout",
+ simpleOutput: true,
+ logsPrefix: "dumpvars-",
+ config: dumpVarConfig,
+ stdio: customStdio,
+ run: dumpVar,
}, {
- flag: "--dumpvars-mode",
- description: "dump the values of one or more legacy make variables, in shell syntax",
- forceDumbOutput: true,
- logsPrefix: "dumpvars-",
- config: dumpVarConfig,
- stdio: customStdio,
- run: dumpVars,
+ flag: "--dumpvars-mode",
+ description: "dump the values of one or more legacy make variables, in shell syntax",
+ simpleOutput: true,
+ logsPrefix: "dumpvars-",
+ config: dumpVarConfig,
+ stdio: customStdio,
+ run: dumpVars,
}, {
flag: "--build-mode",
description: "build modules based on the specified build action",
@@ -125,7 +125,7 @@
os.Exit(1)
}
- output := terminal.NewStatusOutput(c.stdio().Stdout(), os.Getenv("NINJA_STATUS"), c.forceDumbOutput,
+ output := terminal.NewStatusOutput(c.stdio().Stdout(), os.Getenv("NINJA_STATUS"), c.simpleOutput,
build.OsEnvironment().IsEnvTrue("ANDROID_QUIET_BUILD"))
log := logger.New(output)
@@ -172,7 +172,7 @@
buildErrorFile := filepath.Join(logsDir, c.logsPrefix+"build_error")
rbeMetricsFile := filepath.Join(logsDir, c.logsPrefix+"rbe_metrics.pb")
soongMetricsFile := filepath.Join(logsDir, c.logsPrefix+"soong_metrics")
- defer build.UploadMetrics(buildCtx, config, c.forceDumbOutput, buildStarted, buildErrorFile, rbeMetricsFile, soongMetricsFile)
+ defer build.UploadMetrics(buildCtx, config, c.simpleOutput, buildStarted, buildErrorFile, rbeMetricsFile, soongMetricsFile)
os.MkdirAll(logsDir, 0777)
log.SetOutput(filepath.Join(logsDir, c.logsPrefix+"soong.log"))
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 00baa57..1cec289 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -259,9 +259,9 @@
// If AllowMissingDependencies is enabled, the build will not have stopped when
// AddFarVariationDependencies was called on a missing tool, which will result in nonsensical
- // "cmd: unknown location label ..." errors later. Add a dummy file to the local label. The
- // command that uses this dummy file will never be executed because the rule will be replaced with
- // an android.Error rule reporting the missing dependencies.
+ // "cmd: unknown location label ..." errors later. Add a placeholder file to the local label.
+ // The command that uses this placeholder file will never be executed because the rule will be
+ // replaced with an android.Error rule reporting the missing dependencies.
if ctx.Config().AllowMissingDependencies() {
for _, tool := range g.properties.Tools {
if !seenTools[tool] {
@@ -292,9 +292,9 @@
// If AllowMissingDependencies is enabled, the build will not have stopped when
// the dependency was added on a missing SourceFileProducer module, which will result in nonsensical
- // "cmd: label ":..." has no files" errors later. Add a dummy file to the local label. The
- // command that uses this dummy file will never be executed because the rule will be replaced with
- // an android.Error rule reporting the missing dependencies.
+ // "cmd: label ":..." has no files" errors later. Add a placeholder file to the local label.
+ // The command that uses this placeholder file will never be executed because the rule will be
+ // replaced with an android.Error rule reporting the missing dependencies.
ctx.AddMissingDependencies(missingDeps)
addLocationLabel(in, []string{"***missing srcs " + in + "***"})
} else {
diff --git a/java/Android.bp b/java/Android.bp
index fd06c46..e345014 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -10,6 +10,7 @@
"soong-dexpreopt",
"soong-genrule",
"soong-java-config",
+ "soong-python",
"soong-remoteexec",
"soong-tradefed",
],
diff --git a/java/androidmk.go b/java/androidmk.go
index 03994bf..25dd329 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -132,9 +132,7 @@
}
entries.SetString("LOCAL_MODULE_STEM", library.Stem())
- entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", library.linter.outputs.transitiveHTMLZip)
- entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", library.linter.outputs.transitiveTextZip)
- entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", library.linter.outputs.transitiveXMLZip)
+ entries.SetOptionalPaths("LOCAL_SOONG_LINT_REPORTS", library.linter.reports)
},
},
}
@@ -394,9 +392,7 @@
entries.AddStrings("LOCAL_SOONG_BUILT_INSTALLED", extra.String()+":"+install)
}
- entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", app.linter.outputs.transitiveHTMLZip)
- entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", app.linter.outputs.transitiveTextZip)
- entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", app.linter.outputs.transitiveXMLZip)
+ entries.SetOptionalPaths("LOCAL_SOONG_LINT_REPORTS", app.linter.reports)
},
},
ExtraFooters: []android.AndroidMkExtraFootersFunc{
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 190a052..935b839 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -1674,7 +1674,7 @@
impRule := android.NewRuleBuilder()
impCmd := impRule.Command()
- // A dummy action that copies the ninja generated rsp file to a new location. This allows us to
+ // An action that copies the ninja generated rsp file to a new location. This allows us to
// add a large number of inputs to a file without exceeding bash command length limits (which
// would happen if we use the WriteFile rule). The cp is needed because RuleBuilder sets the
// rsp file to be ${output}.rsp.
diff --git a/java/java.go b/java/java.go
index 367b09c..bd476bc 100644
--- a/java/java.go
+++ b/java/java.go
@@ -556,7 +556,20 @@
}
func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
- android.InitAndroidArchModule(module, hod, android.MultilibCommon)
+ initJavaModule(module, hod, false)
+}
+
+func InitJavaModuleMultiTargets(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
+ initJavaModule(module, hod, true)
+}
+
+func initJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported, multiTargets bool) {
+ multilib := android.MultilibCommon
+ if multiTargets {
+ android.InitAndroidMultiTargetsArchModule(module, hod, multilib)
+ } else {
+ android.InitAndroidArchModule(module, hod, multilib)
+ }
android.InitDefaultableModule(module)
}
@@ -575,6 +588,7 @@
}
var (
+ dataNativeBinsTag = dependencyTag{name: "dataNativeBins"}
staticLibTag = dependencyTag{name: "staticlib"}
libTag = dependencyTag{name: "javalib"}
java9LibTag = dependencyTag{name: "java9lib"}
@@ -1707,6 +1721,9 @@
j.linter.compileSdkVersion = lintSDKVersionString(j.sdkVersion())
j.linter.javaLanguageLevel = flags.javaVersion.String()
j.linter.kotlinLanguageLevel = "1.3"
+ if j.ApexName() != "" && ctx.Config().UnbundledBuildApps() {
+ j.linter.buildModuleReportZip = true
+ }
j.linter.lint(ctx)
}
@@ -2190,6 +2207,11 @@
Test_mainline_modules []string
}
+type hostTestProperties struct {
+ // list of native binary modules that should be installed alongside the test
+ Data_native_bins []string `android:"arch_variant"`
+}
+
type testHelperLibraryProperties struct {
// list of compatibility suites (for example "cts", "vts") that the module should be
// installed into.
@@ -2215,6 +2237,12 @@
data android.Paths
}
+type TestHost struct {
+ Test
+
+ testHostProperties hostTestProperties
+}
+
type TestHelperLibrary struct {
Library
@@ -2229,11 +2257,26 @@
testConfig android.Path
}
+func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) {
+ if len(j.testHostProperties.Data_native_bins) > 0 {
+ for _, target := range ctx.MultiTargets() {
+ ctx.AddVariationDependencies(target.Variations(), dataNativeBinsTag, j.testHostProperties.Data_native_bins...)
+ }
+ }
+
+ j.deps(ctx)
+}
+
func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template,
j.testProperties.Test_suites, j.testProperties.Auto_gen_config)
+
j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data)
+ ctx.VisitDirectDepsWithTag(dataNativeBinsTag, func(dep android.Module) {
+ j.data = append(j.data, android.OutputFileForModule(ctx, dep, ""))
+ })
+
j.Library.GenerateAndroidBuildActions(ctx)
}
@@ -2374,14 +2417,15 @@
// A java_test_host has a single variant that produces a `.jar` file containing `.class` files that were
// compiled against the host bootclasspath.
func TestHostFactory() android.Module {
- module := &Test{}
+ module := &TestHost{}
module.addHostProperties()
module.AddProperties(&module.testProperties)
+ module.AddProperties(&module.testHostProperties)
module.Module.properties.Installable = proptools.BoolPtr(true)
- InitJavaModule(module, android.HostSupported)
+ InitJavaModuleMultiTargets(module, android.HostSupported)
return module
}
@@ -2789,6 +2833,10 @@
return nil
}
+func (a *DexImport) LintDepSets() LintDepSets {
+ return LintDepSets{}
+}
+
func (j *DexImport) IsInstallable() bool {
return true
}
diff --git a/java/java_test.go b/java/java_test.go
index db3f187..582ebe9 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -31,6 +31,7 @@
"android/soong/cc"
"android/soong/dexpreopt"
"android/soong/genrule"
+ "android/soong/python"
)
var buildDir string
@@ -81,6 +82,7 @@
ctx.RegisterModuleType("java_plugin", PluginFactory)
ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
ctx.RegisterModuleType("genrule", genrule.GenRuleFactory)
+ ctx.RegisterModuleType("python_binary_host", python.PythonBinaryHostFactory)
RegisterDocsBuildComponents(ctx)
RegisterStubsBuildComponents(ctx)
RegisterSdkLibraryBuildComponents(ctx)
@@ -89,6 +91,7 @@
RegisterPrebuiltApisBuildComponents(ctx)
+ ctx.PreDepsMutators(python.RegisterPythonPreDepsMutators)
ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
ctx.RegisterPreSingletonType("overlay", android.SingletonFactoryAdaptor(OverlaySingletonFactory))
ctx.RegisterPreSingletonType("sdk_versions", android.SingletonFactoryAdaptor(sdkPreSingletonFactory))
@@ -486,7 +489,7 @@
ctx, _ := testJavaWithConfig(t, config)
- // first, sanity check that the -g flag is added to target modules
+ // first, check that the -g flag is added to target modules
targetLibrary := ctx.ModuleForTests("target_library", "android_common")
targetJavaFlags := targetLibrary.Module().VariablesForTests()["javacFlags"]
if !strings.Contains(targetJavaFlags, "-g:source,lines") {
@@ -2008,3 +2011,28 @@
t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
}
}
+
+func TestDataNativeBinaries(t *testing.T) {
+ ctx, config := testJava(t, `
+ java_test_host {
+ name: "foo",
+ srcs: ["a.java"],
+ data_native_bins: ["bin"]
+ }
+
+ python_binary_host {
+ name: "bin",
+ srcs: ["bin.py"],
+ }
+ `)
+
+ buildOS := android.BuildOs.String()
+
+ test := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost)
+ entries := android.AndroidMkEntriesForTest(t, config, "", test)[0]
+ expected := []string{buildDir + "/.intermediates/bin/" + buildOS + "_x86_64_PY3/bin:bin"}
+ actual := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
+ if !reflect.DeepEqual(expected, actual) {
+ t.Errorf("Unexpected test data - expected: %q, actual: %q", expected, actual)
+ }
+}
diff --git a/java/lint.go b/java/lint.go
index 5d2c4f6..1bf7f69 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -69,28 +69,78 @@
outputs lintOutputs
properties LintProperties
+ reports android.Paths
+
buildModuleReportZip bool
}
type lintOutputs struct {
- html android.ModuleOutPath
- text android.ModuleOutPath
- xml android.ModuleOutPath
+ html android.Path
+ text android.Path
+ xml android.Path
- transitiveHTML *android.DepSet
- transitiveText *android.DepSet
- transitiveXML *android.DepSet
-
- transitiveHTMLZip android.OptionalPath
- transitiveTextZip android.OptionalPath
- transitiveXMLZip android.OptionalPath
+ depSets LintDepSets
}
-type lintOutputIntf interface {
+type lintOutputsIntf interface {
lintOutputs() *lintOutputs
}
-var _ lintOutputIntf = (*linter)(nil)
+type lintDepSetsIntf interface {
+ LintDepSets() LintDepSets
+}
+
+type LintDepSets struct {
+ HTML, Text, XML *android.DepSet
+}
+
+type LintDepSetsBuilder struct {
+ HTML, Text, XML *android.DepSetBuilder
+}
+
+func NewLintDepSetBuilder() LintDepSetsBuilder {
+ return LintDepSetsBuilder{
+ HTML: android.NewDepSetBuilder(android.POSTORDER),
+ Text: android.NewDepSetBuilder(android.POSTORDER),
+ XML: android.NewDepSetBuilder(android.POSTORDER),
+ }
+}
+
+func (l LintDepSetsBuilder) Direct(html, text, xml android.Path) LintDepSetsBuilder {
+ l.HTML.Direct(html)
+ l.Text.Direct(text)
+ l.XML.Direct(xml)
+ return l
+}
+
+func (l LintDepSetsBuilder) Transitive(depSets LintDepSets) LintDepSetsBuilder {
+ if depSets.HTML != nil {
+ l.HTML.Transitive(depSets.HTML)
+ }
+ if depSets.Text != nil {
+ l.Text.Transitive(depSets.Text)
+ }
+ if depSets.XML != nil {
+ l.XML.Transitive(depSets.XML)
+ }
+ return l
+}
+
+func (l LintDepSetsBuilder) Build() LintDepSets {
+ return LintDepSets{
+ HTML: l.HTML.Build(),
+ Text: l.Text.Build(),
+ XML: l.XML.Build(),
+ }
+}
+
+func (l *linter) LintDepSets() LintDepSets {
+ return l.outputs.depSets
+}
+
+var _ lintDepSetsIntf = (*linter)(nil)
+
+var _ lintOutputsIntf = (*linter)(nil)
func (l *linter) lintOutputs() *lintOutputs {
return &l.outputs
@@ -202,7 +252,7 @@
return projectXMLPath, configXMLPath, cacheDir, homeDir, deps
}
-// generateManifest adds a command to the rule to write a dummy manifest cat contains the
+// generateManifest adds a command to the rule to write a simple manifest that contains the
// minSdkVersion and targetSdkVersion for modules (like java_library) that don't have a manifest.
func (l *linter) generateManifest(ctx android.ModuleContext, rule *android.RuleBuilder) android.Path {
manifestPath := android.PathForModuleOut(ctx, "lint", "AndroidManifest.xml")
@@ -247,16 +297,11 @@
text := android.PathForModuleOut(ctx, "lint-report.txt")
xml := android.PathForModuleOut(ctx, "lint-report.xml")
- htmlDeps := android.NewDepSetBuilder(android.POSTORDER).Direct(html)
- textDeps := android.NewDepSetBuilder(android.POSTORDER).Direct(text)
- xmlDeps := android.NewDepSetBuilder(android.POSTORDER).Direct(xml)
+ depSetsBuilder := NewLintDepSetBuilder().Direct(html, text, xml)
ctx.VisitDirectDepsWithTag(staticLibTag, func(dep android.Module) {
- if depLint, ok := dep.(lintOutputIntf); ok {
- depLintOutputs := depLint.lintOutputs()
- htmlDeps.Transitive(depLintOutputs.transitiveHTML)
- textDeps.Transitive(depLintOutputs.transitiveText)
- xmlDeps.Transitive(depLintOutputs.transitiveXML)
+ if depLint, ok := dep.(lintDepSetsIntf); ok {
+ depSetsBuilder.Transitive(depLint.LintDepSets())
}
})
@@ -309,26 +354,35 @@
text: text,
xml: xml,
- transitiveHTML: htmlDeps.Build(),
- transitiveText: textDeps.Build(),
- transitiveXML: xmlDeps.Build(),
+ depSets: depSetsBuilder.Build(),
}
if l.buildModuleReportZip {
- htmlZip := android.PathForModuleOut(ctx, "lint-report-html.zip")
- l.outputs.transitiveHTMLZip = android.OptionalPathForPath(htmlZip)
- lintZip(ctx, l.outputs.transitiveHTML.ToSortedList(), htmlZip)
-
- textZip := android.PathForModuleOut(ctx, "lint-report-text.zip")
- l.outputs.transitiveTextZip = android.OptionalPathForPath(textZip)
- lintZip(ctx, l.outputs.transitiveText.ToSortedList(), textZip)
-
- xmlZip := android.PathForModuleOut(ctx, "lint-report-xml.zip")
- l.outputs.transitiveXMLZip = android.OptionalPathForPath(xmlZip)
- lintZip(ctx, l.outputs.transitiveXML.ToSortedList(), xmlZip)
+ l.reports = BuildModuleLintReportZips(ctx, l.LintDepSets())
}
}
+func BuildModuleLintReportZips(ctx android.ModuleContext, depSets LintDepSets) android.Paths {
+ htmlList := depSets.HTML.ToSortedList()
+ textList := depSets.Text.ToSortedList()
+ xmlList := depSets.XML.ToSortedList()
+
+ if len(htmlList) == 0 && len(textList) == 0 && len(xmlList) == 0 {
+ return nil
+ }
+
+ htmlZip := android.PathForModuleOut(ctx, "lint-report-html.zip")
+ lintZip(ctx, htmlList, htmlZip)
+
+ textZip := android.PathForModuleOut(ctx, "lint-report-text.zip")
+ lintZip(ctx, textList, textZip)
+
+ xmlZip := android.PathForModuleOut(ctx, "lint-report-xml.zip")
+ lintZip(ctx, xmlList, xmlZip)
+
+ return android.Paths{htmlZip, textZip, xmlZip}
+}
+
type lintSingleton struct {
htmlZip android.WritablePath
textZip android.WritablePath
@@ -403,7 +457,7 @@
return
}
- if l, ok := m.(lintOutputIntf); ok {
+ if l, ok := m.(lintOutputsIntf); ok {
outputs = append(outputs, l.lintOutputs())
}
})
@@ -414,7 +468,9 @@
var paths android.Paths
for _, output := range outputs {
- paths = append(paths, get(output))
+ if p := get(output); p != nil {
+ paths = append(paths, p)
+ }
}
lintZip(ctx, paths, outputPath)
diff --git a/java/sdk.go b/java/sdk.go
index 6e67a13..5d79d1d 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -214,7 +214,7 @@
// "current" can be built from source and be from prebuilt SDK
return ctx.Config().UnbundledBuildUsePrebuiltSdks()
} else if s.version.isNumbered() {
- // sanity check
+ // validation check
if s.kind != sdkPublic && s.kind != sdkSystem && s.kind != sdkTest {
panic(fmt.Errorf("prebuilt SDK is not not available for sdkKind=%q", s.kind))
return false
diff --git a/java/sdk_library.go b/java/sdk_library.go
index e3ba2c7..8a8d0c9 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1996,6 +1996,15 @@
}
// to satisfy apex.javaDependency interface
+func (module *SdkLibraryImport) LintDepSets() LintDepSets {
+ if module.implLibraryModule == nil {
+ return LintDepSets{}
+ } else {
+ return module.implLibraryModule.LintDepSets()
+ }
+}
+
+// to satisfy apex.javaDependency interface
func (module *SdkLibraryImport) Stem() string {
return module.BaseModuleName()
}
diff --git a/java/testing.go b/java/testing.go
index e761743..1e725fa 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -22,6 +22,8 @@
"android/soong/android"
"android/soong/cc"
+ "android/soong/python"
+
"github.com/google/blueprint"
)
@@ -85,6 +87,10 @@
"prebuilts/sdk/tools/core-lambda-stubs.jar": nil,
"prebuilts/sdk/Android.bp": []byte(`prebuilt_apis { name: "sdk", api_dirs: ["14", "28", "30", "current"],}`),
+ "bin.py": nil,
+ python.StubTemplateHost: []byte(`PYTHON_BINARY = '%interpreter%'
+ MAIN_FILE = '%main%'`),
+
// For java_sdk_library
"api/module-lib-current.txt": nil,
"api/module-lib-removed.txt": nil,
diff --git a/python/binary.go b/python/binary.go
index 695fa12..5a74926 100644
--- a/python/binary.go
+++ b/python/binary.go
@@ -65,7 +65,7 @@
}
var (
- stubTemplateHost = "build/soong/python/scripts/stub_template_host.txt"
+ StubTemplateHost = "build/soong/python/scripts/stub_template_host.txt"
)
func NewBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) {
diff --git a/python/builder.go b/python/builder.go
index 36baecd..dc2d1f1 100644
--- a/python/builder.go
+++ b/python/builder.go
@@ -91,7 +91,7 @@
if !embeddedLauncher {
// the path of stub_template_host.txt from source tree.
- template := android.PathForSource(ctx, stubTemplateHost)
+ template := android.PathForSource(ctx, StubTemplateHost)
implicits = append(implicits, template)
// intermediate output path for __main__.py
diff --git a/python/python.go b/python/python.go
index a6c9e2a..479c729 100644
--- a/python/python.go
+++ b/python/python.go
@@ -30,9 +30,11 @@
)
func init() {
- android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("version_split", versionSplitMutator()).Parallel()
- })
+ android.PreDepsMutators(RegisterPythonPreDepsMutators)
+}
+
+func RegisterPythonPreDepsMutators(ctx android.RegisterMutatorsContext) {
+ ctx.BottomUp("version_split", versionSplitMutator()).Parallel()
}
// the version properties that apply to python libraries and binaries.
@@ -226,15 +228,20 @@
return func(mctx android.BottomUpMutatorContext) {
if base, ok := mctx.Module().(*Module); ok {
versionNames := []string{}
- if base.properties.Version.Py2.Enabled != nil &&
- *(base.properties.Version.Py2.Enabled) == true {
- versionNames = append(versionNames, pyVersion2)
- }
+ // PY3 is first so that we alias the PY3 variant rather than PY2 if both
+ // are available
if !(base.properties.Version.Py3.Enabled != nil &&
*(base.properties.Version.Py3.Enabled) == false) {
versionNames = append(versionNames, pyVersion3)
}
+ if base.properties.Version.Py2.Enabled != nil &&
+ *(base.properties.Version.Py2.Enabled) == true {
+ versionNames = append(versionNames, pyVersion2)
+ }
modules := mctx.CreateVariations(versionNames...)
+ if len(versionNames) > 0 {
+ mctx.AliasVariation(versionNames[0])
+ }
for i, v := range versionNames {
// set the actual version for Python module.
modules[i].(*Module).properties.Actual_version = v
diff --git a/python/python_test.go b/python/python_test.go
index 1245ca1..23db24e 100644
--- a/python/python_test.go
+++ b/python/python_test.go
@@ -301,7 +301,7 @@
filepath.Join("dir", "file2.py"): nil,
filepath.Join("dir", "bin.py"): nil,
filepath.Join("dir", "file4.py"): nil,
- stubTemplateHost: []byte(`PYTHON_BINARY = '%interpreter%'
+ StubTemplateHost: []byte(`PYTHON_BINARY = '%interpreter%'
MAIN_FILE = '%main%'`),
},
expectedBinaries: []pyModule{
@@ -330,9 +330,7 @@
t.Run(d.desc, func(t *testing.T) {
config := android.TestConfig(buildDir, nil, "", d.mockFiles)
ctx := android.NewTestContext()
- ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("version_split", versionSplitMutator()).Parallel()
- })
+ ctx.PreDepsMutators(RegisterPythonPreDepsMutators)
ctx.RegisterModuleType("python_library_host", PythonLibraryHostFactory)
ctx.RegisterModuleType("python_binary_host", PythonBinaryHostFactory)
ctx.RegisterModuleType("python_defaults", defaultsFactory)
diff --git a/rust/binary.go b/rust/binary.go
index 48f51db..1a82c92 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -86,7 +86,7 @@
deps = binary.baseCompiler.compilerDeps(ctx, deps)
if ctx.toolchain().Bionic() {
- deps = binary.baseCompiler.bionicDeps(ctx, deps)
+ deps = bionicDeps(deps)
deps.CrtBegin = "crtbegin_dynamic"
deps.CrtEnd = "crtend_android"
}
@@ -106,8 +106,7 @@
func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
fileName := binary.getStem(ctx) + ctx.toolchain().ExecutableSuffix()
- srcPath, paths := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs)
- deps.SrcDeps = append(deps.SrcDeps, paths...)
+ srcPath, _ := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs)
outputFile := android.PathForModuleOut(ctx, fileName)
binary.unstrippedOutputFile = outputFile
diff --git a/rust/bindgen.go b/rust/bindgen.go
index 132b1fd..e8bbb35 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -15,11 +15,11 @@
package rust
import (
- "github.com/google/blueprint"
"strings"
+ "github.com/google/blueprint"
+
"android/soong/android"
- "android/soong/cc"
ccConfig "android/soong/cc/config"
)
@@ -41,14 +41,17 @@
bindgen = pctx.AndroidStaticRule("bindgen",
blueprint.RuleParams{
Command: "CLANG_PATH=$bindgenClang LIBCLANG_PATH=$bindgenLibClang RUSTFMT=${config.RustBin}/rustfmt " +
- "$bindgenCmd $flags $in -o $out -- $cflags",
+ "$bindgenCmd $flags $in -o $out -- -MD -MF $out.d $cflags",
CommandDeps: []string{"$bindgenCmd"},
+ Deps: blueprint.DepsGCC,
+ Depfile: "$out.d",
},
"flags", "cflags")
)
func init() {
android.RegisterModuleType("rust_bindgen", RustBindgenFactory)
+ android.RegisterModuleType("rust_bindgen_host", RustBindgenHostFactory)
}
var _ SourceProvider = (*bindgenDecorator)(nil)
@@ -82,40 +85,39 @@
Properties BindgenProperties
}
-func (b *bindgenDecorator) libraryExports(ctx android.ModuleContext) (android.Paths, []string) {
- var libraryPaths android.Paths
- var libraryFlags []string
-
- for _, static_lib := range b.Properties.Static_libs {
- if dep, ok := ctx.GetDirectDepWithTag(static_lib, cc.StaticDepTag).(*cc.Module); ok {
- libraryPaths = append(libraryPaths, dep.ExportedIncludeDirs()...)
- libraryFlags = append(libraryFlags, dep.ExportedFlags()...)
- }
- }
- for _, shared_lib := range b.Properties.Shared_libs {
- if dep, ok := ctx.GetDirectDepWithTag(shared_lib, cc.SharedDepTag).(*cc.Module); ok {
- libraryPaths = append(libraryPaths, dep.ExportedIncludeDirs()...)
- libraryFlags = append(libraryFlags, dep.ExportedFlags()...)
- }
- }
-
- return libraryPaths, libraryFlags
-}
-
-func (b *bindgenDecorator) generateSource(ctx android.ModuleContext) android.Path {
+func (b *bindgenDecorator) generateSource(ctx android.ModuleContext, deps PathDeps) android.Path {
ccToolchain := ccConfig.FindToolchain(ctx.Os(), ctx.Arch())
- includes, exportedFlags := b.libraryExports(ctx)
var cflags []string
- cflags = append(cflags, b.Properties.Cflags...)
+ var implicits android.Paths
+
+ implicits = append(implicits, deps.depIncludePaths...)
+ implicits = append(implicits, deps.depSystemIncludePaths...)
+
+ // Default clang flags
+ cflags = append(cflags, "${ccConfig.CommonClangGlobalCflags}")
+ if ctx.Device() {
+ cflags = append(cflags, "${ccConfig.DeviceClangGlobalCflags}")
+ }
+
+ // Toolchain clang flags
cflags = append(cflags, "-target "+ccToolchain.ClangTriple())
cflags = append(cflags, strings.ReplaceAll(ccToolchain.ToolchainClangCflags(), "${config.", "${ccConfig."))
- cflags = append(cflags, exportedFlags...)
- for _, include := range includes {
+
+ // Dependency clang flags and include paths
+ cflags = append(cflags, deps.depClangFlags...)
+ for _, include := range deps.depIncludePaths {
cflags = append(cflags, "-I"+include.String())
}
+ for _, include := range deps.depSystemIncludePaths {
+ cflags = append(cflags, "-isystem "+include.String())
+ }
+
+ // Module defined clang flags and include paths
+ cflags = append(cflags, b.Properties.Cflags...)
for _, include := range b.Properties.Local_include_dirs {
cflags = append(cflags, "-I"+android.PathForModuleSrc(ctx, include).String())
+ implicits = append(implicits, android.PathForModuleSrc(ctx, include))
}
bindgenFlags := defaultBindgenFlags
@@ -133,7 +135,7 @@
Description: "bindgen " + wrapperFile.Path().Rel(),
Output: outputFile,
Input: wrapperFile.Path(),
- Implicits: includes,
+ Implicits: implicits,
Args: map[string]string{
"flags": strings.Join(bindgenFlags, " "),
"cflags": strings.Join(cflags, " "),
@@ -156,6 +158,11 @@
return module.Init()
}
+func RustBindgenHostFactory() android.Module {
+ module, _ := NewRustBindgen(android.HostSupported)
+ return module.Init()
+}
+
func NewRustBindgen(hod android.HostOrDeviceSupported) (*Module, *bindgenDecorator) {
module := newModule(hod, android.MultilibBoth)
@@ -170,6 +177,10 @@
func (b *bindgenDecorator) sourceProviderDeps(ctx DepsContext, deps Deps) Deps {
deps = b.baseSourceProvider.sourceProviderDeps(ctx, deps)
+ if ctx.toolchain().Bionic() {
+ deps = bionicDeps(deps)
+ }
+
deps.SharedLibs = append(deps.SharedLibs, b.Properties.Shared_libs...)
deps.StaticLibs = append(deps.StaticLibs, b.Properties.Static_libs...)
return deps
diff --git a/rust/bindgen_test.go b/rust/bindgen_test.go
index 18e188f..2122ec1 100644
--- a/rust/bindgen_test.go
+++ b/rust/bindgen_test.go
@@ -48,9 +48,9 @@
t.Errorf("missing clang cflags in rust_bindgen rule: cflags %#v", libbindgen.Args["cflags"])
}
if !strings.Contains(libbindgen.Args["cflags"], "-Ishared_include") {
- t.Errorf("missing clang cflags in rust_bindgen rule: cflags %#v", libbindgen.Args["cflags"])
+ t.Errorf("missing shared_libs exported includes in rust_bindgen rule: cflags %#v", libbindgen.Args["cflags"])
}
if !strings.Contains(libbindgen.Args["cflags"], "-Istatic_include") {
- t.Errorf("missing clang cflags in rust_bindgen rule: cflags %#v", libbindgen.Args["cflags"])
+ t.Errorf("missing static_libs exported includes in rust_bindgen rule: cflags %#v", libbindgen.Args["cflags"])
}
}
diff --git a/rust/compiler.go b/rust/compiler.go
index ab3d2f4..040219d 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -199,7 +199,7 @@
return deps
}
-func (compiler *baseCompiler) bionicDeps(ctx DepsContext, deps Deps) Deps {
+func bionicDeps(deps Deps) Deps {
deps.SharedLibs = append(deps.SharedLibs, "liblog")
deps.SharedLibs = append(deps.SharedLibs, "libc")
deps.SharedLibs = append(deps.SharedLibs, "libm")
diff --git a/rust/library.go b/rust/library.go
index acca256..4c6da9d 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -340,7 +340,7 @@
deps = library.baseCompiler.compilerDeps(ctx, deps)
if ctx.toolchain().Bionic() && (library.dylib() || library.shared()) {
- deps = library.baseCompiler.bionicDeps(ctx, deps)
+ deps = bionicDeps(deps)
deps.CrtBegin = "crtbegin_so"
deps.CrtEnd = "crtend_so"
}
@@ -368,8 +368,7 @@
func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
var outputFile android.WritablePath
- srcPath, paths := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs)
- deps.SrcDeps = append(deps.SrcDeps, paths...)
+ srcPath, _ := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs)
flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
diff --git a/rust/proc_macro.go b/rust/proc_macro.go
index 2752dc3..3dd2521 100644
--- a/rust/proc_macro.go
+++ b/rust/proc_macro.go
@@ -65,8 +65,7 @@
fileName := procMacro.getStem(ctx) + ctx.toolchain().ProcMacroSuffix()
outputFile := android.PathForModuleOut(ctx, fileName)
- srcPath, paths := srcPathFromModuleSrcs(ctx, procMacro.baseCompiler.Properties.Srcs)
- deps.SrcDeps = append(deps.SrcDeps, paths...)
+ srcPath, _ := srcPathFromModuleSrcs(ctx, procMacro.baseCompiler.Properties.Srcs)
procMacro.unstrippedOutputFile = outputFile
diff --git a/rust/rust.go b/rust/rust.go
index 28f8e1a..78bf7ad 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -256,6 +256,11 @@
depFlags []string
//ReexportedDeps android.Paths
+ // Used by bindgen modules which call clang
+ depClangFlags []string
+ depIncludePaths android.Paths
+ depSystemIncludePaths android.Paths
+
coverageFiles android.Paths
CrtBegin android.OptionalPath
@@ -671,7 +676,7 @@
mod.compiler.install(ctx, mod.outputFile.Path())
}
} else if mod.sourceProvider != nil {
- outputFile := mod.sourceProvider.generateSource(ctx)
+ outputFile := mod.sourceProvider.generateSource(ctx, deps)
mod.outputFile = android.OptionalPathForPath(outputFile)
mod.subName = ctx.ModuleSubDir()
}
@@ -743,6 +748,8 @@
directProcMacroDeps := []*Module{}
directSharedLibDeps := [](cc.LinkableInterface){}
directStaticLibDeps := [](cc.LinkableInterface){}
+ directSrcProvidersDeps := []*Module{}
+ directSrcDeps := [](android.SourceFileProducer){}
ctx.VisitDirectDeps(func(dep android.Module) {
depName := ctx.OtherModuleName(dep)
@@ -776,6 +783,24 @@
case procMacroDepTag:
directProcMacroDeps = append(directProcMacroDeps, rustDep)
mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, depName)
+ case android.SourceDepTag:
+ // Since these deps are added in path_properties.go via AddDependencies, we need to ensure the correct
+ // OS/Arch variant is used.
+ var helper string
+ if ctx.Host() {
+ helper = "missing 'host_supported'?"
+ } else {
+ helper = "device module defined?"
+ }
+
+ if dep.Target().Os != ctx.Os() {
+ ctx.ModuleErrorf("OS mismatch on dependency %q (%s)", dep.Name(), helper)
+ return
+ } else if dep.Target().Arch.ArchType != ctx.Arch().ArchType {
+ ctx.ModuleErrorf("Arch mismatch on dependency %q (%s)", dep.Name(), helper)
+ return
+ }
+ directSrcProvidersDeps = append(directSrcProvidersDeps, rustDep)
}
//Append the dependencies exportedDirs
@@ -793,6 +818,14 @@
}
+ if srcDep, ok := dep.(android.SourceFileProducer); ok {
+ switch depTag {
+ case android.SourceDepTag:
+ // These are usually genrules which don't have per-target variants.
+ directSrcDeps = append(directSrcDeps, srcDep)
+ }
+ }
+
if ccDep, ok := dep.(cc.LinkableInterface); ok {
//Handle C dependencies
if _, ok := ccDep.(*Module); !ok {
@@ -821,6 +854,11 @@
depFlag = "-lstatic=" + libName
depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
depPaths.depFlags = append(depPaths.depFlags, depFlag)
+ depPaths.depIncludePaths = append(depPaths.depIncludePaths, ccDep.IncludeDirs()...)
+ if mod, ok := ccDep.(*cc.Module); ok {
+ depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, mod.ExportedSystemIncludeDirs()...)
+ depPaths.depClangFlags = append(depPaths.depClangFlags, mod.ExportedFlags()...)
+ }
depPaths.coverageFiles = append(depPaths.coverageFiles, ccDep.CoverageFiles()...)
directStaticLibDeps = append(directStaticLibDeps, ccDep)
mod.Properties.AndroidMkStaticLibs = append(mod.Properties.AndroidMkStaticLibs, depName)
@@ -828,6 +866,11 @@
depFlag = "-ldylib=" + libName
depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
depPaths.depFlags = append(depPaths.depFlags, depFlag)
+ depPaths.depIncludePaths = append(depPaths.depIncludePaths, ccDep.IncludeDirs()...)
+ if mod, ok := ccDep.(*cc.Module); ok {
+ depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, mod.ExportedSystemIncludeDirs()...)
+ depPaths.depClangFlags = append(depPaths.depClangFlags, mod.ExportedFlags()...)
+ }
directSharedLibDeps = append(directSharedLibDeps, ccDep)
mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, depName)
exportDep = true
@@ -868,15 +911,29 @@
sharedLibDepFiles = append(sharedLibDepFiles, dep.OutputFile().Path())
}
+ var srcProviderDepFiles android.Paths
+ for _, dep := range directSrcProvidersDeps {
+ srcs, _ := dep.OutputFiles("")
+ srcProviderDepFiles = append(srcProviderDepFiles, srcs...)
+ }
+ for _, dep := range directSrcDeps {
+ srcs := dep.Srcs()
+ srcProviderDepFiles = append(srcProviderDepFiles, srcs...)
+ }
+
depPaths.RLibs = append(depPaths.RLibs, rlibDepFiles...)
depPaths.DyLibs = append(depPaths.DyLibs, dylibDepFiles...)
depPaths.SharedLibs = append(depPaths.SharedLibs, sharedLibDepFiles...)
depPaths.StaticLibs = append(depPaths.StaticLibs, staticLibDepFiles...)
depPaths.ProcMacros = append(depPaths.ProcMacros, procMacroDepFiles...)
+ depPaths.SrcDeps = append(depPaths.SrcDeps, srcProviderDepFiles...)
// Dedup exported flags from dependencies
depPaths.linkDirs = android.FirstUniqueStrings(depPaths.linkDirs)
depPaths.depFlags = android.FirstUniqueStrings(depPaths.depFlags)
+ depPaths.depClangFlags = android.FirstUniqueStrings(depPaths.depClangFlags)
+ depPaths.depIncludePaths = android.FirstUniquePaths(depPaths.depIncludePaths)
+ depPaths.depSystemIncludePaths = android.FirstUniquePaths(depPaths.depSystemIncludePaths)
return depPaths
}
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 89dfb67..b3bbddb 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -291,6 +291,26 @@
}
}
+func TestSourceProviderTargetMismatch(t *testing.T) {
+ // This might error while building the dependency tree or when calling depsToPaths() depending on the lunched
+ // target, which results in two different errors. So don't check the error, just confirm there is one.
+ testRustError(t, ".*", `
+ rust_proc_macro {
+ name: "libprocmacro",
+ srcs: [
+ "foo.rs",
+ ":libbindings",
+ ],
+ crate_name: "procmacro",
+ }
+ rust_bindgen {
+ name: "libbindings",
+ stem: "bindings",
+ wrapper_src: "src/any.h",
+ }
+ `)
+}
+
// Test to make sure proc_macros use host variants when building device modules.
func TestProcMacroDeviceDeps(t *testing.T) {
ctx := testRust(t, `
diff --git a/rust/source_provider.go b/rust/source_provider.go
index e034d2c..da6147a 100644
--- a/rust/source_provider.go
+++ b/rust/source_provider.go
@@ -33,7 +33,7 @@
var _ SourceProvider = (*baseSourceProvider)(nil)
type SourceProvider interface {
- generateSource(ctx android.ModuleContext) android.Path
+ generateSource(ctx android.ModuleContext, deps PathDeps) android.Path
Srcs() android.Paths
sourceProviderProps() []interface{}
sourceProviderDeps(ctx DepsContext, deps Deps) Deps
@@ -43,7 +43,7 @@
return android.Paths{sp.outputFile}
}
-func (sp *baseSourceProvider) generateSource(ctx android.ModuleContext) android.Path {
+func (sp *baseSourceProvider) generateSource(ctx android.ModuleContext, deps PathDeps) android.Path {
panic("baseSourceProviderModule does not implement generateSource()")
}
diff --git a/third_party/zip/zip_test.go b/third_party/zip/zip_test.go
index 7373660..559c914 100644
--- a/third_party/zip/zip_test.go
+++ b/third_party/zip/zip_test.go
@@ -219,7 +219,7 @@
}
}
-// fakeHash32 is a dummy Hash32 that always returns 0.
+// fakeHash32 is a fake Hash32 that always returns 0.
type fakeHash32 struct {
hash.Hash32
}
diff --git a/ui/build/config.go b/ui/build/config.go
index ba477e6..3fa0479 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -96,7 +96,7 @@
environ: OsEnvironment(),
}
- // Sane default matching ninja
+ // Default matching ninja
ret.parallel = runtime.NumCPU() + 2
ret.keepGoing = 1
diff --git a/ui/build/upload.go b/ui/build/upload.go
index 1cc2e94..a9346e0 100644
--- a/ui/build/upload.go
+++ b/ui/build/upload.go
@@ -44,7 +44,7 @@
// environment variable. The metrics files are copied to a temporary directory
// and the uploader is then executed in the background to allow the user to continue
// working.
-func UploadMetrics(ctx Context, config Config, forceDumbOutput bool, buildStarted time.Time, files ...string) {
+func UploadMetrics(ctx Context, config Config, simpleOutput bool, buildStarted time.Time, files ...string) {
ctx.BeginTrace(metrics.RunSetupTool, "upload_metrics")
defer ctx.EndTrace()
@@ -105,7 +105,7 @@
// Start the uploader in the background as it takes several milliseconds to start the uploader
// and prepare the metrics for upload. This affects small commands like "lunch".
cmd := Command(ctx, config, "upload metrics", uploader, "--upload-metrics", pbFile)
- if forceDumbOutput {
+ if simpleOutput {
cmd.RunOrFatal()
} else {
cmd.RunAndStreamOrFatal()
diff --git a/ui/terminal/Android.bp b/ui/terminal/Android.bp
index b533b0d..aa6e35d 100644
--- a/ui/terminal/Android.bp
+++ b/ui/terminal/Android.bp
@@ -17,7 +17,7 @@
pkgPath: "android/soong/ui/terminal",
deps: ["soong-ui-status"],
srcs: [
- "dumb_status.go",
+ "simple_status.go",
"format.go",
"smart_status.go",
"status.go",
diff --git a/ui/terminal/dumb_status.go b/ui/terminal/simple_status.go
similarity index 70%
rename from ui/terminal/dumb_status.go
rename to ui/terminal/simple_status.go
index 201770f..4e8c568 100644
--- a/ui/terminal/dumb_status.go
+++ b/ui/terminal/simple_status.go
@@ -21,31 +21,31 @@
"android/soong/ui/status"
)
-type dumbStatusOutput struct {
+type simpleStatusOutput struct {
writer io.Writer
formatter formatter
}
-// NewDumbStatusOutput returns a StatusOutput that represents the
+// NewSimpleStatusOutput returns a StatusOutput that represents the
// current build status similarly to Ninja's built-in terminal
// output.
-func NewDumbStatusOutput(w io.Writer, formatter formatter) status.StatusOutput {
- return &dumbStatusOutput{
+func NewSimpleStatusOutput(w io.Writer, formatter formatter) status.StatusOutput {
+ return &simpleStatusOutput{
writer: w,
formatter: formatter,
}
}
-func (s *dumbStatusOutput) Message(level status.MsgLevel, message string) {
+func (s *simpleStatusOutput) Message(level status.MsgLevel, message string) {
if level >= status.StatusLvl {
fmt.Fprintln(s.writer, s.formatter.message(level, message))
}
}
-func (s *dumbStatusOutput) StartAction(action *status.Action, counts status.Counts) {
+func (s *simpleStatusOutput) StartAction(action *status.Action, counts status.Counts) {
}
-func (s *dumbStatusOutput) FinishAction(result status.ActionResult, counts status.Counts) {
+func (s *simpleStatusOutput) FinishAction(result status.ActionResult, counts status.Counts) {
str := result.Description
if str == "" {
str = result.Command
@@ -63,9 +63,9 @@
}
}
-func (s *dumbStatusOutput) Flush() {}
+func (s *simpleStatusOutput) Flush() {}
-func (s *dumbStatusOutput) Write(p []byte) (int, error) {
+func (s *simpleStatusOutput) Write(p []byte) (int, error) {
fmt.Fprint(s.writer, string(p))
return len(p), nil
}
diff --git a/ui/terminal/status.go b/ui/terminal/status.go
index 60dfc70..d8e7392 100644
--- a/ui/terminal/status.go
+++ b/ui/terminal/status.go
@@ -26,12 +26,12 @@
//
// statusFormat takes nearly all the same options as NINJA_STATUS.
// %c is currently unsupported.
-func NewStatusOutput(w io.Writer, statusFormat string, forceDumbOutput, quietBuild bool) status.StatusOutput {
+func NewStatusOutput(w io.Writer, statusFormat string, forceSimpleOutput, quietBuild bool) status.StatusOutput {
formatter := newFormatter(statusFormat, quietBuild)
- if !forceDumbOutput && isSmartTerminal(w) {
+ if !forceSimpleOutput && isSmartTerminal(w) {
return NewSmartStatusOutput(w, formatter)
} else {
- return NewDumbStatusOutput(w, formatter)
+ return NewSimpleStatusOutput(w, formatter)
}
}
diff --git a/ui/terminal/status_test.go b/ui/terminal/status_test.go
index 9f60829..aa69dff 100644
--- a/ui/terminal/status_test.go
+++ b/ui/terminal/status_test.go
@@ -26,64 +26,64 @@
func TestStatusOutput(t *testing.T) {
tests := []struct {
- name string
- calls func(stat status.StatusOutput)
- smart string
- dumb string
+ name string
+ calls func(stat status.StatusOutput)
+ smart string
+ simple string
}{
{
- name: "two actions",
- calls: twoActions,
- smart: "\r\x1b[1m[ 0% 0/2] action1\x1b[0m\x1b[K\r\x1b[1m[ 50% 1/2] action1\x1b[0m\x1b[K\r\x1b[1m[ 50% 1/2] action2\x1b[0m\x1b[K\r\x1b[1m[100% 2/2] action2\x1b[0m\x1b[K\n",
- dumb: "[ 50% 1/2] action1\n[100% 2/2] action2\n",
+ name: "two actions",
+ calls: twoActions,
+ smart: "\r\x1b[1m[ 0% 0/2] action1\x1b[0m\x1b[K\r\x1b[1m[ 50% 1/2] action1\x1b[0m\x1b[K\r\x1b[1m[ 50% 1/2] action2\x1b[0m\x1b[K\r\x1b[1m[100% 2/2] action2\x1b[0m\x1b[K\n",
+ simple: "[ 50% 1/2] action1\n[100% 2/2] action2\n",
},
{
- name: "two parallel actions",
- calls: twoParallelActions,
- smart: "\r\x1b[1m[ 0% 0/2] action1\x1b[0m\x1b[K\r\x1b[1m[ 0% 0/2] action2\x1b[0m\x1b[K\r\x1b[1m[ 50% 1/2] action1\x1b[0m\x1b[K\r\x1b[1m[100% 2/2] action2\x1b[0m\x1b[K\n",
- dumb: "[ 50% 1/2] action1\n[100% 2/2] action2\n",
+ name: "two parallel actions",
+ calls: twoParallelActions,
+ smart: "\r\x1b[1m[ 0% 0/2] action1\x1b[0m\x1b[K\r\x1b[1m[ 0% 0/2] action2\x1b[0m\x1b[K\r\x1b[1m[ 50% 1/2] action1\x1b[0m\x1b[K\r\x1b[1m[100% 2/2] action2\x1b[0m\x1b[K\n",
+ simple: "[ 50% 1/2] action1\n[100% 2/2] action2\n",
},
{
- name: "action with output",
- calls: actionsWithOutput,
- smart: "\r\x1b[1m[ 0% 0/3] action1\x1b[0m\x1b[K\r\x1b[1m[ 33% 1/3] action1\x1b[0m\x1b[K\r\x1b[1m[ 33% 1/3] action2\x1b[0m\x1b[K\r\x1b[1m[ 66% 2/3] action2\x1b[0m\x1b[K\noutput1\noutput2\n\r\x1b[1m[ 66% 2/3] action3\x1b[0m\x1b[K\r\x1b[1m[100% 3/3] action3\x1b[0m\x1b[K\n",
- dumb: "[ 33% 1/3] action1\n[ 66% 2/3] action2\noutput1\noutput2\n[100% 3/3] action3\n",
+ name: "action with output",
+ calls: actionsWithOutput,
+ smart: "\r\x1b[1m[ 0% 0/3] action1\x1b[0m\x1b[K\r\x1b[1m[ 33% 1/3] action1\x1b[0m\x1b[K\r\x1b[1m[ 33% 1/3] action2\x1b[0m\x1b[K\r\x1b[1m[ 66% 2/3] action2\x1b[0m\x1b[K\noutput1\noutput2\n\r\x1b[1m[ 66% 2/3] action3\x1b[0m\x1b[K\r\x1b[1m[100% 3/3] action3\x1b[0m\x1b[K\n",
+ simple: "[ 33% 1/3] action1\n[ 66% 2/3] action2\noutput1\noutput2\n[100% 3/3] action3\n",
},
{
- name: "action with output without newline",
- calls: actionsWithOutputWithoutNewline,
- smart: "\r\x1b[1m[ 0% 0/3] action1\x1b[0m\x1b[K\r\x1b[1m[ 33% 1/3] action1\x1b[0m\x1b[K\r\x1b[1m[ 33% 1/3] action2\x1b[0m\x1b[K\r\x1b[1m[ 66% 2/3] action2\x1b[0m\x1b[K\noutput1\noutput2\n\r\x1b[1m[ 66% 2/3] action3\x1b[0m\x1b[K\r\x1b[1m[100% 3/3] action3\x1b[0m\x1b[K\n",
- dumb: "[ 33% 1/3] action1\n[ 66% 2/3] action2\noutput1\noutput2\n[100% 3/3] action3\n",
+ name: "action with output without newline",
+ calls: actionsWithOutputWithoutNewline,
+ smart: "\r\x1b[1m[ 0% 0/3] action1\x1b[0m\x1b[K\r\x1b[1m[ 33% 1/3] action1\x1b[0m\x1b[K\r\x1b[1m[ 33% 1/3] action2\x1b[0m\x1b[K\r\x1b[1m[ 66% 2/3] action2\x1b[0m\x1b[K\noutput1\noutput2\n\r\x1b[1m[ 66% 2/3] action3\x1b[0m\x1b[K\r\x1b[1m[100% 3/3] action3\x1b[0m\x1b[K\n",
+ simple: "[ 33% 1/3] action1\n[ 66% 2/3] action2\noutput1\noutput2\n[100% 3/3] action3\n",
},
{
- name: "action with error",
- calls: actionsWithError,
- smart: "\r\x1b[1m[ 0% 0/3] action1\x1b[0m\x1b[K\r\x1b[1m[ 33% 1/3] action1\x1b[0m\x1b[K\r\x1b[1m[ 33% 1/3] action2\x1b[0m\x1b[K\r\x1b[1m[ 66% 2/3] action2\x1b[0m\x1b[K\nFAILED: f1 f2\ntouch f1 f2\nerror1\nerror2\n\r\x1b[1m[ 66% 2/3] action3\x1b[0m\x1b[K\r\x1b[1m[100% 3/3] action3\x1b[0m\x1b[K\n",
- dumb: "[ 33% 1/3] action1\n[ 66% 2/3] action2\nFAILED: f1 f2\ntouch f1 f2\nerror1\nerror2\n[100% 3/3] action3\n",
+ name: "action with error",
+ calls: actionsWithError,
+ smart: "\r\x1b[1m[ 0% 0/3] action1\x1b[0m\x1b[K\r\x1b[1m[ 33% 1/3] action1\x1b[0m\x1b[K\r\x1b[1m[ 33% 1/3] action2\x1b[0m\x1b[K\r\x1b[1m[ 66% 2/3] action2\x1b[0m\x1b[K\nFAILED: f1 f2\ntouch f1 f2\nerror1\nerror2\n\r\x1b[1m[ 66% 2/3] action3\x1b[0m\x1b[K\r\x1b[1m[100% 3/3] action3\x1b[0m\x1b[K\n",
+ simple: "[ 33% 1/3] action1\n[ 66% 2/3] action2\nFAILED: f1 f2\ntouch f1 f2\nerror1\nerror2\n[100% 3/3] action3\n",
},
{
- name: "action with empty description",
- calls: actionWithEmptyDescription,
- smart: "\r\x1b[1m[ 0% 0/1] command1\x1b[0m\x1b[K\r\x1b[1m[100% 1/1] command1\x1b[0m\x1b[K\n",
- dumb: "[100% 1/1] command1\n",
+ name: "action with empty description",
+ calls: actionWithEmptyDescription,
+ smart: "\r\x1b[1m[ 0% 0/1] command1\x1b[0m\x1b[K\r\x1b[1m[100% 1/1] command1\x1b[0m\x1b[K\n",
+ simple: "[100% 1/1] command1\n",
},
{
- name: "messages",
- calls: actionsWithMessages,
- smart: "\r\x1b[1m[ 0% 0/2] action1\x1b[0m\x1b[K\r\x1b[1m[ 50% 1/2] action1\x1b[0m\x1b[K\r\x1b[1mstatus\x1b[0m\x1b[K\r\x1b[Kprint\nFAILED: error\n\r\x1b[1m[ 50% 1/2] action2\x1b[0m\x1b[K\r\x1b[1m[100% 2/2] action2\x1b[0m\x1b[K\n",
- dumb: "[ 50% 1/2] action1\nstatus\nprint\nFAILED: error\n[100% 2/2] action2\n",
+ name: "messages",
+ calls: actionsWithMessages,
+ smart: "\r\x1b[1m[ 0% 0/2] action1\x1b[0m\x1b[K\r\x1b[1m[ 50% 1/2] action1\x1b[0m\x1b[K\r\x1b[1mstatus\x1b[0m\x1b[K\r\x1b[Kprint\nFAILED: error\n\r\x1b[1m[ 50% 1/2] action2\x1b[0m\x1b[K\r\x1b[1m[100% 2/2] action2\x1b[0m\x1b[K\n",
+ simple: "[ 50% 1/2] action1\nstatus\nprint\nFAILED: error\n[100% 2/2] action2\n",
},
{
- name: "action with long description",
- calls: actionWithLongDescription,
- smart: "\r\x1b[1m[ 0% 0/2] action with very long descrip\x1b[0m\x1b[K\r\x1b[1m[ 50% 1/2] action with very long descrip\x1b[0m\x1b[K\n",
- dumb: "[ 50% 1/2] action with very long description to test eliding\n",
+ name: "action with long description",
+ calls: actionWithLongDescription,
+ smart: "\r\x1b[1m[ 0% 0/2] action with very long descrip\x1b[0m\x1b[K\r\x1b[1m[ 50% 1/2] action with very long descrip\x1b[0m\x1b[K\n",
+ simple: "[ 50% 1/2] action with very long description to test eliding\n",
},
{
- name: "action with output with ansi codes",
- calls: actionWithOuptutWithAnsiCodes,
- smart: "\r\x1b[1m[ 0% 0/1] action1\x1b[0m\x1b[K\r\x1b[1m[100% 1/1] action1\x1b[0m\x1b[K\n\x1b[31mcolor\x1b[0m\n",
- dumb: "[100% 1/1] action1\ncolor\n",
+ name: "action with output with ansi codes",
+ calls: actionWithOuptutWithAnsiCodes,
+ smart: "\r\x1b[1m[ 0% 0/1] action1\x1b[0m\x1b[K\r\x1b[1m[100% 1/1] action1\x1b[0m\x1b[K\n\x1b[31mcolor\x1b[0m\n",
+ simple: "[100% 1/1] action1\ncolor\n",
},
}
@@ -103,24 +103,24 @@
}
})
- t.Run("dumb", func(t *testing.T) {
- dumb := &bytes.Buffer{}
- stat := NewStatusOutput(dumb, "", false, false)
+ t.Run("simple", func(t *testing.T) {
+ simple := &bytes.Buffer{}
+ stat := NewStatusOutput(simple, "", false, false)
tt.calls(stat)
stat.Flush()
- if g, w := dumb.String(), tt.dumb; g != w {
+ if g, w := simple.String(), tt.simple; g != w {
t.Errorf("want:\n%q\ngot:\n%q", w, g)
}
})
- t.Run("force dumb", func(t *testing.T) {
+ t.Run("force simple", func(t *testing.T) {
smart := &fakeSmartTerminal{termWidth: 40}
stat := NewStatusOutput(smart, "", true, false)
tt.calls(stat)
stat.Flush()
- if g, w := smart.String(), tt.dumb; g != w {
+ if g, w := smart.String(), tt.simple; g != w {
t.Errorf("want:\n%q\ngot:\n%q", w, g)
}
})