blob: 460cc3ef4197aa9c4d7ef9418f0d863a489b7198 [file] [log] [blame]
Artur Satayeveabf2c12021-04-07 15:45:02 +01001/*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package java
18
19import (
Artur Satayev97259dc2021-04-07 15:17:14 +010020 "fmt"
21 "strings"
22
Artur Satayeveabf2c12021-04-07 15:45:02 +010023 "android/soong/android"
24)
25
26// Build rules and utilities to generate individual packages/modules/SdkExtensions/proto/classpaths.proto
27// config files based on build configuration to embed into /system and /apex on a device.
28//
29// See `derive_classpath` service that reads the configs at runtime and defines *CLASSPATH variables
30// on the device.
31
32type classpathType int
33
34const (
35 // Matches definition in packages/modules/SdkExtensions/proto/classpaths.proto
36 BOOTCLASSPATH classpathType = iota
37 DEX2OATBOOTCLASSPATH
38 SYSTEMSERVERCLASSPATH
39)
40
41func (c classpathType) String() string {
42 return [...]string{"BOOTCLASSPATH", "DEX2OATBOOTCLASSPATH", "SYSTEMSERVERCLASSPATH"}[c]
43}
44
45type classpathFragmentProperties struct {
46}
47
48// classpathFragment interface is implemented by a module that contributes jars to a *CLASSPATH
49// variables at runtime.
50type classpathFragment interface {
51 android.Module
52
Artur Satayev97259dc2021-04-07 15:17:14 +010053 classpathFragmentBase() *ClasspathFragmentBase
Artur Satayeveabf2c12021-04-07 15:45:02 +010054}
55
Artur Satayev97259dc2021-04-07 15:17:14 +010056// ClasspathFragmentBase is meant to be embedded in any module types that implement classpathFragment;
Artur Satayeveabf2c12021-04-07 15:45:02 +010057// such modules are expected to call initClasspathFragment().
Artur Satayev97259dc2021-04-07 15:17:14 +010058type ClasspathFragmentBase struct {
Artur Satayeveabf2c12021-04-07 15:45:02 +010059 properties classpathFragmentProperties
60
Artur Satayeveabf2c12021-04-07 15:45:02 +010061 outputFilepath android.OutputPath
Artur Satayev97259dc2021-04-07 15:17:14 +010062 installDirPath android.InstallPath
Artur Satayeveabf2c12021-04-07 15:45:02 +010063}
64
Artur Satayev97259dc2021-04-07 15:17:14 +010065func (c *ClasspathFragmentBase) classpathFragmentBase() *ClasspathFragmentBase {
66 return c
67}
68
69// Initializes ClasspathFragmentBase struct. Must be called by all modules that include ClasspathFragmentBase.
Artur Satayeveabf2c12021-04-07 15:45:02 +010070func initClasspathFragment(c classpathFragment) {
71 base := c.classpathFragmentBase()
72 c.AddProperties(&base.properties)
73}
Artur Satayev97259dc2021-04-07 15:17:14 +010074
75// Matches definition of Jar in packages/modules/SdkExtensions/proto/classpaths.proto
76type classpathJar struct {
77 path string
78 classpath classpathType
79 // TODO(satayev): propagate min/max sdk versions for the jars
80 minSdkVersion int32
81 maxSdkVersion int32
82}
83
satayev128ce2f2021-05-06 13:21:15 +010084func (c *ClasspathFragmentBase) generateClasspathProtoBuildActions(ctx android.ModuleContext) {
Artur Satayev97259dc2021-04-07 15:17:14 +010085 outputFilename := ctx.ModuleName() + ".pb"
86 c.outputFilepath = android.PathForModuleOut(ctx, outputFilename).OutputPath
87 c.installDirPath = android.PathForModuleInstall(ctx, "etc", "classpaths")
88
89 var jars []classpathJar
90 jars = appendClasspathJar(jars, BOOTCLASSPATH, defaultBootclasspath(ctx)...)
91 jars = appendClasspathJar(jars, DEX2OATBOOTCLASSPATH, defaultBootImageConfig(ctx).getAnyAndroidVariant().dexLocationsDeps...)
92 jars = appendClasspathJar(jars, SYSTEMSERVERCLASSPATH, systemServerClasspath(ctx)...)
93
94 generatedJson := android.PathForModuleOut(ctx, outputFilename+".json")
95 writeClasspathsJson(ctx, generatedJson, jars)
96
97 rule := android.NewRuleBuilder(pctx, ctx)
98 rule.Command().
99 BuiltTool("conv_classpaths_proto").
100 Flag("encode").
101 Flag("--format=json").
102 FlagWithInput("--input=", generatedJson).
103 FlagWithOutput("--output=", c.outputFilepath)
104
105 rule.Build("classpath_fragment", "Compiling "+c.outputFilepath.String())
106}
107
108func writeClasspathsJson(ctx android.ModuleContext, output android.WritablePath, jars []classpathJar) {
109 var content strings.Builder
110 fmt.Fprintf(&content, "{\n")
111 fmt.Fprintf(&content, "\"jars\": [\n")
112 for idx, jar := range jars {
113 fmt.Fprintf(&content, "{\n")
114
115 fmt.Fprintf(&content, "\"relativePath\": \"%s\",\n", jar.path)
116 fmt.Fprintf(&content, "\"classpath\": \"%s\"\n", jar.classpath)
117
118 if idx < len(jars)-1 {
119 fmt.Fprintf(&content, "},\n")
120 } else {
121 fmt.Fprintf(&content, "}\n")
122 }
123 }
124 fmt.Fprintf(&content, "]\n")
125 fmt.Fprintf(&content, "}\n")
126 android.WriteFileRule(ctx, output, content.String())
127}
128
129func appendClasspathJar(slice []classpathJar, classpathType classpathType, paths ...string) (result []classpathJar) {
130 result = append(result, slice...)
131 for _, path := range paths {
132 result = append(result, classpathJar{
133 path: path,
134 classpath: classpathType,
135 })
136 }
137 return
138}
139
satayev128ce2f2021-05-06 13:21:15 +0100140func (c *ClasspathFragmentBase) androidMkEntries() []android.AndroidMkEntries {
Artur Satayev97259dc2021-04-07 15:17:14 +0100141 return []android.AndroidMkEntries{android.AndroidMkEntries{
142 Class: "ETC",
143 OutputFile: android.OptionalPathForPath(c.outputFilepath),
144 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
145 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
146 entries.SetString("LOCAL_MODULE_PATH", c.installDirPath.ToMakePath().String())
147 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", c.outputFilepath.Base())
148 },
149 },
150 }}
151}