aboutsummaryrefslogtreecommitdiffstats
path: root/dexpreopt/config.go
blob: 99814019ca66ce116154355e0b5a7b8dfcc8763d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
// Copyright 2018 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 dexpreopt

import (
	"encoding/json"
	"io/ioutil"
	"strings"

	"android/soong/android"
)

// GlobalConfig stores the configuration for dex preopting set by the product
type GlobalConfig struct {
	DefaultNoStripping bool // don't strip dex files by default

	DisablePreopt        bool     // disable preopt for all modules
	DisablePreoptModules []string // modules with preopt disabled by product-specific config

	OnlyPreoptBootImageAndSystemServer bool // only preopt jars in the boot image or system server

	HasSystemOther        bool     // store odex files that match PatternsOnSystemOther on the system_other partition
	PatternsOnSystemOther []string // patterns (using '%' to denote a prefix match) to put odex on the system_other partition

	DisableGenerateProfile bool   // don't generate profiles
	ProfileDir             string // directory to find profiles in

	BootJars []string // modules for jars that form the boot class path

	RuntimeApexJars               []string // modules for jars that are in the runtime apex
	ProductUpdatableBootModules   []string
	ProductUpdatableBootLocations []string

	SystemServerJars []string // jars that form the system server
	SystemServerApps []string // apps that are loaded into system server
	SpeedApps        []string // apps that should be speed optimized

	PreoptFlags []string // global dex2oat flags that should be used if no module-specific dex2oat flags are specified

	DefaultCompilerFilter      string // default compiler filter to pass to dex2oat, overridden by --compiler-filter= in module-specific dex2oat flags
	SystemServerCompilerFilter string // default compiler filter to pass to dex2oat for system server jars

	GenerateDMFiles     bool // generate Dex Metadata files
	NeverAllowStripping bool // whether stripping should not be done - used as build time check to make sure dex files are always available

	NoDebugInfo                 bool // don't generate debug info by default
	AlwaysSystemServerDebugInfo bool // always generate mini debug info for system server modules (overrides NoDebugInfo=true)
	NeverSystemServerDebugInfo  bool // never generate mini debug info for system server modules (overrides NoDebugInfo=false)
	AlwaysOtherDebugInfo        bool // always generate mini debug info for non-system server modules (overrides NoDebugInfo=true)
	NeverOtherDebugInfo         bool // never generate mini debug info for non-system server modules (overrides NoDebugInfo=true)

	MissingUsesLibraries []string // libraries that may be listed in OptionalUsesLibraries but will not be installed by the product

	IsEng        bool // build is a eng variant
	SanitizeLite bool // build is the second phase of a SANITIZE_LITE build

	DefaultAppImages bool // build app images (TODO: .art files?) by default

	Dex2oatXmx string // max heap size for dex2oat
	Dex2oatXms string // initial heap size for dex2oat

	EmptyDirectory string // path to an empty directory

	CpuVariant             map[android.ArchType]string // cpu variant for each architecture
	InstructionSetFeatures map[android.ArchType]string // instruction set for each architecture

	// Only used for boot image
	DirtyImageObjects      android.OptionalPath // path to a dirty-image-objects file
	PreloadedClasses       android.OptionalPath // path to a preloaded-classes file
	BootImageProfiles      android.Paths        // path to a boot-image-profile.txt file
	UseProfileForBootImage bool                 // whether a profile should be used to compile the boot image
	BootFlags              string               // extra flags to pass to dex2oat for the boot image
	Dex2oatImageXmx        string               // max heap size for dex2oat for the boot image
	Dex2oatImageXms        string               // initial heap size for dex2oat for the boot image

	Tools Tools // paths to tools possibly used by the generated commands
}

// Tools contains paths to tools possibly used by the generated commands.  If you add a new tool here you MUST add it
// to the order-only dependency list in DEXPREOPT_GEN_DEPS.
type Tools struct {
	Profman  android.Path
	Dex2oat  android.Path
	Aapt     android.Path
	SoongZip android.Path
	Zip2zip  android.Path

	VerifyUsesLibraries android.Path
	ConstructContext    android.Path
}

