Search in sources :

Example 1 with AndroidDependencyTree

use of com.taobao.android.builder.dependency.AndroidDependencyTree in project atlas by alibaba.

the class TDependencyManager method resolveDependencyForApplicationConfig.

private void resolveDependencyForApplicationConfig(@NonNull final VariantDependencies variantDeps, @Nullable VariantDependencies testedVariantDeps, @Nullable String testedProjectPath, @NonNull Multimap<AndroidLibrary, Configuration> reverseLibMap) {
    boolean needPackageScope = true;
    if (AndroidGradleOptions.buildModelOnly(project)) {
        // if we're only syncing (building the model), then we only need the package
        // scope if we will actually pass it to the IDE.
        Integer modelLevelInt = AndroidGradleOptions.buildModelOnlyVersion(project);
        int modelLevel = AndroidProject.MODEL_LEVEL_0_ORIGNAL;
        if (modelLevelInt != null) {
            modelLevel = modelLevelInt;
        }
        needPackageScope = modelLevel >= AndroidProject.MODEL_LEVEL_2_DEP_GRAPH;
    }
    Configuration compileClasspath = variantDeps.getCompileConfiguration();
    Configuration packageClasspath = variantDeps.getPackageConfiguration();
    if (DEBUG_DEPENDENCY) {
        System.out.println(">>>>>>>>>>");
        System.out.println(project.getName() + ":" + compileClasspath.getName() + "/" + packageClasspath.getName());
    }
    Set<String> resolvedModules = Sets.newHashSet();
    Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts = Maps.newHashMap();
    collectArtifacts(compileClasspath, artifacts);
    collectArtifacts(packageClasspath, artifacts);
    // 不使用官方的扁平化的依赖处理,改用自己处理树状的依赖关系;对于application的依赖,我们只取compile的依赖
    ResolvedDependencyContainer compileResolvedDependencyContainer = new ResolvedDependencyContainer(project);
    Set<ModuleVersionIdentifier> directDependencies = new HashSet<ModuleVersionIdentifier>();
    Set<? extends DependencyResult> projectDependencies = compileClasspath.getIncoming().getResolutionResult().getRoot().getDependencies();
    for (DependencyResult dependencyResult : projectDependencies) {
        if (dependencyResult instanceof ResolvedDependencyResult) {
            ModuleVersionIdentifier moduleVersion = ((ResolvedDependencyResult) dependencyResult).getSelected().getModuleVersion();
            CircleDependencyCheck circleDependencyCheck = new CircleDependencyCheck(moduleVersion);
            if (!directDependencies.contains(moduleVersion)) {
                directDependencies.add(moduleVersion);
                resolveDependency(compileResolvedDependencyContainer, null, ((ResolvedDependencyResult) dependencyResult).getSelected(), artifacts, variantDeps, 0, circleDependencyCheck, circleDependencyCheck.getRootDependencyNode(), resolvedModules);
            }
        }
    }
    AndroidDependencyTree androidDependencyTree = compileResolvedDependencyContainer.reslovedDependencies().toAndroidDependency();
    AtlasBuildContext.androidDependencyTrees.put(variantDeps.getName(), androidDependencyTree);
    //output tree file only once
    if (project.getLogger().isInfoEnabled()) {
        project.getLogger().info("[dependencyTree" + variantDeps.getName() + "]" + JSON.toJSONString(androidDependencyTree.getDependencyJson(), true));
    }
    // 设置reverseMap
    for (AndroidLibrary libInfo : androidDependencyTree.getAarBundles()) {
        reverseLibMap.put(libInfo, variantDeps.getCompileConfiguration());
    }
    Set<String> currentUnresolvedDependencies = Sets.newHashSet();
    // records the artifact we find during package, to detect provided only dependencies.
    Set<String> artifactSet = Sets.newHashSet();
    // start with package dependencies, record the artifacts
    DependencyContainer packagedDependencies;
    if (needPackageScope) {
        packagedDependencies = gatherDependencies(packageClasspath, variantDeps, reverseLibMap, currentUnresolvedDependencies, testedProjectPath, artifactSet, ScopeType.PACKAGE);
    } else {
        packagedDependencies = DependencyContainerImpl.getEmpty();
    }
    // then the compile dependencies, comparing against the record package dependencies
    // to set the provided flag.
    // if we have not compute the package scope, we disable the computation of
    // provided bits. This disables the checks on impossible provided libs (provided aar in
    // apk project).
    ScopeType scopeType = needPackageScope ? ScopeType.COMPILE : ScopeType.COMPILE_ONLY;
    DependencyContainer compileDependencies = gatherDependencies(compileClasspath, variantDeps, reverseLibMap, currentUnresolvedDependencies, testedProjectPath, artifactSet, scopeType);
    if (extraModelInfo.getMode() != STANDARD && compileClasspath.getResolvedConfiguration().hasError()) {
        for (String dependency : currentUnresolvedDependencies) {
            extraModelInfo.handleSyncError(dependency, SyncIssue.TYPE_UNRESOLVED_DEPENDENCY, String.format("Unable to resolve dependency '%s'", dependency));
        }
    }
    // validate the dependencies.
    if (needPackageScope) {
        variantDeps.getChecker().validate(compileDependencies, packagedDependencies, testedVariantDeps);
    }
    if (DEBUG_DEPENDENCY) {
        System.out.println("*** COMPILE DEPS ***");
        for (AndroidLibrary lib : compileDependencies.getAndroidDependencies()) {
            System.out.println("LIB: " + lib);
        }
        for (JavaLibrary jar : compileDependencies.getJarDependencies()) {
            System.out.println("JAR: " + jar);
        }
        for (JavaLibrary jar : compileDependencies.getLocalDependencies()) {
            System.out.println("LOCAL-JAR: " + jar);
        }
        System.out.println("*** PACKAGE DEPS ***");
        for (AndroidLibrary lib : packagedDependencies.getAndroidDependencies()) {
            System.out.println("LIB: " + lib);
        }
        for (JavaLibrary jar : packagedDependencies.getJarDependencies()) {
            System.out.println("JAR: " + jar);
        }
        for (JavaLibrary jar : packagedDependencies.getLocalDependencies()) {
            System.out.println("LOCAL-JAR: " + jar);
        }
        System.out.println("***");
    }
    variantDeps.setDependencies(compileDependencies, packagedDependencies);
    configureBuild(variantDeps);
    if (DEBUG_DEPENDENCY) {
        System.out.println(project.getName() + ":" + compileClasspath.getName() + "/" + packageClasspath.getName());
        System.out.println("<<<<<<<<<<");
    }
}
Also used : Configuration(org.gradle.api.artifacts.Configuration) DependencyResult(org.gradle.api.artifacts.result.DependencyResult) UnresolvedDependencyResult(org.gradle.api.artifacts.result.UnresolvedDependencyResult) ResolvedDependencyResult(org.gradle.api.artifacts.result.ResolvedDependencyResult) AndroidDependencyTree(com.taobao.android.builder.dependency.AndroidDependencyTree) ResolvedDependencyContainer(com.taobao.android.builder.dependency.ResolvedDependencyContainer) DependencyContainer(com.android.builder.dependency.DependencyContainer) ModuleVersionIdentifier(org.gradle.api.artifacts.ModuleVersionIdentifier) ResolvedDependencyContainer(com.taobao.android.builder.dependency.ResolvedDependencyContainer) JavaLibrary(com.android.builder.model.JavaLibrary) AndroidLibrary(com.android.builder.model.AndroidLibrary) CircleDependencyCheck(com.taobao.android.builder.dependency.CircleDependencyCheck) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) ResolvedDependencyResult(org.gradle.api.artifacts.result.ResolvedDependencyResult) HashSet(java.util.HashSet)

