Search in sources :

Example 1 with AndroidPackageableCollection

use of com.facebook.buck.android.AndroidPackageableCollection in project buck by facebook.

the class Project method markNoDxJarsAsProvided.

/**
   * Modifies the {@code scope} of a library dependency to {@code "PROVIDED"}, where appropriate.
   * <p>
   * If an {@code android_binary()} rule uses the {@code no_dx} argument, then the jars in the
   * libraries that should not be dex'ed must be included with {@code scope="PROVIDED"} in
   * IntelliJ.
   * <p>
   * The problem is that if a library is included by two android_binary rules that each need it in a
   * different way (i.e., for one it should be {@code scope="COMPILE"} and another it should be
   * {@code scope="PROVIDED"}), then it must be tagged as {@code scope="PROVIDED"} in all
   * dependent modules and then added as {@code scope="COMPILE"} in the .iml file that corresponds
   * to the android_binary that <em>does not</em> list the library in its {@code no_dx} list.
   */
@VisibleForTesting
static void markNoDxJarsAsProvided(ProjectFilesystem projectFilesystem, List<SerializableModule> modules, Set<Path> noDxJars, SourcePathResolver resolver) {
    Map<String, Path> intelliJLibraryNameToJarPath = Maps.newHashMap();
    for (Path jarPath : noDxJars) {
        String libraryName = getIntellijNameForBinaryJar(jarPath);
        intelliJLibraryNameToJarPath.put(libraryName, jarPath);
    }
    for (SerializableModule module : modules) {
        // For an android_binary() rule, create a set of paths to JAR files (or directories) that
        // must be dex'ed. If a JAR file that is in the no_dx list for some android_binary rule, but
        // is in this set for this android_binary rule, then it should be scope="COMPILE" rather than
        // scope="PROVIDED".
        Set<Path> classpathEntriesToDex;
        if (module.srcRule instanceof AndroidBinary) {
            AndroidBinary androidBinary = (AndroidBinary) module.srcRule;
            AndroidPackageableCollection packageableCollection = androidBinary.getAndroidPackageableCollection();
            classpathEntriesToDex = new HashSet<>(Sets.intersection(noDxJars, FluentIterable.from(packageableCollection.getClasspathEntriesToDex()).transform(resolver::getAbsolutePath).transform(projectFilesystem::relativize).toSet()));
        } else {
            classpathEntriesToDex = ImmutableSet.of();
        }
        // noDxJars, then either change its scope to "COMPILE" or "PROVIDED", as appropriate.
        for (SerializableDependentModule dependentModule : Preconditions.checkNotNull(module.getDependencies())) {
            if (!dependentModule.isLibrary()) {
                continue;
            }
            // This is the IntelliJ name for the library that corresponds to the PrebuiltJarRule.
            String libraryName = dependentModule.getLibraryName();
            Path jarPath = intelliJLibraryNameToJarPath.get(libraryName);
            if (jarPath != null) {
                if (classpathEntriesToDex.contains(jarPath)) {
                    dependentModule.scope = null;
                    classpathEntriesToDex.remove(jarPath);
                } else {
                    dependentModule.scope = "PROVIDED";
                }
            }
        }
        // if it has not already been added to the module.
        for (Path entry : classpathEntriesToDex) {
            String libraryName = getIntellijNameForBinaryJar(entry);
            SerializableDependentModule dependency = SerializableDependentModule.newLibrary(null, libraryName);
            Preconditions.checkNotNull(module.getDependencies()).add(dependency);
        }
    }
}
Also used : Path(java.nio.file.Path) PathSourcePath(com.facebook.buck.rules.PathSourcePath) SourcePath(com.facebook.buck.rules.SourcePath) AndroidBinary(com.facebook.buck.android.AndroidBinary) AndroidPackageableCollection(com.facebook.buck.android.AndroidPackageableCollection) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 2 with AndroidPackageableCollection

use of com.facebook.buck.android.AndroidPackageableCollection in project buck by facebook.