type ModuleConfig struct {
	Name            string
	DexLocation     string // dex location on device
	BuildPath       android.OutputPath
	DexPath         android.Path
	UncompressedDex bool
	HasApkLibraries bool
	PreoptFlags     []string

	ProfileClassListing  android.OptionalPath
	ProfileIsTextListing bool

	EnforceUsesLibraries  bool
	OptionalUsesLibraries []string
	UsesLibraries         []string
	LibraryPaths          map[string]android.Path

	Archs           []android.ArchType
	DexPreoptImages []android.Path

	PreoptBootClassPathDexFiles     android.Paths // file paths of boot class path files
	PreoptBootClassPathDexLocations []string      // virtual locations of boot class path files

	PreoptExtractedApk bool // Overrides OnlyPreoptModules

	NoCreateAppImage    bool
	ForceCreateAppImage bool

	PresignedPrebuilt bool

	NoStripping     bool
	StripInputPath  android.Path
	StripOutputPath android.WritablePath
}

func constructPath(ctx android.PathContext, path string) android.Path {
	buildDirPrefix := ctx.Config().BuildDir() + "/"
	if path == "" {
		return nil
	} else if strings.HasPrefix(path, buildDirPrefix) {
		return android.PathForOutput(ctx, strings.TrimPrefix(path, buildDirPrefix))
	} else {
		return android.PathForSource(ctx, path)
	}
}

func constructPaths(ctx android.PathContext, paths []string) android.Paths {
	var ret android.Paths
	for _, path := range paths {
		ret = append(ret, constructPath(ctx, path))
	}
	return ret
}

func constructPathMap(ctx android.PathContext, paths map[string]string) map[string]android.Path {
	ret := map[string]android.Path{}
	for key, path := range paths {
		ret[key] = constructPath(ctx, path)
	}
	return ret
}

func constructWritablePath(ctx android.PathContext, path string) android.WritablePath {
	if path == "" {
		return nil
	}
	return constructPath(ctx, path).(android.WritablePath)
}

// LoadGlobalConfig reads the global dexpreopt.config file into a GlobalConfig struct.  It is used directly in Soong
// and in dexpreopt_gen called from Make to read the $OUT/dexpreopt.config written by Make.
func LoadGlobalConfig(ctx android.PathContext, path string) (GlobalConfig, error) {
	type GlobalJSONConfig struct {
		GlobalConfig

		// Copies of entries in GlobalConfig that are not constructable without extra parameters.  They will be
		// used to construct the real value manually below.
		DirtyImageObjects string
		PreloadedClasses  string
		BootImageProfiles []string

		Tools struct {
			Profman  string
			Dex2oat  string
			Aapt     string
			SoongZip string
			Zip2zip  string

			VerifyUsesLibraries string
			ConstructContext    string
		}
	}

	config := GlobalJSONConfig{}
	err := loadConfig(ctx, path, &config)
	if err != nil {
		return config.GlobalConfig, err
	}

	// Construct paths that require a PathContext.
	config.GlobalConfig.DirtyImageObjects = android.OptionalPathForPath(constructPath(ctx, config.DirtyImageObjects))
	config.GlobalConfig.PreloadedClasses = android.OptionalPathForPath(constructPath(ctx, config.PreloadedClasses))
	config.GlobalConfig.BootImageProfiles = constructPaths(ctx, config.BootImageProfiles)

	config.GlobalConfig.Tools.Profman = constructPath(ctx, config.Tools.Profman)
	config.GlobalConfig.Tools.Dex2oat = constructPath(ctx, config.Tools.Dex2oat)
	config.GlobalConfig.Tools.Aapt = constructPath(ctx, config.Tools.Aapt)
	config.GlobalConfig.Tools.SoongZip = constructPath(ctx, config.Tools.SoongZip)
	config.GlobalConfig.Tools.Zip2zip = constructPath(ctx, config.Tools.Zip2zip)
	config.GlobalConfig.Tools.VerifyUsesLibraries = constructPath(ctx, config.Tools.VerifyUsesLibraries)
	config.GlobalConfig.Tools.ConstructContext = constructPath(ctx, config.Tools.ConstructContext)

	return config.GlobalConfig, nil
}

