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

Commit 43f08db2 authored by Colin Cross's avatar Colin Cross
Browse files

Dexpreopt soong modules inside soong

Port the dexpreopt logic from Make to the dexpreopt package in Soong,
and use it to dexpreopt Soong modules.  The same package is also
compiled into the dexpreopt_gen binary to generate dexpreopt scripts
for Make modules.

This relands Ib67e2febf9ed921f06e8a86b9ec945c80dff35eb and
I462182638bd57b1367b5bfb0718e975c11ae66f7, along with multiple fixes
to depsfile generation in dexpreopt_gen that caused .odex files for
modules in defined make to be missing dependencies on boot.art, and
a fix to not dexpreopt and strip tests.

Bug: 119412419
Bug: 120273280
Test: no differences to dexpreopt outputs on aosp_sailfish system/,
      only expected changes to dexpreopt outputs on system_other
      (.vdex files for privileged Soong modules no longer incorrectly
      contain .dex contents).
Test: OUT_DIR=$PWD/out m
Test: NINJA_ARGS="-t deps out/target/product/sailfish/obj/APPS/Contacts_intermediates/dexpreopt.zip" m
Change-Id: I6bb2c971cee65d2338839753aa0d84939f335b1b
parent df76efe5
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -224,6 +224,7 @@ bootstrap_go_package {
        "soong",
        "soong-android",
        "soong-cc",
        "soong-dexpreopt",
        "soong-genrule",
        "soong-java-config",
        "soong-tradefed",
@@ -238,6 +239,7 @@ bootstrap_go_package {
        "java/app.go",
        "java/builder.go",
        "java/dex.go",
        "java/dexpreopt.go",
        "java/droiddoc.go",
        "java/gen.go",
        "java/genrule.go",
+20 −4
Original line number Diff line number Diff line
@@ -732,14 +732,18 @@ func (c *config) ModulesLoadedByPrivilegedModules() []string {
	return c.productVariables.ModulesLoadedByPrivilegedModules
}

func (c *config) DefaultStripDex() bool {
	return Bool(c.productVariables.DefaultStripDex)
}

func (c *config) DisableDexPreopt(name string) bool {
	return Bool(c.productVariables.DisableDexPreopt) || InList(name, c.productVariables.DisableDexPreoptModules)
}

func (c *config) DexpreoptGlobalConfig() string {
	return String(c.productVariables.DexpreoptGlobalConfig)
}

func (c *config) DexPreoptProfileDir() string {
	return String(c.productVariables.DexPreoptProfileDir)
}

func (c *deviceConfig) Arches() []Arch {
	var arches []Arch
	for _, target := range c.config.Targets[Android] {
@@ -854,6 +858,18 @@ func (c *deviceConfig) PlatPrivateSepolicyDirs() []string {
	return c.config.productVariables.BoardPlatPrivateSepolicyDirs
}

func (c *config) SecondArchIsTranslated() bool {
	deviceTargets := c.Targets[Android]
	if len(deviceTargets) < 2 {
		return false
	}

	arch := deviceTargets[0].Arch

	return (arch.ArchType == X86 || arch.ArchType == X86_64) &&
		(hasArmAbi(arch) || hasArmAndroidArch(deviceTargets))
}

func (c *config) IntegerOverflowDisabledForPath(path string) bool {
	if c.productVariables.IntegerOverflowExcludePaths == nil {
		return false
+61 −33
Original line number Diff line number Diff line
@@ -659,11 +659,7 @@ func (p SourcePath) OverlayPath(ctx ModuleContext, path Path) OptionalPath {
	if len(paths) == 0 {
		return OptionalPath{}
	}
	relPath, err := filepath.Rel(p.config.srcDir, paths[0])
	if err != nil {
		reportPathError(ctx, err)
		return OptionalPath{}
	}
	relPath := Rel(ctx, p.config.srcDir, paths[0])
	return OptionalPathForPath(PathForSource(ctx, relPath))
}

@@ -788,13 +784,7 @@ func (p ModuleSrcPath) resPathWithName(ctx ModuleContext, name string) ModuleRes

func (p ModuleSrcPath) WithSubDir(ctx ModuleContext, subdir string) ModuleSrcPath {
	subdir = PathForModuleSrc(ctx, subdir).String()
	var err error
	rel, err := filepath.Rel(subdir, p.path)
	if err != nil {
		ctx.ModuleErrorf("source file %q is not under path %q", p.path, subdir)
		return p
	}
	p.rel = rel
	p.rel = Rel(ctx, subdir, p.path)
	return p
}

@@ -932,6 +922,33 @@ func PathForModuleRes(ctx ModuleContext, pathComponents ...string) ModuleResPath
func PathForModuleInstall(ctx ModuleInstallPathContext, pathComponents ...string) OutputPath {
	var outPaths []string
	if ctx.Device() {
		partition := modulePartition(ctx)
		outPaths = []string{"target", "product", ctx.Config().DeviceName(), partition}
	} else {
		switch ctx.Os() {
		case Linux:
			outPaths = []string{"host", "linux-x86"}
		case LinuxBionic:
			// TODO: should this be a separate top level, or shared with linux-x86?
			outPaths = []string{"host", "linux_bionic-x86"}
		default:
			outPaths = []string{"host", ctx.Os().String() + "-x86"}
		}
	}
	if ctx.Debug() {
		outPaths = append([]string{"debug"}, outPaths...)
	}
	outPaths = append(outPaths, pathComponents...)
	return PathForOutput(ctx, outPaths...)
}

func InstallPathToOnDevicePath(ctx PathContext, path OutputPath) string {
	rel := Rel(ctx, PathForOutput(ctx, "target", "product", ctx.Config().DeviceName()).String(), path.String())

	return "/" + rel
}

func modulePartition(ctx ModuleInstallPathContext) string {
	var partition string
	if ctx.InstallInData() {
		partition = "data"
@@ -949,27 +966,10 @@ func PathForModuleInstall(ctx ModuleInstallPathContext, pathComponents ...string
	} else {
		partition = "system"
	}

	if ctx.InstallInSanitizerDir() {
		partition = "data/asan/" + partition
	}
		outPaths = []string{"target", "product", ctx.Config().DeviceName(), partition}
	} else {
		switch ctx.Os() {
		case Linux:
			outPaths = []string{"host", "linux-x86"}
		case LinuxBionic:
			// TODO: should this be a separate top level, or shared with linux-x86?
			outPaths = []string{"host", "linux_bionic-x86"}
		default:
			outPaths = []string{"host", ctx.Os().String() + "-x86"}
		}
	}
	if ctx.Debug() {
		outPaths = append([]string{"debug"}, outPaths...)
	}
	outPaths = append(outPaths, pathComponents...)
	return PathForOutput(ctx, outPaths...)
	return partition
}

// validateSafePath validates a path that we trust (may contain ninja variables).
@@ -1039,3 +1039,31 @@ func PathsForTesting(strs []string) Paths {

	return p
}

// Rel performs the same function as filepath.Rel, but reports errors to a PathContext, and reports an error if
// targetPath is not inside basePath.
func Rel(ctx PathContext, basePath string, targetPath string) string {
	rel, isRel := MaybeRel(ctx, basePath, targetPath)
	if !isRel {
		reportPathErrorf(ctx, "path %q is not under path %q", targetPath, basePath)
		return ""
	}
	return rel
}

// MaybeRel performs the same function as filepath.Rel, but reports errors to a PathContext, and returns false if
// targetPath is not inside basePath.
func MaybeRel(ctx PathContext, basePath string, targetPath string) (string, bool) {
	// filepath.Rel returns an error if one path is absolute and the other is not, handle that case first.
	if filepath.IsAbs(basePath) != filepath.IsAbs(targetPath) {
		return "", false
	}
	rel, err := filepath.Rel(basePath, targetPath)
	if err != nil {
		reportPathError(ctx, err)
		return "", false
	} else if rel == ".." || strings.HasPrefix(rel, "../") || strings.HasPrefix(rel, "/") {
		return "", false
	}
	return rel, true
}
+57 −0
Original line number Diff line number Diff line
@@ -573,3 +573,60 @@ func TestDirectorySortedPaths(t *testing.T) {
		t.Errorf("FilesInDirectory(b):\n %#v\n != \n %#v", inA.Strings(), expectedA)
	}
}

func TestMaybeRel(t *testing.T) {
	testCases := []struct {
		name   string
		base   string
		target string
		out    string
		isRel  bool
	}{
		{
			name:   "normal",
			base:   "a/b/c",
			target: "a/b/c/d",
			out:    "d",
			isRel:  true,
		},
		{
			name:   "parent",
			base:   "a/b/c/d",
			target: "a/b/c",
			isRel:  false,
		},
		{
			name:   "not relative",
			base:   "a/b",
			target: "c/d",
			isRel:  false,
		},
		{
			name:   "abs1",
			base:   "/a",
			target: "a",
			isRel:  false,
		},
		{
			name:   "abs2",
			base:   "a",
			target: "/a",
			isRel:  false,
		},
	}

	for _, testCase := range testCases {
		t.Run(testCase.name, func(t *testing.T) {
			ctx := &configErrorWrapper{}
			out, isRel := MaybeRel(ctx, testCase.base, testCase.target)
			if len(ctx.errors) > 0 {
				t.Errorf("MaybeRel(..., %s, %s) reported unexpected errors %v",
					testCase.base, testCase.target, ctx.errors)
			}
			if isRel != testCase.isRel || out != testCase.out {
				t.Errorf("MaybeRel(..., %s, %s) want %v, %v got %v, %v",
					testCase.base, testCase.target, testCase.out, testCase.isRel, out, isRel)
			}
		})
	}
}
+6 −3
Original line number Diff line number Diff line
@@ -196,9 +196,10 @@ type productVariables struct {

	UncompressPrivAppDex             *bool    `json:",omitempty"`
	ModulesLoadedByPrivilegedModules []string `json:",omitempty"`
	DefaultStripDex                  *bool    `json:",omitempty"`

	DisableDexPreopt        *bool    `json:",omitempty"`
	DisableDexPreoptModules []string `json:",omitempty"`
	DexPreoptProfileDir     *string  `json:",omitempty"`

	IntegerOverflowExcludePaths *[]string `json:",omitempty"`

@@ -257,6 +258,8 @@ type productVariables struct {
	Exclude_draft_ndk_apis *bool `json:",omitempty"`

	FlattenApex *bool `json:",omitempty"`

	DexpreoptGlobalConfig *string `json:",omitempty"`
}

func boolPtr(v bool) *bool {
Loading