Merge "Set ANDROID_HOST_MUSL for musl builds"
diff --git a/android/arch.go b/android/arch.go
index 7ca7336..f7eb963 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -1967,6 +1967,7 @@
srcType := reflect.ValueOf(generalProp).Type()
if srcType == dstType {
archProperties = m.archProperties[i]
+ axisToProps[bazel.NoConfigAxis] = ArchVariantProperties{"": generalProp}
break
}
}
diff --git a/android/bazel.go b/android/bazel.go
index 8c86a95..fa19e52 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -137,7 +137,6 @@
// build/bazel explicitly.
"build/bazel":/* recursive = */ false,
"build/bazel/examples/android_app":/* recursive = */ true,
- "build/bazel/examples/java":/* recursive = */ true,
"build/bazel/bazel_skylib":/* recursive = */ true,
"build/bazel/rules":/* recursive = */ true,
"build/bazel/rules_cc":/* recursive = */ true,
@@ -151,11 +150,10 @@
"external/bazelbuild-rules_android":/* recursive = */ true,
"external/bazel-skylib":/* recursive = */ true,
- "prebuilts/jdk":/* recursive = */ true,
"prebuilts/sdk":/* recursive = */ false,
"prebuilts/sdk/tools":/* recursive = */ false,
"prebuilts/r8":/* recursive = */ false,
- "packages/apps/Music":/* recursive = */ false,
+ "packages/apps/Music":/* recursive = */ true,
}
// Configure modules in these directories to enable bp2build_available: true or false by default.
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 0e7c944..312f009 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -28,8 +28,6 @@
"android/soong/bazel/cquery"
- "github.com/google/blueprint/bootstrap"
-
"android/soong/bazel"
"android/soong/shared"
)
@@ -760,7 +758,7 @@
// Add ninja file dependencies for files which all bazel invocations require.
bazelBuildList := absolutePath(filepath.Join(
- filepath.Dir(bootstrap.CmdlineArgs.ModuleListFile), "bazel.list"))
+ filepath.Dir(ctx.Config().moduleListFile), "bazel.list"))
ctx.AddNinjaFileDeps(bazelBuildList)
data, err := ioutil.ReadFile(bazelBuildList)
diff --git a/android/config.go b/android/config.go
index e3d05a6..35403b8 100644
--- a/android/config.go
+++ b/android/config.go
@@ -79,10 +79,6 @@
return false // Never compile Go code in the main build for debugging
}
-func (c Config) SrcDir() string {
- return c.srcDir
-}
-
// A DeviceConfig object represents the configuration for a particular device
// being built. For now there will only be one of these, but in the future there
// may be multiple devices being built.
@@ -126,7 +122,6 @@
deviceConfig *deviceConfig
- srcDir string // the path of the root source directory
buildDir string // the path of the build output directory
moduleListFile string // the path to the file which lists blueprint files to parse.
@@ -402,7 +397,7 @@
// multiple runs in the same program execution is carried over (such as Bazel
// context or environment deps).
func ConfigForAdditionalRun(c Config) (Config, error) {
- newConfig, err := NewConfig(c.srcDir, c.buildDir, c.moduleListFile, c.env)
+ newConfig, err := NewConfig(c.buildDir, c.moduleListFile, c.env)
if err != nil {
return Config{}, err
}
@@ -413,14 +408,13 @@
// NewConfig creates a new Config object. The srcDir argument specifies the path
// to the root source directory. It also loads the config file, if found.
-func NewConfig(srcDir, buildDir string, moduleListFile string, availableEnv map[string]string) (Config, error) {
+func NewConfig(buildDir string, moduleListFile string, availableEnv map[string]string) (Config, error) {
// Make a config with default options.
config := &config{
ProductVariablesFileName: filepath.Join(buildDir, productVariablesFileName),
env: availableEnv,
- srcDir: srcDir,
buildDir: buildDir,
multilibConflicts: make(map[ArchType]bool),
@@ -439,7 +433,7 @@
return Config{}, err
}
- absSrcDir, err := filepath.Abs(srcDir)
+ absSrcDir, err := filepath.Abs(".")
if err != nil {
return Config{}, err
}
@@ -597,7 +591,7 @@
// GoRoot returns the path to the root directory of the Go toolchain.
func (c *config) GoRoot() string {
- return fmt.Sprintf("%s/prebuilts/go/%s", c.srcDir, c.PrebuiltOS())
+ return fmt.Sprintf("prebuilts/go/%s", c.PrebuiltOS())
}
// PrebuiltBuildTool returns the path to a tool in the prebuilts directory containing
diff --git a/android/filegroup.go b/android/filegroup.go
index 97dd136..54d01d3 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -34,24 +34,6 @@
Srcs bazel.LabelListAttribute
}
-type bazelFilegroup struct {
- BazelTargetModuleBase
- bazelFilegroupAttributes
-}
-
-func BazelFileGroupFactory() Module {
- module := &bazelFilegroup{}
- module.AddProperties(&module.bazelFilegroupAttributes)
- InitBazelTargetModule(module)
- return module
-}
-
-func (bfg *bazelFilegroup) Name() string {
- return bfg.BaseModuleName()
-}
-
-func (bfg *bazelFilegroup) GenerateAndroidBuildActions(ctx ModuleContext) {}
-
func FilegroupBp2Build(ctx TopDownMutatorContext) {
fg, ok := ctx.Module().(*fileGroup)
if !ok || !fg.ConvertWithBp2build(ctx) {
@@ -69,7 +51,7 @@
Bzl_load_location: "//build/bazel/rules:filegroup.bzl",
}
- ctx.CreateBazelTargetModule(BazelFileGroupFactory, fg.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(fg.Name(), props, attrs)
}
type fileGroupProperties struct {
diff --git a/android/module.go b/android/module.go
index 5e2e06a..b571f15 100644
--- a/android/module.go
+++ b/android/module.go
@@ -235,8 +235,8 @@
// VisitDirectDeps calls visit for each direct dependency. If there are multiple
// direct dependencies on the same module visit will be called multiple times on that module
- // and OtherModuleDependencyTag will return a different tag for each. It skips any
- // dependencies that are not an android.Module.
+ // and OtherModuleDependencyTag will return a different tag for each. It raises an error if any of the
+ // dependencies are not an android.Module.
//
// The Module passed to the visit function should not be retained outside of the visit
// function, it may be invalidated by future mutators.
@@ -491,6 +491,11 @@
AddProperties(props ...interface{})
GetProperties() []interface{}
+ // IsConvertedByBp2build returns whether this module was converted via bp2build
+ IsConvertedByBp2build() bool
+ // Bp2buildTargets returns the target(s) generated for Bazel via bp2build for this module
+ Bp2buildTargets() []bp2buildInfo
+
BuildParamsForTests() []BuildParams
RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams
VariablesForTests() map[string]string
@@ -878,6 +883,11 @@
// for example "" for core or "recovery" for recovery. It will often be set to one of the
// constants in image.go, but can also be set to a custom value by individual module types.
ImageVariation string `blueprint:"mutated"`
+
+ // Information about _all_ bp2build targets generated by this module. Multiple targets are
+ // supported as Soong handles some things within a single target that we may choose to split into
+ // multiple targets, e.g. renderscript, protos, yacc within a cc module.
+ Bp2buildInfo []bp2buildInfo `blueprint:"mutated"`
}
type distProperties struct {
@@ -1204,6 +1214,54 @@
vintfFragmentsPaths Paths
}
+// A struct containing all relevant information about a Bazel target converted via bp2build.
+type bp2buildInfo struct {
+ Name string
+ Dir string
+ BazelProps bazel.BazelTargetModuleProperties
+ Attrs interface{}
+}
+
+// TargetName returns the Bazel target name of a bp2build converted target.
+func (b bp2buildInfo) TargetName() string {
+ return b.Name
+}
+
+// TargetPackage returns the Bazel package of a bp2build converted target.
+func (b bp2buildInfo) TargetPackage() string {
+ return b.Dir
+}
+
+// BazelRuleClass returns the Bazel rule class of a bp2build converted target.
+func (b bp2buildInfo) BazelRuleClass() string {
+ return b.BazelProps.Rule_class
+}
+
+// BazelRuleLoadLocation returns the location of the Bazel rule of a bp2build converted target.
+// This may be empty as native Bazel rules do not need to be loaded.
+func (b bp2buildInfo) BazelRuleLoadLocation() string {
+ return b.BazelProps.Bzl_load_location
+}
+
+// BazelAttributes returns the Bazel attributes of a bp2build converted target.
+func (b bp2buildInfo) BazelAttributes() interface{} {
+ return b.Attrs
+}
+
+func (m *ModuleBase) addBp2buildInfo(info bp2buildInfo) {
+ m.commonProperties.Bp2buildInfo = append(m.commonProperties.Bp2buildInfo, info)
+}
+
+// IsConvertedByBp2build returns whether this module was converted via bp2build.
+func (m *ModuleBase) IsConvertedByBp2build() bool {
+ return len(m.commonProperties.Bp2buildInfo) > 0
+}
+
+// Bp2buildTargets returns the Bazel targets bp2build generated for this module.
+func (m *ModuleBase) Bp2buildTargets() []bp2buildInfo {
+ return m.commonProperties.Bp2buildInfo
+}
+
func (m *ModuleBase) AddJSONData(d *map[string]interface{}) {
(*d)["Android"] = map[string]interface{}{}
}
diff --git a/android/mutator.go b/android/mutator.go
index d895669..20ec621 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -270,7 +270,7 @@
// factory method, just like in CreateModule, but also requires
// BazelTargetModuleProperties containing additional metadata for the
// bp2build codegenerator.
- CreateBazelTargetModule(ModuleFactory, string, bazel.BazelTargetModuleProperties, interface{}) BazelTargetModule
+ CreateBazelTargetModule(string, bazel.BazelTargetModuleProperties, interface{})
}
type topDownMutatorContext struct {
@@ -516,26 +516,24 @@
}
func (t *topDownMutatorContext) CreateBazelTargetModule(
- factory ModuleFactory,
name string,
bazelProps bazel.BazelTargetModuleProperties,
- attrs interface{}) BazelTargetModule {
+ attrs interface{}) {
if strings.HasPrefix(name, bazel.BazelTargetModuleNamePrefix) {
panic(fmt.Errorf(
"The %s name prefix is added automatically, do not set it manually: %s",
bazel.BazelTargetModuleNamePrefix,
name))
}
- name = bazel.BazelTargetModuleNamePrefix + name
- nameProp := struct {
- Name *string
- }{
- Name: &name,
+
+ info := bp2buildInfo{
+ Name: name,
+ Dir: t.OtherModuleDir(t.Module()),
+ BazelProps: bazelProps,
+ Attrs: attrs,
}
- b := t.createModuleWithoutInheritance(factory, &nameProp, attrs).(BazelTargetModule)
- b.SetBazelTargetModuleProperties(bazelProps)
- return b
+ t.Module().base().addBp2buildInfo(info)
}
func (t *topDownMutatorContext) AppendProperties(props ...interface{}) {
diff --git a/android/paths.go b/android/paths.go
index 9c9914e..71caaab 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -622,7 +622,7 @@
// It intended for use in globs that only list files that exist, so it allows '$' in
// filenames.
func pathsForModuleSrcFromFullPath(ctx EarlyModulePathContext, paths []string, incDirs bool) Paths {
- prefix := filepath.Join(ctx.Config().srcDir, ctx.ModuleDir()) + "/"
+ prefix := ctx.ModuleDir() + "/"
if prefix == "./" {
prefix = ""
}
@@ -658,7 +658,7 @@
}
// Use Glob so that if the default doesn't exist, a dependency is added so that when it
// is created, we're run again.
- path := filepath.Join(ctx.Config().srcDir, ctx.ModuleDir(), def)
+ path := filepath.Join(ctx.ModuleDir(), def)
return Glob(ctx, path, nil)
}
@@ -986,7 +986,7 @@
// code that is embedding ninja variables in paths
func safePathForSource(ctx PathContext, pathComponents ...string) (SourcePath, error) {
p, err := validateSafePath(pathComponents...)
- ret := SourcePath{basePath{p, ""}, ctx.Config().srcDir}
+ ret := SourcePath{basePath{p, ""}, "."}
if err != nil {
return ret, err
}
@@ -1002,7 +1002,7 @@
// pathForSource creates a SourcePath from pathComponents, but does not check that it exists.
func pathForSource(ctx PathContext, pathComponents ...string) (SourcePath, error) {
p, err := validatePath(pathComponents...)
- ret := SourcePath{basePath{p, ""}, ctx.Config().srcDir}
+ ret := SourcePath{basePath{p, ""}, "."}
if err != nil {
return ret, err
}
diff --git a/apex/apex.go b/apex/apex.go
index add506f..e1fca67 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1100,13 +1100,6 @@
mctx.ModuleErrorf("base property is not set")
return
}
- // Workaround the issue reported in b/191269918 by using the unprefixed module name of this
- // module as the default variation to use if dependencies of this module do not have the correct
- // apex variant name. This name matches the name used to create the variations of modules for
- // which apexModuleTypeRequiresVariant return true.
- // TODO(b/191269918): Remove this workaround.
- unprefixedModuleName := android.RemoveOptionalPrebuiltPrefix(mctx.ModuleName())
- mctx.SetDefaultDependencyVariation(&unprefixedModuleName)
mctx.CreateVariations(apexBundleName)
if strings.HasPrefix(apexBundleName, "com.android.art") {
// TODO(b/183882457): See note for CreateAliasVariation above.
@@ -3238,18 +3231,6 @@
Prebuilts bazel.LabelListAttribute
}
-type bazelApexBundle struct {
- android.BazelTargetModuleBase
- bazelApexBundleAttributes
-}
-
-func BazelApexBundleFactory() android.Module {
- module := &bazelApexBundle{}
- module.AddProperties(&module.bazelApexBundleAttributes)
- android.InitBazelTargetModule(module)
- return module
-}
-
func ApexBundleBp2Build(ctx android.TopDownMutatorContext) {
module, ok := ctx.Module().(*apexBundle)
if !ok {
@@ -3337,11 +3318,5 @@
Bzl_load_location: "//build/bazel/rules:apex.bzl",
}
- ctx.CreateBazelTargetModule(BazelApexBundleFactory, module.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(module.Name(), props, attrs)
}
-
-func (m *bazelApexBundle) Name() string {
- return m.BaseModuleName()
-}
-
-func (m *bazelApexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
diff --git a/apex/key.go b/apex/key.go
index 32a7ce1..468bb8a 100644
--- a/apex/key.go
+++ b/apex/key.go
@@ -203,18 +203,6 @@
Private_key bazel.LabelAttribute
}
-type bazelApexKey struct {
- android.BazelTargetModuleBase
- bazelApexKeyAttributes
-}
-
-func BazelApexKeyFactory() android.Module {
- module := &bazelApexKey{}
- module.AddProperties(&module.bazelApexKeyAttributes)
- android.InitBazelTargetModule(module)
- return module
-}
-
func ApexKeyBp2Build(ctx android.TopDownMutatorContext) {
module, ok := ctx.Module().(*apexKey)
if !ok {
@@ -252,11 +240,5 @@
Bzl_load_location: "//build/bazel/rules:apex_key.bzl",
}
- ctx.CreateBazelTargetModule(BazelApexKeyFactory, module.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(module.Name(), props, attrs)
}
-
-func (m *bazelApexKey) Name() string {
- return m.BaseModuleName()
-}
-
-func (m *bazelApexKey) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
diff --git a/bloaty/bloaty_merger.py b/bloaty/bloaty_merger.py
index 1034462..46ce57f 100644
--- a/bloaty/bloaty_merger.py
+++ b/bloaty/bloaty_merger.py
@@ -24,58 +24,63 @@
import csv
import gzip
+# pylint: disable=import-error
import ninja_rsp
import file_sections_pb2
BLOATY_EXTENSION = ".bloaty.csv"
+
def parse_csv(path):
- """Parses a Bloaty-generated CSV file into a protobuf.
+ """Parses a Bloaty-generated CSV file into a protobuf.
- Args:
- path: The filepath to the CSV file, relative to $ANDROID_TOP.
+ Args:
+ path: The filepath to the CSV file, relative to $ANDROID_TOP.
- Returns:
- A file_sections_pb2.File if the file was found; None otherwise.
- """
- file_proto = None
- with open(path, newline='') as csv_file:
- file_proto = file_sections_pb2.File()
- if path.endswith(BLOATY_EXTENSION):
- file_proto.path = path[:-len(BLOATY_EXTENSION)]
- section_reader = csv.DictReader(csv_file)
- for row in section_reader:
- section = file_proto.sections.add()
- section.name = row["sections"]
- section.vm_size = int(row["vmsize"])
- section.file_size = int(row["filesize"])
- return file_proto
+ Returns:
+ A file_sections_pb2.File if the file was found; None otherwise.
+ """
+ file_proto = None
+ with open(path, newline='') as csv_file:
+ file_proto = file_sections_pb2.File()
+ if path.endswith(BLOATY_EXTENSION):
+ file_proto.path = path[: -len(BLOATY_EXTENSION)]
+ section_reader = csv.DictReader(csv_file)
+ for row in section_reader:
+ section = file_proto.sections.add()
+ section.name = row["sections"]
+ section.vm_size = int(row["vmsize"])
+ section.file_size = int(row["filesize"])
+ return file_proto
+
def create_file_size_metrics(input_list, output_proto):
- """Creates a FileSizeMetrics proto from a list of CSV files.
+ """Creates a FileSizeMetrics proto from a list of CSV files.
- Args:
- input_list: The path to the file which contains the list of CSV files. Each
- filepath is separated by a space.
- output_proto: The path for the output protobuf. It will be compressed using
- gzip.
- """
- metrics = file_sections_pb2.FileSizeMetrics()
- reader = ninja_rsp.NinjaRspFileReader(input_list)
- for csv_path in reader:
- file_proto = parse_csv(csv_path)
- if file_proto:
- metrics.files.append(file_proto)
- with gzip.open(output_proto, "wb") as output:
- output.write(metrics.SerializeToString())
+ Args:
+ input_list: The path to the file which contains the list of CSV files.
+ Each filepath is separated by a space.
+ output_proto: The path for the output protobuf. It will be compressed
+ using gzip.
+ """
+ metrics = file_sections_pb2.FileSizeMetrics()
+ reader = ninja_rsp.NinjaRspFileReader(input_list)
+ for csv_path in reader:
+ file_proto = parse_csv(csv_path)
+ if file_proto:
+ metrics.files.append(file_proto)
+ with gzip.open(output_proto, "wb") as output:
+ output.write(metrics.SerializeToString())
+
def main():
- parser = argparse.ArgumentParser()
- parser.add_argument("input_list_file", help="List of bloaty csv files.")
- parser.add_argument("output_proto", help="Output proto.")
- args = parser.parse_args()
- create_file_size_metrics(args.input_list_file, args.output_proto)
+ parser = argparse.ArgumentParser()
+ parser.add_argument("input_list_file", help="List of bloaty csv files.")
+ parser.add_argument("output_proto", help="Output proto.")
+ args = parser.parse_args()
+ create_file_size_metrics(args.input_list_file, args.output_proto)
+
if __name__ == '__main__':
- main()
+ main()
diff --git a/bloaty/bloaty_merger_test.py b/bloaty/bloaty_merger_test.py
index 9de049a..83680b9 100644
--- a/bloaty/bloaty_merger_test.py
+++ b/bloaty/bloaty_merger_test.py
@@ -14,6 +14,7 @@
import gzip
import unittest
+# pylint: disable=import-error
from pyfakefs import fake_filesystem_unittest
import bloaty_merger
@@ -21,46 +22,46 @@
class BloatyMergerTestCase(fake_filesystem_unittest.TestCase):
- def setUp(self):
- self.setUpPyfakefs()
+ def setUp(self):
+ self.setUpPyfakefs()
- def test_parse_csv(self):
- csv_content = "sections,vmsize,filesize\nsection1,2,3\n"
- self.fs.create_file("file1.bloaty.csv", contents=csv_content)
- pb = bloaty_merger.parse_csv("file1.bloaty.csv")
- self.assertEqual(pb.path, "file1")
- self.assertEqual(len(pb.sections), 1)
- s = pb.sections[0]
- self.assertEqual(s.name, "section1")
- self.assertEqual(s.vm_size, 2)
- self.assertEqual(s.file_size, 3)
+ def test_parse_csv(self):
+ csv_content = "sections,vmsize,filesize\nsection1,2,3\n"
+ self.fs.create_file("file1.bloaty.csv", contents=csv_content)
+ pb = bloaty_merger.parse_csv("file1.bloaty.csv")
+ self.assertEqual(pb.path, "file1")
+ self.assertEqual(len(pb.sections), 1)
+ s = pb.sections[0]
+ self.assertEqual(s.name, "section1")
+ self.assertEqual(s.vm_size, 2)
+ self.assertEqual(s.file_size, 3)
- def test_missing_file(self):
- with self.assertRaises(FileNotFoundError):
- bloaty_merger.parse_csv("missing.bloaty.csv")
+ def test_missing_file(self):
+ with self.assertRaises(FileNotFoundError):
+ bloaty_merger.parse_csv("missing.bloaty.csv")
- def test_malformed_csv(self):
- csv_content = "header1,heaVder2,header3\n4,5,6\n"
- self.fs.create_file("file1.bloaty.csv", contents=csv_content)
- with self.assertRaises(KeyError):
- bloaty_merger.parse_csv("file1.bloaty.csv")
+ def test_malformed_csv(self):
+ csv_content = "header1,heaVder2,header3\n4,5,6\n"
+ self.fs.create_file("file1.bloaty.csv", contents=csv_content)
+ with self.assertRaises(KeyError):
+ bloaty_merger.parse_csv("file1.bloaty.csv")
- def test_create_file_metrics(self):
- file_list = "file1.bloaty.csv file2.bloaty.csv"
- file1_content = "sections,vmsize,filesize\nsection1,2,3\nsection2,7,8"
- file2_content = "sections,vmsize,filesize\nsection1,4,5\n"
+ def test_create_file_metrics(self):
+ file_list = "file1.bloaty.csv file2.bloaty.csv"
+ file1_content = "sections,vmsize,filesize\nsection1,2,3\nsection2,7,8"
+ file2_content = "sections,vmsize,filesize\nsection1,4,5\n"
- self.fs.create_file("files.lst", contents=file_list)
- self.fs.create_file("file1.bloaty.csv", contents=file1_content)
- self.fs.create_file("file2.bloaty.csv", contents=file2_content)
+ self.fs.create_file("files.lst", contents=file_list)
+ self.fs.create_file("file1.bloaty.csv", contents=file1_content)
+ self.fs.create_file("file2.bloaty.csv", contents=file2_content)
- bloaty_merger.create_file_size_metrics("files.lst", "output.pb.gz")
+ bloaty_merger.create_file_size_metrics("files.lst", "output.pb.gz")
- metrics = file_sections_pb2.FileSizeMetrics()
- with gzip.open("output.pb.gz", "rb") as output:
- metrics.ParseFromString(output.read())
+ metrics = file_sections_pb2.FileSizeMetrics()
+ with gzip.open("output.pb.gz", "rb") as output:
+ metrics.ParseFromString(output.read())
if __name__ == '__main__':
- suite = unittest.TestLoader().loadTestsFromTestCase(BloatyMergerTestCase)
- unittest.TextTestRunner(verbosity=2).run(suite)
+ suite = unittest.TestLoader().loadTestsFromTestCase(BloatyMergerTestCase)
+ unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/bp2build/Android.bp b/bp2build/Android.bp
index 9ec637a..78e3a74 100644
--- a/bp2build/Android.bp
+++ b/bp2build/Android.bp
@@ -39,6 +39,7 @@
"cc_library_static_conversion_test.go",
"cc_object_conversion_test.go",
"conversion_test.go",
+ "performance_test.go",
"prebuilt_etc_conversion_test.go",
"python_binary_conversion_test.go",
"sh_conversion_test.go",
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index 96a8b09..a64d474 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -244,7 +244,7 @@
dir := bpCtx.ModuleDir(m)
dirs[dir] = true
- var t BazelTarget
+ var targets []BazelTarget
switch ctx.Mode() {
case Bp2Build:
@@ -258,18 +258,23 @@
if _, exists := buildFileToAppend[pathToBuildFile]; exists {
return
}
- var err error
- t, err = getHandcraftedBuildContent(ctx, b, pathToBuildFile)
+ t, err := getHandcraftedBuildContent(ctx, b, pathToBuildFile)
if err != nil {
panic(fmt.Errorf("Error converting %s: %s", bpCtx.ModuleName(m), err))
}
+ targets = append(targets, t)
// TODO(b/181575318): currently we append the whole BUILD file, let's change that to do
// something more targeted based on the rule type and target
buildFileToAppend[pathToBuildFile] = true
- } else if btm, ok := m.(android.BazelTargetModule); ok {
- t = generateBazelTarget(bpCtx, m, btm)
- metrics.RuleClassCount[t.ruleClass] += 1
- compatLayer.AddNameToLabelEntry(m.Name(), t.Label())
+ } else if aModule, ok := m.(android.Module); ok && aModule.IsConvertedByBp2build() {
+ targets = generateBazelTargets(bpCtx, aModule)
+ for _, t := range targets {
+ if t.name == m.Name() {
+ // only add targets that exist in Soong to compatibility layer
+ compatLayer.AddNameToLabelEntry(m.Name(), t.Label())
+ }
+ metrics.RuleClassCount[t.ruleClass] += 1
+ }
} else {
metrics.TotalModuleCount += 1
return
@@ -281,12 +286,13 @@
// be mapped cleanly to a bazel label.
return
}
- t = generateSoongModuleTarget(bpCtx, m)
+ t := generateSoongModuleTarget(bpCtx, m)
+ targets = append(targets, t)
default:
panic(fmt.Errorf("Unknown code-generation mode: %s", ctx.Mode()))
}
- buildFileToTargets[dir] = append(buildFileToTargets[dir], t)
+ buildFileToTargets[dir] = append(buildFileToTargets[dir], targets...)
})
if generateFilegroups {
// Add a filegroup target that exposes all sources in the subtree of this package
@@ -326,22 +332,38 @@
}, nil
}
-func generateBazelTarget(ctx bpToBuildContext, m blueprint.Module, btm android.BazelTargetModule) BazelTarget {
- ruleClass := btm.RuleClass()
- bzlLoadLocation := btm.BzlLoadLocation()
+func generateBazelTargets(ctx bpToBuildContext, m android.Module) []BazelTarget {
+ var targets []BazelTarget
+ for _, m := range m.Bp2buildTargets() {
+ targets = append(targets, generateBazelTarget(ctx, m))
+ }
+ return targets
+}
+
+type bp2buildModule interface {
+ TargetName() string
+ TargetPackage() string
+ BazelRuleClass() string
+ BazelRuleLoadLocation() string
+ BazelAttributes() interface{}
+}
+
+func generateBazelTarget(ctx bpToBuildContext, m bp2buildModule) BazelTarget {
+ ruleClass := m.BazelRuleClass()
+ bzlLoadLocation := m.BazelRuleLoadLocation()
// extract the bazel attributes from the module.
- props := getBuildProperties(ctx, m)
+ props := extractModuleProperties([]interface{}{m.BazelAttributes()})
delete(props.Attrs, "bp2build_available")
// Return the Bazel target with rule class and attributes, ready to be
// code-generated.
attributes := propsToAttributes(props.Attrs)
- targetName := targetNameForBp2Build(ctx, m)
+ targetName := m.TargetName()
return BazelTarget{
name: targetName,
- packageName: ctx.ModuleDir(m),
+ packageName: m.TargetPackage(),
ruleClass: ruleClass,
bzlLoadLocation: bzlLoadLocation,
content: fmt.Sprintf(
@@ -391,24 +413,21 @@
}
func getBuildProperties(ctx bpToBuildContext, m blueprint.Module) BazelAttributes {
- var allProps map[string]string
// TODO: this omits properties for blueprint modules (blueprint_go_binary,
// bootstrap_go_binary, bootstrap_go_package), which will have to be handled separately.
if aModule, ok := m.(android.Module); ok {
- allProps = ExtractModuleProperties(aModule)
+ return extractModuleProperties(aModule.GetProperties())
}
- return BazelAttributes{
- Attrs: allProps,
- }
+ return BazelAttributes{}
}
// Generically extract module properties and types into a map, keyed by the module property name.
-func ExtractModuleProperties(aModule android.Module) map[string]string {
+func extractModuleProperties(props []interface{}) BazelAttributes {
ret := map[string]string{}
// Iterate over this android.Module's property structs.
- for _, properties := range aModule.GetProperties() {
+ for _, properties := range props {
propertiesValue := reflect.ValueOf(properties)
// Check that propertiesValue is a pointer to the Properties struct, like
// *cc.BaseLinkerProperties or *java.CompilerProperties.
@@ -427,7 +446,9 @@
}
}
- return ret
+ return BazelAttributes{
+ Attrs: ret,
+ }
}
func isStructPtr(t reflect.Type) bool {
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index e5dbda6..0d9106c 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -334,9 +334,7 @@
config := android.TestConfig(buildDir, nil, testCase.bp, nil)
ctx := android.NewTestContext(config)
- ctx.RegisterModuleType("custom", customModuleFactory)
- ctx.RegisterBp2BuildMutator("custom", customBp2BuildMutator)
- ctx.RegisterForBazelConversion()
+ registerCustomModuleForBp2buildConversion(ctx)
_, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
if errored(t, "", errs) {
@@ -482,12 +480,12 @@
name = "bar",
)
-my_proto_library(
- name = "bar_my_proto_library_deps",
-)
-
proto_library(
name = "bar_proto_library_deps",
+)
+
+my_proto_library(
+ name = "bar_my_proto_library_deps",
)`,
expectedBazelTargetCount: 3,
expectedLoadStatements: `load("//build/bazel/rules:proto.bzl", "my_proto_library", "proto_library")
@@ -1215,22 +1213,24 @@
dir := "."
for _, testCase := range testCases {
- config := android.TestConfig(buildDir, nil, testCase.bp, nil)
- ctx := android.NewTestContext(config)
- ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
- ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
- ctx.RegisterForBazelConversion()
+ t.Run(testCase.description, func(t *testing.T) {
+ config := android.TestConfig(buildDir, nil, testCase.bp, nil)
+ ctx := android.NewTestContext(config)
+ ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
+ ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
+ ctx.RegisterForBazelConversion()
- _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
- android.FailIfErrored(t, errs)
- _, errs = ctx.ResolveDependencies(config)
- android.FailIfErrored(t, errs)
+ _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
+ android.FailIfErrored(t, errs)
+ _, errs = ctx.ResolveDependencies(config)
+ android.FailIfErrored(t, errs)
- codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
- bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
- if actualCount := len(bazelTargets); actualCount != testCase.expectedCount {
- t.Fatalf("%s: Expected %d bazel target, got %d", testCase.description, testCase.expectedCount, actualCount)
- }
+ codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
+ bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
+ if actualCount := len(bazelTargets); actualCount != testCase.expectedCount {
+ t.Fatalf("%s: Expected %d bazel target, got %d", testCase.description, testCase.expectedCount, actualCount)
+ }
+ })
}
}
diff --git a/bp2build/bzl_conversion_test.go b/bp2build/bzl_conversion_test.go
index 204c519..9e0c0a1 100644
--- a/bp2build/bzl_conversion_test.go
+++ b/bp2build/bzl_conversion_test.go
@@ -85,6 +85,7 @@
"soong_module_variant": attr.string(),
"soong_module_deps": attr.label_list(providers = [SoongModuleInfo]),
"arch_paths": attr.string_list(),
+ "arch_paths_exclude": attr.string_list(),
# bazel_module start
# "label": attr.string(),
# "bp2build_available": attr.bool(),
@@ -114,6 +115,7 @@
"soong_module_variant": attr.string(),
"soong_module_deps": attr.label_list(providers = [SoongModuleInfo]),
"arch_paths": attr.string_list(),
+ "arch_paths_exclude": attr.string_list(),
"bool_prop": attr.bool(),
"bool_ptr_prop": attr.bool(),
"int64_ptr_prop": attr.int(),
@@ -139,6 +141,7 @@
"soong_module_variant": attr.string(),
"soong_module_deps": attr.label_list(providers = [SoongModuleInfo]),
"arch_paths": attr.string_list(),
+ "arch_paths_exclude": attr.string_list(),
"bool_prop": attr.bool(),
"bool_ptr_prop": attr.bool(),
"int64_ptr_prop": attr.int(),
diff --git a/bp2build/performance_test.go b/bp2build/performance_test.go
new file mode 100644
index 0000000..3283952
--- /dev/null
+++ b/bp2build/performance_test.go
@@ -0,0 +1,175 @@
+// Copyright 2021 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 bp2build
+
+// to run the benchmarks in this file, you must run go test with the -bench.
+// The benchmarked portion will run for the specified time (can be set via -benchtime)
+// This can mean if you are benchmarking a faster portion of a larger operation, it will take
+// longer.
+// If you are seeing a small number of iterations for a specific run, the data is less reliable, to
+// run for longer, set -benchtime to a larger value.
+
+import (
+ "android/soong/android"
+ "fmt"
+ "math"
+ "strings"
+ "testing"
+)
+
+func genCustomModule(i int, convert bool) string {
+ var conversionString string
+ if convert {
+ conversionString = `bazel_module: { bp2build_available: true },`
+ }
+ return fmt.Sprintf(`
+custom {
+ name: "arch_paths_%[1]d",
+ string_list_prop: ["\t", "\n"],
+ string_prop: "a\t\n\r",
+ arch_paths: ["outer", ":outer_dep_%[1]d"],
+ arch: {
+ x86: {
+ arch_paths: ["abc", ":x86_dep_%[1]d"],
+ },
+ x86_64: {
+ arch_paths: ["64bit"],
+ arch_paths_exclude: ["outer"],
+ },
+ },
+ %[2]s
+}
+
+custom {
+ name: "outer_dep_%[1]d",
+ %[2]s
+}
+
+custom {
+ name: "x86_dep_%[1]d",
+ %[2]s
+}
+`, i, conversionString)
+}
+
+func genCustomModuleBp(pctConverted float64) string {
+ modules := 100
+
+ bp := make([]string, 0, modules)
+ toConvert := int(math.Round(float64(modules) * pctConverted))
+
+ for i := 0; i < modules; i++ {
+ bp = append(bp, genCustomModule(i, i < toConvert))
+ }
+ return strings.Join(bp, "\n\n")
+}
+
+var pctToConvert = []float64{0.0, 0.01, 0.05, 0.10, 0.25, 0.5, 0.75, 1.0}
+
+func BenchmarkManyModulesFull(b *testing.B) {
+ dir := "."
+ for _, tcSize := range pctToConvert {
+
+ b.Run(fmt.Sprintf("pctConverted %f", tcSize), func(b *testing.B) {
+ for n := 0; n < b.N; n++ {
+ b.StopTimer()
+ // setup we don't want to measure
+ config := android.TestConfig(buildDir, nil, genCustomModuleBp(tcSize), nil)
+ ctx := android.NewTestContext(config)
+
+ registerCustomModuleForBp2buildConversion(ctx)
+ codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
+
+ b.StartTimer()
+ _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
+ if len(errs) > 0 {
+ b.Fatalf("Unexpected errors: %s", errs)
+ }
+
+ _, errs = ctx.ResolveDependencies(config)
+ if len(errs) > 0 {
+ b.Fatalf("Unexpected errors: %s", errs)
+ }
+
+ generateBazelTargetsForDir(codegenCtx, dir)
+ b.StopTimer()
+ }
+ })
+ }
+}
+
+func BenchmarkManyModulesResolveDependencies(b *testing.B) {
+ dir := "."
+ for _, tcSize := range pctToConvert {
+
+ b.Run(fmt.Sprintf("pctConverted %f", tcSize), func(b *testing.B) {
+ for n := 0; n < b.N; n++ {
+ b.StopTimer()
+ // setup we don't want to measure
+ config := android.TestConfig(buildDir, nil, genCustomModuleBp(tcSize), nil)
+ ctx := android.NewTestContext(config)
+
+ registerCustomModuleForBp2buildConversion(ctx)
+ codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
+
+ _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
+ if len(errs) > 0 {
+ b.Fatalf("Unexpected errors: %s", errs)
+ }
+
+ b.StartTimer()
+ _, errs = ctx.ResolveDependencies(config)
+ b.StopTimer()
+ if len(errs) > 0 {
+ b.Fatalf("Unexpected errors: %s", errs)
+ }
+
+ generateBazelTargetsForDir(codegenCtx, dir)
+ }
+ })
+ }
+}
+
+func BenchmarkManyModulesGenerateBazelTargetsForDir(b *testing.B) {
+ dir := "."
+ for _, tcSize := range pctToConvert {
+
+ b.Run(fmt.Sprintf("pctConverted %f", tcSize), func(b *testing.B) {
+ for n := 0; n < b.N; n++ {
+ b.StopTimer()
+ // setup we don't want to measure
+ config := android.TestConfig(buildDir, nil, genCustomModuleBp(tcSize), nil)
+ ctx := android.NewTestContext(config)
+
+ registerCustomModuleForBp2buildConversion(ctx)
+ codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
+
+ _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
+ if len(errs) > 0 {
+ b.Fatalf("Unexpected errors: %s", errs)
+ }
+
+ _, errs = ctx.ResolveDependencies(config)
+ if len(errs) > 0 {
+ b.Fatalf("Unexpected errors: %s", errs)
+ }
+
+ b.StartTimer()
+ generateBazelTargetsForDir(codegenCtx, dir)
+ b.StopTimer()
+ }
+ })
+ }
+}
diff --git a/bp2build/testing.go b/bp2build/testing.go
index f3cd7f0..266b817 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -33,7 +33,8 @@
Nested_props nestedProps
Nested_props_ptr *nestedProps
- Arch_paths []string `android:"path,arch_variant"`
+ Arch_paths []string `android:"path,arch_variant"`
+ Arch_paths_exclude []string `android:"path,arch_variant"`
}
type customModule struct {
@@ -139,32 +140,24 @@
customBazelModuleAttributes
}
-func customBazelModuleFactory() android.Module {
- module := &customBazelModule{}
- module.AddProperties(&module.customBazelModuleAttributes)
- android.InitBazelTargetModule(module)
- return module
-}
-
-func (m *customBazelModule) Name() string { return m.BaseModuleName() }
-func (m *customBazelModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
-
func customBp2BuildMutator(ctx android.TopDownMutatorContext) {
if m, ok := ctx.Module().(*customModule); ok {
if !m.ConvertWithBp2build(ctx) {
return
}
- paths := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, m.props.Arch_paths))
+ paths := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrcExcludes(ctx, m.props.Arch_paths, m.props.Arch_paths_exclude))
for axis, configToProps := range m.GetArchVariantProperties(ctx, &customProps{}) {
for config, props := range configToProps {
if archProps, ok := props.(*customProps); ok && archProps.Arch_paths != nil {
- paths.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, archProps.Arch_paths))
+ paths.SetSelectValue(axis, config, android.BazelLabelForModuleSrcExcludes(ctx, archProps.Arch_paths, archProps.Arch_paths_exclude))
}
}
}
+ paths.ResolveExcludes()
+
attrs := &customBazelModuleAttributes{
String_prop: m.props.String_prop,
String_list_prop: m.props.String_list_prop,
@@ -175,7 +168,7 @@
Rule_class: "custom",
}
- ctx.CreateBazelTargetModule(customBazelModuleFactory, m.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(m.Name(), props, attrs)
}
}
@@ -194,19 +187,19 @@
Rule_class: "my_library",
Bzl_load_location: "//build/bazel/rules:rules.bzl",
}
- ctx.CreateBazelTargetModule(customBazelModuleFactory, baseName, myLibraryProps, attrs)
+ ctx.CreateBazelTargetModule(baseName, myLibraryProps, attrs)
protoLibraryProps := bazel.BazelTargetModuleProperties{
Rule_class: "proto_library",
Bzl_load_location: "//build/bazel/rules:proto.bzl",
}
- ctx.CreateBazelTargetModule(customBazelModuleFactory, baseName+"_proto_library_deps", protoLibraryProps, attrs)
+ ctx.CreateBazelTargetModule(baseName+"_proto_library_deps", protoLibraryProps, attrs)
myProtoLibraryProps := bazel.BazelTargetModuleProperties{
Rule_class: "my_proto_library",
Bzl_load_location: "//build/bazel/rules:proto.bzl",
}
- ctx.CreateBazelTargetModule(customBazelModuleFactory, baseName+"_my_proto_library_deps", myProtoLibraryProps, attrs)
+ ctx.CreateBazelTargetModule(baseName+"_my_proto_library_deps", myProtoLibraryProps, attrs)
}
}
@@ -216,3 +209,9 @@
buildFileToTargets, _, _ := GenerateBazelTargets(codegenCtx, false)
return buildFileToTargets[dir]
}
+
+func registerCustomModuleForBp2buildConversion(ctx *android.TestContext) {
+ ctx.RegisterModuleType("custom", customModuleFactory)
+ ctx.RegisterBp2BuildMutator("custom", customBp2BuildMutator)
+ ctx.RegisterForBazelConversion()
+}
diff --git a/cc/androidmk.go b/cc/androidmk.go
index bda1006..e95d5a7 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -24,12 +24,12 @@
)
var (
- nativeBridgeSuffix = ".native_bridge"
- productSuffix = ".product"
+ NativeBridgeSuffix = ".native_bridge"
+ ProductSuffix = ".product"
VendorSuffix = ".vendor"
- ramdiskSuffix = ".ramdisk"
+ RamdiskSuffix = ".ramdisk"
VendorRamdiskSuffix = ".vendor_ramdisk"
- recoverySuffix = ".recovery"
+ RecoverySuffix = ".recovery"
sdkSuffix = ".sdk"
)
@@ -182,7 +182,7 @@
if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
var result []string
for _, override := range overrides {
- result = append(result, override+nativeBridgeSuffix)
+ result = append(result, override+NativeBridgeSuffix)
}
return result
}
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 1706d72..537f01c 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -132,27 +132,7 @@
}
func bp2buildParseStaticOrSharedProps(ctx android.TopDownMutatorContext, module *Module, lib *libraryDecorator, isStatic bool) staticOrSharedAttributes {
- var props StaticOrSharedProperties
- if isStatic {
- props = lib.StaticProperties.Static
- } else {
- props = lib.SharedProperties.Shared
- }
-
- system_dynamic_deps := bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.System_shared_libs))
- system_dynamic_deps.ForceSpecifyEmptyList = true
- if system_dynamic_deps.IsEmpty() && props.System_shared_libs != nil {
- system_dynamic_deps.Value.Includes = []bazel.Label{}
- }
-
- attrs := staticOrSharedAttributes{
- Copts: bazel.StringListAttribute{Value: props.Cflags},
- Srcs: bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, props.Srcs)),
- Static_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Static_libs)),
- Dynamic_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Shared_libs)),
- Whole_archive_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleWholeDeps(ctx, props.Whole_static_libs)),
- System_dynamic_deps: system_dynamic_deps,
- }
+ attrs := staticOrSharedAttributes{}
setAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) {
attrs.Copts.SetSelectValue(axis, config, props.Cflags)
@@ -162,6 +142,10 @@
attrs.Whole_archive_deps.SetSelectValue(axis, config, android.BazelLabelForModuleWholeDeps(ctx, props.Whole_static_libs))
attrs.System_dynamic_deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.System_shared_libs))
}
+ // system_dynamic_deps distinguishes between nil/empty list behavior:
+ // nil -> use default values
+ // empty list -> no values specified
+ attrs.System_dynamic_deps.ForceSpecifyEmptyList = true
if isStatic {
for axis, configToProps := range module.GetArchVariantProperties(ctx, &StaticProperties{}) {
@@ -195,18 +179,8 @@
}
func Bp2BuildParsePrebuiltLibraryProps(ctx android.TopDownMutatorContext, module *Module) prebuiltAttributes {
- prebuiltLibraryLinker := module.linker.(*prebuiltLibraryLinker)
- prebuiltLinker := prebuiltLibraryLinker.prebuiltLinker
-
var srcLabelAttribute bazel.LabelAttribute
- if len(prebuiltLinker.properties.Srcs) > 1 {
- ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file\n")
- }
-
- if len(prebuiltLinker.properties.Srcs) == 1 {
- srcLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinker.properties.Srcs[0]))
- }
for axis, configToProps := range module.GetArchVariantProperties(ctx, &prebuiltLinkerProperties{}) {
for config, props := range configToProps {
if prebuiltLinkerProperties, ok := props.(*prebuiltLinkerProperties); ok {
@@ -298,36 +272,7 @@
return bazel.AppendBazelLabelLists(allSrcsLabelList, generatedHdrsAndSrcsLabelList)
}
- for _, props := range module.compiler.compilerProps() {
- if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
- srcs.SetValue(parseSrcs(baseCompilerProps))
- copts.Value = parseCommandLineFlags(baseCompilerProps.Cflags)
- asFlags.Value = parseCommandLineFlags(baseCompilerProps.Asflags)
- conlyFlags.Value = parseCommandLineFlags(baseCompilerProps.Conlyflags)
- cppFlags.Value = parseCommandLineFlags(baseCompilerProps.Cppflags)
- rtti.Value = baseCompilerProps.Rtti
-
- for _, dir := range parseLocalIncludeDirs(baseCompilerProps) {
- copts.Value = append(copts.Value, includeFlags(dir)...)
- asFlags.Value = append(asFlags.Value, includeFlags(dir)...)
- }
- break
- }
- }
-
- // Handle include_build_directory prop. If the property is true, then the
- // target has access to all headers recursively in the package, and has
- // "-I<module-dir>" in its copts.
- if c, ok := module.compiler.(*baseCompiler); ok && c.includeBuildDirectory() {
- copts.Value = append(copts.Value, includeFlags(".")...)
- asFlags.Value = append(asFlags.Value, includeFlags(".")...)
- } else if c, ok := module.compiler.(*libraryDecorator); ok && c.includeBuildDirectory() {
- copts.Value = append(copts.Value, includeFlags(".")...)
- asFlags.Value = append(asFlags.Value, includeFlags(".")...)
- }
-
archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{})
-
for axis, configToProps := range archVariantCompilerProps {
for config, props := range configToProps {
if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
@@ -345,6 +290,14 @@
archVariantAsflags = append(archVariantAsflags, includeFlags(dir)...)
}
+ if axis == bazel.NoConfigAxis {
+ if includeBuildDirectory(baseCompilerProps.Include_build_directory) {
+ flags := includeFlags(".")
+ archVariantCopts = append(archVariantCopts, flags...)
+ archVariantAsflags = append(archVariantAsflags, flags...)
+ }
+ }
+
copts.SetSelectValue(axis, config, archVariantCopts)
asFlags.SetSelectValue(axis, config, archVariantAsflags)
conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Conlyflags))
@@ -423,7 +376,7 @@
var exportedDeps bazel.LabelListAttribute
var dynamicDeps bazel.LabelListAttribute
var wholeArchiveDeps bazel.LabelListAttribute
- var systemSharedDeps bazel.LabelListAttribute
+ systemSharedDeps := bazel.LabelListAttribute{ForceSpecifyEmptyList: true}
var linkopts bazel.StringListAttribute
var versionScript bazel.LabelAttribute
var useLibcrt bazel.BoolAttribute
@@ -434,15 +387,6 @@
var stripAll bazel.BoolAttribute
var stripNone bazel.BoolAttribute
- if libraryDecorator, ok := module.linker.(*libraryDecorator); ok {
- stripProperties := libraryDecorator.stripper.StripProperties
- stripKeepSymbols.Value = stripProperties.Strip.Keep_symbols
- stripKeepSymbolsList.Value = stripProperties.Strip.Keep_symbols_list
- stripKeepSymbolsAndDebugFrame.Value = stripProperties.Strip.Keep_symbols_and_debug_frame
- stripAll.Value = stripProperties.Strip.All
- stripNone.Value = stripProperties.Strip.None
- }
-
for axis, configToProps := range module.GetArchVariantProperties(ctx, &StripProperties{}) {
for config, props := range configToProps {
if stripProperties, ok := props.(*StripProperties); ok {
@@ -455,54 +399,22 @@
}
}
- for _, linkerProps := range module.linker.linkerProps() {
- if baseLinkerProps, ok := linkerProps.(*BaseLinkerProperties); ok {
- // Excludes to parallel Soong:
- // https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0
- staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
- staticDeps.Value = android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs)
- wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
- wholeArchiveDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
-
- systemSharedLibs := android.FirstUniqueStrings(baseLinkerProps.System_shared_libs)
- systemSharedDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, systemSharedLibs))
- systemSharedDeps.ForceSpecifyEmptyList = true
- if systemSharedDeps.Value.IsNil() && baseLinkerProps.System_shared_libs != nil {
- systemSharedDeps.Value.Includes = []bazel.Label{}
- }
-
- sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs)
-
- dynamicDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs))
-
- headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs)
- headerDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, headerLibs))
- // TODO(b/188796939): also handle export_static_lib_headers, export_shared_lib_headers,
- // export_generated_headers
- exportedLibs := android.FirstUniqueStrings(baseLinkerProps.Export_header_lib_headers)
- exportedDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, exportedLibs))
-
- linkopts.Value = getBp2BuildLinkerFlags(baseLinkerProps)
- if baseLinkerProps.Version_script != nil {
- versionScript.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
- }
- useLibcrt.Value = baseLinkerProps.libCrt()
-
- break
- }
- }
-
for axis, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) {
for config, props := range configToProps {
if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok {
+ // Excludes to parallel Soong:
+ // https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0
staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
staticDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs))
wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
- systemSharedLibs := android.FirstUniqueStrings(baseLinkerProps.System_shared_libs)
- if len(systemSharedLibs) == 0 && baseLinkerProps.System_shared_libs != nil {
- systemSharedLibs = baseLinkerProps.System_shared_libs
+ systemSharedLibs := baseLinkerProps.System_shared_libs
+ // systemSharedLibs distinguishes between nil/empty list behavior:
+ // nil -> use default values
+ // empty list -> no values specified
+ if len(systemSharedLibs) > 0 {
+ systemSharedLibs = android.FirstUniqueStrings(systemSharedLibs)
}
systemSharedDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, systemSharedLibs))
@@ -642,22 +554,24 @@
// are root-relative.
includeDirs := libraryDecorator.flagExporter.Properties.Export_system_include_dirs
includeDirs = append(includeDirs, libraryDecorator.flagExporter.Properties.Export_include_dirs...)
- includeDirsAttribute := bazel.MakeStringListAttribute(includeDirs)
+ var includeDirsAttribute bazel.StringListAttribute
- getVariantIncludeDirs := func(includeDirs []string, flagExporterProperties *FlagExporterProperties) []string {
+ getVariantIncludeDirs := func(includeDirs []string, flagExporterProperties *FlagExporterProperties, subtract bool) []string {
variantIncludeDirs := flagExporterProperties.Export_system_include_dirs
variantIncludeDirs = append(variantIncludeDirs, flagExporterProperties.Export_include_dirs...)
- // To avoid duplicate includes when base includes + arch includes are combined
- // TODO: This doesn't take conflicts between arch and os includes into account
- variantIncludeDirs = bazel.SubtractStrings(variantIncludeDirs, includeDirs)
+ if subtract {
+ // To avoid duplicate includes when base includes + arch includes are combined
+ // TODO: Add something similar to ResolveExcludes() in bazel/properties.go
+ variantIncludeDirs = bazel.SubtractStrings(variantIncludeDirs, includeDirs)
+ }
return variantIncludeDirs
}
for axis, configToProps := range module.GetArchVariantProperties(ctx, &FlagExporterProperties{}) {
for config, props := range configToProps {
if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
- archVariantIncludeDirs := getVariantIncludeDirs(includeDirs, flagExporterProperties)
+ archVariantIncludeDirs := getVariantIncludeDirs(includeDirs, flagExporterProperties, axis != bazel.NoConfigAxis)
if len(archVariantIncludeDirs) > 0 {
includeDirsAttribute.SetSelectValue(axis, config, archVariantIncludeDirs)
}
diff --git a/cc/cc.go b/cc/cc.go
index f65af30..243f0a5 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -822,6 +822,16 @@
}
func (c *Module) AddJSONData(d *map[string]interface{}) {
+ var hasAidl, hasLex, hasProto, hasRenderscript, hasSysprop, hasWinMsg, hasYacc bool
+ if b, ok := c.compiler.(*baseCompiler); ok {
+ hasAidl = b.hasSrcExt(".aidl")
+ hasLex = b.hasSrcExt(".l") || b.hasSrcExt(".ll")
+ hasProto = b.hasSrcExt(".proto")
+ hasRenderscript = b.hasSrcExt(".rscript") || b.hasSrcExt(".fs")
+ hasSysprop = b.hasSrcExt(".sysprop")
+ hasWinMsg = b.hasSrcExt(".mc")
+ hasYacc = b.hasSrcExt(".y") || b.hasSrcExt(".yy")
+ }
c.AndroidModuleBase().AddJSONData(d)
(*d)["Cc"] = map[string]interface{}{
"SdkVersion": c.SdkVersion(),
@@ -858,6 +868,14 @@
"IsVendorPublicLibrary": c.IsVendorPublicLibrary(),
"ApexSdkVersion": c.apexSdkVersion,
"TestFor": c.TestFor(),
+ "AidlSrcs": hasAidl,
+ "LexSrcs": hasLex,
+ "ProtoSrcs": hasProto,
+ "RenderscriptSrcs": hasRenderscript,
+ "SyspropSrcs": hasSysprop,
+ "WinMsgSrcs": hasWinMsg,
+ "YaccSrsc": hasYacc,
+ "OnlyCSrcs": !(hasAidl || hasLex || hasProto || hasRenderscript || hasSysprop || hasWinMsg || hasYacc),
}
}
@@ -1632,7 +1650,7 @@
return ""
}
vndkVersion = ctx.DeviceConfig().ProductVndkVersion()
- nameSuffix = productSuffix
+ nameSuffix = ProductSuffix
} else {
vndkVersion = ctx.DeviceConfig().VndkVersion()
nameSuffix = VendorSuffix
@@ -1652,7 +1670,7 @@
c.Properties.SubName = ""
if c.Target().NativeBridge == android.NativeBridgeEnabled {
- c.Properties.SubName += nativeBridgeSuffix
+ c.Properties.SubName += NativeBridgeSuffix
}
llndk := c.IsLlndk()
@@ -1668,11 +1686,11 @@
// such suffixes are already hard-coded in prebuilts/vndk/.../Android.bp.
c.Properties.SubName += VendorSuffix
} else if c.InRamdisk() && !c.OnlyInRamdisk() {
- c.Properties.SubName += ramdiskSuffix
+ c.Properties.SubName += RamdiskSuffix
} else if c.InVendorRamdisk() && !c.OnlyInVendorRamdisk() {
c.Properties.SubName += VendorRamdiskSuffix
} else if c.InRecovery() && !c.OnlyInRecovery() {
- c.Properties.SubName += recoverySuffix
+ c.Properties.SubName += RecoverySuffix
} else if c.IsSdkVariant() && (c.Properties.SdkAndPlatformVariantVisibleToMake || c.SplitPerApiLevel()) {
c.Properties.SubName += sdkSuffix
if c.SplitPerApiLevel() {
@@ -3029,13 +3047,13 @@
// core module, so update the dependency name here accordingly.
return libName + ccDep.SubName()
} else if ccDep.InRamdisk() && !ccDep.OnlyInRamdisk() {
- return libName + ramdiskSuffix
+ return libName + RamdiskSuffix
} else if ccDep.InVendorRamdisk() && !ccDep.OnlyInVendorRamdisk() {
return libName + VendorRamdiskSuffix
} else if ccDep.InRecovery() && !ccDep.OnlyInRecovery() {
- return libName + recoverySuffix
+ return libName + RecoverySuffix
} else if ccDep.Target().NativeBridge == android.NativeBridgeEnabled {
- return libName + nativeBridgeSuffix
+ return libName + NativeBridgeSuffix
} else {
return libName
}
diff --git a/cc/compiler.go b/cc/compiler.go
index 03214c8..34d68a1 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -261,8 +261,12 @@
return []interface{}{&compiler.Properties, &compiler.Proto}
}
+func includeBuildDirectory(prop *bool) bool {
+ return proptools.BoolDefault(prop, true)
+}
+
func (compiler *baseCompiler) includeBuildDirectory() bool {
- return proptools.BoolDefault(compiler.Properties.Include_build_directory, true)
+ return includeBuildDirectory(compiler.Properties.Include_build_directory)
}
func (compiler *baseCompiler) compilerInit(ctx BaseModuleContext) {}
diff --git a/cc/config/global.go b/cc/config/global.go
index 248822f..9773345 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -355,6 +355,9 @@
exportedStringListVars.Set("CommonGlobalIncludes", commonGlobalIncludes)
pctx.PrefixedExistentPathsForSourcesVariable("CommonGlobalIncludes", "-I", commonGlobalIncludes)
+ exportStringStaticVariable("CLANG_DEFAULT_VERSION", ClangDefaultVersion)
+ exportStringStaticVariable("CLANG_DEFAULT_SHORT_VERSION", ClangDefaultShortVersion)
+
pctx.SourcePathVariable("ClangDefaultBase", ClangDefaultBase)
pctx.VariableFunc("ClangBase", func(ctx android.PackageVarContext) string {
if override := ctx.Config().Getenv("LLVM_PREBUILTS_BASE"); override != "" {
diff --git a/cc/library.go b/cc/library.go
index b2360e9..1526f81 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -27,6 +27,7 @@
"android/soong/bazel"
"android/soong/bazel/cquery"
"android/soong/cc/config"
+
"github.com/google/blueprint"
"github.com/google/blueprint/pathtools"
)
@@ -256,24 +257,6 @@
None bazel.BoolAttribute
}
-type bazelCcLibrary struct {
- android.BazelTargetModuleBase
- bazelCcLibraryAttributes
-}
-
-func (m *bazelCcLibrary) Name() string {
- return m.BaseModuleName()
-}
-
-func (m *bazelCcLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
-
-func BazelCcLibraryFactory() android.Module {
- module := &bazelCcLibrary{}
- module.AddProperties(&module.bazelCcLibraryAttributes)
- android.InitBazelTargetModule(module)
- return module
-}
-
func CcLibraryBp2Build(ctx android.TopDownMutatorContext) {
m, ok := ctx.Module().(*Module)
if !ok || !m.ConvertWithBp2build(ctx) {
@@ -346,7 +329,7 @@
Bzl_load_location: "//build/bazel/rules:full_cc_library.bzl",
}
- ctx.CreateBazelTargetModule(BazelCcLibraryFactory, m.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(m.Name(), props, attrs)
}
// cc_library creates both static and/or shared libraries for a device and/or
@@ -1754,7 +1737,7 @@
mayUseCoreVariant = false
}
- if ctx.Config().CFIEnabledForPath(ctx.ModuleDir()) && ctx.Arch().ArchType == android.Arm64 {
+ if ctx.Config().CFIEnabledForPath(ctx.ModuleDir()) {
mayUseCoreVariant = false
}
@@ -2414,7 +2397,7 @@
Bzl_load_location: "//build/bazel/rules:cc_library_static.bzl",
}
- ctx.CreateBazelTargetModule(BazelCcLibraryStaticFactory, module.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(module.Name(), props, attrs)
}
func CcLibraryStaticBp2Build(ctx android.TopDownMutatorContext) {
diff --git a/cc/library_headers.go b/cc/library_headers.go
index 1a276f4..44a7a71 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -111,18 +111,6 @@
System_dynamic_deps bazel.LabelListAttribute
}
-type bazelCcLibraryHeaders struct {
- android.BazelTargetModuleBase
- bazelCcLibraryHeadersAttributes
-}
-
-func BazelCcLibraryHeadersFactory() android.Module {
- module := &bazelCcLibraryHeaders{}
- module.AddProperties(&module.bazelCcLibraryHeadersAttributes)
- android.InitBazelTargetModule(module)
- return module
-}
-
func CcLibraryHeadersBp2Build(ctx android.TopDownMutatorContext) {
module, ok := ctx.Module().(*Module)
if !ok {
@@ -155,11 +143,5 @@
Bzl_load_location: "//build/bazel/rules:cc_library_headers.bzl",
}
- ctx.CreateBazelTargetModule(BazelCcLibraryHeadersFactory, module.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(module.Name(), props, attrs)
}
-
-func (m *bazelCcLibraryHeaders) Name() string {
- return m.BaseModuleName()
-}
-
-func (m *bazelCcLibraryHeaders) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
diff --git a/cc/object.go b/cc/object.go
index 5952f1e..606e368 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -130,24 +130,6 @@
Asflags bazel.StringListAttribute
}
-type bazelObject struct {
- android.BazelTargetModuleBase
- bazelObjectAttributes
-}
-
-func (m *bazelObject) Name() string {
- return m.BaseModuleName()
-}
-
-func (m *bazelObject) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
-
-func BazelObjectFactory() android.Module {
- module := &bazelObject{}
- module.AddProperties(&module.bazelObjectAttributes)
- android.InitBazelTargetModule(module)
- return module
-}
-
// ObjectBp2Build is the bp2build converter from cc_object modules to the
// Bazel equivalent target, plus any necessary include deps for the cc_object.
func ObjectBp2Build(ctx android.TopDownMutatorContext) {
@@ -200,7 +182,7 @@
Bzl_load_location: "//build/bazel/rules:cc_object.bzl",
}
- ctx.CreateBazelTargetModule(BazelObjectFactory, m.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(m.Name(), props, attrs)
}
func (object *objectLinker) appendLdflags(flags []string) {
diff --git a/cc/sanitize.go b/cc/sanitize.go
index b244394..dd15ae1 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -437,8 +437,8 @@
}
}
- // Enable CFI for all components in the include paths (for Aarch64 only)
- if s.Cfi == nil && ctx.Config().CFIEnabledForPath(ctx.ModuleDir()) && ctx.Arch().ArchType == android.Arm64 {
+ // Enable CFI for non-host components in the include paths
+ if s.Cfi == nil && ctx.Config().CFIEnabledForPath(ctx.ModuleDir()) && !ctx.Host() {
s.Cfi = proptools.BoolPtr(true)
if inList("cfi", ctx.Config().SanitizeDeviceDiag()) {
s.Diag.Cfi = proptools.BoolPtr(true)
diff --git a/cc/snapshot_prebuilt.go b/cc/snapshot_prebuilt.go
index 9672c0f..9570664 100644
--- a/cc/snapshot_prebuilt.go
+++ b/cc/snapshot_prebuilt.go
@@ -61,7 +61,7 @@
}
func (recoverySnapshotImage) moduleNameSuffix() string {
- return recoverySuffix
+ return RecoverySuffix
}
// Override existing vendor and recovery snapshot for cc module specific extra functions
diff --git a/cc/symbolfile/__init__.py b/cc/symbolfile/__init__.py
index 31c4443..f8d1841 100644
--- a/cc/symbolfile/__init__.py
+++ b/cc/symbolfile/__init__.py
@@ -329,7 +329,7 @@
def parse(self) -> List[Version]:
"""Parses the symbol file and returns a list of Version objects."""
versions = []
- while self.next_line() != '':
+ while self.next_line():
assert self.current_line is not None
if '{' in self.current_line:
versions.append(self.parse_version())
@@ -376,7 +376,7 @@
symbols: List[Symbol] = []
global_scope = True
cpp_symbols = False
- while self.next_line() != '':
+ while self.next_line():
if '}' in self.current_line:
# Line is something like '} BASE; # tags'. Both base and tags
# are optional here.
@@ -428,11 +428,11 @@
A return value of '' indicates EOF.
"""
line = self.input_file.readline()
- while line.strip() == '' or line.strip().startswith('#'):
+ while not line.strip() or line.strip().startswith('#'):
line = self.input_file.readline()
# We want to skip empty lines, but '' indicates EOF.
- if line == '':
+ if not line:
break
self.current_line = line
return self.current_line
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 0099e87..8aea037 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -25,9 +25,9 @@
"android/soong/bp2build"
"android/soong/shared"
-
"github.com/google/blueprint/bootstrap"
"github.com/google/blueprint/deptools"
+ "github.com/google/blueprint/pathtools"
"android/soong/android"
)
@@ -38,12 +38,16 @@
availableEnvFile string
usedEnvFile string
+ globFile string
+ globListDir string
delveListen string
delvePath string
docFile string
bazelQueryViewDir string
bp2buildMarker string
+
+ cmdlineArgs bootstrap.Args
)
func init() {
@@ -61,6 +65,21 @@
flag.StringVar(&docFile, "soong_docs", "", "build documentation file to output")
flag.StringVar(&bazelQueryViewDir, "bazel_queryview_dir", "", "path to the bazel queryview directory relative to --top")
flag.StringVar(&bp2buildMarker, "bp2build_marker", "", "If set, run bp2build, touch the specified marker file then exit")
+
+ flag.StringVar(&cmdlineArgs.OutFile, "o", "build.ninja", "the Ninja file to output")
+ flag.StringVar(&globFile, "globFile", "build-globs.ninja", "the Ninja file of globs to output")
+ flag.StringVar(&globListDir, "globListDir", "", "the directory containing the glob list files")
+ flag.StringVar(&cmdlineArgs.BuildDir, "b", ".", "the build output directory")
+ flag.StringVar(&cmdlineArgs.NinjaBuildDir, "n", "", "the ninja builddir directory")
+ flag.StringVar(&cmdlineArgs.DepFile, "d", "", "the dependency file to output")
+ flag.StringVar(&cmdlineArgs.Cpuprofile, "cpuprofile", "", "write cpu profile to file")
+ flag.StringVar(&cmdlineArgs.TraceFile, "trace", "", "write trace to file")
+ flag.StringVar(&cmdlineArgs.Memprofile, "memprofile", "", "write memory profile to file")
+ flag.BoolVar(&cmdlineArgs.NoGC, "nogc", false, "turn off GC for debugging")
+ flag.BoolVar(&cmdlineArgs.RunGoTests, "t", false, "build and run go tests during bootstrap")
+ flag.BoolVar(&cmdlineArgs.UseValidations, "use-validations", false, "use validations to depend on go tests")
+ flag.StringVar(&cmdlineArgs.ModuleListFile, "l", "", "file that lists filepaths to parse")
+ flag.BoolVar(&cmdlineArgs.EmptyNinjaFile, "empty-ninja-file", false, "write out a 0-byte ninja file")
}
func newNameResolver(config android.Config) *android.NameResolver {
@@ -90,8 +109,8 @@
return ctx
}
-func newConfig(srcDir, outDir string, availableEnv map[string]string) android.Config {
- configuration, err := android.NewConfig(srcDir, outDir, bootstrap.CmdlineArgs.ModuleListFile, availableEnv)
+func newConfig(outDir string, availableEnv map[string]string) android.Config {
+ configuration, err := android.NewConfig(outDir, cmdlineArgs.ModuleListFile, availableEnv)
if err != nil {
fmt.Fprintf(os.Stderr, "%s", err)
os.Exit(1)
@@ -107,7 +126,7 @@
func runMixedModeBuild(configuration android.Config, firstCtx *android.Context, extraNinjaDeps []string) {
var firstArgs, secondArgs bootstrap.Args
- firstArgs = bootstrap.CmdlineArgs
+ firstArgs = cmdlineArgs
configuration.SetStopBefore(bootstrap.StopBeforeWriteNinja)
bootstrap.RunBlueprint(firstArgs, firstCtx.Context, configuration)
@@ -123,9 +142,13 @@
os.Exit(1)
}
secondCtx := newContext(secondConfig, true)
- secondArgs = bootstrap.CmdlineArgs
+ secondArgs = cmdlineArgs
ninjaDeps := bootstrap.RunBlueprint(secondArgs, secondCtx.Context, secondConfig)
ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
+
+ globListFiles := writeBuildGlobsNinjaFile(secondCtx.SrcDir(), configuration.BuildDir(), secondCtx.Globs, configuration)
+ ninjaDeps = append(ninjaDeps, globListFiles...)
+
err = deptools.WriteDepFile(shared.JoinPath(topDir, secondArgs.DepFile), secondArgs.OutFile, ninjaDeps)
if err != nil {
fmt.Fprintf(os.Stderr, "Error writing depfile '%s': %s\n", secondArgs.DepFile, err)
@@ -145,7 +168,7 @@
func runSoongDocs(configuration android.Config) {
ctx := newContext(configuration, false)
- soongDocsArgs := bootstrap.CmdlineArgs
+ soongDocsArgs := cmdlineArgs
bootstrap.RunBlueprint(soongDocsArgs, ctx.Context, configuration)
if err := writeDocs(ctx, configuration, docFile); err != nil {
fmt.Fprintf(os.Stderr, "%s", err)
@@ -174,6 +197,17 @@
writeFakeNinjaFile(extraNinjaDeps, configuration.BuildDir())
}
+func writeBuildGlobsNinjaFile(srcDir, buildDir string, globs func() pathtools.MultipleGlobResults, config interface{}) []string {
+ globDir := bootstrap.GlobDirectory(buildDir, globListDir)
+ bootstrap.WriteBuildGlobsNinjaFile(&bootstrap.GlobSingleton{
+ GlobLister: globs,
+ GlobFile: globFile,
+ GlobDir: globDir,
+ SrcDir: srcDir,
+ }, config)
+ return bootstrap.GlobFileListFiles(globDir)
+}
+
// doChosenActivity runs Soong for a specific activity, like bp2build, queryview
// or the actual Soong build for the build.ninja file. Returns the top level
// output file of the specific activity.
@@ -183,7 +217,7 @@
generateQueryView := bazelQueryViewDir != ""
jsonModuleFile := configuration.Getenv("SOONG_DUMP_JSON_MODULE_GRAPH")
- blueprintArgs := bootstrap.CmdlineArgs
+ blueprintArgs := cmdlineArgs
prepareBuildActions := !generateQueryView && jsonModuleFile == ""
if bazelConversionRequested {
// Run the alternate pipeline of bp2build mutators and singleton to convert
@@ -198,6 +232,10 @@
} else {
ninjaDeps := bootstrap.RunBlueprint(blueprintArgs, ctx.Context, configuration)
ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
+
+ globListFiles := writeBuildGlobsNinjaFile(ctx.SrcDir(), configuration.BuildDir(), ctx.Globs, configuration)
+ ninjaDeps = append(ninjaDeps, globListFiles...)
+
err := deptools.WriteDepFile(shared.JoinPath(topDir, blueprintArgs.DepFile), blueprintArgs.OutFile, ninjaDeps)
if err != nil {
fmt.Fprintf(os.Stderr, "Error writing depfile '%s': %s\n", blueprintArgs.DepFile, err)
@@ -208,16 +246,16 @@
// Convert the Soong module graph into Bazel BUILD files.
if generateQueryView {
runQueryView(configuration, ctx)
- return bootstrap.CmdlineArgs.OutFile // TODO: This is a lie
+ return cmdlineArgs.OutFile // TODO: This is a lie
}
if jsonModuleFile != "" {
writeJsonModuleGraph(configuration, ctx, jsonModuleFile, extraNinjaDeps)
- return bootstrap.CmdlineArgs.OutFile // TODO: This is a lie
+ return cmdlineArgs.OutFile // TODO: This is a lie
}
writeMetrics(configuration)
- return bootstrap.CmdlineArgs.OutFile
+ return cmdlineArgs.OutFile
}
// soong_ui dumps the available environment variables to
@@ -256,9 +294,7 @@
availableEnv := parseAvailableEnv()
- // The top-level Blueprints file is passed as the first argument.
- srcDir := filepath.Dir(flag.Arg(0))
- configuration := newConfig(srcDir, outDir, availableEnv)
+ configuration := newConfig(outDir, availableEnv)
extraNinjaDeps := []string{
configuration.ProductVariablesFileName,
usedEnvFile,
@@ -420,7 +456,7 @@
// Read the bazel.list file that the Soong Finder already dumped earlier (hopefully)
// It contains the locations of BUILD files, BUILD.bazel files, etc. in the source dir
func getExistingBazelRelatedFiles(topDir string) ([]string, error) {
- bazelFinderFile := filepath.Join(filepath.Dir(bootstrap.CmdlineArgs.ModuleListFile), "bazel.list")
+ bazelFinderFile := filepath.Join(filepath.Dir(cmdlineArgs.ModuleListFile), "bazel.list")
if !filepath.IsAbs(bazelFinderFile) {
// Assume this was a relative path under topDir
bazelFinderFile = filepath.Join(topDir, bazelFinderFile)
@@ -451,8 +487,8 @@
// Android.bp files. It must not depend on the values of per-build product
// configurations or variables, since those will generate different BUILD
// files based on how the user has configured their tree.
- bp2buildCtx.SetModuleListFile(bootstrap.CmdlineArgs.ModuleListFile)
- modulePaths, err := bp2buildCtx.ListModulePaths(configuration.SrcDir())
+ bp2buildCtx.SetModuleListFile(cmdlineArgs.ModuleListFile)
+ modulePaths, err := bp2buildCtx.ListModulePaths(".")
if err != nil {
panic(err)
}
@@ -465,17 +501,12 @@
// Run the loading and analysis pipeline to prepare the graph of regular
// Modules parsed from Android.bp files, and the BazelTargetModules mapped
// from the regular Modules.
- blueprintArgs := bootstrap.CmdlineArgs
+ blueprintArgs := cmdlineArgs
ninjaDeps := bootstrap.RunBlueprint(blueprintArgs, bp2buildCtx.Context, configuration)
ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
- // Generate out/soong/.bootstrap/build-globs.ninja with the actions to generate flattened globfiles
- // containing the globs seen during bp2build conversion
- if blueprintArgs.GlobFile != "" {
- bootstrap.WriteBuildGlobsNinjaFile(bootstrap.StageMain, bp2buildCtx.Context, blueprintArgs, configuration)
- }
- // Add the depfile on the expanded globs in out/soong/.primary/globs
- ninjaDeps = append(ninjaDeps, bootstrap.GlobFileListFiles(configuration)...)
+ globListFiles := writeBuildGlobsNinjaFile(bp2buildCtx.SrcDir(), configuration.BuildDir(), bp2buildCtx.Globs, configuration)
+ ninjaDeps = append(ninjaDeps, globListFiles...)
// Run the code-generation phase to convert BazelTargetModules to BUILD files
// and print conversion metrics to the user.
@@ -493,8 +524,8 @@
"bazel-" + filepath.Base(topDir),
}
- if bootstrap.CmdlineArgs.NinjaBuildDir[0] != '/' {
- excludes = append(excludes, bootstrap.CmdlineArgs.NinjaBuildDir)
+ if cmdlineArgs.NinjaBuildDir[0] != '/' {
+ excludes = append(excludes, cmdlineArgs.NinjaBuildDir)
}
existingBazelRelatedFiles, err := getExistingBazelRelatedFiles(topDir)
@@ -509,7 +540,7 @@
excludes = append(excludes, getTemporaryExcludes()...)
symlinkForestDeps := bp2build.PlantSymlinkForest(
- topDir, workspaceRoot, generatedRoot, configuration.SrcDir(), excludes)
+ topDir, workspaceRoot, generatedRoot, ".", excludes)
// Only report metrics when in bp2build mode. The metrics aren't relevant
// for queryview, since that's a total repo-wide conversion and there's a
@@ -528,12 +559,4 @@
// Create an empty bp2build marker file.
touch(shared.JoinPath(topDir, bp2buildMarker))
-
- // bp2build *always* writes a fake Ninja file containing just the nothing
- // phony target if it ever re-runs. This allows bp2build to exit early with
- // GENERATE_BAZEL_FILES=1 m nothing.
- //
- // If bp2build is invoked as part of an integrated mixed build, the fake
- // build.ninja file will be rewritten later into the real file anyway.
- writeFakeNinjaFile(extraNinjaDeps, codegenContext.Config().BuildDir())
}
diff --git a/dexpreopt/class_loader_context.go b/dexpreopt/class_loader_context.go
index 245af2c..ebb8959 100644
--- a/dexpreopt/class_loader_context.go
+++ b/dexpreopt/class_loader_context.go
@@ -193,6 +193,9 @@
// The name of the library.
Name string
+ // If the library is optional or required.
+ Optional bool
+
// On-host build path to the library dex file (used in dex2oat argument --class-loader-context).
Host android.Path
@@ -256,7 +259,7 @@
// Add class loader context for the given library to the map entry for the given SDK version.
func (clcMap ClassLoaderContextMap) addContext(ctx android.ModuleInstallPathContext, sdkVer int, lib string,
- hostPath, installPath android.Path, nestedClcMap ClassLoaderContextMap) error {
+ optional bool, hostPath, installPath android.Path, nestedClcMap ClassLoaderContextMap) error {
// For prebuilts, library should have the same name as the source module.
lib = android.RemoveOptionalPrebuiltPrefix(lib)
@@ -304,6 +307,7 @@
clcMap[sdkVer] = append(clcMap[sdkVer], &ClassLoaderContext{
Name: lib,
+ Optional: optional,
Host: hostPath,
Device: devicePath,
Subcontexts: subcontexts,
@@ -316,9 +320,9 @@
// about paths). For the subset of libraries that are used in dexpreopt, their build/install paths
// are validated later before CLC is used (in validateClassLoaderContext).
func (clcMap ClassLoaderContextMap) AddContext(ctx android.ModuleInstallPathContext, sdkVer int,
- lib string, hostPath, installPath android.Path, nestedClcMap ClassLoaderContextMap) {
+ lib string, optional bool, hostPath, installPath android.Path, nestedClcMap ClassLoaderContextMap) {
- err := clcMap.addContext(ctx, sdkVer, lib, hostPath, installPath, nestedClcMap)
+ err := clcMap.addContext(ctx, sdkVer, lib, optional, hostPath, installPath, nestedClcMap)
if err != nil {
ctx.ModuleErrorf(err.Error())
}
@@ -361,15 +365,21 @@
// Returns top-level libraries in the CLC (conditional CLC, i.e. compatibility libraries are not
// included). This is the list of libraries that should be in the <uses-library> tags in the
// manifest. Some of them may be present in the source manifest, others are added by manifest_fixer.
-func (clcMap ClassLoaderContextMap) UsesLibs() (ulibs []string) {
+// Required and optional libraries are in separate lists.
+func (clcMap ClassLoaderContextMap) UsesLibs() (required []string, optional []string) {
if clcMap != nil {
clcs := clcMap[AnySdkVersion]
- ulibs = make([]string, 0, len(clcs))
+ required = make([]string, 0, len(clcs))
+ optional = make([]string, 0, len(clcs))
for _, clc := range clcs {
- ulibs = append(ulibs, clc.Name)
+ if clc.Optional {
+ optional = append(optional, clc.Name)
+ } else {
+ required = append(required, clc.Name)
+ }
}
}
- return ulibs
+ return required, optional
}
func (clcMap ClassLoaderContextMap) Dump() string {
@@ -388,7 +398,8 @@
// TODO(b/132357300): remove "android.hidl.manager" and "android.hidl.base" for non-system apps.
//
func fixClassLoaderContext(clcMap ClassLoaderContextMap) {
- usesLibs := clcMap.UsesLibs()
+ required, optional := clcMap.UsesLibs()
+ usesLibs := append(required, optional...)
for sdkVer, clcs := range clcMap {
if sdkVer == AnySdkVersion {
diff --git a/dexpreopt/class_loader_context_test.go b/dexpreopt/class_loader_context_test.go
index 610a4c9..0b7b546 100644
--- a/dexpreopt/class_loader_context_test.go
+++ b/dexpreopt/class_loader_context_test.go
@@ -49,32 +49,34 @@
//
ctx := testContext()
+ optional := false
+
m := make(ClassLoaderContextMap)
- m.AddContext(ctx, AnySdkVersion, "a", buildPath(ctx, "a"), installPath(ctx, "a"), nil)
- m.AddContext(ctx, AnySdkVersion, "b", buildPath(ctx, "b"), installPath(ctx, "b"), nil)
- m.AddContext(ctx, AnySdkVersion, "c", buildPath(ctx, "c"), installPath(ctx, "c"), nil)
+ m.AddContext(ctx, AnySdkVersion, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
+ m.AddContext(ctx, AnySdkVersion, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil)
+ m.AddContext(ctx, AnySdkVersion, "c", optional, buildPath(ctx, "c"), installPath(ctx, "c"), nil)
// Add some libraries with nested subcontexts.
m1 := make(ClassLoaderContextMap)
- m1.AddContext(ctx, AnySdkVersion, "a1", buildPath(ctx, "a1"), installPath(ctx, "a1"), nil)
- m1.AddContext(ctx, AnySdkVersion, "b1", buildPath(ctx, "b1"), installPath(ctx, "b1"), nil)
+ m1.AddContext(ctx, AnySdkVersion, "a1", optional, buildPath(ctx, "a1"), installPath(ctx, "a1"), nil)
+ m1.AddContext(ctx, AnySdkVersion, "b1", optional, buildPath(ctx, "b1"), installPath(ctx, "b1"), nil)
m2 := make(ClassLoaderContextMap)
- m2.AddContext(ctx, AnySdkVersion, "a2", buildPath(ctx, "a2"), installPath(ctx, "a2"), nil)
- m2.AddContext(ctx, AnySdkVersion, "b2", buildPath(ctx, "b2"), installPath(ctx, "b2"), nil)
- m2.AddContext(ctx, AnySdkVersion, "c2", buildPath(ctx, "c2"), installPath(ctx, "c2"), m1)
+ m2.AddContext(ctx, AnySdkVersion, "a2", optional, buildPath(ctx, "a2"), installPath(ctx, "a2"), nil)
+ m2.AddContext(ctx, AnySdkVersion, "b2", optional, buildPath(ctx, "b2"), installPath(ctx, "b2"), nil)
+ m2.AddContext(ctx, AnySdkVersion, "c2", optional, buildPath(ctx, "c2"), installPath(ctx, "c2"), m1)
m3 := make(ClassLoaderContextMap)
- m3.AddContext(ctx, AnySdkVersion, "a3", buildPath(ctx, "a3"), installPath(ctx, "a3"), nil)
- m3.AddContext(ctx, AnySdkVersion, "b3", buildPath(ctx, "b3"), installPath(ctx, "b3"), nil)
+ m3.AddContext(ctx, AnySdkVersion, "a3", optional, buildPath(ctx, "a3"), installPath(ctx, "a3"), nil)
+ m3.AddContext(ctx, AnySdkVersion, "b3", optional, buildPath(ctx, "b3"), installPath(ctx, "b3"), nil)
- m.AddContext(ctx, AnySdkVersion, "d", buildPath(ctx, "d"), installPath(ctx, "d"), m2)
+ m.AddContext(ctx, AnySdkVersion, "d", optional, buildPath(ctx, "d"), installPath(ctx, "d"), m2)
// When the same library is both in conditional and unconditional context, it should be removed
// from conditional context.
- m.AddContext(ctx, 42, "f", buildPath(ctx, "f"), installPath(ctx, "f"), nil)
- m.AddContext(ctx, AnySdkVersion, "f", buildPath(ctx, "f"), installPath(ctx, "f"), nil)
+ m.AddContext(ctx, 42, "f", optional, buildPath(ctx, "f"), installPath(ctx, "f"), nil)
+ m.AddContext(ctx, AnySdkVersion, "f", optional, buildPath(ctx, "f"), installPath(ctx, "f"), nil)
// Merge map with implicit root library that is among toplevel contexts => does nothing.
m.AddContextMap(m1, "c")
@@ -83,12 +85,12 @@
m.AddContextMap(m3, "m_g")
// Compatibility libraries with unknown install paths get default paths.
- m.AddContext(ctx, 29, AndroidHidlManager, buildPath(ctx, AndroidHidlManager), nil, nil)
- m.AddContext(ctx, 29, AndroidHidlBase, buildPath(ctx, AndroidHidlBase), nil, nil)
+ m.AddContext(ctx, 29, AndroidHidlManager, optional, buildPath(ctx, AndroidHidlManager), nil, nil)
+ m.AddContext(ctx, 29, AndroidHidlBase, optional, buildPath(ctx, AndroidHidlBase), nil, nil)
// Add "android.test.mock" to conditional CLC, observe that is gets removed because it is only
// needed as a compatibility library if "android.test.runner" is in CLC as well.
- m.AddContext(ctx, 30, AndroidTestMock, buildPath(ctx, AndroidTestMock), nil, nil)
+ m.AddContext(ctx, 30, AndroidTestMock, optional, buildPath(ctx, AndroidTestMock), nil, nil)
valid, validationError := validateClassLoaderContext(m)
@@ -96,10 +98,10 @@
var haveStr string
var havePaths android.Paths
- var haveUsesLibs []string
+ var haveUsesLibsReq, haveUsesLibsOpt []string
if valid && validationError == nil {
haveStr, havePaths = ComputeClassLoaderContext(m)
- haveUsesLibs = m.UsesLibs()
+ haveUsesLibsReq, haveUsesLibsOpt = m.UsesLibs()
}
// Test that validation is successful (all paths are known).
@@ -148,20 +150,25 @@
// Test for libraries that are added by the manifest_fixer.
t.Run("uses libs", func(t *testing.T) {
- wantUsesLibs := []string{"a", "b", "c", "d", "f", "a3", "b3"}
- if !reflect.DeepEqual(wantUsesLibs, haveUsesLibs) {
- t.Errorf("\nwant uses libs: %s\nhave uses libs: %s", wantUsesLibs, haveUsesLibs)
+ wantUsesLibsReq := []string{"a", "b", "c", "d", "f", "a3", "b3"}
+ wantUsesLibsOpt := []string{}
+ if !reflect.DeepEqual(wantUsesLibsReq, haveUsesLibsReq) {
+ t.Errorf("\nwant required uses libs: %s\nhave required uses libs: %s", wantUsesLibsReq, haveUsesLibsReq)
+ }
+ if !reflect.DeepEqual(wantUsesLibsOpt, haveUsesLibsOpt) {
+ t.Errorf("\nwant optional uses libs: %s\nhave optional uses libs: %s", wantUsesLibsOpt, haveUsesLibsOpt)
}
})
}
func TestCLCJson(t *testing.T) {
ctx := testContext()
+ optional := false
m := make(ClassLoaderContextMap)
- m.AddContext(ctx, 28, "a", buildPath(ctx, "a"), installPath(ctx, "a"), nil)
- m.AddContext(ctx, 29, "b", buildPath(ctx, "b"), installPath(ctx, "b"), nil)
- m.AddContext(ctx, 30, "c", buildPath(ctx, "c"), installPath(ctx, "c"), nil)
- m.AddContext(ctx, AnySdkVersion, "d", buildPath(ctx, "d"), installPath(ctx, "d"), nil)
+ m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
+ m.AddContext(ctx, 29, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil)
+ m.AddContext(ctx, 30, "c", optional, buildPath(ctx, "c"), installPath(ctx, "c"), nil)
+ m.AddContext(ctx, AnySdkVersion, "d", optional, buildPath(ctx, "d"), installPath(ctx, "d"), nil)
jsonCLC := toJsonClassLoaderContext(m)
restored := fromJsonClassLoaderContext(ctx, jsonCLC)
android.AssertIntEquals(t, "The size of the maps should be the same.", len(m), len(restored))
@@ -181,20 +188,25 @@
// Test that unknown library paths cause a validation error.
func testCLCUnknownPath(t *testing.T, whichPath string) {
ctx := testContext()
+ optional := false
m := make(ClassLoaderContextMap)
if whichPath == "build" {
- m.AddContext(ctx, AnySdkVersion, "a", nil, nil, nil)
+ m.AddContext(ctx, AnySdkVersion, "a", optional, nil, nil, nil)
} else {
- m.AddContext(ctx, AnySdkVersion, "a", buildPath(ctx, "a"), nil, nil)
+ m.AddContext(ctx, AnySdkVersion, "a", optional, buildPath(ctx, "a"), nil, nil)
}
// The library should be added to <uses-library> tags by the manifest_fixer.
t.Run("uses libs", func(t *testing.T) {
- haveUsesLibs := m.UsesLibs()
- wantUsesLibs := []string{"a"}
- if !reflect.DeepEqual(wantUsesLibs, haveUsesLibs) {
- t.Errorf("\nwant uses libs: %s\nhave uses libs: %s", wantUsesLibs, haveUsesLibs)
+ haveUsesLibsReq, haveUsesLibsOpt := m.UsesLibs()
+ wantUsesLibsReq := []string{"a"}
+ wantUsesLibsOpt := []string{}
+ if !reflect.DeepEqual(wantUsesLibsReq, haveUsesLibsReq) {
+ t.Errorf("\nwant required uses libs: %s\nhave required uses libs: %s", wantUsesLibsReq, haveUsesLibsReq)
+ }
+ if !reflect.DeepEqual(wantUsesLibsOpt, haveUsesLibsOpt) {
+ t.Errorf("\nwant optional uses libs: %s\nhave optional uses libs: %s", wantUsesLibsOpt, haveUsesLibsOpt)
}
})
@@ -216,10 +228,11 @@
// An attempt to add conditional nested subcontext should fail.
func TestCLCNestedConditional(t *testing.T) {
ctx := testContext()
+ optional := false
m1 := make(ClassLoaderContextMap)
- m1.AddContext(ctx, 42, "a", buildPath(ctx, "a"), installPath(ctx, "a"), nil)
+ m1.AddContext(ctx, 42, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
m := make(ClassLoaderContextMap)
- err := m.addContext(ctx, AnySdkVersion, "b", buildPath(ctx, "b"), installPath(ctx, "b"), m1)
+ err := m.addContext(ctx, AnySdkVersion, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), m1)
checkError(t, err, "nested class loader context shouldn't have conditional part")
}
@@ -227,11 +240,12 @@
// they end up in the order that agrees with PackageManager.
func TestCLCSdkVersionOrder(t *testing.T) {
ctx := testContext()
+ optional := false
m := make(ClassLoaderContextMap)
- m.AddContext(ctx, 28, "a", buildPath(ctx, "a"), installPath(ctx, "a"), nil)
- m.AddContext(ctx, 29, "b", buildPath(ctx, "b"), installPath(ctx, "b"), nil)
- m.AddContext(ctx, 30, "c", buildPath(ctx, "c"), installPath(ctx, "c"), nil)
- m.AddContext(ctx, AnySdkVersion, "d", buildPath(ctx, "d"), installPath(ctx, "d"), nil)
+ m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
+ m.AddContext(ctx, 29, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil)
+ m.AddContext(ctx, 30, "c", optional, buildPath(ctx, "c"), installPath(ctx, "c"), nil)
+ m.AddContext(ctx, AnySdkVersion, "d", optional, buildPath(ctx, "d"), installPath(ctx, "d"), nil)
valid, validationError := validateClassLoaderContext(m)
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index 8aeb0dd..3213e5c 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -662,18 +662,6 @@
Installable bazel.BoolAttribute
}
-type bazelPrebuiltEtc struct {
- android.BazelTargetModuleBase
- bazelPrebuiltEtcAttributes
-}
-
-func BazelPrebuiltEtcFactory() android.Module {
- module := &bazelPrebuiltEtc{}
- module.AddProperties(&module.bazelPrebuiltEtcAttributes)
- android.InitBazelTargetModule(module)
- return module
-}
-
func PrebuiltEtcBp2Build(ctx android.TopDownMutatorContext) {
module, ok := ctx.Module().(*PrebuiltEtc)
if !ok {
@@ -723,11 +711,5 @@
Bzl_load_location: "//build/bazel/rules:prebuilt_etc.bzl",
}
- ctx.CreateBazelTargetModule(BazelPrebuiltEtcFactory, module.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(module.Name(), props, attrs)
}
-
-func (m *bazelPrebuiltEtc) Name() string {
- return m.BaseModuleName()
-}
-
-func (m *bazelPrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
diff --git a/genrule/genrule.go b/genrule/genrule.go
index fdb3618..bde6e97 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -826,18 +826,6 @@
Cmd string
}
-type bazelGenrule struct {
- android.BazelTargetModuleBase
- bazelGenruleAttributes
-}
-
-func BazelGenruleFactory() android.Module {
- module := &bazelGenrule{}
- module.AddProperties(&module.bazelGenruleAttributes)
- android.InitBazelTargetModule(module)
- return module
-}
-
func GenruleBp2Build(ctx android.TopDownMutatorContext) {
m, ok := ctx.Module().(*Module)
if !ok || !m.ConvertWithBp2build(ctx) {
@@ -904,15 +892,9 @@
}
// Create the BazelTargetModule.
- ctx.CreateBazelTargetModule(BazelGenruleFactory, m.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(m.Name(), props, attrs)
}
-func (m *bazelGenrule) Name() string {
- return m.BaseModuleName()
-}
-
-func (m *bazelGenrule) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
-
var Bool = proptools.Bool
var String = proptools.String
diff --git a/java/aar.go b/java/aar.go
index 04727e4..afbaea2 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -502,11 +502,12 @@
if sdkDep.hasFrameworkLibs() {
a.aapt.deps(ctx, sdkDep)
}
+ a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
}
func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.aapt.isLibrary = true
- a.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)
+ a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts)
a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()
diff --git a/java/android_manifest.go b/java/android_manifest.go
index 331f941..1f7234d 100644
--- a/java/android_manifest.go
+++ b/java/android_manifest.go
@@ -71,12 +71,12 @@
args = append(args, "--use-embedded-dex")
}
- for _, usesLib := range classLoaderContexts.UsesLibs() {
- if inList(usesLib, dexpreopt.OptionalCompatUsesLibs) {
- args = append(args, "--optional-uses-library", usesLib)
- } else {
- args = append(args, "--uses-library", usesLib)
- }
+ requiredUsesLibs, optionalUsesLibs := classLoaderContexts.UsesLibs()
+ for _, usesLib := range requiredUsesLibs {
+ args = append(args, "--uses-library", usesLib)
+ }
+ for _, usesLib := range optionalUsesLibs {
+ args = append(args, "--optional-uses-library", usesLib)
}
if hasNoCode {
diff --git a/java/androidmk.go b/java/androidmk.go
index 04357e0..68ccd82 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -114,7 +114,8 @@
entries.SetPath("LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR", library.jacocoReportClassesFile)
}
- entries.AddStrings("LOCAL_EXPORT_SDK_LIBRARIES", library.classLoaderContexts.UsesLibs()...)
+ requiredUsesLibs, optionalUsesLibs := library.classLoaderContexts.UsesLibs()
+ entries.AddStrings("LOCAL_EXPORT_SDK_LIBRARIES", append(requiredUsesLibs, optionalUsesLibs...)...)
if len(library.additionalCheckedModules) != 0 {
entries.AddStrings("LOCAL_ADDITIONAL_CHECKED_MODULE", library.additionalCheckedModules.Strings()...)
diff --git a/java/app.go b/java/app.go
index 35ed27f..e7661df 100755
--- a/java/app.go
+++ b/java/app.go
@@ -649,8 +649,12 @@
a.usesLibrary.freezeEnforceUsesLibraries()
// Add implicit SDK libraries to <uses-library> list.
- for _, usesLib := range a.classLoaderContexts.UsesLibs() {
- a.usesLibrary.addLib(usesLib, inList(usesLib, dexpreopt.OptionalCompatUsesLibs))
+ requiredUsesLibs, optionalUsesLibs := a.classLoaderContexts.UsesLibs()
+ for _, usesLib := range requiredUsesLibs {
+ a.usesLibrary.addLib(usesLib, false)
+ }
+ for _, usesLib := range optionalUsesLibs {
+ a.usesLibrary.addLib(usesLib, true)
}
// Check that the <uses-library> list is coherent with the manifest.
@@ -1220,17 +1224,17 @@
func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, hasFrameworkLibs bool) {
if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
- ctx.AddVariationDependencies(nil, usesLibTag, u.usesLibraryProperties.Uses_libs...)
- ctx.AddVariationDependencies(nil, usesLibTag, u.presentOptionalUsesLibs(ctx)...)
+ ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs...)
+ ctx.AddVariationDependencies(nil, usesLibOptTag, u.presentOptionalUsesLibs(ctx)...)
// Only add these extra dependencies if the module depends on framework libs. This avoids
// creating a cyclic dependency:
// e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
if hasFrameworkLibs {
// Dexpreopt needs paths to the dex jars of these libraries in order to construct
// class loader context for dex2oat. Add them as a dependency with a special tag.
- ctx.AddVariationDependencies(nil, usesLibCompat29Tag, dexpreopt.CompatUsesLibs29...)
- ctx.AddVariationDependencies(nil, usesLibCompat28Tag, dexpreopt.OptionalCompatUsesLibs28...)
- ctx.AddVariationDependencies(nil, usesLibCompat30Tag, dexpreopt.OptionalCompatUsesLibs30...)
+ ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...)
+ ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
+ ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
}
}
}
@@ -1289,7 +1293,7 @@
replaceInList(u.usesLibraryProperties.Uses_libs, dep, libName)
replaceInList(u.usesLibraryProperties.Optional_uses_libs, dep, libName)
}
- clcMap.AddContext(ctx, tag.sdkVersion, libName,
+ clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional,
lib.DexJarBuildPath(), lib.DexJarInstallPath(), lib.ClassLoaderContexts())
} else if ctx.Config().AllowMissingDependencies() {
ctx.AddMissingDependencies([]string{dep})
@@ -1381,18 +1385,6 @@
Certificate string
}
-type bazelAndroidAppCertificate struct {
- android.BazelTargetModuleBase
- bazelAndroidAppCertificateAttributes
-}
-
-func BazelAndroidAppCertificateFactory() android.Module {
- module := &bazelAndroidAppCertificate{}
- module.AddProperties(&module.bazelAndroidAppCertificateAttributes)
- android.InitBazelTargetModule(module)
- return module
-}
-
func AndroidAppCertificateBp2Build(ctx android.TopDownMutatorContext) {
module, ok := ctx.Module().(*AndroidAppCertificate)
if !ok {
@@ -1424,11 +1416,5 @@
Bzl_load_location: "//build/bazel/rules:android_app_certificate.bzl",
}
- ctx.CreateBazelTargetModule(BazelAndroidAppCertificateFactory, module.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(module.Name(), props, attrs)
}
-
-func (m *bazelAndroidAppCertificate) Name() string {
- return m.BaseModuleName()
-}
-
-func (m *bazelAndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
diff --git a/java/app_test.go b/java/app_test.go
index 7997f7a..c14c65d 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -2285,6 +2285,49 @@
sdk_version: "current",
}
+ java_library {
+ name: "runtime-required-x",
+ srcs: ["a.java"],
+ installable: true,
+ sdk_version: "current",
+ }
+
+ java_library {
+ name: "runtime-optional-x",
+ srcs: ["a.java"],
+ installable: true,
+ sdk_version: "current",
+ }
+
+ android_library {
+ name: "static-x",
+ uses_libs: ["runtime-required-x"],
+ optional_uses_libs: ["runtime-optional-x"],
+ sdk_version: "current",
+ }
+
+ java_library {
+ name: "runtime-required-y",
+ srcs: ["a.java"],
+ installable: true,
+ sdk_version: "current",
+ }
+
+ java_library {
+ name: "runtime-optional-y",
+ srcs: ["a.java"],
+ installable: true,
+ sdk_version: "current",
+ }
+
+ java_library {
+ name: "static-y",
+ srcs: ["a.java"],
+ uses_libs: ["runtime-required-y"],
+ optional_uses_libs: ["runtime-optional-y"],
+ sdk_version: "current",
+ }
+
// A library that has to use "provides_uses_lib", because:
// - it is not an SDK library
// - its library name is different from its module name
@@ -2307,6 +2350,8 @@
// statically linked component libraries should not pull their SDK libraries,
// so "fred" should not be added to class loader context
"fred.stubs",
+ "static-x",
+ "static-y",
],
uses_libs: [
"foo",
@@ -2355,8 +2400,12 @@
`--uses-library quuz ` +
`--uses-library foo ` + // TODO(b/132357300): "foo" should not be passed to manifest_fixer
`--uses-library com.non.sdk.lib ` + // TODO(b/132357300): "com.non.sdk.lib" should not be passed to manifest_fixer
- `--uses-library bar ` + // TODO(b/132357300): "bar" should not be passed to manifest_fixer
- `--uses-library runtime-library`
+ `--uses-library runtime-library ` +
+ `--uses-library runtime-required-x ` + // TODO(b/132357300): "runtime-required-x" should not be passed to manifest_fixer
+ `--uses-library runtime-required-y ` + // TODO(b/132357300): "runtime-required-y" should not be passed to manifest_fixer
+ `--optional-uses-library bar ` + // TODO(b/132357300): "bar" should not be passed to manifest_fixer
+ `--optional-uses-library runtime-optional-x ` + // TODO(b/132357300): "runtime-optional-x" should not be passed to manifest_fixer
+ `--optional-uses-library runtime-optional-y` // TODO(b/132357300): "runtime-optional-y" should not be passed to manifest_fixer
android.AssertStringEquals(t, "manifest_fixer args", expectManifestFixerArgs, actualManifestFixerArgs)
// Test that all libraries are verified (library order matters).
@@ -2366,8 +2415,12 @@
`--uses-library qux ` +
`--uses-library quuz ` +
`--uses-library runtime-library ` +
+ `--uses-library runtime-required-x ` +
+ `--uses-library runtime-required-y ` +
`--optional-uses-library bar ` +
- `--optional-uses-library baz `
+ `--optional-uses-library baz ` +
+ `--optional-uses-library runtime-optional-x ` +
+ `--optional-uses-library runtime-optional-y `
android.AssertStringDoesContain(t, "verify cmd args", verifyCmd, verifyArgs)
// Test that all libraries are verified for an APK (library order matters).
@@ -2387,7 +2440,11 @@
`PCL[/system/framework/foo.jar]#` +
`PCL[/system/framework/non-sdk-lib.jar]#` +
`PCL[/system/framework/bar.jar]#` +
- `PCL[/system/framework/runtime-library.jar]`
+ `PCL[/system/framework/runtime-library.jar]#` +
+ `PCL[/system/framework/runtime-required-x.jar]#` +
+ `PCL[/system/framework/runtime-optional-x.jar]#` +
+ `PCL[/system/framework/runtime-required-y.jar]#` +
+ `PCL[/system/framework/runtime-optional-y.jar] `
android.AssertStringDoesContain(t, "dexpreopt app cmd args", cmd, w)
// Test conditional context for target SDK version 28.
diff --git a/java/base.go b/java/base.go
index d8cd6b3..ea5b137 100644
--- a/java/base.go
+++ b/java/base.go
@@ -605,7 +605,12 @@
if dep != nil {
if component, ok := dep.(SdkLibraryComponentDependency); ok {
if lib := component.OptionalSdkLibraryImplementation(); lib != nil {
- ctx.AddVariationDependencies(nil, usesLibTag, *lib)
+ // Add library as optional if it's one of the optional compatibility libs.
+ tag := usesLibReqTag
+ if android.InList(*lib, dexpreopt.OptionalCompatUsesLibs) {
+ tag = usesLibOptTag
+ }
+ ctx.AddVariationDependencies(nil, tag, *lib)
}
}
}
diff --git a/java/java.go b/java/java.go
index b6e2a54..b46324f 100644
--- a/java/java.go
+++ b/java/java.go
@@ -248,13 +248,15 @@
type usesLibraryDependencyTag struct {
dependencyTag
- sdkVersion int // SDK version in which the library appared as a standalone library.
+ sdkVersion int // SDK version in which the library appared as a standalone library.
+ optional bool // If the dependency is optional or required.
}
-func makeUsesLibraryDependencyTag(sdkVersion int) usesLibraryDependencyTag {
+func makeUsesLibraryDependencyTag(sdkVersion int, optional bool) usesLibraryDependencyTag {
return usesLibraryDependencyTag{
dependencyTag: dependencyTag{name: fmt.Sprintf("uses-library-%d", sdkVersion)},
sdkVersion: sdkVersion,
+ optional: optional,
}
}
@@ -283,10 +285,11 @@
syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"}
jniInstallTag = installDependencyTag{name: "jni install"}
binaryInstallTag = installDependencyTag{name: "binary install"}
- usesLibTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion)
- usesLibCompat28Tag = makeUsesLibraryDependencyTag(28)
- usesLibCompat29Tag = makeUsesLibraryDependencyTag(29)
- usesLibCompat30Tag = makeUsesLibraryDependencyTag(30)
+ usesLibReqTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false)
+ usesLibOptTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, true)
+ usesLibCompat28OptTag = makeUsesLibraryDependencyTag(28, true)
+ usesLibCompat29ReqTag = makeUsesLibraryDependencyTag(29, false)
+ usesLibCompat30OptTag = makeUsesLibraryDependencyTag(30, true)
)
func IsLibDepTag(depTag blueprint.DependencyTag) bool {
@@ -508,7 +511,7 @@
j.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter))
}
j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
- j.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)
+ j.classLoaderContexts = j.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
j.compile(ctx, nil)
// Collect the module directory for IDE info in java/jdeps.go.
@@ -527,6 +530,7 @@
func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
j.deps(ctx)
+ j.usesLibrary.deps(ctx, false)
}
const (
@@ -1807,8 +1811,10 @@
}
depTag := ctx.OtherModuleDependencyTag(depModule)
- if depTag == libTag || depTag == usesLibTag {
+ if depTag == libTag {
// Ok, propagate <uses-library> through non-static library dependencies.
+ } else if tag, ok := depTag.(usesLibraryDependencyTag); ok && tag.sdkVersion == dexpreopt.AnySdkVersion {
+ // Ok, propagate <uses-library> through non-compatibility <uses-library> dependencies.
} else if depTag == staticLibTag {
// Propagate <uses-library> through static library dependencies, unless it is a component
// library (such as stubs). Component libraries have a dependency on their SDK library,
@@ -1826,7 +1832,7 @@
// <uses_library> and should not be added to CLC, but the transitive <uses-library> dependencies
// from its CLC should be added to the current CLC.
if sdkLib != nil {
- clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib,
+ clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, false,
dep.DexJarBuildPath(), dep.DexJarInstallPath(), dep.ClassLoaderContexts())
} else {
clcMap.AddContextMap(dep.ClassLoaderContexts(), depName)
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index 8e0618e..938bb28 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -156,8 +156,9 @@
// test if baz has exported SDK lib names foo and bar to qux
qux := result.ModuleForTests("qux", "android_common")
if quxLib, ok := qux.Module().(*Library); ok {
- sdkLibs := quxLib.ClassLoaderContexts().UsesLibs()
- android.AssertDeepEquals(t, "qux exports", []string{"foo", "bar", "fred", "quuz"}, sdkLibs)
+ requiredSdkLibs, optionalSdkLibs := quxLib.ClassLoaderContexts().UsesLibs()
+ android.AssertDeepEquals(t, "qux exports (required)", []string{"fred", "quuz", "foo", "bar"}, requiredSdkLibs)
+ android.AssertDeepEquals(t, "qux exports (optional)", []string{}, optionalSdkLibs)
}
}
diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go
index 7ceac41..b05d340 100644
--- a/mk2rbc/mk2rbc.go
+++ b/mk2rbc/mk2rbc.go
@@ -118,7 +118,7 @@
"notdir": {baseName + ".notdir", starlarkTypeString, hiddenArgNone},
"my-dir": {"!my-dir", starlarkTypeString, hiddenArgNone},
"patsubst": {baseName + ".mkpatsubst", starlarkTypeString, hiddenArgNone},
- "produce_copy_files": {baseName + ".produce_copy_files", starlarkTypeList, hiddenArgNone},
+ "product-copy-files-by-pattern": {baseName + ".product_copy_files_by_pattern", starlarkTypeList, hiddenArgNone},
"require-artifacts-in-path": {baseName + ".require_artifacts_in_path", starlarkTypeVoid, hiddenArgNone},
"require-artifacts-in-path-relaxed": {baseName + ".require_artifacts_in_path_relaxed", starlarkTypeVoid, hiddenArgNone},
// TODO(asmundak): remove it once all calls are removed from configuration makefiles. see b/183161002
@@ -419,14 +419,7 @@
{"TARGET_COPY_OUT_TEST_HARNESS_RAMDISK", "test_harness_ramdisk"},
{"TARGET_COPY_OUT_ROOT", "root"},
{"TARGET_COPY_OUT_RECOVERY", "recovery"},
- {"TARGET_COPY_OUT_VENDOR", "||VENDOR-PATH-PH||"},
{"TARGET_COPY_OUT_VENDOR_RAMDISK", "vendor_ramdisk"},
- {"TARGET_COPY_OUT_PRODUCT", "||PRODUCT-PATH-PH||"},
- {"TARGET_COPY_OUT_PRODUCT_SERVICES", "||PRODUCT-PATH-PH||"},
- {"TARGET_COPY_OUT_SYSTEM_EXT", "||SYSTEM_EXT-PATH-PH||"},
- {"TARGET_COPY_OUT_ODM", "||ODM-PATH-PH||"},
- {"TARGET_COPY_OUT_VENDOR_DLKM", "||VENDOR_DLKM-PATH-PH||"},
- {"TARGET_COPY_OUT_ODM_DLKM", "||ODM_DLKM-PATH-PH||"},
// TODO(asmundak): to process internal config files, we need the following variables:
// BOARD_CONFIG_VENDOR_PATH
// TARGET_VENDOR
diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go
index a14c7a4..46212ee 100644
--- a/mk2rbc/mk2rbc_test.go
+++ b/mk2rbc/mk2rbc_test.go
@@ -259,7 +259,7 @@
ifdef PRODUCT_NAME
# Comment
else
- TARGET_COPY_OUT_VENDOR := foo
+ TARGET_COPY_OUT_RECOVERY := foo
endif
`,
expected: `load("//build/make/core:product_config.rbc", "rblf")
@@ -270,7 +270,7 @@
# Comment
pass
else:
- # MK2RBC TRANSLATION ERROR: cannot set predefined variable TARGET_COPY_OUT_VENDOR to "foo", its value should be "||VENDOR-PATH-PH||"
+ # MK2RBC TRANSLATION ERROR: cannot set predefined variable TARGET_COPY_OUT_RECOVERY to "foo", its value should be "recovery"
pass
rblf.warning("product.mk", "partially successful conversion")
`,
@@ -669,6 +669,7 @@
$(call add_soong_config_namespace,snsconfig)
$(call add_soong_config_var_value,snsconfig,imagetype,odm_image)
PRODUCT_COPY_FILES := $(call copy-files,$(wildcard foo*.mk),etc)
+PRODUCT_COPY_FILES := $(call product-copy-files-by-pattern,from/%,to/%,a b c)
`,
expected: `load("//build/make/core:product_config.rbc", "rblf")
@@ -689,6 +690,7 @@
rblf.add_soong_config_namespace(g, "snsconfig")
rblf.add_soong_config_var_value(g, "snsconfig", "imagetype", "odm_image")
cfg["PRODUCT_COPY_FILES"] = rblf.copy_files(rblf.expand_wildcard("foo*.mk"), "etc")
+ cfg["PRODUCT_COPY_FILES"] = rblf.product_copy_files_by_pattern("from/%", "to/%", "a b c")
`,
},
{
diff --git a/python/binary.go b/python/binary.go
index e955492..b106536 100644
--- a/python/binary.go
+++ b/python/binary.go
@@ -41,24 +41,6 @@
Python_version string
}
-type bazelPythonBinary struct {
- android.BazelTargetModuleBase
- bazelPythonBinaryAttributes
-}
-
-func BazelPythonBinaryFactory() android.Module {
- module := &bazelPythonBinary{}
- module.AddProperties(&module.bazelPythonBinaryAttributes)
- android.InitBazelTargetModule(module)
- return module
-}
-
-func (m *bazelPythonBinary) Name() string {
- return m.BaseModuleName()
-}
-
-func (m *bazelPythonBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
-
func PythonBinaryBp2Build(ctx android.TopDownMutatorContext) {
m, ok := ctx.Module().(*Module)
if !ok || !m.ConvertWithBp2build(ctx) {
@@ -112,7 +94,7 @@
Rule_class: "py_binary",
}
- ctx.CreateBazelTargetModule(BazelPythonBinaryFactory, m.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(m.Name(), props, attrs)
}
type BinaryProperties struct {
diff --git a/python/python.go b/python/python.go
index 0f5b788..83844e6 100644
--- a/python/python.go
+++ b/python/python.go
@@ -675,7 +675,7 @@
if !isPythonLibModule(child) {
ctx.PropertyErrorf("libs",
"the dependency %q of module %q is not Python library!",
- ctx.ModuleName(), ctx.OtherModuleName(child))
+ ctx.OtherModuleName(child), ctx.ModuleName())
}
// collect source and data paths, checking that there are no duplicate output file conflicts
if dep, ok := child.(pythonDependency); ok {
diff --git a/rust/compiler.go b/rust/compiler.go
index 6b3ccfc..7bd9af4 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -65,7 +65,11 @@
)
type BaseCompilerProperties struct {
- // path to the source file that is the main entry point of the program (e.g. main.rs or lib.rs)
+ // path to the source file that is the main entry point of the program (e.g. main.rs or lib.rs).
+ // Only a single source file can be defined. Modules which generate source can be included by prefixing
+ // the module name with ":", for example ":libfoo_bindgen"
+ //
+ // If no source file is defined, a single generated source module can be defined to be used as the main source.
Srcs []string `android:"path,arch_variant"`
// name of the lint set that should be used to validate this module.
@@ -362,7 +366,9 @@
} else {
deps.SharedLibs = append(deps.SharedLibs, bionicLibs...)
}
-
+ if ctx.RustModule().StaticExecutable() {
+ deps.StaticLibs = append(deps.StaticLibs, "libunwind")
+ }
if libRuntimeBuiltins := config.BuiltinsRuntimeLibrary(ctx.toolchain()); libRuntimeBuiltins != "" {
deps.StaticLibs = append(deps.StaticLibs, libRuntimeBuiltins)
}
@@ -391,8 +397,15 @@
}
if compiler.location == InstallInData && ctx.RustModule().UseVndk() {
- dir = filepath.Join(dir, "vendor")
+ if ctx.RustModule().InProduct() {
+ dir = filepath.Join(dir, "product")
+ } else if ctx.RustModule().InVendor() {
+ dir = filepath.Join(dir, "vendor")
+ } else {
+ ctx.ModuleErrorf("Unknown data+VNDK installation kind")
+ }
}
+
return android.PathForModuleInstall(ctx, dir, compiler.subDir,
compiler.relativeInstallPath(), compiler.relative)
}
@@ -436,12 +449,18 @@
srcIndex = i
}
}
- if numSrcs != 1 {
+ if numSrcs > 1 {
ctx.PropertyErrorf("srcs", incorrectSourcesError)
}
+
+ // If a main source file is not provided we expect only a single SourceProvider module to be defined
+ // within srcs, with the expectation that the first source it provides is the entry point.
if srcIndex != 0 {
ctx.PropertyErrorf("srcs", "main source file must be the first in srcs")
+ } else if numSrcs > 1 {
+ ctx.PropertyErrorf("srcs", "only a single generated source module can be defined without a main source file.")
}
+
paths := android.PathsForModuleSrc(ctx, srcs)
return paths[srcIndex], paths[1:]
}
diff --git a/rust/doc.go b/rust/doc.go
index e7f1371..fe3581b 100644
--- a/rust/doc.go
+++ b/rust/doc.go
@@ -29,6 +29,14 @@
type rustdocSingleton struct{}
func (n *rustdocSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ docDir := android.PathForOutput(ctx, "rustdoc")
+ docZip := android.PathForOutput(ctx, "rustdoc.zip")
+ rule := android.NewRuleBuilder(pctx, ctx)
+ zipCmd := rule.Command().BuiltTool("soong_zip").
+ FlagWithOutput("-o ", docZip).
+ FlagWithArg("-C ", docDir.String()).
+ FlagWithArg("-D ", docDir.String())
+
ctx.VisitAllModules(func(module android.Module) {
if !module.Enabled() {
return
@@ -36,8 +44,10 @@
if m, ok := module.(*Module); ok {
if m.docTimestampFile.Valid() {
- ctx.Phony("rustdoc", m.docTimestampFile.Path())
+ zipCmd.Implicit(m.docTimestampFile.Path())
}
}
})
+ rule.Build("rustdoc-zip", "Zipping all built Rust documentation...")
+ ctx.Phony("rustdoc", docZip)
}
diff --git a/rust/image.go b/rust/image.go
index 3b54f12..5d57f15 100644
--- a/rust/image.go
+++ b/rust/image.go
@@ -34,11 +34,11 @@
}
func (mod *Module) ProductAvailable() bool {
- return false
+ return Bool(mod.VendorProperties.Product_available)
}
func (mod *Module) RamdiskAvailable() bool {
- return false
+ return Bool(mod.Properties.Ramdisk_available)
}
func (mod *Module) VendorRamdiskAvailable() bool {
@@ -50,7 +50,7 @@
}
func (mod *Module) RecoveryAvailable() bool {
- return false
+ return Bool(mod.Properties.Recovery_available)
}
func (mod *Module) ExtraVariants() []string {
@@ -62,9 +62,7 @@
}
func (mod *Module) SetRamdiskVariantNeeded(b bool) {
- if b {
- panic("Setting ramdisk variant needed for Rust module is unsupported: " + mod.BaseModuleName())
- }
+ mod.Properties.RamdiskVariantNeeded = b
}
func (mod *Module) SetVendorRamdiskVariantNeeded(b bool) {
@@ -72,9 +70,7 @@
}
func (mod *Module) SetRecoveryVariantNeeded(b bool) {
- if b {
- panic("Setting recovery variant needed for Rust module is unsupported: " + mod.BaseModuleName())
- }
+ mod.Properties.RecoveryVariantNeeded = b
}
func (mod *Module) SetCoreVariantNeeded(b bool) {
@@ -99,7 +95,7 @@
}
func (mod *Module) RamdiskVariantNeeded(android.BaseModuleContext) bool {
- return mod.InRamdisk()
+ return mod.Properties.RamdiskVariantNeeded
}
func (mod *Module) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
@@ -107,7 +103,7 @@
}
func (mod *Module) RecoveryVariantNeeded(android.BaseModuleContext) bool {
- return mod.InRecovery()
+ return mod.Properties.RecoveryVariantNeeded
}
func (mod *Module) ExtraImageVariations(android.BaseModuleContext) []string {
@@ -140,12 +136,17 @@
}
func (ctx *moduleContext) ProductSpecific() bool {
- return false
+ return ctx.ModuleContext.ProductSpecific() || ctx.RustModule().productSpecificModuleContext()
+}
+
+func (c *Module) productSpecificModuleContext() bool {
+ // Additionally check if this module is inProduct() that means it is a "product" variant of a
+ // module. As well as product specific modules, product variants must be installed to /product.
+ return c.InProduct()
}
func (mod *Module) InRecovery() bool {
- // TODO(b/165791368)
- return false
+ return mod.ModuleBase.InRecovery() || mod.ModuleBase.InstallInRecovery()
}
func (mod *Module) InVendorRamdisk() bool {
@@ -166,6 +167,11 @@
return false
}
+func (mod *Module) OnlyInProduct() bool {
+ //TODO(b/165791368)
+ return false
+}
+
// Returns true when this module is configured to have core and vendor variants.
func (mod *Module) HasVendorVariant() bool {
return Bool(mod.VendorProperties.Vendor_available) || Bool(mod.VendorProperties.Odm_available)
@@ -181,7 +187,7 @@
}
func (mod *Module) InProduct() bool {
- return false
+ return mod.Properties.ImageVariationPrefix == cc.ProductVariationPrefix
}
// Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor
@@ -193,6 +199,8 @@
m := module.(*Module)
if variant == android.VendorRamdiskVariation {
m.MakeAsPlatform()
+ } else if variant == android.RecoveryVariation {
+ m.MakeAsPlatform()
} else if strings.HasPrefix(variant, cc.VendorVariationPrefix) {
m.Properties.ImageVariationPrefix = cc.VendorVariationPrefix
m.Properties.VndkVersion = strings.TrimPrefix(variant, cc.VendorVariationPrefix)
@@ -204,6 +212,9 @@
m.Properties.HideFromMake = true
m.HideFromMake()
}
+ } else if strings.HasPrefix(variant, cc.ProductVariationPrefix) {
+ m.Properties.ImageVariationPrefix = cc.ProductVariationPrefix
+ m.Properties.VndkVersion = strings.TrimPrefix(variant, cc.ProductVariationPrefix)
}
}
@@ -211,10 +222,7 @@
// Rust does not support installing to the product image yet.
vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
- if Bool(mod.VendorProperties.Product_available) {
- mctx.PropertyErrorf("product_available",
- "Rust modules do not yet support being available to the product image")
- } else if mctx.ProductSpecific() {
+ if mctx.ProductSpecific() {
mctx.PropertyErrorf("product_specific",
"Rust modules do not yet support installing to the product image.")
} else if Bool(mod.VendorProperties.Double_loadable) {
diff --git a/rust/rust.go b/rust/rust.go
index 4ceeef1..0cd299d 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -84,6 +84,8 @@
// Set by imageMutator
CoreVariantNeeded bool `blueprint:"mutated"`
VendorRamdiskVariantNeeded bool `blueprint:"mutated"`
+ RamdiskVariantNeeded bool `blueprint:"mutated"`
+ RecoveryVariantNeeded bool `blueprint:"mutated"`
ExtraVariants []string `blueprint:"mutated"`
// Allows this module to use non-APEX version of libraries. Useful
@@ -94,11 +96,18 @@
SnapshotSharedLibs []string `blueprint:"mutated"`
SnapshotStaticLibs []string `blueprint:"mutated"`
+ // Make this module available when building for ramdisk.
+ // On device without a dedicated recovery partition, the module is only
+ // available after switching root into
+ // /first_stage_ramdisk. To expose the module before switching root, install
+ // the recovery variant instead.
+ Ramdisk_available *bool
+
// Make this module available when building for vendor ramdisk.
// On device without a dedicated recovery partition, the module is only
// available after switching root into
// /first_stage_ramdisk. To expose the module before switching root, install
- // the recovery variant instead (TODO(b/165791368) recovery not yet supported)
+ // the recovery variant instead
Vendor_ramdisk_available *bool
// Normally Soong uses the directory structure to decide which modules
@@ -115,6 +124,9 @@
// framework module from the recovery snapshot.
Exclude_from_recovery_snapshot *bool
+ // Make this module available when building for recovery
+ Recovery_available *bool
+
// Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
Min_sdk_version *string
@@ -762,6 +774,10 @@
}
func (mod *Module) nativeCoverage() bool {
+ // Bug: http://b/137883967 - native-bridge modules do not currently work with coverage
+ if mod.Target().NativeBridge == android.NativeBridgeEnabled {
+ return false
+ }
return mod.compiler != nil && mod.compiler.nativeCoverage()
}
@@ -804,9 +820,21 @@
// Differentiate static libraries that are vendor available
if mod.UseVndk() {
- mod.Properties.SubName += cc.VendorSuffix
+ if mod.InProduct() && !mod.OnlyInProduct() {
+ mod.Properties.SubName += cc.ProductSuffix
+ } else {
+ mod.Properties.SubName += cc.VendorSuffix
+ }
+ } else if mod.InRamdisk() && !mod.OnlyInRamdisk() {
+ mod.Properties.SubName += cc.RamdiskSuffix
} else if mod.InVendorRamdisk() && !mod.OnlyInVendorRamdisk() {
mod.Properties.SubName += cc.VendorRamdiskSuffix
+ } else if mod.InRecovery() && !mod.OnlyInRecovery() {
+ mod.Properties.SubName += cc.RecoverySuffix
+ }
+
+ if mod.Target().NativeBridge == android.NativeBridgeEnabled {
+ mod.Properties.SubName += cc.NativeBridgeSuffix
}
if !toolchain.Supported() {
@@ -1205,6 +1233,18 @@
return mod.compiler.inData()
}
+func (mod *Module) InstallInRamdisk() bool {
+ return mod.InRamdisk()
+}
+
+func (mod *Module) InstallInVendorRamdisk() bool {
+ return mod.InVendorRamdisk()
+}
+
+func (mod *Module) InstallInRecovery() bool {
+ return mod.InRecovery()
+}
+
func linkPathFromFilePath(filepath android.Path) string {
return strings.Split(filepath.String(), filepath.Base())[0]
}
diff --git a/scripts/build-rustdocs.sh b/scripts/build-rustdocs.sh
index ad8ba16..fda9688 100755
--- a/scripts/build-rustdocs.sh
+++ b/scripts/build-rustdocs.sh
@@ -27,5 +27,5 @@
if [ -n "${DIST_DIR}" ]; then
mkdir -p ${DIST_DIR}
- cp -r ${OUT_DIR}/soong/rustdoc $DIST_DIR/rustdoc
+ cp ${OUT_DIR}/soong/rustdoc.zip $DIST_DIR
fi
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 1647428..c6e98c7 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -527,18 +527,6 @@
// visibility
}
-type bazelShBinary struct {
- android.BazelTargetModuleBase
- bazelShBinaryAttributes
-}
-
-func BazelShBinaryFactory() android.Module {
- module := &bazelShBinary{}
- module.AddProperties(&module.bazelShBinaryAttributes)
- android.InitBazelTargetModule(module)
- return module
-}
-
func ShBinaryBp2Build(ctx android.TopDownMutatorContext) {
m, ok := ctx.Module().(*ShBinary)
if !ok || !m.ConvertWithBp2build(ctx) {
@@ -556,13 +544,7 @@
Rule_class: "sh_binary",
}
- ctx.CreateBazelTargetModule(BazelShBinaryFactory, m.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(m.Name(), props, attrs)
}
-func (m *bazelShBinary) Name() string {
- return m.BaseModuleName()
-}
-
-func (m *bazelShBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
-
var Bool = proptools.Bool
diff --git a/tests/bootstrap_test.sh b/tests/bootstrap_test.sh
index 1258684..76b2ee9 100755
--- a/tests/bootstrap_test.sh
+++ b/tests/bootstrap_test.sh
@@ -144,7 +144,7 @@
run_soong
local ninja_mtime1=$(stat -c "%y" out/soong/build.ninja)
- local glob_deps_file=out/soong/.primary/globs/0.d
+ local glob_deps_file=out/soong/.bootstrap/globs/0.d
if [ -e "$glob_deps_file" ]; then
fail "Glob deps file unexpectedly written on first build"
@@ -477,7 +477,8 @@
run_soong
local mtime1=$(stat -c "%y" out/soong/build.ninja)
- prebuilts/build-tools/linux-x86/bin/ninja -f out/soong/build.ninja soong_docs
+ prebuilts/build-tools/linux-x86/bin/ninja -f out/combined.ninja soong_docs
+
run_soong
local mtime2=$(stat -c "%y" out/soong/build.ninja)
@@ -526,18 +527,14 @@
[[ -e out/soong/workspace ]] || fail "Bazel workspace not created"
}
-function test_bp2build_generates_fake_ninja_file {
+function test_bp2build_generates_marker_file {
setup
create_mock_bazel
run_bp2build
- if [[ ! -f "./out/soong/build.ninja" ]]; then
- fail "./out/soong/build.ninja was not generated"
- fi
-
- if ! grep "build nothing: phony" "./out/soong/build.ninja"; then
- fail "missing phony nothing target in out/soong/build.ninja"
+ if [[ ! -f "./out/soong/.bootstrap/bp2build_workspace_marker" ]]; then
+ fail "Marker file was not generated"
fi
}
@@ -577,10 +574,10 @@
setup
GENERATE_BAZEL_FILES=1 run_soong
- local mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local mtime1=$(stat -c "%y" out/soong/.bootstrap/bp2build_workspace_marker)
GENERATE_BAZEL_FILES=1 run_soong
- local mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local mtime2=$(stat -c "%y" out/soong/.bootstrap/bp2build_workspace_marker)
if [[ "$mtime1" != "$mtime2" ]]; then
fail "Output Ninja file changed on null build"
@@ -712,6 +709,41 @@
grep -q "b/${GENERATED_BUILD_FILE_NAME}' exist" "$MOCK_TOP/errors" || fail "Error for b/${GENERATED_BUILD_FILE_NAME} not found"
}
+function test_bp2build_back_and_forth_null_build {
+ setup
+
+ run_soong
+ local output_mtime1=$(stat -c "%y" out/soong/build.ninja)
+
+ GENERATE_BAZEL_FILES=1 run_soong
+ local output_mtime2=$(stat -c "%y" out/soong/build.ninja)
+ if [[ "$output_mtime1" != "$output_mtime2" ]]; then
+ fail "Output Ninja file changed when switching to bp2build"
+ fi
+
+ local marker_mtime1=$(stat -c "%y" out/soong/.bootstrap/bp2build_workspace_marker)
+
+ run_soong
+ local output_mtime3=$(stat -c "%y" out/soong/build.ninja)
+ local marker_mtime2=$(stat -c "%y" out/soong/.bootstrap/bp2build_workspace_marker)
+ if [[ "$output_mtime1" != "$output_mtime3" ]]; then
+ fail "Output Ninja file changed when switching to regular build from bp2build"
+ fi
+ if [[ "$marker_mtime1" != "$marker_mtime2" ]]; then
+ fail "bp2build marker file changed when switching to regular build from bp2build"
+ fi
+
+ GENERATE_BAZEL_FILES=1 run_soong
+ local output_mtime4=$(stat -c "%y" out/soong/build.ninja)
+ local marker_mtime3=$(stat -c "%y" out/soong/.bootstrap/bp2build_workspace_marker)
+ if [[ "$output_mtime1" != "$output_mtime4" ]]; then
+ fail "Output Ninja file changed when switching back to bp2build"
+ fi
+ if [[ "$marker_mtime1" != "$marker_mtime3" ]]; then
+ fail "bp2build marker file changed when switching back to bp2build"
+ fi
+}
+
test_smoke
test_null_build
test_null_build_after_docs
@@ -727,8 +759,9 @@
test_dump_json_module_graph
test_write_to_source_tree
test_bp2build_smoke
-test_bp2build_generates_fake_ninja_file
+test_bp2build_generates_marker_file
test_bp2build_null_build
+test_bp2build_back_and_forth_null_build
test_bp2build_add_android_bp
test_bp2build_add_to_glob
test_bp2build_bazel_workspace_structure
diff --git a/tests/bp2build_bazel_test.sh b/tests/bp2build_bazel_test.sh
index b5c6863..9bd85a4 100755
--- a/tests/bp2build_bazel_test.sh
+++ b/tests/bp2build_bazel_test.sh
@@ -48,60 +48,6 @@
test_bp2build_null_build_with_globs
-function test_soong_after_bp2build_regenerates_build_globs_ninja() {
- setup
-
- mkdir -p foo/bar
- cat > foo/bar/Android.bp <<'EOF'
-filegroup {
- name: "bp2build-files",
- srcs: ["bp2build.*"],
- bazel_module: { bp2build_available: true },
-}
-
-filegroup {
- name: "soong-files",
- srcs: ["soong.*"],
-}
-EOF
- touch foo/bar/bp2build.txt foo/bar/soong.txt
-
- build_globs_file="out/soong/.bootstrap/build-globs.ninja"
-
- # Test: the build-globs file for bp2build should only contain the bp2build-files
- # glob, whereas the build-globs file for soong should contain both bp2build-files
- # and soong-files globs.
-
- run_bp2build
- local output_mtime1=$(stat -c "%y" "${build_globs_file}")
-
- if ! grep "\"foo/bar/bp2build.*\"" "${build_globs_file}"; then
- fail "bp2build filegroup globs not found in bp2build's globs file"
- fi
-
- if grep "\"foo/bar/soong.*\"" "${build_globs_file}"; then
- fail "soong filegroup globs unexpectedly found in bp2build's globs file"
- fi
-
- run_soong
- local output_mtime2=$(stat -c "%y" "${build_globs_file}")
-
- if [[ "$output_mtime1" == "$output_mtime2" ]]; then
- fail "Output build-globs.ninja file did not change"
- fi
-
- if ! grep "\"foo/bar/bp2build.*\"" "${build_globs_file}"; then
- fail "bp2build filegroup globs not found in bp2build's globs file"
- fi
-
- if ! grep "\"foo/bar/soong.*\"" "${build_globs_file}"; then
- fail "soong filegroup globs not found in bp2build's globs file"
- fi
-
-}
-
-test_soong_after_bp2build_regenerates_build_globs_ninja
-
function test_bp2build_generates_all_buildfiles {
setup
create_mock_bazel
diff --git a/ui/build/config.go b/ui/build/config.go
index 9768a44..956406d 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -739,6 +739,14 @@
return filepath.Join(c.OutDir(), "soong")
}
+func (c *configImpl) MainNinjaFile() string {
+ return shared.JoinPath(c.SoongOutDir(), "build.ninja")
+}
+
+func (c *configImpl) Bp2BuildMarkerFile() string {
+ return shared.JoinPath(c.SoongOutDir(), ".bootstrap/bp2build_workspace_marker")
+}
+
func (c *configImpl) TempDir() string {
return shared.TempDirForOutDir(c.SoongOutDir())
}
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 190c955..8ef8c74 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -71,16 +71,11 @@
// A tiny struct used to tell Blueprint that it's in bootstrap mode. It would
// probably be nicer to use a flag in bootstrap.Args instead.
type BlueprintConfig struct {
- srcDir string
buildDir string
ninjaBuildDir string
debugCompilation bool
}
-func (c BlueprintConfig) SrcDir() string {
- return "."
-}
-
func (c BlueprintConfig) BuildDir() string {
return c.buildDir
}
@@ -114,17 +109,20 @@
}
}
-func bootstrapBlueprint(ctx Context, config Config, integratedBp2Build bool) {
+func bootstrapBlueprint(ctx Context, config Config) {
ctx.BeginTrace(metrics.RunSoong, "blueprint bootstrap")
defer ctx.EndTrace()
var args bootstrap.Args
- mainNinjaFile := shared.JoinPath(config.SoongOutDir(), "build.ninja")
bootstrapGlobFile := shared.JoinPath(config.SoongOutDir(), ".bootstrap/build-globs.ninja")
- // .bootstrap/build.ninja "includes" .bootstrap/build-globs.ninja for incremental builds
- // generate an empty glob before running any rule in .bootstrap/build.ninja
+ bp2buildGlobFile := shared.JoinPath(config.SoongOutDir(), ".bootstrap/build-globs.bp2build.ninja")
+
+ // The glob .ninja files are subninja'd. However, they are generated during
+ // the build itself so we write an empty file so that the subninja doesn't
+ // fail on clean builds
writeEmptyGlobFile(ctx, bootstrapGlobFile)
+ writeEmptyGlobFile(ctx, bp2buildGlobFile)
bootstrapDepFile := shared.JoinPath(config.SoongOutDir(), ".bootstrap/build.ninja.d")
args.RunGoTests = !config.skipSoongTests
@@ -137,7 +135,7 @@
// The primary builder (aka soong_build) will use bootstrapGlobFile as the globFile to generate build.ninja(.d)
// Building soong_build does not require a glob file
// Using "" instead of "<soong_build_glob>.ninja" will ensure that an unused glob file is not written to out/soong/.bootstrap during StagePrimary
- args.GlobFile = ""
+ args.Subninjas = []string{bootstrapGlobFile, bp2buildGlobFile}
args.GeneratingPrimaryBuilder = true
args.EmptyNinjaFile = config.EmptyNinjaFile()
@@ -146,48 +144,51 @@
args.DelvePath = shared.ResolveDelveBinary()
}
- commonArgs := bootstrap.PrimaryBuilderExtraFlags(args, bootstrapGlobFile, mainNinjaFile)
- bp2BuildMarkerFile := shared.JoinPath(config.SoongOutDir(), ".bootstrap/bp2build_workspace_marker")
+ commonArgs := bootstrap.PrimaryBuilderExtraFlags(args, config.MainNinjaFile())
mainSoongBuildInputs := []string{"Android.bp"}
- if integratedBp2Build {
- mainSoongBuildInputs = append(mainSoongBuildInputs, bp2BuildMarkerFile)
+ if config.bazelBuildMode() == mixedBuild {
+ mainSoongBuildInputs = append(mainSoongBuildInputs, config.Bp2BuildMarkerFile())
}
- soongBuildArgs := make([]string, 0)
+ soongBuildArgs := []string{
+ "--globListDir", "globs",
+ "--globFile", bootstrapGlobFile,
+ }
+
soongBuildArgs = append(soongBuildArgs, commonArgs...)
soongBuildArgs = append(soongBuildArgs, environmentArgs(config, "")...)
soongBuildArgs = append(soongBuildArgs, "Android.bp")
mainSoongBuildInvocation := bootstrap.PrimaryBuilderInvocation{
Inputs: mainSoongBuildInputs,
- Outputs: []string{mainNinjaFile},
+ Outputs: []string{config.MainNinjaFile()},
Args: soongBuildArgs,
}
- if integratedBp2Build {
- bp2buildArgs := []string{"--bp2build_marker", bp2BuildMarkerFile}
- bp2buildArgs = append(bp2buildArgs, commonArgs...)
- bp2buildArgs = append(bp2buildArgs, environmentArgs(config, ".bp2build")...)
- bp2buildArgs = append(bp2buildArgs, "Android.bp")
+ bp2buildArgs := []string{
+ "--bp2build_marker", config.Bp2BuildMarkerFile(),
+ "--globListDir", "globs.bp2build",
+ "--globFile", bp2buildGlobFile,
+ }
- bp2buildInvocation := bootstrap.PrimaryBuilderInvocation{
- Inputs: []string{"Android.bp"},
- Outputs: []string{bp2BuildMarkerFile},
- Args: bp2buildArgs,
- }
- args.PrimaryBuilderInvocations = []bootstrap.PrimaryBuilderInvocation{bp2buildInvocation}
- if config.bazelBuildMode() == mixedBuild {
- args.PrimaryBuilderInvocations = append(args.PrimaryBuilderInvocations, mainSoongBuildInvocation)
- }
- } else {
- args.PrimaryBuilderInvocations = []bootstrap.PrimaryBuilderInvocation{mainSoongBuildInvocation}
+ bp2buildArgs = append(bp2buildArgs, commonArgs...)
+ bp2buildArgs = append(bp2buildArgs, environmentArgs(config, ".bp2build")...)
+ bp2buildArgs = append(bp2buildArgs, "Android.bp")
+
+ bp2buildInvocation := bootstrap.PrimaryBuilderInvocation{
+ Inputs: []string{"Android.bp"},
+ Outputs: []string{config.Bp2BuildMarkerFile()},
+ Args: bp2buildArgs,
+ }
+ args.PrimaryBuilderInvocations = []bootstrap.PrimaryBuilderInvocation{
+ bp2buildInvocation,
+ mainSoongBuildInvocation,
}
blueprintCtx := blueprint.NewContext()
blueprintCtx.SetIgnoreUnknownModuleTypes(true)
blueprintConfig := BlueprintConfig{
- srcDir: os.Getenv("TOP"),
buildDir: config.SoongOutDir(),
ninjaBuildDir: config.OutDir(),
debugCompilation: os.Getenv("SOONG_DELVE") != "",
@@ -220,18 +221,16 @@
// unused variables were changed?
envFile := filepath.Join(config.SoongOutDir(), availableEnvFile)
- for _, n := range []string{".bootstrap", ".minibootstrap"} {
- dir := filepath.Join(config.SoongOutDir(), n)
- if err := os.MkdirAll(dir, 0755); err != nil {
- ctx.Fatalf("Cannot mkdir " + dir)
- }
+ dir := filepath.Join(config.SoongOutDir(), ".bootstrap")
+ if err := os.MkdirAll(dir, 0755); err != nil {
+ ctx.Fatalf("Cannot mkdir " + dir)
}
buildMode := config.bazelBuildMode()
integratedBp2Build := (buildMode == mixedBuild) || (buildMode == generateBuildFiles)
// This is done unconditionally, but does not take a measurable amount of time
- bootstrapBlueprint(ctx, config, integratedBp2Build)
+ bootstrapBlueprint(ctx, config)
soongBuildEnv := config.Environment().Copy()
soongBuildEnv.Set("TOP", os.Getenv("TOP"))
@@ -265,10 +264,10 @@
}
}()
- runMicrofactory(ctx, config, ".minibootstrap/bpglob", "github.com/google/blueprint/bootstrap/bpglob",
+ runMicrofactory(ctx, config, ".bootstrap/bpglob", "github.com/google/blueprint/bootstrap/bpglob",
map[string]string{"github.com/google/blueprint": "build/blueprint"})
- ninja := func(name, file string) {
+ ninja := func(name, ninjaFile string, targets ...string) {
ctx.BeginTrace(metrics.RunSoong, name)
defer ctx.EndTrace()
@@ -276,8 +275,7 @@
nr := status.NewNinjaReader(ctx, ctx.Status.StartTool(), fifo)
defer nr.Close()
- cmd := Command(ctx, config, "soong "+name,
- config.PrebuiltBuildTool("ninja"),
+ ninjaArgs := []string{
"-d", "keepdepfile",
"-d", "stats",
"-o", "usesphonyoutputs=yes",
@@ -287,7 +285,12 @@
"-w", "missingoutfile=err",
"-j", strconv.Itoa(config.Parallel()),
"--frontend_file", fifo,
- "-f", filepath.Join(config.SoongOutDir(), file))
+ "-f", filepath.Join(config.SoongOutDir(), ninjaFile),
+ }
+
+ ninjaArgs = append(ninjaArgs, targets...)
+ cmd := Command(ctx, config, "soong "+name,
+ config.PrebuiltBuildTool("ninja"), ninjaArgs...)
var ninjaEnv Environment
@@ -299,8 +302,17 @@
cmd.Sandbox = soongSandbox
cmd.RunAndStreamOrFatal()
}
- // This build generates <builddir>/build.ninja, which is used later by build/soong/ui/build/build.go#Build().
- ninja("bootstrap", ".bootstrap/build.ninja")
+
+ var target string
+
+ if config.bazelBuildMode() == generateBuildFiles {
+ target = config.Bp2BuildMarkerFile()
+ } else {
+ // This build generates <builddir>/build.ninja, which is used later by build/soong/ui/build/build.go#Build().
+ target = config.MainNinjaFile()
+ }
+
+ ninja("bootstrap", ".bootstrap/build.ninja", target)
var soongBuildMetrics *soong_metrics_proto.SoongBuildMetrics
if shouldCollectBuildSoongMetrics(config) {
diff --git a/ui/build/test_build.go b/ui/build/test_build.go
index a910c06..57ceaba 100644
--- a/ui/build/test_build.go
+++ b/ui/build/test_build.go
@@ -65,7 +65,6 @@
outDir := config.OutDir()
bootstrapDir := filepath.Join(outDir, "soong", ".bootstrap")
- miniBootstrapDir := filepath.Join(outDir, "soong", ".minibootstrap")
modulePathsDir := filepath.Join(outDir, ".module_paths")
variablesFilePath := filepath.Join(outDir, "soong", "soong.variables")
@@ -89,7 +88,6 @@
continue
}
if strings.HasPrefix(line, bootstrapDir) ||
- strings.HasPrefix(line, miniBootstrapDir) ||
strings.HasPrefix(line, modulePathsDir) ||
line == variablesFilePath ||
line == dexpreoptConfigFilePath ||