Example 2 with AndroidDependencyTree

use of com.taobao.android.builder.dependency.AndroidDependencyTree in project atlas by alibaba.

the class AppVariantOutputContext method getAwbTransformMap.

public synchronized Map<String, AwbTransform> getAwbTransformMap() {
    //TODO
    if (awbTransformMap.isEmpty()) {
        AndroidDependencyTree dependencyTree = AtlasBuildContext.androidDependencyTrees.get(variantContext.getVariantName());
        for (AwbBundle awbBundle : dependencyTree.getAwbBundles()) {
            //生成AwbTransform对象
            AwbTransform awbTransform = new AwbTransform(awbBundle);
            //                awbTransform.setInputDir(awbJavaCompile.getDestinationDir());
            //ADD R.class
            awbTransform.getInputLibraries().addAll(awbBundle.getLibraryJars());
            //                awbTransform.getInputLibraries().addAll(appVariantOutputContext.getJAwbavaOutputDir(awbBundle));
            awbTransformMap.put(awbBundle.getName(), awbTransform);
        }
    }
    return awbTransformMap;
}
Also used : AndroidDependencyTree(com.taobao.android.builder.dependency.AndroidDependencyTree) AwbBundle(com.taobao.android.builder.dependency.model.AwbBundle)

Example 3 with AndroidDependencyTree

