def _MergeJarInfoFiles(output, inputs): """Merge several .jar.info files to generate an .apk.jar.info. Args: output: output file path. inputs: List of .jar.info or .jar files. """ info_data = dict() for path in inputs: # For non-prebuilts: .jar.info files are written by compile_java.py and map # .class files to .java source paths. # # For prebuilts: No .jar.info file exists, we scan the .jar files here and # map .class files to the .jar. # # For .aar files: We look for a "source.info" file in the containing # directory in order to map classes back to the .aar (rather than mapping # them to the extracted .jar file). if path.endswith('.info'): info_data.update(jar_info_utils.ParseJarInfoFile(path)) else: attributed_path = path if not path.startswith('..'): parent_path = os.path.dirname(path) # See if it's an sub-jar within the .aar. if os.path.basename(parent_path) == 'libs': parent_path = os.path.dirname(parent_path) aar_source_info_path = os.path.join(parent_path, 'source.info') # source.info files exist only for jars from android_aar_prebuilt(). # E.g. Could have an java_prebuilt() pointing to a generated .jar. if os.path.exists(aar_source_info_path): attributed_path = jar_info_utils.ReadAarSourceInfo( aar_source_info_path) with zipfile.ZipFile(path) as zip_info: for name in zip_info.namelist(): fully_qualified_name = _FullJavaNameFromClassFilePath(name) if fully_qualified_name: info_data[fully_qualified_name] = _TransformAarPaths( '{}/{}'.format(attributed_path, name)) # only_if_changed=False since no build rules depend on this as an input. with build_utils.AtomicOutput(output, only_if_changed=False) as f: jar_info_utils.WriteJarInfoFile(f, info_data)
def _ZipResources(resource_dirs, zip_path, ignore_pattern): # ignore_pattern is a string of ':' delimited list of globs used to ignore # files that should not be part of the final resource zip. files_to_zip = [] path_info = resource_utils.ResourceInfoFile() for index, resource_dir in enumerate(resource_dirs): attributed_aar = None if not resource_dir.startswith('..'): aar_source_info_path = os.path.join(os.path.dirname(resource_dir), 'source.info') if os.path.exists(aar_source_info_path): attributed_aar = jar_info_utils.ReadAarSourceInfo( aar_source_info_path) for path, archive_path in resource_utils.IterResourceFilesInDirectories( [resource_dir], ignore_pattern): attributed_path = path if attributed_aar: attributed_path = os.path.join(attributed_aar, 'res', path[len(resource_dir) + 1:]) # Use the non-prefixed archive_path in the .info file. path_info.AddMapping(archive_path, attributed_path) resource_dir_name = os.path.basename(resource_dir) archive_path = '{}_{}/{}'.format(index, resource_dir_name, archive_path) files_to_zip.append((archive_path, path)) path_info.Write(zip_path + '.info') with zipfile.ZipFile(zip_path, 'w') as z: # This magic comment signals to resource_utils.ExtractDeps that this zip is # not just the contents of a single res dir, without the encapsulating res/ # (like the outputs of android_generated_resources targets), but instead has # the contents of possibly multiple res/ dirs each within an encapsulating # directory within the zip. z.comment = resource_utils.MULTIPLE_RES_MAGIC_STRING build_utils.DoZip(files_to_zip, z)