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

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

Merge "Remove timestamp based filelist file for tracking Python dependencies"

parents 0b9be363 1db85407
Loading
Loading
Loading
Loading
+24 −3
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ var (
	zipsToNotStrip   = make(zipsToNotStripSet)
	stripDirEntries  = flag.Bool("D", false, "strip directory entries from the output zip file")
	manifest         = flag.String("m", "", "manifest file to insert in jar")
	pyMain           = flag.String("pm", "", "__main__.py file to insert in par")
	entrypoint       = flag.String("e", "", "par entrypoint file to insert in par")
	ignoreDuplicates = flag.Bool("ignore-duplicates", false, "take each entry from the first zip it exists in and don't warn")
)
@@ -75,7 +76,7 @@ func init() {

func main() {
	flag.Usage = func() {
		fmt.Fprintln(os.Stderr, "usage: merge_zips [-jpsD] [-m manifest] [-e entrypoint] output [inputs...]")
		fmt.Fprintln(os.Stderr, "usage: merge_zips [-jpsD] [-m manifest] [-e entrypoint] [-pm __main__.py] output [inputs...]")
		flag.PrintDefaults()
	}

@@ -125,8 +126,12 @@ func main() {
		log.Fatal(errors.New("must specify -p when specifying a entrypoint via -e"))
	}

	if *pyMain != "" && !*emulatePar {
		log.Fatal(errors.New("must specify -p when specifying a Python __main__.py via -pm"))
	}

	// do merge
	err = mergeZips(readers, writer, *manifest, *entrypoint, *sortEntries, *emulateJar, *emulatePar,
	err = mergeZips(readers, writer, *manifest, *entrypoint, *pyMain, *sortEntries, *emulateJar, *emulatePar,
		*stripDirEntries, *ignoreDuplicates)
	if err != nil {
		log.Fatal(err)
@@ -218,7 +223,7 @@ type fileMapping struct {
	source zipSource
}

func mergeZips(readers []namedZipReader, writer *zip.Writer, manifest, entrypoint string,
func mergeZips(readers []namedZipReader, writer *zip.Writer, manifest, entrypoint, pyMain string,
	sortEntries, emulateJar, emulatePar, stripDirEntries, ignoreDuplicates bool) error {

	sourceByDest := make(map[string]zipSource, 0)
@@ -268,6 +273,22 @@ func mergeZips(readers []namedZipReader, writer *zip.Writer, manifest, entrypoin
		addMapping("entry_point.txt", fileSource)
	}

	if pyMain != "" {
		buf, err := ioutil.ReadFile(pyMain)
		if err != nil {
			return err
		}
		fh := &zip.FileHeader{
			Name:               "__main__.py",
			Method:             zip.Store,
			UncompressedSize64: uint64(len(buf)),
		}
		fh.SetMode(0700)
		fh.SetModTime(jar.DefaultTime)
		fileSource := bufferEntry{fh, buf}
		addMapping("__main__.py", fileSource)
	}

	if emulatePar {
		// the runfiles packages needs to be populated with "__init__.py".
		newPyPkgs := []string{}
+14 −88
Original line number Diff line number Diff line
@@ -18,8 +18,6 @@ package python

import (
	"fmt"
	"path/filepath"
	"strings"

	"android/soong/android"
)
@@ -80,89 +78,44 @@ func (binary *binaryDecorator) bootstrapperProps() []interface{} {
	return []interface{}{&binary.binaryProperties}
}

func (binary *binaryDecorator) bootstrap(ctx android.ModuleContext, actual_version string,
	embedded_launcher bool, srcsPathMappings []pathMapping, parSpec parSpec,
	depsPyRunfiles []string, depsParSpecs []parSpec) android.OptionalPath {
	// no Python source file for compiling .par file.
	if len(srcsPathMappings) == 0 {
		return android.OptionalPath{}
	}

	// the runfiles packages needs to be populated with "__init__.py".
	newPyPkgs := []string{}
	// the set to de-duplicate the new Python packages above.
	newPyPkgSet := make(map[string]bool)
	// the runfiles dirs have been treated as packages.
	existingPyPkgSet := make(map[string]bool)

	wholePyRunfiles := []string{}
	for _, path := range srcsPathMappings {
		wholePyRunfiles = append(wholePyRunfiles, path.dest)
	}
	wholePyRunfiles = append(wholePyRunfiles, depsPyRunfiles...)

	// find all the runfiles dirs which have been treated as packages.
	for _, path := range wholePyRunfiles {
		if filepath.Base(path) != initFileName {
			continue
		}
		existingPyPkg := PathBeforeLastSlash(path)
		if _, found := existingPyPkgSet[existingPyPkg]; found {
			panic(fmt.Errorf("found init file path duplicates: %q for module: %q.",
				path, ctx.ModuleName()))
		} else {
			existingPyPkgSet[existingPyPkg] = true
		}
		parentPath := PathBeforeLastSlash(existingPyPkg)
		populateNewPyPkgs(parentPath, existingPyPkgSet, newPyPkgSet, &newPyPkgs)
	}

	// create new packages under runfiles tree.
	for _, path := range wholePyRunfiles {
		if filepath.Base(path) == initFileName {
			continue
		}
		parentPath := PathBeforeLastSlash(path)
		populateNewPyPkgs(parentPath, existingPyPkgSet, newPyPkgSet, &newPyPkgs)
	}
func (binary *binaryDecorator) bootstrap(ctx android.ModuleContext, actualVersion string,
	embeddedLauncher bool, srcsPathMappings []pathMapping, srcsZip android.Path,
	depsSrcsZips android.Paths) android.OptionalPath {

	main := binary.getPyMainFile(ctx, srcsPathMappings)
	if main == "" {
		return android.OptionalPath{}
	}

	var launcher_path android.Path
	if embedded_launcher {
	var launcherPath android.Path
	if embeddedLauncher {
		ctx.VisitDirectDepsWithTag(launcherTag, func(m android.Module) {
			if provider, ok := m.(IntermPathProvider); ok {
				if launcher_path != nil {
				if launcherPath != nil {
					panic(fmt.Errorf("launcher path was found before: %q",
						launcher_path))
						launcherPath))
				}
				launcher_path = provider.IntermPathForModuleOut().Path()
				launcherPath = provider.IntermPathForModuleOut().Path()
			}
		})
	}

	binFile := registerBuildActionForParFile(ctx, embedded_launcher, launcher_path,
		binary.getHostInterpreterName(ctx, actual_version),
		main, binary.getStem(ctx), newPyPkgs, append(depsParSpecs, parSpec))
	binFile := registerBuildActionForParFile(ctx, embeddedLauncher, launcherPath,
		binary.getHostInterpreterName(ctx, actualVersion),
		main, binary.getStem(ctx), append(android.Paths{srcsZip}, depsSrcsZips...))

	return android.OptionalPathForPath(binFile)
}

// get host interpreter name.
func (binary *binaryDecorator) getHostInterpreterName(ctx android.ModuleContext,
	actual_version string) string {
	actualVersion string) string {
	var interp string
	switch actual_version {
	switch actualVersion {
	case pyVersion2:
		interp = "python2.7"
	case pyVersion3:
		interp = "python3"
	default:
		panic(fmt.Errorf("unknown Python actualVersion: %q for module: %q.",
			actual_version, ctx.ModuleName()))
			actualVersion, ctx.ModuleName()))
	}

	return interp
@@ -196,30 +149,3 @@ func (binary *binaryDecorator) getStem(ctx android.ModuleContext) string {

	return stem + String(binary.binaryProperties.Suffix)
}

// Sets the given directory and all its ancestor directories as Python packages.
func populateNewPyPkgs(pkgPath string, existingPyPkgSet,
	newPyPkgSet map[string]bool, newPyPkgs *[]string) {
	for pkgPath != "" {
		if _, found := existingPyPkgSet[pkgPath]; found {
			break
		}
		if _, found := newPyPkgSet[pkgPath]; !found {
			newPyPkgSet[pkgPath] = true
			*newPyPkgs = append(*newPyPkgs, pkgPath)
			// Gets its ancestor directory by trimming last slash.
			pkgPath = PathBeforeLastSlash(pkgPath)
		} else {
			break
		}
	}
}

// filepath.Dir("abc") -> "." and filepath.Dir("/abc") -> "/". However,
// the PathBeforeLastSlash() will return "" for both cases above.
func PathBeforeLastSlash(path string) string {
	if idx := strings.LastIndex(path, "/"); idx != -1 {
		return path[:idx]
	}
	return ""
}
+42 −105
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@ package python
// This file contains Ninja build actions for building Python program.

import (
	"fmt"
	"strings"

	"android/soong/android"
@@ -29,25 +28,30 @@ import (
var (
	pctx = android.NewPackageContext("android/soong/python")

	host_par = pctx.AndroidStaticRule("host_par",
	zip = pctx.AndroidStaticRule("zip",
		blueprint.RuleParams{
			Command: `touch $initFile && ` +
				`sed -e 's/%interpreter%/$interp/g' -e 's/%main%/$main/g' $template > $stub && ` +
				`$parCmd -o $parFile $parArgs && echo '#!/usr/bin/env python' | cat - $parFile > $out && ` +
				`chmod +x $out && (rm -f $initFile; rm -f $stub; rm -f $parFile)`,
			CommandDeps: []string{"$parCmd", "$template"},
			Command:     `$parCmd -o $out $args`,
			CommandDeps: []string{"$parCmd"},
		},
		"initFile", "interp", "main", "template", "stub", "parCmd", "parFile", "parArgs")
		"args")

	embedded_par = pctx.AndroidStaticRule("embedded_par",
	hostPar = pctx.AndroidStaticRule("hostPar",
		blueprint.RuleParams{
			Command: `touch $initFile && ` +
				`echo '$main' > $entry_point && ` +
				`$parCmd -o $parFile $parArgs && cat $launcher | cat - $parFile > $out && ` +
				`chmod +x $out && (rm -f $initFile; rm -f $entry_point; rm -f $parFile)`,
			CommandDeps: []string{"$parCmd"},
			Command: `sed -e 's/%interpreter%/$interp/g' -e 's/%main%/$main/g' $template > $stub && ` +
				`$mergeParCmd -p -pm $stub $mergedZip $srcsZips && echo '#!/usr/bin/env python' | cat - $mergedZip > $out && ` +
				`chmod +x $out && (rm -f $stub; rm -f $mergedZip)`,
			CommandDeps: []string{"$mergeParCmd"},
		},
		"interp", "main", "template", "stub", "mergedZip", "srcsZips")

	embeddedPar = pctx.AndroidStaticRule("embeddedPar",
		blueprint.RuleParams{
			Command: `echo '$main' > $entryPoint &&` +
				`$mergeParCmd -p -e $entryPoint $mergedZip $srcsZips && cat $launcher | cat - $mergedZip > $out && ` +
				`chmod +x $out && (rm -f $entryPoint; rm -f $mergedZip)`,
			CommandDeps: []string{"$mergeParCmd"},
		},
		"initFile", "main", "entry_point", "parCmd", "parFile", "parArgs", "launcher")
		"main", "entryPoint", "mergedZip", "srcsZips", "launcher")
)

func init() {
@@ -55,98 +59,36 @@ func init() {
	pctx.Import("android/soong/common")

	pctx.HostBinToolVariable("parCmd", "soong_zip")
	pctx.HostBinToolVariable("mergeParCmd", "merge_zips")
}

type fileListSpec struct {
	fileList     android.Path
	relativeRoot string
}

type parSpec struct {
	rootPrefix string

	fileListSpecs []fileListSpec
}
func registerBuildActionForParFile(ctx android.ModuleContext, embeddedLauncher bool,
	launcherPath android.Path, interpreter, main, binName string,
	srcsZips android.Paths) android.Path {

func (p parSpec) soongParArgs() string {
	ret := `-P ` + p.rootPrefix

	for _, spec := range p.fileListSpecs {
		ret += ` -C ` + spec.relativeRoot + ` -l ` + spec.fileList.String()
	}

	return ret
}

func registerBuildActionForModuleFileList(ctx android.ModuleContext,
	name string, files android.Paths) android.Path {
	fileList := android.PathForModuleOut(ctx, name+".list")

	content := []string{}
	for _, file := range files {
		content = append(content, file.String())
	}

	ctx.Build(pctx, android.BuildParams{
		Rule:        android.WriteFile,
		Description: "generate " + fileList.Rel(),
		Output:      fileList,
		Implicits:   files,
		Args: map[string]string{
			"content": strings.Join(content, `\n`),
		},
	})

	return fileList
}

func registerBuildActionForParFile(ctx android.ModuleContext, embedded_launcher bool,
	launcher_path android.Path, interpreter, main, binName string,
	newPyPkgs []string, parSpecs []parSpec) android.Path {

	// .intermediate output path for __init__.py
	initFile := android.PathForModuleOut(ctx, initFileName).String()

	// .intermediate output path for par file.
	parFile := android.PathForModuleOut(ctx, binName+parFileExt)
	// .intermediate output path for merged zip file.
	mergedZip := android.PathForModuleOut(ctx, binName+".mergedzip")

	// .intermediate output path for bin executable.
	binFile := android.PathForModuleOut(ctx, binName)

	// implicit dependency for parFile build action.
	implicits := android.Paths{}
	for _, p := range parSpecs {
		for _, f := range p.fileListSpecs {
			implicits = append(implicits, f.fileList)
		}
	}

	parArgs := []string{}
	parArgs = append(parArgs, `-P "" `+`-C `+strings.TrimSuffix(initFile, initFileName)+` -f `+initFile)
	for _, pkg := range newPyPkgs {
		parArgs = append(parArgs, `-P `+pkg+` -f `+initFile)
	}
	for _, p := range parSpecs {
		parArgs = append(parArgs, p.soongParArgs())
	}
	implicits := srcsZips

	if !embedded_launcher {
	if !embeddedLauncher {
		// the path of stub_template_host.txt from source tree.
		template := android.PathForSource(ctx, stubTemplateHost)
		implicits = append(implicits, template)

		// intermediate output path for __main__.py
		stub := android.PathForModuleOut(ctx, mainFileName).String()

		// added stub file to the soong_zip args.
		parArgs = append(parArgs, `-P "" `+`-C `+strings.TrimSuffix(stub, mainFileName)+` -f `+stub)

		ctx.Build(pctx, android.BuildParams{
			Rule:        host_par,
			Rule:        hostPar,
			Description: "host python archive",
			Output:      binFile,
			Implicits:   implicits,
			Args: map[string]string{
				"initFile": initFile,
				"interp": strings.Replace(interpreter, "/", `\/`, -1),
				// we need remove "runfiles/" suffix since stub script starts
				// searching for main file in each sub-dir of "runfiles" directory tree.
@@ -154,33 +96,28 @@ func registerBuildActionForParFile(ctx android.ModuleContext, embedded_launcher
					"/", `\/`, -1),
				"template":  template.String(),
				"stub":      stub,
				"parFile":  parFile.String(),
				"parArgs":  strings.Join(parArgs, " "),
				"mergedZip": mergedZip.String(),
				"srcsZips":  strings.Join(srcsZips.Strings(), " "),
			},
		})
	} else {
		// added launcher_path to the implicits Ninja dependencies.
		implicits = append(implicits, launcher_path)
		// added launcherPath to the implicits Ninja dependencies.
		implicits = append(implicits, launcherPath)

		// .intermediate output path for entry_point.txt
		entryPoint := android.PathForModuleOut(ctx, entryPointFile).String()

		// added entry_point file to the soong_zip args.
		parArgs = append(parArgs, `-P "" `+`-C `+fmt.Sprintf(
			"%q", strings.TrimSuffix(entryPoint, entryPointFile))+` -f `+entryPoint)

		ctx.Build(pctx, android.BuildParams{
			Rule:        embedded_par,
			Rule:        embeddedPar,
			Description: "embedded python archive",
			Output:      binFile,
			Implicits:   implicits,
			Args: map[string]string{
				"initFile":    initFile,
				"main":       main,
				"entry_point": entryPoint,
				"parFile":     parFile.String(),
				"parArgs":     strings.Join(parArgs, " "),
				"launcher":    launcher_path.String(),
				"entryPoint": entryPoint,
				"mergedZip":  mergedZip.String(),
				"srcsZips":   strings.Join(srcsZips.Strings(), " "),
				"launcher":   launcherPath.String(),
			},
		})
	}
+51 −49
Original line number Diff line number Diff line
@@ -132,18 +132,15 @@ type Module struct {
	// pathMapping: <dest: runfile_path, src: source_path>
	dataPathMappings []pathMapping

	// soong_zip arguments of all its dependencies.
	depsParSpecs []parSpec
	// the zip filepath for zipping current module source/data files.
	srcsZip android.Path

	// Python runfiles paths of all its dependencies.
	depsPyRunfiles []string
	// dependency modules' zip filepath for zipping current module source/data files.
	depsSrcsZips android.Paths

	// (.intermediate) module output path as installation source.
	installSource android.OptionalPath

	// the soong_zip arguments for zipping current module source/data files.
	parSpec parSpec

	subAndroidMkOnce map[subAndroidMkProvider]bool
}

@@ -156,9 +153,9 @@ func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Mo

type bootstrapper interface {
	bootstrapperProps() []interface{}
	bootstrap(ctx android.ModuleContext, Actual_version string, embedded_launcher bool,
		srcsPathMappings []pathMapping, parSpec parSpec,
		depsPyRunfiles []string, depsParSpecs []parSpec) android.OptionalPath
	bootstrap(ctx android.ModuleContext, ActualVersion string, embeddedLauncher bool,
		srcsPathMappings []pathMapping, srcsZip android.Path,
		depsSrcsZips android.Paths) android.OptionalPath
}

type installer interface {
@@ -168,7 +165,7 @@ type installer interface {
type PythonDependency interface {
	GetSrcsPathMappings() []pathMapping
	GetDataPathMappings() []pathMapping
	GetParSpec() parSpec
	GetSrcsZip() android.Path
}

func (p *Module) GetSrcsPathMappings() []pathMapping {
@@ -179,8 +176,8 @@ func (p *Module) GetDataPathMappings() []pathMapping {
	return p.dataPathMappings
}

func (p *Module) GetParSpec() parSpec {
	return p.parSpec
func (p *Module) GetSrcsZip() android.Path {
	return p.srcsZip
}

var _ PythonDependency = (*Module)(nil)
@@ -339,13 +336,12 @@ func (p *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	if p.bootstrapper != nil {
		// TODO(nanzhang): Since embedded launcher is not supported for Python3 for now,
		// so we initialize "embedded_launcher" to false.
		embedded_launcher := false
		embeddedLauncher := false
		if p.properties.Actual_version == pyVersion2 {
			embedded_launcher = p.isEmbeddedLauncherEnabled(pyVersion2)
			embeddedLauncher = p.isEmbeddedLauncherEnabled(pyVersion2)
		}
		p.installSource = p.bootstrapper.bootstrap(ctx, p.properties.Actual_version,
			embedded_launcher, p.srcsPathMappings, p.parSpec, p.depsPyRunfiles,
			p.depsParSpecs)
			embeddedLauncher, p.srcsPathMappings, p.srcsZip, p.depsSrcsZips)
	}

	if p.installer != nil && p.installSource.Valid() {
@@ -378,11 +374,11 @@ func (p *Module) GeneratePythonBuildActions(ctx android.ModuleContext) {
	expandedData := ctx.ExpandSources(p.properties.Data, nil)

	// sanitize pkg_path.
	pkg_path := String(p.properties.Pkg_path)
	if pkg_path != "" {
		pkg_path = filepath.Clean(String(p.properties.Pkg_path))
		if pkg_path == ".." || strings.HasPrefix(pkg_path, "../") ||
			strings.HasPrefix(pkg_path, "/") {
	pkgPath := String(p.properties.Pkg_path)
	if pkgPath != "" {
		pkgPath = filepath.Clean(String(p.properties.Pkg_path))
		if pkgPath == ".." || strings.HasPrefix(pkgPath, "../") ||
			strings.HasPrefix(pkgPath, "/") {
			ctx.PropertyErrorf("pkg_path",
				"%q must be a relative path contained in par file.",
				String(p.properties.Pkg_path))
@@ -390,31 +386,31 @@ func (p *Module) GeneratePythonBuildActions(ctx android.ModuleContext) {
		}
		if p.properties.Is_internal != nil && *p.properties.Is_internal {
			// pkg_path starts from "internal/" implicitly.
			pkg_path = filepath.Join(internal, pkg_path)
			pkgPath = filepath.Join(internal, pkgPath)
		} else {
			// pkg_path starts from "runfiles/" implicitly.
			pkg_path = filepath.Join(runFiles, pkg_path)
			pkgPath = filepath.Join(runFiles, pkgPath)
		}
	} else {
		if p.properties.Is_internal != nil && *p.properties.Is_internal {
			// pkg_path starts from "runfiles/" implicitly.
			pkg_path = internal
			pkgPath = internal
		} else {
			// pkg_path starts from "runfiles/" implicitly.
			pkg_path = runFiles
			pkgPath = runFiles
		}
	}

	p.genModulePathMappings(ctx, pkg_path, expandedSrcs, expandedData)

	p.parSpec = p.dumpFileList(ctx, pkg_path)
	p.genModulePathMappings(ctx, pkgPath, expandedSrcs, expandedData)

	p.uniqWholeRunfilesTree(ctx)

	p.srcsZip = p.createSrcsZip(ctx, pkgPath)
}

// generate current module unique pathMappings: <dest: runfiles_path, src: source_path>
// for python/data files.
func (p *Module) genModulePathMappings(ctx android.ModuleContext, pkg_path string,
func (p *Module) genModulePathMappings(ctx android.ModuleContext, pkgPath string,
	expandedSrcs, expandedData android.Paths) {
	// fetch <runfiles_path, source_path> pairs from "src" and "data" properties to
	// check duplicates.
@@ -426,7 +422,7 @@ func (p *Module) genModulePathMappings(ctx android.ModuleContext, pkg_path strin
			ctx.PropertyErrorf("srcs", "found non (.py) file: %q!", s.String())
			continue
		}
		runfilesPath := filepath.Join(pkg_path, s.Rel())
		runfilesPath := filepath.Join(pkgPath, s.Rel())
		identifiers := strings.Split(strings.TrimSuffix(runfilesPath, pyExt), "/")
		for _, token := range identifiers {
			if !pyIdentifierRegexp.MatchString(token) {
@@ -445,7 +441,7 @@ func (p *Module) genModulePathMappings(ctx android.ModuleContext, pkg_path strin
			ctx.PropertyErrorf("data", "found (.py) file: %q!", d.String())
			continue
		}
		runfilesPath := filepath.Join(pkg_path, d.Rel())
		runfilesPath := filepath.Join(pkgPath, d.Rel())
		if fillInMap(ctx, destToPyData, runfilesPath, d.String(), p.Name(), p.Name()) {
			p.dataPathMappings = append(p.dataPathMappings,
				pathMapping{dest: runfilesPath, src: d})
@@ -454,12 +450,9 @@ func (p *Module) genModulePathMappings(ctx android.ModuleContext, pkg_path strin

}

// register build actions to dump filelist to disk.
func (p *Module) dumpFileList(ctx android.ModuleContext, pkg_path string) parSpec {
// register build actions to zip current module's sources.
func (p *Module) createSrcsZip(ctx android.ModuleContext, pkgPath string) android.Path {
	relativeRootMap := make(map[string]android.Paths)
	// the soong_zip params in order to pack current module's Python/data files.
	ret := parSpec{rootPrefix: pkg_path}

	pathMappings := append(p.srcsPathMappings, p.dataPathMappings...)

	// "srcs" or "data" properties may have filegroup so it might happen that
@@ -482,15 +475,29 @@ func (p *Module) dumpFileList(ctx android.ModuleContext, pkg_path string) parSpe
	}
	sort.Strings(keys)

	parArgs := []string{}
	parArgs = append(parArgs, `-P `+pkgPath)
	implicits := android.Paths{}
	for _, k := range keys {
		// use relative root as filelist name.
		fileListPath := registerBuildActionForModuleFileList(
			ctx, strings.Replace(k, "/", "_", -1), relativeRootMap[k])
		ret.fileListSpecs = append(ret.fileListSpecs,
			fileListSpec{fileList: fileListPath, relativeRoot: k})
	}
		parArgs = append(parArgs, `-C `+k)
		for _, path := range relativeRootMap[k] {
			parArgs = append(parArgs, `-f `+path.String())
			implicits = append(implicits, path)
		}
	}

	srcsZip := android.PathForModuleOut(ctx, ctx.ModuleName()+".zip")
	ctx.Build(pctx, android.BuildParams{
		Rule:        zip,
		Description: "python library archive",
		Output:      srcsZip,
		Implicits:   implicits,
		Args: map[string]string{
			"args": strings.Join(parArgs, " "),
		},
	})

	return ret
	return srcsZip
}

func isPythonLibModule(module blueprint.Module) bool {
@@ -537,9 +544,6 @@ func (p *Module) uniqWholeRunfilesTree(ctx android.ModuleContext) {
					ctx.OtherModuleName(module)) {
					continue
				}
				// binary needs the Python runfiles paths from all its
				// dependencies to fill __init__.py in each runfiles dir.
				p.depsPyRunfiles = append(p.depsPyRunfiles, path.dest)
			}
			data := dep.GetDataPathMappings()
			for _, path := range data {
@@ -547,9 +551,7 @@ func (p *Module) uniqWholeRunfilesTree(ctx android.ModuleContext) {
					path.dest, path.src.String(), ctx.ModuleName(),
					ctx.OtherModuleName(module))
			}
			// binary needs the soong_zip arguments from all its
			// dependencies to generate executable par file.
			p.depsParSpecs = append(p.depsParSpecs, dep.GetParSpec())
			p.depsSrcsZips = append(p.depsSrcsZips, dep.GetSrcsZip())
		}
	})
}
+26 −42
Original line number Diff line number Diff line
@@ -32,9 +32,8 @@ type pyModule struct {
	name          string
	actualVersion string
	pyRunfiles    []string
	depsPyRunfiles []string
	parSpec        string
	depsParSpecs   []string
	srcsZip       string
	depsSrcsZips  []string
}

var (
@@ -313,14 +312,10 @@ var (
						"runfiles/e/default_py3.py",
						"runfiles/e/file4.py",
					},
					depsPyRunfiles: []string{
						"runfiles/a/b/file1.py",
						"runfiles/c/d/file2.py",
					},
					parSpec: "-P runfiles/e -C dir/ -l @prefix@/.intermediates/dir/bin/PY3/dir_.list",
					depsParSpecs: []string{
						"-P runfiles/a/b -C dir/ -l @prefix@/.intermediates/dir/lib5/PY3/dir_.list",
						"-P runfiles/c/d -C dir/ -l @prefix@/.intermediates/dir/lib6/PY3/dir_.list",
					srcsZip: "@prefix@/.intermediates/dir/bin/PY3/bin.zip",
					depsSrcsZips: []string{
						"@prefix@/.intermediates/dir/lib5/PY3/lib5.zip",
						"@prefix@/.intermediates/dir/lib6/PY3/lib6.zip",
					},
				},
			},
@@ -356,8 +351,9 @@ func TestPythonModule(t *testing.T) {
					testErrs = append(testErrs,
						expectModule(t, ctx, buildDir, e.name,
							e.actualVersion,
							e.pyRunfiles, e.depsPyRunfiles,
							e.parSpec, e.depsParSpecs)...)
							e.srcsZip,
							e.pyRunfiles,
							e.depsSrcsZips)...)
				}
			}
			fail(t, testErrs)
@@ -388,9 +384,8 @@ func expectErrors(t *testing.T, actErrs []error, expErrs []string) (testErrs []e
	return
}

func expectModule(t *testing.T, ctx *android.TestContext, buildDir, name, variant string,
	expPyRunfiles, expDepsPyRunfiles []string,
	expParSpec string, expDepsParSpecs []string) (testErrs []error) {
func expectModule(t *testing.T, ctx *android.TestContext, buildDir, name, variant, expectedSrcsZip string,
	expectedPyRunfiles, expectedDepsSrcsZips []string) (testErrs []error) {
	module := ctx.ModuleForTests(name, variant)

	base, baseOk := module.Module().(*Module)
@@ -398,47 +393,36 @@ func expectModule(t *testing.T, ctx *android.TestContext, buildDir, name, varian
		t.Fatalf("%s is not Python module!", name)
	}

	actPyRunfiles := []string{}
	actualPyRunfiles := []string{}
	for _, path := range base.srcsPathMappings {
		actPyRunfiles = append(actPyRunfiles, path.dest)
		actualPyRunfiles = append(actualPyRunfiles, path.dest)
	}

	if !reflect.DeepEqual(actPyRunfiles, expPyRunfiles) {
	if !reflect.DeepEqual(actualPyRunfiles, expectedPyRunfiles) {
		testErrs = append(testErrs, errors.New(fmt.Sprintf(
			`binary "%s" variant "%s" has unexpected pyRunfiles: %q!`,
			base.Name(),
			base.properties.Actual_version,
			actPyRunfiles)))
			actualPyRunfiles)))
	}

	if !reflect.DeepEqual(base.depsPyRunfiles, expDepsPyRunfiles) {
	if base.srcsZip.String() != strings.Replace(expectedSrcsZip, "@prefix@", buildDir, 1) {
		testErrs = append(testErrs, errors.New(fmt.Sprintf(
			`binary "%s" variant "%s" has unexpected depsPyRunfiles: %q!`,
			`binary "%s" variant "%s" has unexpected srcsZip: %q!`,
			base.Name(),
			base.properties.Actual_version,
			base.depsPyRunfiles)))
			base.srcsZip)))
	}

	if base.parSpec.soongParArgs() != strings.Replace(expParSpec, "@prefix@", buildDir, 1) {
		testErrs = append(testErrs, errors.New(fmt.Sprintf(
			`binary "%s" variant "%s" has unexpected parSpec: %q!`,
			base.Name(),
			base.properties.Actual_version,
			base.parSpec.soongParArgs())))
	for i, _ := range expectedDepsSrcsZips {
		expectedDepsSrcsZips[i] = strings.Replace(expectedDepsSrcsZips[i], "@prefix@", buildDir, 1)
	}

	actDepsParSpecs := []string{}
	for i, p := range base.depsParSpecs {
		actDepsParSpecs = append(actDepsParSpecs, p.soongParArgs())
		expDepsParSpecs[i] = strings.Replace(expDepsParSpecs[i], "@prefix@", buildDir, 1)
	}

	if !reflect.DeepEqual(actDepsParSpecs, expDepsParSpecs) {
	if !reflect.DeepEqual(base.depsSrcsZips.Strings(), expectedDepsSrcsZips) {
		testErrs = append(testErrs, errors.New(fmt.Sprintf(
			`binary "%s" variant "%s" has unexpected depsParSpecs: %q!`,
			`binary "%s" variant "%s" has unexpected depsSrcsZips: %q!`,
			base.Name(),
			base.properties.Actual_version,
			actDepsParSpecs)))
			base.depsSrcsZips)))
	}

	return