diff --git a/apex/androidmk.go b/apex/androidmk.go index 44082836f..99cd75ef1 100644 --- a/apex/androidmk.go +++ b/apex/androidmk.go @@ -450,12 +450,21 @@ func (a *apexBundle) androidMkForType() android.AndroidMkData { fmt.Fprintf(w, dist) } - if a.coverageOutputPath.String() != "" { + if a.apisUsedByModuleFile.String() != "" { goal := "apps_only" - distFile := a.coverageOutputPath.String() + distFile := a.apisUsedByModuleFile.String() fmt.Fprintf(w, "ifneq (,$(filter $(my_register_name),$(TARGET_BUILD_APPS)))\n"+ " $(call dist-for-goals,%s,%s:ndk_apis_usedby_apex/$(notdir %s))\n"+ - "endif", + "endif\n", + goal, distFile, distFile) + } + + if a.apisBackedByModuleFile.String() != "" { + goal := "apps_only" + distFile := a.apisBackedByModuleFile.String() + fmt.Fprintf(w, "ifneq (,$(filter $(my_register_name),$(TARGET_BUILD_APPS)))\n"+ + " $(call dist-for-goals,%s,%s:ndk_apis_backedby_apex/$(notdir %s))\n"+ + "endif\n", goal, distFile, distFile) } } diff --git a/apex/apex.go b/apex/apex.go index 507d3ed0e..384d6c7a6 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -390,7 +390,8 @@ type apexBundle struct { isCompressed bool // Path of API coverage generate file - coverageOutputPath android.ModuleOutPath + apisUsedByModuleFile android.ModuleOutPath + apisBackedByModuleFile android.ModuleOutPath } // apexFileClass represents a type of file that can be included in APEX. diff --git a/apex/builder.go b/apex/builder.go index e6bc3bdb4..67314d85b 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -687,7 +687,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { implicitInputs = append(implicitInputs, unsignedOutputFile) // Run coverage analysis - apisUsedbyOutputFile := android.PathForModuleOut(ctx, a.Name()+".txt") + apisUsedbyOutputFile := android.PathForModuleOut(ctx, a.Name()+"_using.txt") ctx.Build(pctx, android.BuildParams{ Rule: generateAPIsUsedbyApexRule, Implicits: implicitInputs, @@ -698,7 +698,19 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { "readelf": "${config.ClangBin}/llvm-readelf", }, }) - a.coverageOutputPath = apisUsedbyOutputFile + a.apisUsedByModuleFile = apisUsedbyOutputFile + + apisBackedbyOutputFile := android.PathForModuleOut(ctx, a.Name()+"_backing.txt") + ndkLibraryList := android.PathForSource(ctx, "system/core/rootdir/etc/public.libraries.android.txt") + rule := android.NewRuleBuilder(pctx, ctx) + rule.Command(). + Tool(android.PathForSource(ctx, "build/soong/scripts/gen_ndk_backedby_apex.sh")). + Text(imageDir.String()). + Implicits(implicitInputs). + Output(apisBackedbyOutputFile). + Input(ndkLibraryList) + rule.Build("ndk_backedby_list", "Generate API libraries backed by Apex") + a.apisBackedByModuleFile = apisBackedbyOutputFile bundleConfig := a.buildBundleConfig(ctx) diff --git a/scripts/gen_ndk_backedby_apex.sh b/scripts/gen_ndk_backedby_apex.sh new file mode 100755 index 000000000..e0da60236 --- /dev/null +++ b/scripts/gen_ndk_backedby_apex.sh @@ -0,0 +1,55 @@ +#!/bin/bash -e + +# Copyright 2020 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generates NDK API txt file used by Mainline modules. NDK APIs would have value +# "UND" in Ndx column and have suffix "@LIB_NAME" in Name column. +# For example, current line llvm-readelf output is: +# 1: 00000000 0 FUNC GLOBAL DEFAULT UND dlopen@LIBC +# After the parse function below "dlopen" would be write to the output file. +printHelp() { + echo "**************************** Usage Instructions ****************************" + echo "This script is used to generate the Mainline modules backed-by NDK symbols." + echo "" + echo "To run this script use: ./ndk_backedby_module.sh \$BINARY_IMAGE_DIRECTORY \$OUTPUT_FILE_PATH \$NDK_LIB_NAME_LIST" + echo "For example: If all the module image files that you would like to run is under directory '/myModule' and output write to /backedby.txt then the command would be:" + echo "./ndk_usedby_module.sh /myModule /backedby.txt /ndkLibList.txt" + echo "If the module1 is backing lib1 then the backedby.txt would contains: " + echo "lib1" +} + +genBackedByList() { + dir="$1" + [[ ! -e "$2" ]] && echo "" >> "$2" + while IFS= read -r line + do + soFileName=$(echo "$line" | sed 's/\(.*so\).*/\1/') + if [[ ! -z "$soFileName" && "$soFileName" != *"#"* ]] + then + find "$dir" -type f -name "$soFileName" -exec echo "$soFileName" >> "$2" \; + fi + done < "$3" +} + +if [[ "$1" == "help" ]] +then + printHelp +elif [[ "$#" -ne 3 ]] +then + echo "Wrong argument length. Expecting 3 argument representing image file directory, output path, path to ndk library list." +else + [[ -e "$2" ]] && rm "$2" + genBackedByList "$1" "$2" "$3" +fi