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

Commit b47a1d52 authored by Doug Anderson's avatar Doug Anderson Committed by Gerrit Code Review
Browse files

Merge "Add 'dsts' property to prebuilt_etc" into main

parents 0636fa36 79688ff5
Loading
Loading
Loading
Loading
+46 −11
Original line number Diff line number Diff line
@@ -78,9 +78,16 @@ type prebuiltEtcProperties struct {
	Src proptools.Configurable[string] `android:"path,arch_variant,replace_instead_of_append"`

	// Source files of this prebuilt. Can reference a genrule type module with the ":module" syntax.
	// Mutually exclusive with src. When used, filename_from_src is set to true.
	// Mutually exclusive with src. When used, filename_from_src is set to true unless dsts is also
	// set. May use globs in filenames.
	Srcs proptools.Configurable[[]string] `android:"path,arch_variant"`

	// Destination files of this prebuilt. Requires srcs to be used and causes srcs not to implicitly
	// set filename_from_src. This can be used to install each source file to a different directory
	// and/or change filenames when files are installed. Must be exactly one entry per source file,
	// which means care must be taken if srcs has globs.
	Dsts proptools.Configurable[[]string] `android:"path,arch_variant"`

	// Optional name for the installed file. If unspecified, name of the module is used as the file
	// name. Only available when using a single source (src).
	Filename *string `android:"arch_variant"`
@@ -166,7 +173,7 @@ type PrebuiltEtc struct {
	// The base install location when soc_specific property is set to true, e.g. "firmware" for
	// prebuilt_firmware.
	socInstallDirBase      string
	installDirPath         android.InstallPath
	installDirPaths        []android.InstallPath
	additionalDependencies *android.Paths

	usedSrcsProperty bool
@@ -279,7 +286,10 @@ func (p *PrebuiltEtc) SourceFilePath(ctx android.ModuleContext) android.Path {
}

func (p *PrebuiltEtc) InstallDirPath() android.InstallPath {
	return p.installDirPath
	if len(p.installDirPaths) != 1 {
		panic(fmt.Errorf("InstallDirPath not available on multi-source prebuilt %q", p.Name()))
	}
	return p.installDirPaths[0]
}

// This allows other derivative modules (e.g. prebuilt_etc_xml) to perform
@@ -338,12 +348,16 @@ func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	if srcProperty.IsPresent() && len(srcsProperty) > 0 {
		ctx.PropertyErrorf("src", "src is set. Cannot set srcs")
	}
	dstsProperty := p.properties.Dsts.GetOrDefault(ctx, nil)
	if len(dstsProperty) > 0 && len(srcsProperty) == 0 {
		ctx.PropertyErrorf("dsts", "dsts is set. Must use srcs")
	}

	// Check that `sub_dir` and `relative_install_path` are not set at the same time.
	if p.subdirProperties.Sub_dir != nil && p.subdirProperties.Relative_install_path != nil {
		ctx.PropertyErrorf("sub_dir", "relative_install_path is set. Cannot set sub_dir")
	}
	p.installDirPath = android.PathForModuleInstall(ctx, p.installBaseDir(ctx), p.SubDir())
	baseInstallDirPath := android.PathForModuleInstall(ctx, p.installBaseDir(ctx), p.SubDir())

	filename := proptools.String(p.properties.Filename)
	filenameFromSrc := proptools.Bool(p.properties.Filename_from_src)
@@ -379,10 +393,11 @@ func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
			filename:       filename,
			sourceFilePath: p.sourceFilePaths[0],
			outputFilePath: p.outputFilePaths[0],
			installDirPath: p.installDirPath,
			installDirPath: baseInstallDirPath,
			symlinks:       p.properties.Symlinks,
		}
		installs = append(installs, ip)
		p.installDirPaths = append(p.installDirPaths, baseInstallDirPath)
	} else if len(srcsProperty) > 0 {
		p.usedSrcsProperty = true
		if filename != "" {
@@ -392,20 +407,39 @@ func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
			ctx.PropertyErrorf("symlinks", "symlinks cannot be set when using srcs")
		}
		if p.properties.Filename_from_src != nil {
			if len(dstsProperty) > 0 {
				ctx.PropertyErrorf("filename_from_src", "dsts is set. Cannot set filename_from_src")
			} else {
				ctx.PropertyErrorf("filename_from_src", "filename_from_src is implicitly set to true when using srcs")
			}
		}
		p.sourceFilePaths = android.PathsForModuleSrc(ctx, srcsProperty)
		for _, src := range p.sourceFilePaths {
			filename := src.Base()
		if len(dstsProperty) > 0 && len(p.sourceFilePaths) != len(dstsProperty) {
			ctx.PropertyErrorf("dsts", "Must have one entry in dsts per source file")
		}
		for i, src := range p.sourceFilePaths {
			var filename string
			var installDirPath android.InstallPath

			if len(dstsProperty) > 0 {
				var dstdir string

				dstdir, filename = filepath.Split(dstsProperty[i])
				installDirPath = baseInstallDirPath.Join(ctx, dstdir)
			} else {
				filename = src.Base()
				installDirPath = baseInstallDirPath
			}
			output := android.PathForModuleOut(ctx, filename).OutputPath
			ip := installProperties{
				filename:       filename,
				sourceFilePath: src,
				outputFilePath: output,
				installDirPath: p.installDirPath,
				installDirPath: installDirPath,
			}
			p.outputFilePaths = append(p.outputFilePaths, output)
			installs = append(installs, ip)
			p.installDirPaths = append(p.installDirPaths, installDirPath)
		}
	} else if ctx.Config().AllowMissingDependencies() {
		// If no srcs was set and AllowMissingDependencies is enabled then
@@ -421,9 +455,10 @@ func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
			filename:       filename,
			sourceFilePath: p.sourceFilePaths[0],
			outputFilePath: p.outputFilePaths[0],
			installDirPath: p.installDirPath,
			installDirPath: baseInstallDirPath,
		}
		installs = append(installs, ip)
		p.installDirPaths = append(p.installDirPaths, baseInstallDirPath)
	} else {
		ctx.PropertyErrorf("src", "missing prebuilt source file")
		return
@@ -493,7 +528,7 @@ func (p *PrebuiltEtc) AndroidMkEntries() []android.AndroidMkEntries {
		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
			func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
				entries.SetString("LOCAL_MODULE_TAGS", "optional")
				entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.String())
				entries.SetString("LOCAL_MODULE_PATH", p.installDirPaths[0].String())
				entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePaths[0].Base())
				if len(p.properties.Symlinks) > 0 {
					entries.AddStrings("LOCAL_MODULE_SYMLINKS", p.properties.Symlinks...)
+121 −14
Original line number Diff line number Diff line
@@ -119,6 +119,113 @@ func TestPrebuiltEtcMultipleSrcs(t *testing.T) {
	android.AssertStringEquals(t, "output file path", "foo.conf", p.outputFilePaths[2].Base())
}

func TestPrebuiltEtcDsts(t *testing.T) {
	result := prepareForPrebuiltEtcTest.RunTestWithBp(t, `
		prebuilt_etc {
			name: "foo",
			srcs: ["foo.conf", "bar.conf"],
			dsts: ["foodir/foo.conf", "bardir/extradir/different.name"],
		}
	`)

	p := result.Module("foo", "android_arm64_armv8-a").(*PrebuiltEtc)
	android.AssertStringEquals(t, "output file path", "foo.conf", p.outputFilePaths[0].Base())
	android.AssertStringEquals(t, "output file path", "different.name", p.outputFilePaths[1].Base())

	expectedPaths := [...]string{
		"out/soong/target/product/test_device/system/etc/foodir",
		"out/soong/target/product/test_device/system/etc/bardir/extradir",
	}
	android.AssertPathRelativeToTopEquals(t, "install dir", expectedPaths[0], p.installDirPaths[0])
	android.AssertPathRelativeToTopEquals(t, "install dir", expectedPaths[1], p.installDirPaths[1])
}

func TestPrebuiltEtcDstsPlusRelativeInstallPath(t *testing.T) {
	result := prepareForPrebuiltEtcTest.RunTestWithBp(t, `
		prebuilt_etc {
			name: "foo",
			srcs: ["foo.conf", "bar.conf"],
			dsts: ["foodir/foo.conf", "bardir/extradir/different.name"],
			relative_install_path: "somewhere",
		}
	`)

	p := result.Module("foo", "android_arm64_armv8-a").(*PrebuiltEtc)
	android.AssertStringEquals(t, "output file path", "foo.conf", p.outputFilePaths[0].Base())
	android.AssertStringEquals(t, "output file path", "different.name", p.outputFilePaths[1].Base())

	expectedPaths := [...]string{
		"out/soong/target/product/test_device/system/etc/somewhere/foodir",
		"out/soong/target/product/test_device/system/etc/somewhere/bardir/extradir",
	}
	android.AssertPathRelativeToTopEquals(t, "install dir", expectedPaths[0], p.installDirPaths[0])
	android.AssertPathRelativeToTopEquals(t, "install dir", expectedPaths[1], p.installDirPaths[1])
}

func TestPrebuiltEtcDstsSrcGlob(t *testing.T) {
	result := prepareForPrebuiltEtcTest.RunTestWithBp(t, `
		prebuilt_etc {
			name: "foo",
			srcs: ["*.conf"],
			dsts: ["a.conf", "b.conf", "c.conf"],
		}
	`)

	p := result.Module("foo", "android_arm64_armv8-a").(*PrebuiltEtc)
	android.AssertStringEquals(t, "output file path", "a.conf", p.outputFilePaths[0].Base())
	android.AssertStringEquals(t, "output file path", "b.conf", p.outputFilePaths[1].Base())
	android.AssertStringEquals(t, "output file path", "c.conf", p.outputFilePaths[2].Base())
}

func TestPrebuiltEtcDstsSrcGlobDstsTooShort(t *testing.T) {
	prepareForPrebuiltEtcTest.
		ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern("Must have one entry in dsts per source file")).
		RunTestWithBp(t, `
			prebuilt_etc {
				name: "foo",
				srcs: ["*.conf"],
				dsts: ["a.conf", "b.conf"],
			}
		`)
}