use of com.taobao.android.builder.dependency.AndroidDependencyTree in project atlas by alibaba.

the class AtlasLibTaskManager method createAwbBundle.

private AwbBundle createAwbBundle(LibVariantContext libVariantContext, String variantName) throws IOException {
    AndroidDependencyTree libDependencyTree = AtlasBuildContext.libDependencyTrees.get(variantName);
    if (null == libDependencyTree) {
        dependencyManager.resolveDependencyForConfig(libVariantContext.getVariantDependency(), true);
        libDependencyTree = AtlasBuildContext.libDependencyTrees.get(variantName);
    }
    String groupName = (String) project.getGroup();
    String name = "";
    String version = (String) project.getVersion();
    if (project.hasProperty("archivesBaseName")) {
        name = (String) project.getProperties().get("archivesBaseName");
    } else {
        name = project.getName();
    }
    File explodedDir = project.file(project.getBuildDir().getAbsolutePath() + "/" + FD_INTERMEDIATES + "/exploded-awb/" + computeArtifactPath(groupName, name, version));
    FileUtils.deleteDirectory(explodedDir);
    AwbBundle awbBundle = new AwbBundle(libVariantContext.getBundleTask().getArchivePath(), explodedDir, new ArrayList<LibraryDependency>(), new ArrayList<JarDependency>(), groupName + ":" + name, libVariantContext.getVariantName(), project.getPath(), null, new MavenCoordinatesImpl(groupName, name, version));
    new AwoDependency(libVariantContext).parseDependency(libDependencyTree, awbBundle);
    return awbBundle;
}
Also used : JarDependency(com.android.builder.dependency.JarDependency) MavenCoordinatesImpl(com.android.builder.dependency.MavenCoordinatesImpl) AwoDependency(com.taobao.android.builder.tasks.awo.utils.AwoDependency) LibraryDependency(com.android.builder.dependency.LibraryDependency) AndroidDependencyTree(com.taobao.android.builder.dependency.AndroidDependencyTree) AwbBundle(com.taobao.android.builder.dependency.model.AwbBundle) File(java.io.File)

Example 4 with AndroidDependencyTree

use of com.taobao.android.builder.dependency.AndroidDependencyTree in project atlas by alibaba.

the class PackageAwbsTask method createAwbPackages.

/**
     * 生成so的目录
     */
