Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f181bc97 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Integrate Metalava to Soong Build"

parents a9ccbb7b 79614d1c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -121,6 +121,7 @@ func init() {
	pctx.HostJavaToolVariable("DesugarJar", "desugar.jar")
	pctx.HostJavaToolVariable("JsilverJar", "jsilver.jar")
	pctx.HostJavaToolVariable("DoclavaJar", "doclava.jar")
	pctx.HostJavaToolVariable("MetalavaJar", "metalava.jar")

	pctx.HostBinToolVariable("SoongJavacWrapper", "soong_javac_wrapper")

+213 −84
Original line number Diff line number Diff line
@@ -64,6 +64,28 @@ var (
				`&& touch $out ) || (echo failed to update public API ; exit 38)`,
		},
		"apiFile", "apiFileToCheck", "removedApiFile", "removedApiFileToCheck")

	metalava = pctx.AndroidStaticRule("metalava",
		blueprint.RuleParams{
			Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && mkdir -p "$outDir" "$srcJarDir" "$stubsDir" && ` +
				`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
				`${config.JavaCmd} -jar ${config.MetalavaJar} -encoding UTF-8 -source 1.8 @$out.rsp @$srcJarDir/list ` +
				`$bootclasspathArgs $classpathArgs -sourcepath $sourcepath --no-banner --color ` +
				`--stubs $stubsDir --quiet --write-stubs-source-list $outDir/stubs_src_list $opts && ` +
				`${config.SoongZipCmd} -write_if_changed -d -o $docZip -C $outDir -D $outDir && ` +
				`${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir`,
			CommandDeps: []string{
				"${config.ZipSyncCmd}",
				"${config.JavaCmd}",
				"${config.MetalavaJar}",
				"${config.JavadocCmd}",
				"${config.SoongZipCmd}",
			},
			Rspfile:        "$out.rsp",
			RspfileContent: "$in",
			Restat:         true,
		},
		"outDir", "srcJarDir", "stubsDir", "srcJars", "bootclasspathArgs", "classpathArgs", "sourcepath", "opts", "docZip")
)

func init() {
@@ -204,6 +226,19 @@ type DroiddocProperties struct {

		Current ApiToCheck
	}

	// if set to true, create stubs through Metalava instead of Doclava. Javadoc/Doclava is
	// currently still used for documentation generation, and will be replaced by Dokka soon.
	Metalava_enabled *bool

	// user can specify the version of previous released API file in order to do compatibility check.
	Metalava_previous_api *string

	// is set to true, Metalava will allow framework SDK to contain annotations.
	Metalava_annotations_enabled *bool

	// a XML files set to merge annotations.
	Metalava_merge_annotations_dir *string
}

