Merge "Add a nice install paths for module SDKs and exports."
diff --git a/android/apex.go b/android/apex.go
index 43a42df..026d685 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -116,6 +116,10 @@
return m
}
+func (m *ApexModuleBase) ApexAvailable() []string {
+ return m.ApexProperties.Apex_available
+}
+
func (m *ApexModuleBase) BuildForApexes(apexes []ApexInfo) {
m.apexVariationsLock.Lock()
defer m.apexVariationsLock.Unlock()
diff --git a/android/notices.go b/android/notices.go
index bf273b5..07cf3e4 100644
--- a/android/notices.go
+++ b/android/notices.go
@@ -22,7 +22,7 @@
func init() {
pctx.SourcePathVariable("merge_notices", "build/soong/scripts/mergenotice.py")
- pctx.SourcePathVariable("generate_notice", "build/make/tools/generate-notice-files.py")
+ pctx.SourcePathVariable("generate_notice", "build/soong/scripts/generate-notice-files.py")
pctx.HostBinToolVariable("minigzip", "minigzip")
}
diff --git a/cc/cc.go b/cc/cc.go
index cc54f7a..e5e724e 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1465,6 +1465,13 @@
c.Properties.HideFromMake = false // unhide
// Note: this is still non-installable
}
+
+ // glob exported headers for snapshot, if BOARD_VNDK_VERSION is current.
+ if i, ok := c.linker.(snapshotLibraryInterface); ok && ctx.DeviceConfig().VndkVersion() == "current" {
+ if isSnapshotAware(ctx, c) {
+ i.collectHeadersForSnapshot(ctx)
+ }
+ }
}
if c.installable() {
diff --git a/cc/config/tidy.go b/cc/config/tidy.go
index dd52a0e..4ac9e58 100644
--- a/cc/config/tidy.go
+++ b/cc/config/tidy.go
@@ -30,10 +30,12 @@
}
return strings.Join([]string{
"-*",
+ "bugprone*",
"clang-diagnostic-unused-command-line-argument",
"google*",
"misc-macro-parentheses",
"performance*",
+ "-bugprone-narrowing-conversions",
"-google-readability*",
"-google-runtime-references",
}, ",")
diff --git a/cc/library.go b/cc/library.go
index 6ffb7fc..0159cee 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -379,6 +379,68 @@
*baseCompiler
*baseLinker
*baseInstaller
+
+ collectedSnapshotHeaders android.Paths
+}
+
+// collectHeadersForSnapshot collects all exported headers from library.
+// It globs header files in the source tree for exported include directories,
+// and tracks generated header files separately.
+//
+// This is to be called from GenerateAndroidBuildActions, and then collected
+// header files can be retrieved by snapshotHeaders().
+func (l *libraryDecorator) collectHeadersForSnapshot(ctx android.ModuleContext) {
+ ret := android.Paths{}
+
+ // Headers in the source tree should be globbed. On the contrast, generated headers
+ // can't be globbed, and they should be manually collected.
+ // So, we first filter out intermediate directories (which contains generated headers)
+ // from exported directories, and then glob headers under remaining directories.
+ for _, path := range append(l.exportedDirs(), l.exportedSystemDirs()...) {
+ dir := path.String()
+ // Skip if dir is for generated headers
+ if strings.HasPrefix(dir, android.PathForOutput(ctx).String()) {
+ continue
+ }
+ exts := headerExts
+ // Glob all files under this special directory, because of C++ headers.
+ if strings.HasPrefix(dir, "external/libcxx/include") {
+ exts = []string{""}
+ }
+ for _, ext := range exts {
+ glob, err := ctx.GlobWithDeps(dir+"/**/*"+ext, nil)
+ if err != nil {
+ ctx.ModuleErrorf("glob failed: %#v", err)
+ return
+ }
+ for _, header := range glob {
+ if strings.HasSuffix(header, "/") {
+ continue
+ }
+ ret = append(ret, android.PathForSource(ctx, header))
+ }
+ }
+ }
+
+ // Collect generated headers
+ for _, header := range append(l.exportedGeneratedHeaders(), l.exportedDeps()...) {
+ // TODO(b/148123511): remove exportedDeps after cleaning up genrule
+ if strings.HasSuffix(header.Base(), "-phony") {
+ continue
+ }
+ ret = append(ret, header)
+ }
+
+ l.collectedSnapshotHeaders = ret
+}
+
+// This returns all exported header files, both generated ones and headers from source tree.
+// collectHeadersForSnapshot() must be called before calling this.
+func (l *libraryDecorator) snapshotHeaders() android.Paths {
+ if l.collectedSnapshotHeaders == nil {
+ panic("snapshotHeaders() must be called after collectHeadersForSnapshot()")
+ }
+ return l.collectedSnapshotHeaders
}
func (library *libraryDecorator) linkerProps() []interface{} {
diff --git a/cc/snapshot_utils.go b/cc/snapshot_utils.go
index 73388ce..4012def 100644
--- a/cc/snapshot_utils.go
+++ b/cc/snapshot_utils.go
@@ -14,8 +14,6 @@
package cc
import (
- "strings"
-
"android/soong/android"
)
@@ -26,6 +24,8 @@
type snapshotLibraryInterface interface {
exportedFlagsProducer
libraryInterface
+ collectHeadersForSnapshot(ctx android.ModuleContext)
+ snapshotHeaders() android.Paths
}
var _ snapshotLibraryInterface = (*prebuiltLibraryLinker)(nil)
@@ -58,49 +58,13 @@
return snapshot, found
}
-func exportedHeaders(ctx android.SingletonContext, l exportedFlagsProducer) android.Paths {
- var ret android.Paths
-
- // Headers in the source tree should be globbed. On the contrast, generated headers
- // can't be globbed, and they should be manually collected.
- // So, we first filter out intermediate directories (which contains generated headers)
- // from exported directories, and then glob headers under remaining directories.
- for _, path := range append(l.exportedDirs(), l.exportedSystemDirs()...) {
- dir := path.String()
- // Skip if dir is for generated headers
- if strings.HasPrefix(dir, android.PathForOutput(ctx).String()) {
- continue
- }
- exts := headerExts
- // Glob all files under this special directory, because of C++ headers.
- if strings.HasPrefix(dir, "external/libcxx/include") {
- exts = []string{""}
- }
- for _, ext := range exts {
- glob, err := ctx.GlobWithDeps(dir+"/**/*"+ext, nil)
- if err != nil {
- ctx.Errorf("%#v\n", err)
- return nil
- }
- for _, header := range glob {
- if strings.HasSuffix(header, "/") {
- continue
- }
- ret = append(ret, android.PathForSource(ctx, header))
- }
- }
+func isSnapshotAware(ctx android.ModuleContext, m *Module) bool {
+ if _, _, ok := isVndkSnapshotLibrary(ctx.DeviceConfig(), m); ok {
+ return ctx.Config().VndkSnapshotBuildArtifacts()
+ } else if isVendorSnapshotModule(m, ctx.ModuleDir()) {
+ return true
}
-
- // Collect generated headers
- for _, header := range append(l.exportedGeneratedHeaders(), l.exportedDeps()...) {
- // TODO(b/148123511): remove exportedDeps after cleaning up genrule
- if strings.HasSuffix(header.Base(), "-phony") {
- continue
- }
- ret = append(ret, header)
- }
-
- return ret
+ return false
}
func copyFile(ctx android.SingletonContext, path android.Path, out string) android.OutputPath {
diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go
index 20762a8..5801fc7 100644
--- a/cc/vendor_snapshot.go
+++ b/cc/vendor_snapshot.go
@@ -428,12 +428,12 @@
// AOSP. They are not guaranteed to be compatible with older vendor images. (e.g. might
// depend on newer VNDK) So they are captured as vendor snapshot To build older vendor
// image and newer system image altogether.
-func isVendorSnapshotModule(ctx android.SingletonContext, m *Module) bool {
+func isVendorSnapshotModule(m *Module, moduleDir string) bool {
if !m.Enabled() {
return false
}
// skip proprietary modules, but include all VNDK (static)
- if isVendorProprietaryPath(ctx.ModuleDir(m)) && !m.IsVndk() {
+ if isVendorProprietaryPath(moduleDir) && !m.IsVndk() {
return false
}
if m.Target().Os.Class != android.Device {
@@ -525,14 +525,6 @@
var headers android.Paths
- type vendorSnapshotLibraryInterface interface {
- exportedFlagsProducer
- libraryInterface
- }
-
- var _ vendorSnapshotLibraryInterface = (*prebuiltLibraryLinker)(nil)
- var _ vendorSnapshotLibraryInterface = (*libraryDecorator)(nil)
-
installSnapshot := func(m *Module) android.Paths {
targetArch := "arch-" + m.Target().Arch.ArchType.String()
if m.Target().Arch.ArchVariant != "" {
@@ -588,7 +580,7 @@
var propOut string
- if l, ok := m.linker.(vendorSnapshotLibraryInterface); ok {
+ if l, ok := m.linker.(snapshotLibraryInterface); ok {
// library flags
prop.ExportedFlags = l.exportedFlags()
for _, dir := range l.exportedDirs() {
@@ -652,13 +644,18 @@
ctx.VisitAllModules(func(module android.Module) {
m, ok := module.(*Module)
- if !ok || !isVendorSnapshotModule(ctx, m) {
+ if !ok {
+ return
+ }
+
+ moduleDir := ctx.ModuleDir(module)
+ if !isVendorSnapshotModule(m, moduleDir) {
return
}
snapshotOutputs = append(snapshotOutputs, installSnapshot(m)...)
- if l, ok := m.linker.(vendorSnapshotLibraryInterface); ok {
- headers = append(headers, exportedHeaders(ctx, l)...)
+ if l, ok := m.linker.(snapshotLibraryInterface); ok {
+ headers = append(headers, l.snapshotHeaders()...)
}
if len(m.NoticeFiles()) > 0 {
diff --git a/cc/vndk.go b/cc/vndk.go
index d0492fc..e02e7b5 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -496,6 +496,28 @@
vndkSnapshotZipFile android.OptionalPath
}
+func isVndkSnapshotLibrary(config android.DeviceConfig, m *Module) (i snapshotLibraryInterface, vndkType string, isVndkSnapshotLib bool) {
+ if m.Target().NativeBridge == android.NativeBridgeEnabled {
+ return nil, "", false
+ }
+ if !m.inVendor() || !m.installable() || m.isSnapshotPrebuilt() {
+ return nil, "", false
+ }
+ l, ok := m.linker.(snapshotLibraryInterface)
+ if !ok || !l.shared() {
+ return nil, "", false
+ }
+ if m.VndkVersion() == config.PlatformVndkVersion() && m.IsVndk() && !m.isVndkExt() {
+ if m.isVndkSp() {
+ return l, "vndk-sp", true
+ } else {
+ return l, "vndk-core", true
+ }
+ }
+
+ return nil, "", false
+}
+
func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
// build these files even if PlatformVndkVersion or BoardVndkVersion is not set
c.buildVndkLibrariesTxtFiles(ctx)
@@ -598,35 +620,13 @@
return ret, true
}
- isVndkSnapshotLibrary := func(m *Module) (i snapshotLibraryInterface, vndkType string, isVndkSnapshotLib bool) {
- if m.Target().NativeBridge == android.NativeBridgeEnabled {
- return nil, "", false
- }
- if !m.inVendor() || !m.installable() || m.isSnapshotPrebuilt() {
- return nil, "", false
- }
- l, ok := m.linker.(snapshotLibraryInterface)
- if !ok || !l.shared() {
- return nil, "", false
- }
- if m.VndkVersion() == ctx.DeviceConfig().PlatformVndkVersion() && m.IsVndk() && !m.isVndkExt() {
- if m.isVndkSp() {
- return l, "vndk-sp", true
- } else {
- return l, "vndk-core", true
- }
- }
-
- return nil, "", false
- }
-
ctx.VisitAllModules(func(module android.Module) {
m, ok := module.(*Module)
if !ok || !m.Enabled() {
return
}
- l, vndkType, ok := isVndkSnapshotLibrary(m)
+ l, vndkType, ok := isVndkSnapshotLibrary(ctx.DeviceConfig(), m)
if !ok {
return
}
@@ -655,7 +655,7 @@
}
if ctx.Config().VndkSnapshotBuildArtifacts() {
- headers = append(headers, exportedHeaders(ctx, l)...)
+ headers = append(headers, l.snapshotHeaders()...)
}
})
diff --git a/scripts/generate-notice-files.py b/scripts/generate-notice-files.py
new file mode 100755
index 0000000..49011b2
--- /dev/null
+++ b/scripts/generate-notice-files.py
@@ -0,0 +1,267 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2012 The Android Open Source Project
+#
+# 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.
+"""
+Usage: generate-notice-files --text-output [plain text output file] \
+ --html-output [html output file] \
+ --xml-output [xml output file] \
+ -t [file title] -s [directory of notices]
+
+Generate the Android notice files, including both text and html files.
+
+-h to display this usage message and exit.
+"""
+from collections import defaultdict
+import argparse
+import hashlib
+import itertools
+import os
+import os.path
+import re
+import sys
+
+MD5_BLOCKSIZE = 1024 * 1024
+HTML_ESCAPE_TABLE = {
+ "&": "&",
+ '"': """,
+ "'": "'",
+ ">": ">",
+ "<": "<",
+ }
+
+def hexify(s):
+ return ("%02x"*len(s)) % tuple(map(ord, s))
+
+def md5sum(filename):
+ """Calculate an MD5 of the file given by FILENAME,
+ and return hex digest as a string.
+ Output should be compatible with md5sum command"""
+
+ f = open(filename, "rb")
+ sum = hashlib.md5()
+ while 1:
+ block = f.read(MD5_BLOCKSIZE)
+ if not block:
+ break
+ sum.update(block)
+ f.close()
+ return hexify(sum.digest())
+
+
+def html_escape(text):
+ """Produce entities within text."""
+ return "".join(HTML_ESCAPE_TABLE.get(c,c) for c in text)
+
+HTML_OUTPUT_CSS="""
+<style type="text/css">
+body { padding: 0; font-family: sans-serif; }
+.same-license { background-color: #eeeeee; border-top: 20px solid white; padding: 10px; }
+.label { font-weight: bold; }
+.file-list { margin-left: 1em; color: blue; }
+</style>
+"""
+
+def combine_notice_files_html(file_hash, input_dir, output_filename):
+ """Combine notice files in FILE_HASH and output a HTML version to OUTPUT_FILENAME."""
+
+ SRC_DIR_STRIP_RE = re.compile(input_dir + "(/.*).txt")
+
+ # Set up a filename to row id table (anchors inside tables don't work in
+ # most browsers, but href's to table row ids do)
+ id_table = {}
+ id_count = 0
+ for value in file_hash:
+ for filename in value:
+ id_table[filename] = id_count
+ id_count += 1
+
+ # Open the output file, and output the header pieces
+ output_file = open(output_filename, "wb")
+
+ print >> output_file, "<html><head>"
+ print >> output_file, HTML_OUTPUT_CSS
+ print >> output_file, '</head><body topmargin="0" leftmargin="0" rightmargin="0" bottommargin="0">'
+
+ # Output our table of contents
+ print >> output_file, '<div class="toc">'
+ print >> output_file, "<ul>"
+
+ # Flatten the list of lists into a single list of filenames
+ sorted_filenames = sorted(itertools.chain.from_iterable(file_hash))
+
+ # Print out a nice table of contents
+ for filename in sorted_filenames:
+ stripped_filename = SRC_DIR_STRIP_RE.sub(r"\1", filename)
+ print >> output_file, '<li><a href="#id%d">%s</a></li>' % (id_table.get(filename), stripped_filename)
+
+ print >> output_file, "</ul>"
+ print >> output_file, "</div><!-- table of contents -->"
+ # Output the individual notice file lists
+ print >>output_file, '<table cellpadding="0" cellspacing="0" border="0">'
+ for value in file_hash:
+ print >> output_file, '<tr id="id%d"><td class="same-license">' % id_table.get(value[0])
+ print >> output_file, '<div class="label">Notices for file(s):</div>'
+ print >> output_file, '<div class="file-list">'
+ for filename in value:
+ print >> output_file, "%s <br/>" % (SRC_DIR_STRIP_RE.sub(r"\1", filename))
+ print >> output_file, "</div><!-- file-list -->"
+ print >> output_file
+ print >> output_file, '<pre class="license-text">'
+ print >> output_file, html_escape(open(value[0]).read())
+ print >> output_file, "</pre><!-- license-text -->"
+ print >> output_file, "</td></tr><!-- same-license -->"
+ print >> output_file
+ print >> output_file
+ print >> output_file
+
+ # Finish off the file output
+ print >> output_file, "</table>"
+ print >> output_file, "</body></html>"
+ output_file.close()
+
+def combine_notice_files_text(file_hash, input_dir, output_filename, file_title):
+ """Combine notice files in FILE_HASH and output a text version to OUTPUT_FILENAME."""
+
+ SRC_DIR_STRIP_RE = re.compile(input_dir + "(/.*).txt")
+ output_file = open(output_filename, "wb")
+ print >> output_file, file_title
+ for value in file_hash:
+ print >> output_file, "============================================================"
+ print >> output_file, "Notices for file(s):"
+ for filename in value:
+ print >> output_file, SRC_DIR_STRIP_RE.sub(r"\1", filename)
+ print >> output_file, "------------------------------------------------------------"
+ print >> output_file, open(value[0]).read()
+ output_file.close()
+
+def combine_notice_files_xml(files_with_same_hash, input_dir, output_filename):
+ """Combine notice files in FILE_HASH and output a XML version to OUTPUT_FILENAME."""
+
+ SRC_DIR_STRIP_RE = re.compile(input_dir + "(/.*).txt")
+
+ # Set up a filename to row id table (anchors inside tables don't work in
+ # most browsers, but href's to table row ids do)
+ id_table = {}
+ for file_key in files_with_same_hash.keys():
+ for filename in files_with_same_hash[file_key]:
+ id_table[filename] = file_key
+
+ # Open the output file, and output the header pieces
+ output_file = open(output_filename, "wb")
+
+ print >> output_file, '<?xml version="1.0" encoding="utf-8"?>'
+ print >> output_file, "<licenses>"
+
+ # Flatten the list of lists into a single list of filenames
+ sorted_filenames = sorted(id_table.keys())
+
+ # Print out a nice table of contents
+ for filename in sorted_filenames:
+ stripped_filename = SRC_DIR_STRIP_RE.sub(r"\1", filename)
+ print >> output_file, '<file-name contentId="%s">%s</file-name>' % (id_table.get(filename), stripped_filename)
+
+ print >> output_file
+ print >> output_file
+
+ processed_file_keys = []
+ # Output the individual notice file lists
+ for filename in sorted_filenames:
+ file_key = id_table.get(filename)
+ if file_key in processed_file_keys:
+ continue
+ processed_file_keys.append(file_key)
+
+ print >> output_file, '<file-content contentId="%s"><![CDATA[%s]]></file-content>' % (file_key, html_escape(open(filename).read()))
+ print >> output_file
+
+ # Finish off the file output
+ print >> output_file, "</licenses>"
+ output_file.close()
+
+def get_args():
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ '--text-output', required=True,
+ help='The text output file path.')
+ parser.add_argument(
+ '--html-output',
+ help='The html output file path.')
+ parser.add_argument(
+ '--xml-output',
+ help='The xml output file path.')
+ parser.add_argument(
+ '-t', '--title', required=True,
+ help='The file title.')
+ parser.add_argument(
+ '-s', '--source-dir', required=True,
+ help='The directory containing notices.')
+ parser.add_argument(
+ '-i', '--included-subdirs', action='append',
+ help='The sub directories which should be included.')
+ parser.add_argument(
+ '-e', '--excluded-subdirs', action='append',
+ help='The sub directories which should be excluded.')
+ return parser.parse_args()
+
+def main(argv):
+ args = get_args()
+
+ txt_output_file = args.text_output
+ html_output_file = args.html_output
+ xml_output_file = args.xml_output
+ file_title = args.title
+ included_subdirs = []
+ excluded_subdirs = []
+ if args.included_subdirs is not None:
+ included_subdirs = args.included_subdirs
+ if args.excluded_subdirs is not None:
+ excluded_subdirs = args.excluded_subdirs
+
+ # Find all the notice files and md5 them
+ input_dir = os.path.normpath(args.source_dir)
+ files_with_same_hash = defaultdict(list)
+ for root, dir, files in os.walk(input_dir):
+ for file in files:
+ matched = True
+ if len(included_subdirs) > 0:
+ matched = False
+ for subdir in included_subdirs:
+ if (root == (input_dir + '/' + subdir) or
+ root.startswith(input_dir + '/' + subdir + '/')):
+ matched = True
+ break
+ elif len(excluded_subdirs) > 0:
+ for subdir in excluded_subdirs:
+ if (root == (input_dir + '/' + subdir) or
+ root.startswith(input_dir + '/' + subdir + '/')):
+ matched = False
+ break
+ if matched and file.endswith(".txt"):
+ filename = os.path.join(root, file)
+ file_md5sum = md5sum(filename)
+ files_with_same_hash[file_md5sum].append(filename)
+
+ filesets = [sorted(files_with_same_hash[md5]) for md5 in sorted(files_with_same_hash.keys())]
+
+ combine_notice_files_text(filesets, input_dir, txt_output_file, file_title)
+
+ if html_output_file is not None:
+ combine_notice_files_html(filesets, input_dir, html_output_file)
+
+ if xml_output_file is not None:
+ combine_notice_files_xml(files_with_same_hash, input_dir, xml_output_file)
+
+if __name__ == "__main__":
+ main(sys.argv)
diff --git a/scripts/mergenotice.py b/scripts/mergenotice.py
index 407ae8c..fe99073 100755
--- a/scripts/mergenotice.py
+++ b/scripts/mergenotice.py
@@ -16,7 +16,7 @@
#
"""
Merges input notice files to the output file while ignoring duplicated files
-This script shouldn't be confused with build/make/tools/generate-notice-files.py
+This script shouldn't be confused with build/soong/scripts/generate-notice-files.py
which is responsible for creating the final notice file for all artifacts
installed. This script has rather limited scope; it is meant to create a merged
notice file for a set of modules that are packaged together, e.g. in an APEX.
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index 45b548c..a14890e 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -414,6 +414,7 @@
"Test.cpp",
"aidl/foo/bar/Test.aidl",
],
+ apex_available: ["apex1", "apex2"],
export_include_dirs: ["include"],
aidl: {
export_aidl_headers: true,
@@ -430,6 +431,10 @@
cc_prebuilt_library_shared {
name: "mysdk_mynativelib@current",
sdk_member_name: "mynativelib",
+ apex_available: [
+ "apex1",
+ "apex2",
+ ],
export_include_dirs: ["include/include"],
arch: {
arm64: {
@@ -448,6 +453,10 @@
cc_prebuilt_library_shared {
name: "mynativelib",
prefer: false,
+ apex_available: [
+ "apex1",
+ "apex2",
+ ],
export_include_dirs: ["include/include"],
arch: {
arm64: {
diff --git a/sdk/update.go b/sdk/update.go
index 087b8bc..b335777 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -550,6 +550,8 @@
m := s.bpFile.newModule(moduleType)
m.AddProperty("name", name)
+ variant := member.Variants()[0]
+
if s.sdk.isInternalMember(name) {
// An internal member is only referenced from the sdk snapshot which is in the
// same package so can be marked as private.
@@ -557,7 +559,7 @@
} else {
// Extract visibility information from a member variant. All variants have the same
// visibility so it doesn't matter which one is used.
- visibility := android.EffectiveVisibilityRules(s.ctx, member.Variants()[0])
+ visibility := android.EffectiveVisibilityRules(s.ctx, variant)
if len(visibility) != 0 {
m.AddProperty("visibility", visibility)
}
@@ -565,6 +567,14 @@
addHostDeviceSupportedProperties(&s.sdk.ModuleBase, m)
+ // Where available copy apex_available properties from the member.
+ if apexAware, ok := variant.(interface{ ApexAvailable() []string }); ok {
+ apexAvailable := apexAware.ApexAvailable()
+ if len(apexAvailable) > 0 {
+ m.AddProperty("apex_available", apexAvailable)
+ }
+ }
+
s.prebuiltModules[name] = m
s.prebuiltOrder = append(s.prebuiltOrder, m)
return m