@TaskAction
void createAwbPackages() throws ExecutionException, InterruptedException {
    AndroidDependencyTree androidDependencyTree = AtlasBuildContext.androidDependencyTrees.get(getVariantName());
    if (null == androidDependencyTree) {
        return;
    }
    final ProcessOutputHandler outputHandler = new ParsingProcessOutputHandler(new ToolOutputParser(new DexParser(), Message.Kind.ERROR, getILogger()), new ToolOutputParser(new DexParser(), getILogger()), getBuilder().getErrorReporter());
    ExecutorServicesHelper executorServicesHelper = new ExecutorServicesHelper(taskName, getLogger(), 0);
    List<Runnable> runnables = new ArrayList<>();
    final AtomicLong dexTotalTime = new AtomicLong(0);
    final AtomicLong packageTotalTime = new AtomicLong(0);
    final Map<String, Long[]> monitors = new HashMap<String, Long[]>();
    long startTime = System.currentTimeMillis();
    for (final AwbBundle awbBundle : androidDependencyTree.getAwbBundles()) {
        runnables.add(new Runnable() {

            @Override
            public void run() {
                try {
                    long start = System.currentTimeMillis();
                    //create dex
                    File dexOutputFile = appVariantContext.getAwbDexOutput(awbBundle.getName());
                    emptyFolder(dexOutputFile);
                    // if some of our .jar input files exist, just reset the inputDir to null
                    AwbTransform awbTransform = appVariantOutputContext.getAwbTransformMap().get(awbBundle.getName());
                    List<File> inputFiles = new ArrayList<File>();
                    inputFiles.addAll(awbTransform.getInputFiles());
                    inputFiles.addAll(awbTransform.getInputLibraries());
                    if (null != awbTransform.getInputDir()) {
                        inputFiles.add(awbTransform.getInputDir());
                    }
                    AtlasBuildContext.androidBuilder.convertByteCode(inputFiles, dexOutputFile, appVariantContext.getVariantData().getVariantConfiguration().isMultiDexEnabled(), null, androidConfig.getDexOptions(), true, outputHandler);
                    //create package
                    long endDex = System.currentTimeMillis();
                    //PACKAGE APP:
                    File resourceFile = appVariantOutputContext.getAwbAndroidResourcesMap().get(awbBundle.getName()).getPackageOutputFile();
                    Set<File> dexFolders = new HashSet<File>();
                    dexFolders.add(dexOutputFile);
                    Set<File> jniFolders = Sets.newHashSet();
                    if (appVariantOutputContext.getAwbJniFolder(awbBundle) != null && appVariantOutputContext.getAwbJniFolder(awbBundle).exists()) {
                        jniFolders.add(appVariantOutputContext.getAwbJniFolder(awbBundle));
                    }
                    Set<File> javaResourcesLocations = Sets.newHashSet();
                    if (appVariantContext.getAtlasExtension().getTBuildConfig().getMergeAwbJavaRes()) {
                        javaResourcesLocations.addAll(awbBundle.getLibraryJars());
                    }
                    //getBuilder().packageCodeSplitApk();
                    getBuilder().oldPackageApk(resourceFile.getAbsolutePath(), dexFolders, javaResourcesLocations, jniFolders, null, getAbiFilters(), config.getBuildType().isJniDebuggable(), null, getOutputFile(awbBundle), config.getMinSdkVersion().getApiLevel(), new Predicate<String>() {

                        @Override
                        public boolean apply(@Nullable String s) {
                            return false;
                        }
                    });
                    long endPackage = System.currentTimeMillis();
                    dexTotalTime.addAndGet(endDex - start);
                    packageTotalTime.addAndGet(endPackage - endDex);
                    monitors.put(awbBundle.getName(), new Long[] { endDex - start, endPackage - endDex });
                } catch (Throwable e) {
                    e.printStackTrace();
                    throw new GradleException("package " + awbBundle.getName() + " failed");
                }
            }
        });
    }
    executorServicesHelper.execute(runnables);
    if (getLogger().isInfoEnabled()) {
        getLogger().info(">>>>> packageAwbs >>>>>>>>>>>>");
        getLogger().info("totalTime is " + (System.currentTimeMillis() - startTime));
        getLogger().info("dexTotalTime is " + dexTotalTime);
        getLogger().info("packageTotalTime is " + packageTotalTime);
        String format = "[packageawb]  bundle:%50s  dexTime: %10d  packageTime: %10d ";
        for (String bundle : monitors.keySet()) {
            Long[] value = monitors.get(bundle);
            getLogger().info(String.format(format, bundle, value[0], value[1]));
        }
        getLogger().info(">>>>> packageAwbs >>>>>>>>>>>>");
    }
}
Also used : HashSet(java.util.HashSet) ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) AndroidDependencyTree(com.taobao.android.builder.dependency.AndroidDependencyTree) Predicate(com.google.common.base.Predicate) ExecutorServicesHelper(com.taobao.android.builder.tools.concurrent.ExecutorServicesHelper) ToolOutputParser(com.android.ide.common.blame.parser.ToolOutputParser) ArrayList(java.util.ArrayList) List(java.util.List) AwbBundle(com.taobao.android.builder.dependency.model.AwbBundle) ParsingProcessOutputHandler(com.android.ide.common.blame.ParsingProcessOutputHandler) ParsingProcessOutputHandler(com.android.ide.common.blame.ParsingProcessOutputHandler) ProcessOutputHandler(com.android.ide.common.process.ProcessOutputHandler) AtomicLong(java.util.concurrent.atomic.AtomicLong) DexParser(com.android.ide.common.blame.parser.DexParser) AwbTransform(com.android.build.gradle.internal.api.AwbTransform) GradleException(org.gradle.api.GradleException) AtomicLong(java.util.concurrent.atomic.AtomicLong) File(java.io.File) Nullable(javax.annotation.Nullable) MtlBaseTaskAction(com.taobao.android.builder.tasks.manager.MtlBaseTaskAction) TaskAction(org.gradle.api.tasks.TaskAction)