type Javadoc struct {
@@ -556,10 +591,7 @@ func (d *Droiddoc) checkLastReleasedApi() bool {
func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
	d.Javadoc.addDeps(ctx)

	if String(d.properties.Custom_template) == "" {
		// TODO: This is almost always droiddoc-templates-sdk
		ctx.PropertyErrorf("custom_template", "must specify a template")
	} else {
	if String(d.properties.Custom_template) != "" {
		ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
	}

@@ -578,6 +610,10 @@ func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
		android.ExtractSourceDeps(ctx, d.properties.Check_api.Last_released.Api_file)
		android.ExtractSourceDeps(ctx, d.properties.Check_api.Last_released.Removed_api_file)
	}

	if String(d.properties.Metalava_previous_api) != "" {
		android.ExtractSourceDeps(ctx, d.properties.Metalava_previous_api)
	}
}

func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -587,6 +623,9 @@ func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	implicits = append(implicits, deps.bootClasspath...)
	implicits = append(implicits, deps.classpath...)

	bootClasspathArgs := deps.bootClasspath.FormJavaClassPath("-bootclasspath")
	classpathArgs := deps.classpath.FormJavaClassPath("-classpath")

	argFiles := ctx.ExpandSources(d.properties.Arg_files, nil)
	argFilesMap := map[string]android.Path{}

@@ -615,19 +654,31 @@ func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	})

	if err != nil {
		ctx.PropertyErrorf("extra_args", "%s", err.Error())
		ctx.PropertyErrorf("args", "%s", err.Error())
		return
	}

	var bootClasspathArgs, classpathArgs string
	if len(deps.bootClasspath.Strings()) > 0 {
		bootClasspathArgs = "-bootclasspath " + strings.Join(deps.bootClasspath.Strings(), ":")
	genDocsForMetalava := false
	var metalavaArgs string
	if Bool(d.properties.Metalava_enabled) {
		if strings.Contains(args, "--generate-documentation") {
			if !strings.Contains(args, "-nodocs") {
				genDocsForMetalava = true
			}
			// TODO(nanzhang): Add a Soong property to handle documentation args.
			metalavaArgs = strings.Split(args, "--generate-documentation")[0]
		} else {
			metalavaArgs = args
		}
	if len(deps.classpath.Strings()) > 0 {
		classpathArgs = "-classpath " + strings.Join(deps.classpath.Strings(), ":")
	}

	var templateDir string
	var templateDir, htmlDirArgs, htmlDir2Args string
	if !Bool(d.properties.Metalava_enabled) || genDocsForMetalava {
		if String(d.properties.Custom_template) == "" {
			// TODO: This is almost always droiddoc-templates-sdk
			ctx.PropertyErrorf("custom_template", "must specify a template")
		}

		ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
			if t, ok := m.(*DroiddocTemplate); ok {
				implicits = append(implicits, t.deps...)
@@ -637,14 +688,12 @@ func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
			}
		})

	var htmlDirArgs string
		if len(d.properties.Html_dirs) > 0 {
			htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
			implicits = append(implicits, ctx.Glob(htmlDir.Join(ctx, "**/*").String(), nil)...)
			htmlDirArgs = "-htmldir " + htmlDir.String()
		}

	var htmlDir2Args string
		if len(d.properties.Html_dirs) > 1 {
			htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
			implicits = append(implicits, ctx.Glob(htmlDir2.Join(ctx, "**/*").String(), nil)...)
@@ -661,6 +710,7 @@ func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
		for _, kt := range knownTags {
			args = args + " -knowntags " + kt.String()
		}

		for _, hdf := range d.properties.Hdf {
			args = args + " -hdf " + hdf
		}
@@ -688,51 +738,66 @@ func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
			// TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
			args = args + " -resourcesoutdir " + String(d.properties.Resourcesoutdir)
		}
	}

	var docArgsForMetalava string
	if Bool(d.properties.Metalava_enabled) && genDocsForMetalava {
		docArgsForMetalava = strings.Split(args, "--generate-documentation")[1]
	}

	var implicitOutputs android.WritablePaths

	if d.checkCurrentApi() || d.checkLastReleasedApi() || String(d.properties.Api_filename) != "" {
		d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
		args = args + " -api " + d.apiFile.String()
		metalavaArgs = metalavaArgs + " --api " + d.apiFile.String()
		implicitOutputs = append(implicitOutputs, d.apiFile)
	}

	if d.checkCurrentApi() || d.checkLastReleasedApi() || String(d.properties.Removed_api_filename) != "" {
		d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
		args = args + " -removedApi " + d.removedApiFile.String()
		metalavaArgs = metalavaArgs + " --removed-api " + d.removedApiFile.String()
		implicitOutputs = append(implicitOutputs, d.removedApiFile)
	}

	if String(d.properties.Private_api_filename) != "" {
		d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
		args = args + " -privateApi " + d.privateApiFile.String()
		metalavaArgs = metalavaArgs + " --private-api " + d.privateApiFile.String()
		implicitOutputs = append(implicitOutputs, d.privateApiFile)
	}

	if String(d.properties.Private_dex_api_filename) != "" {
		d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
		args = args + " -privateDexApi " + d.privateDexApiFile.String()
		metalavaArgs = metalavaArgs + " --private-dex-api " + d.privateDexApiFile.String()
		implicitOutputs = append(implicitOutputs, d.privateDexApiFile)
	}

	if String(d.properties.Removed_dex_api_filename) != "" {
		d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
		args = args + " -removedDexApi " + d.removedDexApiFile.String()
		metalavaArgs = metalavaArgs + " --removed-dex-api " + d.removedDexApiFile.String()
		implicitOutputs = append(implicitOutputs, d.removedDexApiFile)
	}

	if String(d.properties.Exact_api_filename) != "" {
		d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
		args = args + " -exactApi " + d.exactApiFile.String()
		metalavaArgs = metalavaArgs + " --exact-api " + d.exactApiFile.String()
		implicitOutputs = append(implicitOutputs, d.exactApiFile)
	}

	implicits = append(implicits, d.Javadoc.srcJars...)

	implicitOutputs = append(implicitOutputs, d.Javadoc.docZip)
	for _, o := range d.properties.Out {
		implicitOutputs = append(implicitOutputs, android.PathForModuleGen(ctx, o))
	}

	jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
	doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
	implicits = append(implicits, jsilver)
	implicits = append(implicits, doclava)

	var date string
	if runtime.GOOS == "darwin" {
@@ -741,22 +806,22 @@ func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
		date = `date -d`
	}

	opts := "-source 1.8 -J-Xmx1600m -J-XX:-OmitStackTraceInFastThrow -XDignore.symbol.file " +
	doclavaOpts := "-source 1.8 -J-Xmx1600m -J-XX:-OmitStackTraceInFastThrow -XDignore.symbol.file " +
		"-doclet com.google.doclava.Doclava -docletpath " + jsilver.String() + ":" + doclava.String() + " " +
		"-templatedir " + templateDir + " " + htmlDirArgs + " " + htmlDir2Args + " " +
		"-hdf page.build " + ctx.Config().BuildId() + "-" + ctx.Config().BuildNumberFromFile() + " " +
		`-hdf page.now "$$(` + date + ` @$$(cat ` + ctx.Config().Getenv("BUILD_DATETIME_FILE") + `) "+%d %b %Y %k:%M")" ` +
		" " + args
		`-hdf page.now "$$(` + date + ` @$$(cat ` + ctx.Config().Getenv("BUILD_DATETIME_FILE") + `) "+%d %b %Y %k:%M")" `

	if !Bool(d.properties.Metalava_enabled) {
		opts := doclavaOpts + args

		implicits = append(implicits, jsilver)
		implicits = append(implicits, doclava)

		if BoolDefault(d.properties.Create_stubs, true) {
			opts += " -stubs " + android.PathForModuleOut(ctx, "docs", "stubsDir").String()
		}

	implicitOutputs = append(implicitOutputs, d.Javadoc.docZip)
	for _, o := range d.properties.Out {
		implicitOutputs = append(implicitOutputs, android.PathForModuleGen(ctx, o))
	}

		ctx.Build(pctx, android.BuildParams{
			Rule:            javadoc,
			Description:     "Droiddoc",
@@ -776,6 +841,71 @@ func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
				"docZip":            d.Javadoc.docZip.String(),
			},
		})
	} else {
		opts := metalavaArgs

		buildArgs := map[string]string{
			"outDir":            android.PathForModuleOut(ctx, "docs", "out").String(),
			"srcJarDir":         android.PathForModuleOut(ctx, "docs", "srcjars").String(),
			"stubsDir":          android.PathForModuleOut(ctx, "docs", "stubsDir").String(),
			"srcJars":           strings.Join(d.Javadoc.srcJars.Strings(), " "),
			"bootclasspathArgs": bootClasspathArgs,
			"classpathArgs":     classpathArgs,
			"sourcepath":        strings.Join(d.Javadoc.sourcepaths.Strings(), ":"),
			"docZip":            d.Javadoc.docZip.String(),
		}

		var previousApi android.Path
		if String(d.properties.Metalava_previous_api) != "" {
			previousApi = ctx.ExpandSource(String(d.properties.Metalava_previous_api),
				"metalava_previous_api")
			opts += " --check-compatibility  --previous-api " + previousApi.String()
			implicits = append(implicits, previousApi)
		}

		if Bool(d.properties.Metalava_annotations_enabled) {
			if String(d.properties.Metalava_previous_api) == "" {
				ctx.PropertyErrorf("metalava_previous_api",
					"has to be non-empty if annotations was enabled!")
			}
			opts += " --include-annotations --migrate-nullness"

			annotationsZip := android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
			implicitOutputs = append(implicitOutputs, annotationsZip)

			if String(d.properties.Metalava_merge_annotations_dir) == "" {
				ctx.PropertyErrorf("metalava_merge_annotations",
					"has to be non-empty if annotations was enabled!")
			}

			mergeAnnotationsDir := android.PathForModuleSrc(ctx,
				String(d.properties.Metalava_merge_annotations_dir))
			implicits = append(implicits, ctx.Glob(mergeAnnotationsDir.Join(ctx, "**/*").String(), nil)...)

			opts += " --extract-annotations " + annotationsZip.String() + " --merge-annotations " + mergeAnnotationsDir.String()
			// TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
			opts += "--hide HiddenTypedefConstant --hide SuperfluousPrefix --hide AnnotationExtraction"
		}

		if genDocsForMetalava {
			opts += " --generate-documentation ${config.JavadocCmd} -encoding UTF-8 STUBS_SOURCE_LIST " +
				doclavaOpts + docArgsForMetalava + bootClasspathArgs + " " + classpathArgs + " " + " -sourcepath " +
				strings.Join(d.Javadoc.sourcepaths.Strings(), ":") + " -quiet -d $outDir "
			implicits = append(implicits, jsilver)
			implicits = append(implicits, doclava)
		}

		buildArgs["opts"] = opts
		ctx.Build(pctx, android.BuildParams{
			Rule:            metalava,
			Description:     "Metalava",
			Output:          d.Javadoc.stubsSrcJar,
			Inputs:          d.Javadoc.srcFiles,
			Implicits:       implicits,
			ImplicitOutputs: implicitOutputs,
			Args:            buildArgs,
		})
	}

	java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")

@@ -831,7 +961,6 @@ func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
			},
		})
	}

	if d.checkLastReleasedApi() && !ctx.Config().IsPdkBuild() {
		d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")