use of com.facebook.buck.android.AndroidResource in project buck by facebook.
the class Project method walkRuleAndAdd.
/**
* Walks the dependencies of a build rule and adds the appropriate DependentModules to the
* specified dependencies collection. All library dependencies will be added before any module
* dependencies. See {@code ProjectTest#testThatJarsAreListedBeforeModules()} for details on why
* this behavior is important.
*/
@SuppressWarnings("PMD.LooseCoupling")
private void walkRuleAndAdd(final BuildRule rule, final boolean isForTests, final LinkedHashSet<SerializableDependentModule> dependencies, @Nullable final BuildRule srcTarget) {
final Path basePathForRule = rule.getBuildTarget().getBasePath();
Set<BuildRule> targetsToWalk;
if (rule instanceof JavaTest) {
targetsToWalk = ((JavaTest) rule).getCompiledTestsLibrary().getDeps();
} else {
targetsToWalk = rule.getDeps();
}
new AbstractBreadthFirstTraversal<BuildRule>(targetsToWalk) {
private final LinkedHashSet<SerializableDependentModule> librariesToAdd = Sets.newLinkedHashSet();
private final LinkedHashSet<SerializableDependentModule> modulesToAdd = Sets.newLinkedHashSet();
@Override
public ImmutableSet<BuildRule> visit(BuildRule dep) {
// Hack: we don't want uber R.java to show up in the deps that IntelliJ sees.
if (dep.getBuildTarget().toString().endsWith("_uber_r_dot_java")) {
return ImmutableSet.of();
}
ImmutableSet<BuildRule> depsToVisit;
if (rule.getProperties().is(PACKAGING) || dep instanceof AndroidResource || dep == rule) {
depsToVisit = dep.getDeps();
} else if (dep.getProperties().is(LIBRARY) && dep instanceof ExportDependencies) {
depsToVisit = ((ExportDependencies) dep).getExportedDeps();
} else {
depsToVisit = ImmutableSet.of();
}
// should contain the union of :lib and :test's deps as dependent modules.
if (isForTests && depsToVisit.isEmpty() && dep.getBuildTarget().getBasePath().equals(basePathForRule) && !dep.equals(srcTarget)) {
depsToVisit = dep.getDeps();
}
SerializableDependentModule dependentModule;
if (androidAars.contains(dep)) {
AndroidPrebuiltAar aar = androidAars.getParentAar(dep);
dependentModule = SerializableDependentModule.newLibrary(aar.getBuildTarget(), getIntellijNameForAar(aar));
} else if (dep instanceof PrebuiltJar) {
libraryJars.add(dep);
String libraryName = getIntellijNameForRule(dep);
dependentModule = SerializableDependentModule.newLibrary(dep.getBuildTarget(), libraryName);
} else if (dep instanceof AndroidPrebuiltAar) {
androidAars.add((AndroidPrebuiltAar) dep);
String libraryName = getIntellijNameForAar(dep);
dependentModule = SerializableDependentModule.newLibrary(dep.getBuildTarget(), libraryName);
} else if ((dep instanceof CxxLibrary) || (dep instanceof NdkLibrary) || (dep instanceof JavaLibrary) || (dep instanceof AndroidResource)) {
String moduleName = getIntellijNameForRule(dep);
dependentModule = SerializableDependentModule.newModule(dep.getBuildTarget(), moduleName);
} else {
return depsToVisit;
}
if (librariesToAdd.contains(dependentModule) || modulesToAdd.contains(dependentModule)) {
return depsToVisit;
}
if (isForTests) {
dependentModule.scope = "TEST";
} else {
// If the dependentModule has already been added in the "TEST" scope, then it should be
// removed and then re-added using the current (compile) scope.
String currentScope = dependentModule.scope;
dependentModule.scope = "TEST";
if (dependencies.contains(dependentModule)) {
dependencies.remove(dependentModule);
}
dependentModule.scope = currentScope;
}
// dependencies collection once the traversal is complete in the onComplete() method.
if (dependentModule.isLibrary()) {
librariesToAdd.add(dependentModule);
} else {
modulesToAdd.add(dependentModule);
}
return depsToVisit;
}
@Override
protected void onComplete() {
dependencies.addAll(librariesToAdd);
dependencies.addAll(modulesToAdd);
}
}.start();
}
use of com.facebook.buck.android.AndroidResource in project buck by facebook.
the class Project method createModuleForProjectConfig.
@SuppressWarnings("PMD.LooseCoupling")
private SerializableModule createModuleForProjectConfig(ProjectConfig projectConfig, Optional<Path> rJava) throws IOException {
BuildRule projectRule = Preconditions.checkNotNull(projectConfig.getProjectRule());
Preconditions.checkState(projectRule instanceof AndroidBinary || projectRule instanceof AndroidLibrary || projectRule instanceof AndroidResource || projectRule instanceof JavaBinary || projectRule instanceof JavaLibrary || projectRule instanceof JavaTest || projectRule instanceof CxxLibrary || projectRule instanceof NdkLibrary, "project_config() does not know how to process a src_target of type %s (%s).", projectRule.getType(), projectRule.getBuildTarget());
LinkedHashSet<SerializableDependentModule> dependencies = Sets.newLinkedHashSet();
final BuildTarget target = projectConfig.getBuildTarget();
SerializableModule module = new SerializableModule(projectRule, target);
module.name = getIntellijNameForRule(projectRule);
module.isIntelliJPlugin = projectConfig.getIsIntelliJPlugin();
Path relativePath = projectConfig.getBuildTarget().getBasePath();
module.pathToImlFile = relativePath.resolve(module.name + ".iml");
// List the module source as the first dependency.
boolean includeSourceFolder = true;
// Do the tests before the sources so they appear earlier in the classpath. When tests are run,
// their classpath entries may be deliberately shadowing production classpath entries.
// tests folder
boolean hasSourceFoldersForTestRule = addSourceFolders(module, projectConfig.getTestRule(), projectConfig.getTestsSourceRoots(), true);
// test dependencies
BuildRule testRule = projectConfig.getTestRule();
if (testRule != null) {
walkRuleAndAdd(testRule, true, /* isForTests */
dependencies, projectConfig.getSrcRule());
}
// src folder
boolean hasSourceFoldersForSrcRule = addSourceFolders(module, projectConfig.getSrcRule(), projectConfig.getSourceRoots(), false);
addRootExcludes(module, projectConfig.getSrcRule(), projectFilesystem);
// non-library Android project with no source roots specified.
if (!hasSourceFoldersForTestRule && !hasSourceFoldersForSrcRule) {
includeSourceFolder = false;
}
// IntelliJ expects all Android projects to have a gen/ folder, even if there is no src/
// directory specified.
boolean isAndroidRule = projectRule.getProperties().is(ANDROID);
if (isAndroidRule) {
boolean hasSourceFolders = !module.sourceFolders.isEmpty();
module.sourceFolders.add(SerializableModule.SourceFolder.GEN);
if (!hasSourceFolders) {
includeSourceFolder = true;
}
}
// src dependencies
// Note that isForTests is false even if projectRule is the project_config's test_target.
walkRuleAndAdd(projectRule, false, /* isForTests */
dependencies, projectConfig.getSrcRule());
Path basePath = projectConfig.getBuildTarget().getBasePath();
// Specify another path for intellij to generate gen/ for each android module,
// so that it will not disturb our glob() rules.
// To specify the location of gen, Intellij requires the relative path from
// the base path of current build target.
module.moduleGenPath = generateRelativeGenPath(projectFilesystem, basePath);
if (turnOffAutoSourceGeneration && rJava.isPresent()) {
module.moduleRJavaPath = basePath.relativize(Paths.get("")).resolve(rJava.get());
}
SerializableDependentModule jdkDependency;
if (isAndroidRule) {
// android details
if (projectRule instanceof NdkLibrary) {
NdkLibrary ndkLibrary = (NdkLibrary) projectRule;
module.isAndroidLibraryProject = true;
module.keystorePath = null;
module.nativeLibs = relativePath.relativize(ndkLibrary.getLibraryPath());
} else if (projectRule instanceof AndroidLibrary) {
module.isAndroidLibraryProject = true;
module.keystorePath = null;
module.resFolder = intellijConfig.getAndroidResources().orElse(null);
module.assetFolder = intellijConfig.getAndroidAssets().orElse(null);
} else if (projectRule instanceof AndroidResource) {
AndroidResource androidResource = (AndroidResource) projectRule;
module.resFolder = createRelativeResourcesPath(Optional.ofNullable(androidResource.getRes()).map(resolver::getAbsolutePath).map(projectFilesystem::relativize).orElse(null), target);
module.isAndroidLibraryProject = true;
module.keystorePath = null;
} else if (projectRule instanceof AndroidBinary) {
AndroidBinary androidBinary = (AndroidBinary) projectRule;
module.resFolder = intellijConfig.getAndroidResources().orElse(null);
module.assetFolder = intellijConfig.getAndroidAssets().orElse(null);
module.isAndroidLibraryProject = false;
module.binaryPath = generateRelativeAPKPath(projectFilesystem, projectRule.getBuildTarget().getShortName(), basePath);
KeystoreProperties keystoreProperties = KeystoreProperties.createFromPropertiesFile(resolver.getAbsolutePath(androidBinary.getKeystore().getPathToStore()), resolver.getRelativePath(androidBinary.getKeystore().getPathToPropertiesFile()), projectFilesystem);
// getKeystore() returns an absolute path, but an IntelliJ module
// expects the path to the keystore to be relative to the module root.
// First, grab the aboslute path to the project config.
BuildTarget projectTarget = projectConfig.getBuildTarget();
Path modulePath = projectTarget.getCellPath().resolve(projectTarget.getBasePath());
// Now relativize to the keystore path, which is absolute too.
module.keystorePath = modulePath.relativize(keystoreProperties.getKeystore());
} else {
module.isAndroidLibraryProject = true;
module.keystorePath = null;
}
module.hasAndroidFacet = true;
module.proguardConfigPath = null;
module.androidManifest = resolveAndroidManifestRelativePath(basePath);
// List this last so that classes from modules can shadow classes in the JDK.
jdkDependency = SerializableDependentModule.newInheritedJdk();
} else {
module.hasAndroidFacet = false;
if (module.isIntelliJPlugin()) {
jdkDependency = SerializableDependentModule.newIntelliJPluginJdk();
} else {
jdkDependency = SerializableDependentModule.newStandardJdk(intellijConfig.getJdkName(), intellijConfig.getJdkType());
}
}
// Assign the dependencies.
module.setModuleDependencies(createDependenciesInOrder(includeSourceFolder, dependencies, jdkDependency));
// Annotation processing generates sources for IntelliJ to consume, but does so outside
// the module directory to avoid messing up globbing.
JavaLibrary javaLibrary = null;
if (projectRule instanceof JavaLibrary) {
javaLibrary = (JavaLibrary) projectRule;
}
if (javaLibrary != null) {
Optional<Path> processingParams = javaLibrary.getGeneratedSourcePath();
if (processingParams.isPresent()) {
module.annotationGenPath = basePath.relativize(processingParams.get());
module.annotationGenIsForTest = !hasSourceFoldersForSrcRule;
}
}
return module;
}
use of com.facebook.buck.android.AndroidResource 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;
}
use of com.facebook.buck.android.AndroidResource in project buck by facebook.
the class ReactNativeLibraryGraphEnhancer method enhanceForAndroid.
public AndroidReactNativeLibrary enhanceForAndroid(BuildRuleParams params, BuildRuleResolver resolver, AndroidReactNativeLibraryDescription.Args args) {
SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(resolver);
BuildTarget originalBuildTarget = params.getBuildTarget();
ReactNativeBundle bundle = createReactNativeBundle(params, resolver, ruleFinder, BuildTarget.builder(originalBuildTarget).addFlavors(REACT_NATIVE_BUNDLE_FLAVOR).build(), args, ReactNativePlatform.ANDROID);
resolver.addToIndex(bundle);
ImmutableList.Builder<BuildRule> extraDeps = ImmutableList.builder();
extraDeps.add(bundle);
if (args.rDotJavaPackage.isPresent()) {
BuildRuleParams paramsForResource = params.withAppendedFlavor(REACT_NATIVE_ANDROID_RES_FLAVOR).copyReplacingExtraDeps(Suppliers.ofInstance(ImmutableSortedSet.of(bundle)));
SourcePath resources = new ExplicitBuildTargetSourcePath(bundle.getBuildTarget(), bundle.getResources());
BuildRule resource = new AndroidResource(paramsForResource, ruleFinder, /* deps */
ImmutableSortedSet.of(), resources, /* resSrcs */
ImmutableSortedMap.of(), args.rDotJavaPackage.get(), /* assets */
null, /* assetsSrcs */
ImmutableSortedMap.of(), /* manifest */
null, /* hasWhitelistedStrings */
false);
resolver.addToIndex(resource);
extraDeps.add(resource);
}
return new AndroidReactNativeLibrary(params.copyAppendingExtraDeps(extraDeps.build()), bundle);
}
Aggregations