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);
}
}
}
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;
}
Aggregations