github.com/westcoastroms/westcoastroms-build@v0.0.0-20190928114312-2350e5a73030/build/soong/java/dex.go (about)

     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  
    15  package java
    16  
    17  import (
    18  	"strings"
    19  
    20  	"github.com/google/blueprint"
    21  
    22  	"android/soong/android"
    23  )
    24  
    25  var desugar = pctx.AndroidStaticRule("desugar",
    26  	blueprint.RuleParams{
    27  		Command: `rm -rf $dumpDir && mkdir -p $dumpDir && ` +
    28  			`${config.JavaCmd} ` +
    29  			`-Djdk.internal.lambda.dumpProxyClasses=$$(cd $dumpDir && pwd) ` +
    30  			`$javaFlags ` +
    31  			`-jar ${config.DesugarJar} $classpathFlags $desugarFlags ` +
    32  			`-i $in -o $out`,
    33  		CommandDeps: []string{"${config.DesugarJar}", "${config.JavaCmd}"},
    34  	},
    35  	"javaFlags", "classpathFlags", "desugarFlags", "dumpDir")
    36  
    37  func (j *Module) desugar(ctx android.ModuleContext, flags javaBuilderFlags,
    38  	classesJar android.Path, jarName string) android.Path {
    39  
    40  	desugarFlags := []string{
    41  		"--min_sdk_version " + j.minSdkVersionNumber(ctx),
    42  		"--desugar_try_with_resources_if_needed=false",
    43  		"--allow_empty_bootclasspath",
    44  	}
    45  
    46  	if inList("--core-library", j.deviceProperties.Dxflags) {
    47  		desugarFlags = append(desugarFlags, "--core_library")
    48  	}
    49  
    50  	desugarJar := android.PathForModuleOut(ctx, "desugar", jarName)
    51  	dumpDir := android.PathForModuleOut(ctx, "desugar", "classes")
    52  
    53  	javaFlags := ""
    54  	if ctx.Config().UseOpenJDK9() {
    55  		javaFlags = "--add-opens java.base/java.lang.invoke=ALL-UNNAMED"
    56  	}
    57  
    58  	var classpathFlags []string
    59  	classpathFlags = append(classpathFlags, flags.bootClasspath.FormDesugarClasspath("--bootclasspath_entry")...)
    60  	classpathFlags = append(classpathFlags, flags.classpath.FormDesugarClasspath("--classpath_entry")...)
    61  
    62  	var deps android.Paths
    63  	deps = append(deps, flags.bootClasspath...)
    64  	deps = append(deps, flags.classpath...)
    65  
    66  	ctx.Build(pctx, android.BuildParams{
    67  		Rule:        desugar,
    68  		Description: "desugar",
    69  		Output:      desugarJar,
    70  		Input:       classesJar,
    71  		Implicits:   deps,
    72  		Args: map[string]string{
    73  			"dumpDir":        dumpDir.String(),
    74  			"javaFlags":      javaFlags,
    75  			"classpathFlags": strings.Join(classpathFlags, " "),
    76  			"desugarFlags":   strings.Join(desugarFlags, " "),
    77  		},
    78  	})
    79  
    80  	return desugarJar
    81  }
    82  
    83  var dx = pctx.AndroidStaticRule("dx",
    84  	blueprint.RuleParams{
    85  		Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
    86  			`${config.DxCmd} --dex --output=$outDir $dxFlags $in && ` +
    87  			`${config.SoongZipCmd} -o $outDir/classes.dex.jar -C $outDir -D $outDir && ` +
    88  			`${config.MergeZipsCmd} -D -stripFile "*.class" $out $outDir/classes.dex.jar $in`,
    89  		CommandDeps: []string{
    90  			"${config.DxCmd}",
    91  			"${config.SoongZipCmd}",
    92  			"${config.MergeZipsCmd}",
    93  		},
    94  	},
    95  	"outDir", "dxFlags")
    96  
    97  var d8 = pctx.AndroidStaticRule("d8",
    98  	blueprint.RuleParams{
    99  		Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
   100  			`${config.D8Cmd} --output $outDir $dxFlags $in && ` +
   101  			`${config.SoongZipCmd} -o $outDir/classes.dex.jar -C $outDir -D $outDir && ` +
   102  			`${config.MergeZipsCmd} -D -stripFile "*.class" $out $outDir/classes.dex.jar $in`,
   103  		CommandDeps: []string{
   104  			"${config.D8Cmd}",
   105  			"${config.SoongZipCmd}",
   106  			"${config.MergeZipsCmd}",
   107  		},
   108  	},
   109  	"outDir", "dxFlags")
   110  
   111  var r8 = pctx.AndroidStaticRule("r8",
   112  	blueprint.RuleParams{
   113  		Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
   114  			`${config.R8Cmd} -injars $in --output $outDir ` +
   115  			`--force-proguard-compatibility ` +
   116  			`-printmapping $outDict ` +
   117  			`$dxFlags $r8Flags && ` +
   118  			`${config.SoongZipCmd} -o $outDir/classes.dex.jar -C $outDir -D $outDir && ` +
   119  			`${config.MergeZipsCmd} -D -stripFile "*.class" $out $outDir/classes.dex.jar $in`,
   120  		CommandDeps: []string{
   121  			"${config.R8Cmd}",
   122  			"${config.SoongZipCmd}",
   123  			"${config.MergeZipsCmd}",
   124  		},
   125  	},
   126  	"outDir", "outDict", "dxFlags", "r8Flags")
   127  
   128  func (j *Module) dxFlags(ctx android.ModuleContext, fullD8 bool) []string {
   129  	flags := j.deviceProperties.Dxflags
   130  	if fullD8 {
   131  		// Translate all the DX flags to D8 ones until all the build files have been migrated
   132  		// to D8 flags. See: b/69377755
   133  		flags = android.RemoveListFromList(flags,
   134  			[]string{"--core-library", "--dex", "--multi-dex"})
   135  	}
   136  
   137  	if ctx.Config().Getenv("NO_OPTIMIZE_DX") != "" {
   138  		if fullD8 {
   139  			flags = append(flags, "--debug")
   140  		} else {
   141  			flags = append(flags, "--no-optimize")
   142  		}
   143  	}
   144  
   145  	if ctx.Config().Getenv("GENERATE_DEX_DEBUG") != "" {
   146  		flags = append(flags,
   147  			"--debug",
   148  			"--verbose")
   149  		if !fullD8 {
   150  			flags = append(flags,
   151  				"--dump-to="+android.PathForModuleOut(ctx, "classes.lst").String(),
   152  				"--dump-width=1000")
   153  		}
   154  	}
   155  
   156  	if fullD8 {
   157  		flags = append(flags, "--min-api "+j.minSdkVersionNumber(ctx))
   158  	} else {
   159  		flags = append(flags, "--min-sdk-version="+j.minSdkVersionNumber(ctx))
   160  	}
   161  	return flags
   162  }
   163  
   164  func (j *Module) r8Flags(ctx android.ModuleContext, flags javaBuilderFlags) (r8Flags []string, r8Deps android.Paths) {
   165  	opt := j.deviceProperties.Optimize
   166  
   167  	// When an app contains references to APIs that are not in the SDK specified by
   168  	// its LOCAL_SDK_VERSION for example added by support library or by runtime
   169  	// classes added by desugar, we artifically raise the "SDK version" "linked" by
   170  	// ProGuard, to
   171  	// - suppress ProGuard warnings of referencing symbols unknown to the lower SDK version.
   172  	// - prevent ProGuard stripping subclass in the support library that extends class added in the higher SDK version.
   173  	// See b/20667396
   174  	var proguardRaiseDeps classpath
   175  	ctx.VisitDirectDepsWithTag(proguardRaiseTag, func(dep android.Module) {
   176  		proguardRaiseDeps = append(proguardRaiseDeps, dep.(Dependency).HeaderJars()...)
   177  	})
   178  
   179  	r8Flags = append(r8Flags, proguardRaiseDeps.FormJavaClassPath("-libraryjars"))
   180  	r8Flags = append(r8Flags, flags.bootClasspath.FormJavaClassPath("-libraryjars"))
   181  	r8Flags = append(r8Flags, flags.classpath.FormJavaClassPath("-libraryjars"))
   182  	r8Flags = append(r8Flags, "-forceprocessing")
   183  
   184  	flagFiles := android.Paths{
   185  		android.PathForSource(ctx, "build/make/core/proguard.flags"),
   186  	}
   187  
   188  	if j.shouldInstrumentStatic(ctx) {
   189  		flagFiles = append(flagFiles,
   190  			android.PathForSource(ctx, "build/make/core/proguard.jacoco.flags"))
   191  	}
   192  
   193  	flagFiles = append(flagFiles, j.extraProguardFlagFiles...)
   194  	// TODO(ccross): static android library proguard files
   195  
   196  	r8Flags = append(r8Flags, android.JoinWithPrefix(flagFiles.Strings(), "-include "))
   197  	r8Deps = append(r8Deps, flagFiles...)
   198  
   199  	// TODO(b/70942988): This is included from build/make/core/proguard.flags
   200  	r8Deps = append(r8Deps, android.PathForSource(ctx,
   201  		"build/make/core/proguard_basic_keeps.flags"))
   202  
   203  	r8Flags = append(r8Flags, j.deviceProperties.Optimize.Proguard_flags...)
   204  
   205  	// TODO(ccross): Don't shrink app instrumentation tests by default.
   206  	if !Bool(opt.Shrink) {
   207  		r8Flags = append(r8Flags, "-dontshrink")
   208  	}
   209  
   210  	if !Bool(opt.Optimize) {
   211  		r8Flags = append(r8Flags, "-dontoptimize")
   212  	}
   213  
   214  	// TODO(ccross): error if obufscation + app instrumentation test.
   215  	if !Bool(opt.Obfuscate) {
   216  		r8Flags = append(r8Flags, "-dontobfuscate")
   217  	}
   218  
   219  	return r8Flags, r8Deps
   220  }
   221  
   222  func (j *Module) compileDex(ctx android.ModuleContext, flags javaBuilderFlags,
   223  	classesJar android.Path, jarName string) android.Path {
   224  
   225  	useR8 := Bool(j.deviceProperties.Optimize.Enabled)
   226  	fullD8 := useR8 || ctx.Config().UseD8Desugar()
   227  
   228  	if !fullD8 {
   229  		classesJar = j.desugar(ctx, flags, classesJar, jarName)
   230  	}
   231  
   232  	dxFlags := j.dxFlags(ctx, fullD8)
   233  
   234  	// Compile classes.jar into classes.dex and then javalib.jar
   235  	javalibJar := android.PathForModuleOut(ctx, "dex", jarName)
   236  	outDir := android.PathForModuleOut(ctx, "dex")
   237  
   238  	if useR8 {
   239  		// TODO(ccross): if this is an instrumentation test of an obfuscated app, use the
   240  		// dictionary of the app and move the app from libraryjars to injars.
   241  		j.proguardDictionary = android.PathForModuleOut(ctx, "proguard_dictionary")
   242  		r8Flags, r8Deps := j.r8Flags(ctx, flags)
   243  		ctx.Build(pctx, android.BuildParams{
   244  			Rule:        r8,
   245  			Description: "r8",
   246  			Output:      javalibJar,
   247  			Input:       classesJar,
   248  			Implicits:   r8Deps,
   249  			Args: map[string]string{
   250  				"dxFlags": strings.Join(dxFlags, " "),
   251  				"r8Flags": strings.Join(r8Flags, " "),
   252  				"outDict": j.proguardDictionary.String(),
   253  				"outDir":  outDir.String(),
   254  			},
   255  		})
   256  	} else {
   257  		rule := dx
   258  		desc := "dx"
   259  		if fullD8 {
   260  			rule = d8
   261  			desc = "d8"
   262  		}
   263  		ctx.Build(pctx, android.BuildParams{
   264  			Rule:        rule,
   265  			Description: desc,
   266  			Output:      javalibJar,
   267  			Input:       classesJar,
   268  			Args: map[string]string{
   269  				"dxFlags": strings.Join(dxFlags, " "),
   270  				"outDir":  outDir.String(),
   271  			},
   272  		})
   273  	}
   274  
   275  	j.dexJarFile = javalibJar
   276  	return javalibJar
   277  }