the class Project method createModulesForProjectConfigs.

@VisibleForTesting
List<SerializableModule> createModulesForProjectConfigs() throws IOException {
    List<SerializableModule> modules = Lists.newArrayList();
    // Convert the project_config() targets into modules and find the union of all jars passed to
    // no_dx.
    ImmutableSet.Builder<Path> noDxJarsBuilder = ImmutableSet.builder();
    for (ProjectConfig projectConfig : rules) {
        BuildRule srcRule = projectConfig.getSrcRule();
        if (srcRule instanceof AndroidBinary) {
            AndroidBinary androidBinary = (AndroidBinary) srcRule;
            AndroidPackageableCollection packageableCollection = androidBinary.getAndroidPackageableCollection();
            ImmutableSortedSet<Path> dxAbsolutePaths = resolver.getAllAbsolutePaths(packageableCollection.getNoDxClasspathEntries());
            noDxJarsBuilder.addAll(dxAbsolutePaths.stream().map(projectFilesystem::relativize).iterator());
        }
        final Optional<Path> rJava;
        if (srcRule instanceof AndroidLibrary) {
            AndroidLibrary androidLibrary = (AndroidLibrary) srcRule;
            BuildTarget dummyRDotJavaTarget = AndroidLibraryGraphEnhancer.getDummyRDotJavaTarget(androidLibrary.getBuildTarget());
            Path src = DummyRDotJava.getRDotJavaSrcFolder(dummyRDotJavaTarget, projectFilesystem);
            rJava = Optional.of(src);
        } else if (srcRule instanceof AndroidResource) {
            AndroidResource androidResource = (AndroidResource) srcRule;
            BuildTarget dummyRDotJavaTarget = AndroidLibraryGraphEnhancer.getDummyRDotJavaTarget(androidResource.getBuildTarget());
            Path src = DummyRDotJava.getRDotJavaSrcFolder(dummyRDotJavaTarget, projectFilesystem);
            rJava = Optional.of(src);
        } else {
            rJava = Optional.empty();
        }
        SerializableModule module = createModuleForProjectConfig(projectConfig, rJava);
        modules.add(module);
    }
    ImmutableSet<Path> noDxJars = noDxJarsBuilder.build();
    // Update module dependencies to apply scope="PROVIDED", where appropriate.
    markNoDxJarsAsProvided(projectFilesystem, modules, noDxJars, resolver);
    return modules;
}
Also used : Path(java.nio.file.Path) PathSourcePath(com.facebook.buck.rules.PathSourcePath) SourcePath(com.facebook.buck.rules.SourcePath) AndroidBinary(com.facebook.buck.android.AndroidBinary) AndroidResource(com.facebook.buck.android.AndroidResource) ProjectConfig(com.facebook.buck.rules.ProjectConfig) ImmutableSet(com.google.common.collect.ImmutableSet) AndroidLibrary(com.facebook.buck.android.AndroidLibrary) BuildTarget(com.facebook.buck.model.BuildTarget) BuildRule(com.facebook.buck.rules.BuildRule) AndroidPackageableCollection(com.facebook.buck.android.AndroidPackageableCollection) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Aggregations

AndroidBinary (com.facebook.buck.android.AndroidBinary)2 AndroidPackageableCollection (com.facebook.buck.android.AndroidPackageableCollection)2 PathSourcePath (com.facebook.buck.rules.PathSourcePath)2 SourcePath (com.facebook.buck.rules.SourcePath)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)2 Path (java.nio.file.Path)2 AndroidLibrary (com.facebook.buck.android.AndroidLibrary)1 AndroidResource (com.facebook.buck.android.AndroidResource)1 BuildTarget (com.facebook.buck.model.BuildTarget)1 BuildRule (com.facebook.buck.rules.BuildRule)1 ProjectConfig (com.facebook.buck.rules.ProjectConfig)1 ImmutableSet (com.google.common.collect.ImmutableSet)1