1// Copyright 2022 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package multitree
16
17import (
18	"android/soong/android"
19	"strings"
20
21	"github.com/google/blueprint"
22)
23
24var (
25	apiImportNameSuffix = ".apiimport"
26)
27
28func init() {
29	RegisterApiImportsModule(android.InitRegistrationContext)
30	android.RegisterMakeVarsProvider(pctx, makeVarsProvider)
31}
32
33func RegisterApiImportsModule(ctx android.RegistrationContext) {
34	ctx.RegisterModuleType("api_imports", apiImportsFactory)
35}
36
37type ApiImports struct {
38	android.ModuleBase
39	properties apiImportsProperties
40}
41
42type apiImportsProperties struct {
43	Shared_libs      []string // List of C shared libraries from API surfaces
44	Header_libs      []string // List of C header libraries from API surfaces
45	Apex_shared_libs []string // List of C shared libraries with APEX stubs
46}
47
48// 'api_imports' is a module which describes modules available from API surfaces.
49// This module is required to get the list of all imported API modules, because
50// it is discouraged to loop and fetch all modules from its type information. The
51// only module with name 'api_imports' will be used from the build.
52func apiImportsFactory() android.Module {
53	module := &ApiImports{}
54	module.AddProperties(&module.properties)
55	android.InitAndroidModule(module)
56	return module
57}
58
59func (imports *ApiImports) GenerateAndroidBuildActions(ctx android.ModuleContext) {
60	// ApiImport module does not generate any build actions
61}
62
63type ApiImportInfo struct {
64	SharedLibs, HeaderLibs, ApexSharedLibs map[string]string
65}
66
67var ApiImportsProvider = blueprint.NewMutatorProvider[ApiImportInfo]("deps")
68
69// Store module lists into ApiImportInfo and share it over mutator provider.
70func (imports *ApiImports) DepsMutator(ctx android.BottomUpMutatorContext) {
71	generateNameMapWithSuffix := func(names []string) map[string]string {
72		moduleNameMap := make(map[string]string)
73		for _, name := range names {
74			moduleNameMap[name] = name + apiImportNameSuffix
75		}
76
77		return moduleNameMap
78	}
79
80	sharedLibs := generateNameMapWithSuffix(imports.properties.Shared_libs)
81	headerLibs := generateNameMapWithSuffix(imports.properties.Header_libs)
82	apexSharedLibs := generateNameMapWithSuffix(imports.properties.Apex_shared_libs)
83
84	android.SetProvider(ctx, ApiImportsProvider, ApiImportInfo{
85		SharedLibs:     sharedLibs,
86		HeaderLibs:     headerLibs,
87		ApexSharedLibs: apexSharedLibs,
88	})
89}
90
91func GetApiImportSuffix() string {
92	return apiImportNameSuffix
93}
94
95func makeVarsProvider(ctx android.MakeVarsContext) {
96	ctx.VisitAllModules(func(m android.Module) {
97		if i, ok := m.(*ApiImports); ok {
98			ctx.Strict("API_IMPORTED_SHARED_LIBRARIES", strings.Join(i.properties.Shared_libs, " "))
99			ctx.Strict("API_IMPORTED_HEADER_LIBRARIES", strings.Join(i.properties.Header_libs, " "))
100		}
101	})
102}
103