Search in sources :

Example 1 with NdkLibrary

use of com.facebook.buck.android.NdkLibrary 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();
}
Also used : Path(java.nio.file.Path) PathSourcePath(com.facebook.buck.rules.PathSourcePath) SourcePath(com.facebook.buck.rules.SourcePath) CxxLibrary(com.facebook.buck.cxx.CxxLibrary) ExportDependencies(com.facebook.buck.rules.ExportDependencies) AndroidResource(com.facebook.buck.android.AndroidResource) PrebuiltJar(com.facebook.buck.jvm.java.PrebuiltJar) ImmutableSet(com.google.common.collect.ImmutableSet) JavaLibrary(com.facebook.buck.jvm.java.JavaLibrary) JavaTest(com.facebook.buck.jvm.java.JavaTest) AndroidPrebuiltAar(com.facebook.buck.android.AndroidPrebuiltAar) BuildRule(com.facebook.buck.rules.BuildRule) NdkLibrary(com.facebook.buck.android.NdkLibrary)

Example 2 with NdkLibrary

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

the class ProjectTest method testNdkLibraryHasCorrectPath.

@Test
public void testNdkLibraryHasCorrectPath() throws Exception {
    BuildRuleResolver ruleResolver = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer());
    // Build up a the graph that corresponds to:
    //
    // ndk_library(
    //   name = 'foo-jni'
    // )
    //
    // project_config(
    //   src_target = ':foo-jni',
    // )
    ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
    BuildTarget fooJni = BuildTargetFactory.newInstance("//third_party/java/foo/jni:foo-jni");
    NdkLibrary ndkLibrary = new NdkLibraryBuilder(fooJni).build(ruleResolver, projectFilesystem);
    ProjectConfig ndkProjectConfig = ProjectConfigBuilder.createBuilder(BuildTargetFactory.newInstance("//third_party/java/foo/jni:project_config")).setSrcRule(ndkLibrary.getBuildTarget()).build(ruleResolver);
    ProjectWithModules projectWithModules = getModulesForActionGraph(ruleResolver, ImmutableSortedSet.of(ndkProjectConfig), null, /* javaPackageFinder */
    null);
    List<SerializableModule> modules = projectWithModules.modules;
    assertEquals("Should be one module for the ndk_library.", 1, modules.size());
    SerializableModule androidLibraryModule = Iterables.getOnlyElement(modules);
    assertListEquals(ImmutableList.of(SerializableDependentModule.newSourceFolder(), SerializableDependentModule.newInheritedJdk()), androidLibraryModule.getDependencies());
    assertEquals(Paths.get(String.format("../../../../%s", ndkLibrary.getLibraryPath())), androidLibraryModule.nativeLibs);
}
Also used : ProjectConfig(com.facebook.buck.rules.ProjectConfig) FakeProjectFilesystem(com.facebook.buck.testutil.FakeProjectFilesystem) BuildTarget(com.facebook.buck.model.BuildTarget) FakeProjectFilesystem(com.facebook.buck.testutil.FakeProjectFilesystem) ProjectFilesystem(com.facebook.buck.io.ProjectFilesystem) DefaultTargetNodeToBuildRuleTransformer(com.facebook.buck.rules.DefaultTargetNodeToBuildRuleTransformer) NdkLibrary(com.facebook.buck.android.NdkLibrary) NdkLibraryBuilder(com.facebook.buck.android.NdkLibraryBuilder) BuildRuleResolver(com.facebook.buck.rules.BuildRuleResolver) Test(org.junit.Test)

Example 3 with NdkLibrary

use of com.facebook.buck.android.NdkLibrary 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;
}
Also used : Path(java.nio.file.Path) PathSourcePath(com.facebook.buck.rules.PathSourcePath) SourcePath(com.facebook.buck.rules.SourcePath) CxxLibrary(com.facebook.buck.cxx.CxxLibrary) AndroidBinary(com.facebook.buck.android.AndroidBinary) JavaBinary(com.facebook.buck.jvm.java.JavaBinary) AndroidResource(com.facebook.buck.android.AndroidResource) JavaLibrary(com.facebook.buck.jvm.java.JavaLibrary) AndroidLibrary(com.facebook.buck.android.AndroidLibrary) BuildTarget(com.facebook.buck.model.BuildTarget) JavaTest(com.facebook.buck.jvm.java.JavaTest) BuildRule(com.facebook.buck.rules.BuildRule) NdkLibrary(com.facebook.buck.android.NdkLibrary) KeystoreProperties(com.facebook.buck.android.KeystoreProperties)

Aggregations

NdkLibrary (com.facebook.buck.android.NdkLibrary)3 AndroidResource (com.facebook.buck.android.AndroidResource)2 CxxLibrary (com.facebook.buck.cxx.CxxLibrary)2 JavaLibrary (com.facebook.buck.jvm.java.JavaLibrary)2 JavaTest (com.facebook.buck.jvm.java.JavaTest)2 BuildTarget (com.facebook.buck.model.BuildTarget)2 BuildRule (com.facebook.buck.rules.BuildRule)2 PathSourcePath (com.facebook.buck.rules.PathSourcePath)2 SourcePath (com.facebook.buck.rules.SourcePath)2 Path (java.nio.file.Path)2 AndroidBinary (com.facebook.buck.android.AndroidBinary)1 AndroidLibrary (com.facebook.buck.android.AndroidLibrary)1 AndroidPrebuiltAar (com.facebook.buck.android.AndroidPrebuiltAar)1 KeystoreProperties (com.facebook.buck.android.KeystoreProperties)1 NdkLibraryBuilder (com.facebook.buck.android.NdkLibraryBuilder)1 ProjectFilesystem (com.facebook.buck.io.ProjectFilesystem)1 JavaBinary (com.facebook.buck.jvm.java.JavaBinary)1 PrebuiltJar (com.facebook.buck.jvm.java.PrebuiltJar)1 BuildRuleResolver (com.facebook.buck.rules.BuildRuleResolver)1 DefaultTargetNodeToBuildRuleTransformer (com.facebook.buck.rules.DefaultTargetNodeToBuildRuleTransformer)1