diff options
Diffstat (limited to 'python/python.go')
-rw-r--r-- | python/python.go | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/python/python.go b/python/python.go index 10c11ada0..e2786b8d6 100644 --- a/python/python.go +++ b/python/python.go @@ -20,11 +20,13 @@ import ( "fmt" "path/filepath" "regexp" + "sort" "strings" "android/soong/cc" "github.com/google/blueprint" + "github.com/google/blueprint/depset" "github.com/google/blueprint/proptools" "android/soong/android" @@ -36,6 +38,7 @@ type PythonLibraryInfo struct { SrcsZip android.Path PrecompiledSrcsZip android.Path PkgPath string + BundleSharedLibs android.Paths } var PythonLibraryInfoProvider = blueprint.NewProvider[PythonLibraryInfo]() @@ -105,6 +108,10 @@ type BaseProperties struct { // list of the Python libraries compatible both with Python2 and Python3. Libs []string `android:"arch_variant"` + // TODO: b/403060602 - add unit tests for this property and related code + // list of shared libraries that should be packaged with the python code for this module. + Shared_libs []string `android:"arch_variant"` + Version struct { // Python2-specific properties, including whether Python2 is supported for this module // and version-specific sources, exclusions and dependencies. @@ -158,6 +165,10 @@ type PythonLibraryModule struct { precompiledSrcsZip android.Path sourceProperties android.SourceProperties + + // The shared libraries that should be bundled with the python code for + // any standalone python binaries that depend on this module. + bundleSharedLibs android.Paths } // newModule generates new Python base module @@ -197,6 +208,10 @@ func (p *PythonLibraryModule) getBaseProperties() *BaseProperties { return &p.properties } +func (p *PythonLibraryModule) getBundleSharedLibs() android.Paths { + return p.bundleSharedLibs +} + func (p *PythonLibraryModule) init() android.Module { p.AddProperties(&p.properties, &p.protoProperties, &p.sourceProperties) android.InitAndroidArchModule(p, p.hod, p.multilib) @@ -224,6 +239,7 @@ type installDependencyTag struct { var ( pythonLibTag = dependencyTag{name: "pythonLib"} javaDataTag = dependencyTag{name: "javaData"} + sharedLibTag = dependencyTag{name: "sharedLib"} // The python interpreter, with soong module name "py3-launcher" or "py3-launcher-autorun". launcherTag = dependencyTag{name: "launcher"} launcherSharedLibTag = installDependencyTag{name: "launcherSharedLib"} @@ -288,6 +304,12 @@ func (p *PythonLibraryModule) DepsMutator(ctx android.BottomUpMutatorContext) { javaDataVariation := []blueprint.Variation{{"arch", android.Common.String()}} ctx.AddVariationDependencies(javaDataVariation, javaDataTag, p.properties.Java_data...) + if ctx.Host() { + ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), sharedLibTag, p.properties.Shared_libs...) + } else if len(p.properties.Shared_libs) > 0 { + ctx.PropertyErrorf("shared_libs", "shared_libs is not supported for device builds") + } + p.AddDepsOnPythonLauncherAndStdlib(ctx, hostStdLibTag, hostLauncherTag, hostlauncherSharedLibTag, false, ctx.Config().BuildOSTarget) } @@ -377,6 +399,25 @@ func (p *PythonLibraryModule) GenerateAndroidBuildActions(ctx android.ModuleCont expandedData = append(expandedData, android.OutputFilesForModule(ctx, javaData, "")...) } + var directImplementationDeps android.Paths + var transitiveImplementationDeps []depset.DepSet[android.Path] + ctx.VisitDirectDepsProxyWithTag(sharedLibTag, func(dep android.ModuleProxy) { + sharedLibInfo, _ := android.OtherModuleProvider(ctx, dep, cc.SharedLibraryInfoProvider) + if sharedLibInfo.SharedLibrary != nil { + expandedData = append(expandedData, android.OutputFilesForModule(ctx, dep, "")...) + directImplementationDeps = append(directImplementationDeps, android.OutputFilesForModule(ctx, dep, "")...) + if info, ok := android.OtherModuleProvider(ctx, dep, cc.ImplementationDepInfoProvider); ok { + transitiveImplementationDeps = append(transitiveImplementationDeps, info.ImplementationDeps) + p.bundleSharedLibs = append(p.bundleSharedLibs, info.ImplementationDeps.ToList()...) + } + } else { + ctx.PropertyErrorf("shared_libs", "%q of type %q is not supported", dep.Name(), ctx.OtherModuleType(dep)) + } + }) + android.SetProvider(ctx, cc.ImplementationDepInfoProvider, &cc.ImplementationDepInfo{ + ImplementationDeps: depset.New(depset.PREORDER, directImplementationDeps, transitiveImplementationDeps), + }) + // Validate pkg_path property pkgPath := String(p.properties.Pkg_path) if pkgPath != "" { @@ -408,6 +449,7 @@ func (p *PythonLibraryModule) GenerateAndroidBuildActions(ctx android.ModuleCont SrcsZip: p.getSrcsZip(), PkgPath: p.getPkgPath(), PrecompiledSrcsZip: p.getPrecompiledSrcsZip(), + BundleSharedLibs: p.getBundleSharedLibs(), }) } @@ -684,6 +726,57 @@ func (p *PythonLibraryModule) collectPathsFromTransitiveDeps(ctx android.ModuleC return result } +func (p *PythonLibraryModule) collectSharedLibDeps(ctx android.ModuleContext) android.Paths { + seen := make(map[android.Module]bool) + + var result android.Paths + + ctx.WalkDepsProxy(func(child, _ android.ModuleProxy) bool { + // we only collect dependencies tagged as python library deps + if ctx.OtherModuleDependencyTag(child) != pythonLibTag { + return false + } + if seen[child] { + return false + } + seen[child] = true + dep, isLibrary := android.OtherModuleProvider(ctx, child, PythonLibraryInfoProvider) + if isLibrary { + result = append(result, dep.BundleSharedLibs...) + } + return true + }) + return result +} + +func (p *PythonLibraryModule) zipSharedLibs(ctx android.ModuleContext, bundleSharedLibs android.Paths) android.Path { + // sort the paths to keep the output deterministic + sort.Slice(bundleSharedLibs, func(i, j int) bool { + return bundleSharedLibs[i].String() < bundleSharedLibs[j].String() + }) + + parArgs := []string{"-symlinks=false", "-P lib64"} + paths := android.Paths{} + for _, path := range bundleSharedLibs { + // specify relative root of file in following -f arguments + parArgs = append(parArgs, `-C `+filepath.Dir(path.String())) + parArgs = append(parArgs, `-f `+path.String()) + paths = append(paths, path) + } + srcsZip := android.PathForModuleOut(ctx, ctx.ModuleName()+".sharedlibs.srcszip") + ctx.Build(pctx, android.BuildParams{ + Rule: zip, + Description: "bundle shared libraries for python binary", + Output: srcsZip, + Implicits: paths, + Args: map[string]string{ + "args": strings.Join(parArgs, " "), + }, + }) + return srcsZip +} + + // chckForDuplicateOutputPath checks whether outputPath has already been included in map m, which // would result in two files being placed in the same location. // If there is a duplicate path, an error is thrown and true is returned |