Example 5 with AndroidDependencyTree

use of com.taobao.android.builder.dependency.AndroidDependencyTree in project atlas by alibaba.

the class DataBindingProcessLayoutAwbsConfigAction method execute.

@Override
public void execute(MtlParallelTask parallelTask) {
    super.execute(parallelTask);
    AndroidDependencyTree androidDependencyTree = AtlasBuildContext.androidDependencyTrees.get(parallelTask.getVariantName());
    if (null == androidDependencyTree) {
        return;
    }
    DataBindingBuilder dataBindingBuilder = new DataBindingBuilder();
    dataBindingBuilder.setPrintMachineReadableOutput(false);
    dataBindingBuilder.setDebugLogEnabled(appVariantContext.getProject().getLogger().isDebugEnabled());
    List<DefaultTask> tasks = new ArrayList<DefaultTask>();
    for (final AwbBundle awbBundle : androidDependencyTree.getAwbBundles()) {
        AwbDataBindingProcessLayoutsConfigAction processLayoutsConfigAction = new AwbDataBindingProcessLayoutsConfigAction(appVariantContext, awbBundle, dataBindingBuilder);
        DataBindingProcessLayoutsTask dataBindingProcessLayoutsTask = TaskCreater.create(appVariantContext.getProject(), processLayoutsConfigAction.getName(), processLayoutsConfigAction.getType());
        processLayoutsConfigAction.execute(dataBindingProcessLayoutsTask);
        tasks.add(dataBindingProcessLayoutsTask);
    }
    parallelTask.parallelTask = tasks;
    parallelTask.uniqueTaskName = getName();
    parallelTask.concurrent = true;
}
Also used : ArrayList(java.util.ArrayList) DefaultTask(org.gradle.api.DefaultTask) DataBindingProcessLayoutsTask(com.android.build.gradle.internal.tasks.databinding.DataBindingProcessLayoutsTask) AndroidDependencyTree(com.taobao.android.builder.dependency.AndroidDependencyTree) DataBindingBuilder(android.databinding.tool.DataBindingBuilder) AwbBundle(com.taobao.android.builder.dependency.model.AwbBundle)

Aggregations

AndroidDependencyTree (com.taobao.android.builder.dependency.AndroidDependencyTree)24 AwbBundle (com.taobao.android.builder.dependency.model.AwbBundle)19 ArrayList (java.util.ArrayList)14 File (java.io.File)12 MtlBaseTaskAction (com.taobao.android.builder.tasks.manager.MtlBaseTaskAction)9 TaskAction (org.gradle.api.tasks.TaskAction)9 GradleException (org.gradle.api.GradleException)8 ExecutorServicesHelper (com.taobao.android.builder.tools.concurrent.ExecutorServicesHelper)5 DefaultTask (org.gradle.api.DefaultTask)5 BundleInfo (com.taobao.android.builder.tools.bundleinfo.model.BundleInfo)4 IOException (java.io.IOException)4 HashSet (java.util.HashSet)4 StopExecutionException (org.gradle.api.tasks.StopExecutionException)3 DataBindingBuilder (android.databinding.tool.DataBindingBuilder)2 AppVariantOutputContext (com.android.build.gradle.internal.api.AppVariantOutputContext)2 AwbTransform (com.android.build.gradle.internal.api.AwbTransform)2 VariantScope (com.android.build.gradle.internal.scope.VariantScope)2 BaseVariantOutputData (com.android.build.gradle.internal.variant.BaseVariantOutputData)2 AndroidLibrary (com.android.builder.model.AndroidLibrary)2 AwoDependency (com.taobao.android.builder.tasks.awo.utils.AwoDependency)2