Example #1
0
  @Override
  protected ImmutableList<String> getShellCommandInternal(ExecutionContext context) {
    Optional<Path> ndkRoot = context.getAndroidPlatformTarget().getNdkDirectory();
    if (!ndkRoot.isPresent()) {
      throw new HumanReadableException(
          "Must define a local.properties file"
              + " with a property named 'ndk.dir' that points to the absolute path of"
              + " your Android NDK directory, or set ANDROID_NDK.");
    }
    Optional<Path> ndkBuild =
        new ExecutableFinder().getOptionalExecutable(Paths.get("ndk-build"), ndkRoot.get());
    if (!ndkBuild.isPresent()) {
      throw new HumanReadableException("Unable to find ndk-build");
    }

    ConcurrencyLimit concurrencyLimit = context.getConcurrencyLimit();

    ImmutableList.Builder<String> builder = ImmutableList.builder();
    builder.add(
        ndkBuild.get().toAbsolutePath().toString(),
        "-j",
        // TODO(user): using -j here is wrong.  It lets make run too many work when we do other
        // work in parallel.  Instead, implement the GNU Make job server so make and Buck can
        // coordinate job concurrency.
        Integer.toString(concurrencyLimit.threadLimit),
        "-C",
        this.root.toString());

    if (concurrencyLimit.loadLimit < Double.POSITIVE_INFINITY) {
      builder.add("--load-average", Double.toString(concurrencyLimit.loadLimit));
    }

    Iterable<String> flags = Iterables.transform(this.flags, macroExpander);
    builder.addAll(flags);

    ProjectFilesystem projectFilesystem = context.getProjectFilesystem();
    Function<Path, Path> absolutifier = projectFilesystem.getAbsolutifier();

    // We want relative, not absolute, paths in the debug-info for binaries we build using
    // ndk_library.  Absolute paths are machine-specific, but relative ones should be the
    // same everywhere.

    Path relativePathToProject =
        absolutifier.apply(this.root).relativize(projectFilesystem.getRootPath());
    builder.add(
        "APP_PROJECT_PATH=" + absolutifier.apply(buildArtifactsDirectory) + File.separatorChar,
        "APP_BUILD_SCRIPT=" + absolutifier.apply(makefile),
        "NDK_OUT=" + absolutifier.apply(buildArtifactsDirectory) + File.separatorChar,
        "NDK_LIBS_OUT=" + projectFilesystem.resolve(binDirectory),
        "BUCK_PROJECT_DIR=" + relativePathToProject);

    // Suppress the custom build step messages (e.g. "Compile++ ...").
    if (Platform.detect() == Platform.WINDOWS) {
      builder.add("host-echo-build-step=@REM");
    } else {
      builder.add("host-echo-build-step=@#");
    }

    // If we're running verbosely, force all the subcommands from the ndk build to be printed out.
    if (context.getVerbosity().shouldPrintCommand()) {
      builder.add("V=1");
      // Otherwise, suppress everything, including the "make: entering directory..." messages.
    } else {
      builder.add("--silent");
    }

    return builder.build();
  }