// LoadModuleConfig reads a per-module dexpreopt.config file into a ModuleConfig struct.  It is not used in Soong, which
// receives a ModuleConfig struct directly from java/dexpreopt.go.  It is used in dexpreopt_gen called from oMake to
// read the module dexpreopt.config written by Make.
func LoadModuleConfig(ctx android.PathContext, path string) (ModuleConfig, error) {
	type ModuleJSONConfig struct {
		ModuleConfig

		// Copies of entries in ModuleConfig that are not constructable without extra parameters.  They will be
		// used to construct the real value manually below.
		BuildPath                   string
		DexPath                     string
		ProfileClassListing         string
		LibraryPaths                map[string]string
		DexPreoptImages             []string
		PreoptBootClassPathDexFiles []string
		StripInputPath              string
		StripOutputPath             string
	}

	config := ModuleJSONConfig{}

	err := loadConfig(ctx, path, &config)
	if err != nil {
		return config.ModuleConfig, err
	}

	// Construct paths that require a PathContext.
	config.ModuleConfig.BuildPath = constructPath(ctx, config.BuildPath).(android.OutputPath)
	config.ModuleConfig.DexPath = constructPath(ctx, config.DexPath)
	config.ModuleConfig.ProfileClassListing = android.OptionalPathForPath(constructPath(ctx, config.ProfileClassListing))
	config.ModuleConfig.LibraryPaths = constructPathMap(ctx, config.LibraryPaths)
	config.ModuleConfig.DexPreoptImages = constructPaths(ctx, config.DexPreoptImages)
	config.ModuleConfig.PreoptBootClassPathDexFiles = constructPaths(ctx, config.PreoptBootClassPathDexFiles)
	config.ModuleConfig.StripInputPath = constructPath(ctx, config.StripInputPath)
	config.ModuleConfig.StripOutputPath = constructWritablePath(ctx, config.StripOutputPath)

	return config.ModuleConfig, nil
}

func loadConfig(ctx android.PathContext, path string, config interface{}) error {
	r, err := ctx.Fs().Open(path)
	if err != nil {
		return err
	}
	defer r.Close()

	data, err := ioutil.ReadAll(r)
	if err != nil {
		return err
	}

	err = json.Unmarshal(data, config)
	if err != nil {
		return err
	}

	return nil
}

func GlobalConfigForTests(ctx android.PathContext) GlobalConfig {
	return GlobalConfig{
		DefaultNoStripping:                 false,
		DisablePreopt:                      false,
		DisablePreoptModules:               nil,
		OnlyPreoptBootImageAndSystemServer: false,
		HasSystemOther:                     false,
		PatternsOnSystemOther:              nil,
		DisableGenerateProfile:             false,
		ProfileDir:                         "",
		BootJars:                           nil,
		RuntimeApexJars:                    nil,
		ProductUpdatableBootModules:        nil,
		ProductUpdatableBootLocations:      nil,
		SystemServerJars:                   nil,
		SystemServerApps:                   nil,
		SpeedApps:                          nil,
		PreoptFlags:                        nil,
		DefaultCompilerFilter:              "",
		SystemServerCompilerFilter:         "",
		GenerateDMFiles:                    false,
		NeverAllowStripping:                false,
		NoDebugInfo:                        false,
		AlwaysSystemServerDebugInfo:        false,
		NeverSystemServerDebugInfo:         false,
		AlwaysOtherDebugInfo:               false,
		NeverOtherDebugInfo:                false,
		MissingUsesLibraries:               nil,
		IsEng:                              false,
		SanitizeLite:                       false,
		DefaultAppImages:                   false,
		Dex2oatXmx:                         "",
		Dex2oatXms:                         "",
		EmptyDirectory:                     "empty_dir",
		CpuVariant:                         nil,
		InstructionSetFeatures:             nil,
		DirtyImageObjects:                  android.OptionalPath{},
		PreloadedClasses:                   android.OptionalPath{},
		BootImageProfiles:                  nil,
		UseProfileForBootImage:             false,
		BootFlags:                          "",
		Dex2oatImageXmx:                    "",
		Dex2oatImageXms:                    "",
		Tools: Tools{
			Profman:             android.PathForTesting("profman"),
			Dex2oat:             android.PathForTesting("dex2oat"),
			Aapt:                android.PathForTesting("aapt"),
			SoongZip:            android.PathForTesting("soong_zip"),
			Zip2zip:             android.PathForTesting("zip2zip"),
			VerifyUsesLibraries: android.PathForTesting("verify_uses_libraries.sh"),
			ConstructContext:    android.PathForTesting("construct_context.sh"),
		},
	}
}