• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2017 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 java
16
17import (
18	"strings"
19
20	"github.com/google/blueprint"
21
22	"android/soong/android"
23)
24
25var d8 = pctx.AndroidStaticRule("d8",
26	blueprint.RuleParams{
27		Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
28			`${config.D8Cmd} ${config.DexFlags} --output $outDir $d8Flags $in && ` +
29			`${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
30			`${config.MergeZipsCmd} -D -stripFile "**/*.class" $out $outDir/classes.dex.jar $in`,
31		CommandDeps: []string{
32			"${config.D8Cmd}",
33			"${config.SoongZipCmd}",
34			"${config.MergeZipsCmd}",
35		},
36	},
37	"outDir", "d8Flags", "zipFlags")
38
39var r8 = pctx.AndroidStaticRule("r8",
40	blueprint.RuleParams{
41		Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
42			`rm -f "$outDict" && ` +
43			`${config.R8Cmd} ${config.DexFlags} -injars $in --output $outDir ` +
44			`--force-proguard-compatibility ` +
45			`--no-data-resources ` +
46			`-printmapping $outDict ` +
47			`$r8Flags && ` +
48			`touch "$outDict" && ` +
49			`${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
50			`${config.MergeZipsCmd} -D -stripFile "**/*.class" $out $outDir/classes.dex.jar $in`,
51		CommandDeps: []string{
52			"${config.R8Cmd}",
53			"${config.SoongZipCmd}",
54			"${config.MergeZipsCmd}",
55		},
56	},
57	"outDir", "outDict", "r8Flags", "zipFlags")
58
59func (j *Module) dexCommonFlags(ctx android.ModuleContext) []string {
60	flags := j.deviceProperties.Dxflags
61	// Translate all the DX flags to D8 ones until all the build files have been migrated
62	// to D8 flags. See: b/69377755
63	flags = android.RemoveListFromList(flags,
64		[]string{"--core-library", "--dex", "--multi-dex"})
65
66	if ctx.Config().Getenv("NO_OPTIMIZE_DX") != "" {
67		flags = append(flags, "--debug")
68	}
69
70	if ctx.Config().Getenv("GENERATE_DEX_DEBUG") != "" {
71		flags = append(flags,
72			"--debug",
73			"--verbose")
74	}
75
76	minSdkVersion, err := sdkVersionToNumberAsString(ctx, j.minSdkVersion())
77	if err != nil {
78		ctx.PropertyErrorf("min_sdk_version", "%s", err)
79	}
80
81	flags = append(flags, "--min-api "+minSdkVersion)
82	return flags
83}
84
85func (j *Module) d8Flags(ctx android.ModuleContext, flags javaBuilderFlags) ([]string, android.Paths) {
86	d8Flags := j.dexCommonFlags(ctx)
87
88	d8Flags = append(d8Flags, flags.bootClasspath.FormTurbineClasspath("--lib ")...)
89	d8Flags = append(d8Flags, flags.classpath.FormTurbineClasspath("--lib ")...)
90
91	var d8Deps android.Paths
92	d8Deps = append(d8Deps, flags.bootClasspath...)
93	d8Deps = append(d8Deps, flags.classpath...)
94
95	return d8Flags, d8Deps
96}
97
98func (j *Module) r8Flags(ctx android.ModuleContext, flags javaBuilderFlags) (r8Flags []string, r8Deps android.Paths) {
99	opt := j.deviceProperties.Optimize
100
101	// When an app contains references to APIs that are not in the SDK specified by
102	// its LOCAL_SDK_VERSION for example added by support library or by runtime
103	// classes added by desugaring, we artifically raise the "SDK version" "linked" by
104	// ProGuard, to
105	// - suppress ProGuard warnings of referencing symbols unknown to the lower SDK version.
106	// - prevent ProGuard stripping subclass in the support library that extends class added in the higher SDK version.
107	// See b/20667396
108	var proguardRaiseDeps classpath
109	ctx.VisitDirectDepsWithTag(proguardRaiseTag, func(dep android.Module) {
110		proguardRaiseDeps = append(proguardRaiseDeps, dep.(Dependency).HeaderJars()...)
111	})
112
113	r8Flags = append(r8Flags, j.dexCommonFlags(ctx)...)
114
115	r8Flags = append(r8Flags, proguardRaiseDeps.FormJavaClassPath("-libraryjars"))
116	r8Flags = append(r8Flags, flags.bootClasspath.FormJavaClassPath("-libraryjars"))
117	r8Flags = append(r8Flags, flags.classpath.FormJavaClassPath("-libraryjars"))
118	r8Flags = append(r8Flags, "-forceprocessing")
119
120	r8Deps = append(r8Deps, proguardRaiseDeps...)
121	r8Deps = append(r8Deps, flags.bootClasspath...)
122	r8Deps = append(r8Deps, flags.classpath...)
123
124	flagFiles := android.Paths{
125		android.PathForSource(ctx, "build/make/core/proguard.flags"),
126	}
127
128	if j.shouldInstrumentStatic(ctx) {
129		flagFiles = append(flagFiles,
130			android.PathForSource(ctx, "build/make/core/proguard.jacoco.flags"))
131	}
132
133	flagFiles = append(flagFiles, j.extraProguardFlagFiles...)
134	// TODO(ccross): static android library proguard files
135
136	flagFiles = append(flagFiles, android.PathsForModuleSrc(ctx, j.deviceProperties.Optimize.Proguard_flags_files)...)
137
138	r8Flags = append(r8Flags, android.JoinWithPrefix(flagFiles.Strings(), "-include "))
139	r8Deps = append(r8Deps, flagFiles...)
140
141	// TODO(b/70942988): This is included from build/make/core/proguard.flags
142	r8Deps = append(r8Deps, android.PathForSource(ctx,
143		"build/make/core/proguard_basic_keeps.flags"))
144
145	r8Flags = append(r8Flags, j.deviceProperties.Optimize.Proguard_flags...)
146
147	// TODO(ccross): Don't shrink app instrumentation tests by default.
148	if !Bool(opt.Shrink) {
149		r8Flags = append(r8Flags, "-dontshrink")
150	}
151
152	if !Bool(opt.Optimize) {
153		r8Flags = append(r8Flags, "-dontoptimize")
154	}
155
156	// TODO(ccross): error if obufscation + app instrumentation test.
157	if !Bool(opt.Obfuscate) {
158		r8Flags = append(r8Flags, "-dontobfuscate")
159	}
160	// TODO(ccross): if this is an instrumentation test of an obfuscated app, use the
161	// dictionary of the app and move the app from libraryjars to injars.
162
163	// Don't strip out debug information for eng builds.
164	if ctx.Config().Eng() {
165		r8Flags = append(r8Flags, "--debug")
166	}
167
168	return r8Flags, r8Deps
169}
170
171func (j *Module) compileDex(ctx android.ModuleContext, flags javaBuilderFlags,
172	classesJar android.Path, jarName string) android.ModuleOutPath {
173
174	useR8 := j.deviceProperties.EffectiveOptimizeEnabled()
175
176	// Compile classes.jar into classes.dex and then javalib.jar
177	javalibJar := android.PathForModuleOut(ctx, "dex", jarName)
178	outDir := android.PathForModuleOut(ctx, "dex")
179
180	zipFlags := "--ignore_missing_files"
181	if j.deviceProperties.UncompressDex {
182		zipFlags += " -L 0"
183	}
184
185	if useR8 {
186		proguardDictionary := android.PathForModuleOut(ctx, "proguard_dictionary")
187		j.proguardDictionary = proguardDictionary
188		r8Flags, r8Deps := j.r8Flags(ctx, flags)
189		ctx.Build(pctx, android.BuildParams{
190			Rule:           r8,
191			Description:    "r8",
192			Output:         javalibJar,
193			ImplicitOutput: proguardDictionary,
194			Input:          classesJar,
195			Implicits:      r8Deps,
196			Args: map[string]string{
197				"r8Flags":  strings.Join(r8Flags, " "),
198				"zipFlags": zipFlags,
199				"outDict":  j.proguardDictionary.String(),
200				"outDir":   outDir.String(),
201			},
202		})
203	} else {
204		d8Flags, d8Deps := j.d8Flags(ctx, flags)
205		ctx.Build(pctx, android.BuildParams{
206			Rule:        d8,
207			Description: "d8",
208			Output:      javalibJar,
209			Input:       classesJar,
210			Implicits:   d8Deps,
211			Args: map[string]string{
212				"d8Flags":  strings.Join(d8Flags, " "),
213				"zipFlags": zipFlags,
214				"outDir":   outDir.String(),
215			},
216		})
217	}
218	if j.deviceProperties.UncompressDex {
219		alignedJavalibJar := android.PathForModuleOut(ctx, "aligned", jarName)
220		TransformZipAlign(ctx, alignedJavalibJar, javalibJar)
221		javalibJar = alignedJavalibJar
222	}
223
224	return javalibJar
225}
226