diff --git a/android/packaging.go b/android/packaging.go index a10699715..aac321933 100644 --- a/android/packaging.go +++ b/android/packaging.go @@ -40,6 +40,15 @@ type PackagingSpec struct { executable bool } +// Get file name of installed package +func (p *PackagingSpec) FileName() string { + if p.relPathInPackage != "" { + return filepath.Base(p.relPathInPackage) + } + + return "" +} + type PackageModule interface { Module packagingBase() *PackagingBase diff --git a/cc/Android.bp b/cc/Android.bp index ff2cdf374..88104e295 100644 --- a/cc/Android.bp +++ b/cc/Android.bp @@ -72,6 +72,8 @@ bootstrap_go_package { "vendor_public_library.go", "testing.go", + + "stub_library.go", ], testSrcs: [ "cc_test.go", diff --git a/cc/stub_library.go b/cc/stub_library.go new file mode 100644 index 000000000..76d236ce6 --- /dev/null +++ b/cc/stub_library.go @@ -0,0 +1,82 @@ +// Copyright 2020 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cc + +import ( + "strings" + + "android/soong/android" +) + +func init() { + // Use singleton type to gather all generated soong modules. + android.RegisterSingletonType("stublibraries", stubLibrariesSingleton) +} + +type stubLibraries struct { + stubLibraryMap map[string]bool +} + +// Check if the module defines stub, or itself is stub +func isStubTarget(m *Module) bool { + if m.IsStubs() || m.HasStubsVariants() { + return true + } + + // Library which defines LLNDK Stub is also Stub target. + // Pure LLNDK Stub target would not contain any packaging + // with target file path. + if library, ok := m.linker.(*libraryDecorator); ok { + if library.Properties.Llndk_stubs != nil { + return true + } + } + + return false +} + +// Get target file name to be installed from this module +func getInstalledFileName(m *Module) string { + for _, ps := range m.PackagingSpecs() { + if name := ps.FileName(); name != "" { + return name + } + } + return "" +} + +func (s *stubLibraries) GenerateBuildActions(ctx android.SingletonContext) { + // Visit all generated soong modules and store stub library file names. + ctx.VisitAllModules(func(module android.Module) { + if m, ok := module.(*Module); ok { + if isStubTarget(m) { + if name := getInstalledFileName(m); name != "" { + s.stubLibraryMap[name] = true + } + } + } + }) +} + +func stubLibrariesSingleton() android.Singleton { + return &stubLibraries{ + stubLibraryMap: make(map[string]bool), + } +} + +func (s *stubLibraries) MakeVars(ctx android.MakeVarsContext) { + // Convert stub library file names into Makefile variable. + ctx.Strict("STUB_LIBRARIES", strings.Join(android.SortedStringKeys(s.stubLibraryMap), " ")) +} diff --git a/linkerconfig/linkerconfig.go b/linkerconfig/linkerconfig.go index 1c44c746f..623c9dd12 100644 --- a/linkerconfig/linkerconfig.go +++ b/linkerconfig/linkerconfig.go @@ -102,6 +102,7 @@ func (l *linkerConfig) AndroidMkEntries() []android.AndroidMkEntries { entries.SetString("LOCAL_MODULE_PATH", l.installDirPath.ToMakePath().String()) entries.SetString("LOCAL_INSTALLED_MODULE_STEM", l.outputFilePath.Base()) entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !installable) + entries.SetString("LINKER_CONFIG_PATH_"+l.Name(), l.OutputFile().String()) }, }, }} diff --git a/scripts/conv_linker_config.py b/scripts/conv_linker_config.py index 81425fb35..fca71ad56 100644 --- a/scripts/conv_linker_config.py +++ b/scripts/conv_linker_config.py @@ -18,8 +18,10 @@ import argparse import collections import json +import os import linker_config_pb2 +from google.protobuf.descriptor import FieldDescriptor from google.protobuf.json_format import ParseDict from google.protobuf.text_format import MessageToString @@ -43,6 +45,25 @@ def Print(args): print(MessageToString(pb)) +def SystemProvide(args): + pb = linker_config_pb2.LinkerConfig() + with open(args.source, 'rb') as f: + pb.ParseFromString(f.read()) + libraries = args.value.split() + + def IsInLibPath(lib_name): + lib_path = os.path.join(args.system, 'lib', lib_name) + lib64_path = os.path.join(args.system, 'lib64', lib_name) + return os.path.exists(lib_path) or os.path.islink(lib_path) or os.path.exists(lib64_path) or os.path.islink(lib64_path) + + installed_libraries = list(filter(IsInLibPath, libraries)) + for item in installed_libraries: + if item not in getattr(pb, 'provideLibs'): + getattr(pb, 'provideLibs').append(item) + with open(args.output, 'wb') as f: + f.write(pb.SerializeToString()) + + def GetArgParser(): parser = argparse.ArgumentParser() subparsers = parser.add_subparsers() @@ -73,6 +94,32 @@ def GetArgParser(): help='Source linker configuration file in protobuf.') print_proto.set_defaults(func=Print) + system_provide_libs = subparsers.add_parser( + 'systemprovide', help='Append system provide libraries into the configuration.') + system_provide_libs.add_argument( + '-s', + '--source', + required=True, + type=str, + help='Source linker configuration file in protobuf.') + system_provide_libs.add_argument( + '-o', + '--output', + required=True, + type=str, + help='Target linker configuration file to write in protobuf.') + system_provide_libs.add_argument( + '--value', + required=True, + type=str, + help='Values of the libraries to append. If there are more than one it should be separated by empty space') + system_provide_libs.add_argument( + '--system', + required=True, + type=str, + help='Path of the system image.') + system_provide_libs.set_defaults(func=SystemProvide) + return parser