func TestPrebuiltEtcDstsSrcGlobDstsTooLong(t *testing.T) {
	prepareForPrebuiltEtcTest.
		ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern("Must have one entry in dsts per source file")).
		RunTestWithBp(t, `
			prebuilt_etc {
				name: "foo",
				srcs: ["*.conf"],
				dsts: ["a.conf", "b.conf", "c.conf", "d.conf"],
			}
		`)
}

func TestPrebuiltEtcCannotDstsWithSrc(t *testing.T) {
	prepareForPrebuiltEtcTest.
		ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern("dsts is set. Must use srcs")).
		RunTestWithBp(t, `
			prebuilt_etc {
				name: "foo.conf",
				src: "foo.conf",
				dsts: ["a.conf"],
			}
		`)
}

func TestPrebuiltEtcCannotDstsWithFilenameFromSrc(t *testing.T) {
	prepareForPrebuiltEtcTest.
		ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern("dsts is set. Cannot set filename_from_src")).
		RunTestWithBp(t, `
			prebuilt_etc {
				name: "foo.conf",
				srcs: ["foo.conf"],
				dsts: ["a.conf"],
				filename_from_src: true,
			}
		`)
}

func TestPrebuiltEtcAndroidMk(t *testing.T) {
	result := prepareForPrebuiltEtcTest.RunTestWithBp(t, `
		prebuilt_etc {
@@ -165,7 +272,7 @@ func TestPrebuiltEtcRelativeInstallPathInstallDirPath(t *testing.T) {

	p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
	expected := "out/soong/target/product/test_device/system/etc/bar"
	android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
	android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPaths[0])
}

func TestPrebuiltEtcCannotSetRelativeInstallPathAndSubDir(t *testing.T) {
@@ -231,7 +338,7 @@ func TestPrebuiltRootInstallDirPath(t *testing.T) {

	p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
	expected := "out/soong/target/product/test_device/system"
	android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
	android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPaths[0])
}

func TestPrebuiltRootInstallDirPathValidate(t *testing.T) {
@@ -256,7 +363,7 @@ func TestPrebuiltAvbInstallDirPath(t *testing.T) {

	p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
	expected := "out/soong/target/product/test_device/root/avb"
	android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
	android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPaths[0])
}

func TestPrebuiltAvdInstallDirPathValidate(t *testing.T) {
@@ -280,7 +387,7 @@ func TestPrebuiltUserShareInstallDirPath(t *testing.T) {

	p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
	expected := "out/soong/target/product/test_device/system/usr/share/bar"
	android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
	android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPaths[0])
}

func TestPrebuiltUserShareHostInstallDirPath(t *testing.T) {
@@ -295,7 +402,7 @@ func TestPrebuiltUserShareHostInstallDirPath(t *testing.T) {
	buildOS := result.Config.BuildOS.String()
	p := result.Module("foo.conf", buildOS+"_common").(*PrebuiltEtc)
	expected := filepath.Join("out/soong/host", result.Config.PrebuiltOS(), "usr", "share", "bar")
	android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
	android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPaths[0])
}

func TestPrebuiltPrebuiltUserHyphenDataInstallDirPath(t *testing.T) {
@@ -309,7 +416,7 @@ func TestPrebuiltPrebuiltUserHyphenDataInstallDirPath(t *testing.T) {

	p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
	expected := "out/soong/target/product/test_device/system/usr/hyphen-data/bar"
	android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
	android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPaths[0])
}

func TestPrebuiltPrebuiltUserKeyLayoutInstallDirPath(t *testing.T) {
@@ -323,7 +430,7 @@ func TestPrebuiltPrebuiltUserKeyLayoutInstallDirPath(t *testing.T) {

	p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
	expected := "out/soong/target/product/test_device/system/usr/keylayout/bar"
	android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
	android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPaths[0])
}

func TestPrebuiltPrebuiltUserKeyCharsInstallDirPath(t *testing.T) {
@@ -337,7 +444,7 @@ func TestPrebuiltPrebuiltUserKeyCharsInstallDirPath(t *testing.T) {

	p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
	expected := "out/soong/target/product/test_device/system/usr/keychars/bar"
	android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
	android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPaths[0])
}

func TestPrebuiltPrebuiltUserIdcInstallDirPath(t *testing.T) {
@@ -351,7 +458,7 @@ func TestPrebuiltPrebuiltUserIdcInstallDirPath(t *testing.T) {

	p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
	expected := "out/soong/target/product/test_device/system/usr/idc/bar"
	android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
	android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPaths[0])
}

func TestPrebuiltFontInstallDirPath(t *testing.T) {
@@ -364,7 +471,7 @@ func TestPrebuiltFontInstallDirPath(t *testing.T) {

	p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
	expected := "out/soong/target/product/test_device/system/fonts"
	android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
	android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPaths[0])
}

func TestPrebuiltOverlayInstallDirPath(t *testing.T) {
@@ -377,7 +484,7 @@ func TestPrebuiltOverlayInstallDirPath(t *testing.T) {

	p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
	expected := "out/soong/target/product/test_device/system/overlay"
	android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
	android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPaths[0])
}

func TestPrebuiltFirmwareDirPath(t *testing.T) {
@@ -409,7 +516,7 @@ func TestPrebuiltFirmwareDirPath(t *testing.T) {
		t.Run(tt.description, func(t *testing.T) {
			result := prepareForPrebuiltEtcTest.RunTestWithBp(t, tt.config)
			p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
			android.AssertPathRelativeToTopEquals(t, "install dir", tt.expectedPath, p.installDirPath)
			android.AssertPathRelativeToTopEquals(t, "install dir", tt.expectedPath, p.installDirPaths[0])
		})
	}
}
@@ -443,7 +550,7 @@ func TestPrebuiltDSPDirPath(t *testing.T) {
		t.Run(tt.description, func(t *testing.T) {
			result := prepareForPrebuiltEtcTest.RunTestWithBp(t, tt.config)
			p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
			android.AssertPathRelativeToTopEquals(t, "install dir", tt.expectedPath, p.installDirPath)
			android.AssertPathRelativeToTopEquals(t, "install dir", tt.expectedPath, p.installDirPaths[0])
		})
	}
}
@@ -477,7 +584,7 @@ func TestPrebuiltRFSADirPath(t *testing.T) {
		t.Run(tt.description, func(t *testing.T) {
			result := prepareForPrebuiltEtcTest.RunTestWithBp(t, tt.config)
			p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
			android.AssertPathRelativeToTopEquals(t, "install dir", tt.expectedPath, p.installDirPath)
			android.AssertPathRelativeToTopEquals(t, "install dir", tt.expectedPath, p.installDirPaths[0])
		})
	}
}