예제 #1
0
 private void addResourceProcessingSteps(
     Path sourcePath, Path destinationPath, ImmutableList.Builder<Step> stepsBuilder) {
   String sourcePathExtension =
       Files.getFileExtension(sourcePath.toString()).toLowerCase(Locale.US);
   switch (sourcePathExtension) {
     case "plist":
     case "stringsdict":
       LOG.debug("Converting plist %s to binary plist %s", sourcePath, destinationPath);
       stepsBuilder.add(
           new PlistProcessStep(
               sourcePath,
               destinationPath,
               ImmutableMap.<String, NSObject>of(),
               ImmutableMap.<String, NSObject>of(),
               PlistProcessStep.OutputFormat.BINARY));
       break;
     case "xib":
       String compiledNibFilename =
           Files.getNameWithoutExtension(destinationPath.toString()) + ".nib";
       Path compiledNibPath = destinationPath.getParent().resolve(compiledNibFilename);
       LOG.debug("Compiling XIB %s to NIB %s", sourcePath, destinationPath);
       stepsBuilder.add(
           new IbtoolStep(ibtool.getCommandPrefix(getResolver()), sourcePath, compiledNibPath));
       break;
     default:
       stepsBuilder.add(CopyStep.forFile(sourcePath, destinationPath));
       break;
   }
 }
예제 #2
0
 public void addStepsToCopyExtensionBundlesDependencies(ImmutableList.Builder<Step> stepsBuilder) {
   for (SourcePath sourcePath : extensionBundlePaths) {
     Path plugInsDestPath = bundleRoot.resolve(destinations.getPlugInsPath());
     stepsBuilder.add(new MkdirStep(plugInsDestPath));
     stepsBuilder.add(
         CopyStep.forDirectory(
             getResolver().getPath(sourcePath),
             plugInsDestPath,
             CopyStep.DirectoryMode.DIRECTORY_AND_CONTENTS));
   }
 }
예제 #3
0
  @Override
  public ImmutableList<Step> getBuildSteps(
      BuildContext context, final BuildableContext buildableContext) {
    ImmutableList.Builder<Step> steps = ImmutableList.builder();

    // Create a copy of the JAR in case it was generated by another rule.
    Path resolvedBinaryJar = getResolver().getAbsolutePath(binaryJar);
    steps.add(new MkdirStep(getProjectFilesystem(), copiedBinaryJar.getParent()));
    steps.add(CopyStep.forFile(getProjectFilesystem(), resolvedBinaryJar, copiedBinaryJar));
    buildableContext.recordArtifact(copiedBinaryJar);

    // Create a step to compute the ABI key.
    steps.add(new MkdirStep(getProjectFilesystem(), internalAbiJar.getParent()));
    steps.add(new RmStep(getProjectFilesystem(), internalAbiJar, true));
    steps.add(
        new CalculateAbiStep(
            buildableContext, getProjectFilesystem(), resolvedBinaryJar, internalAbiJar));

    JavaLibraryRules.addAccumulateClassNamesStep(this, buildableContext, steps);

    return steps.build();
  }
예제 #4
0
  @Override
  public ImmutableList<Step> getBuildSteps(
      BuildContext context, BuildableContext buildableContext) {
    ImmutableList.Builder<Step> stepsBuilder = ImmutableList.builder();

    Path metadataPath = getMetadataPath();

    Path infoPlistInputPath = getResolver().getPath(infoPlist);
    Path infoPlistSubstitutionTempPath = BuildTargets.getScratchPath(getBuildTarget(), "%s.plist");
    Path infoPlistOutputPath = metadataPath.resolve("Info.plist");

    stepsBuilder.add(
        new MakeCleanDirectoryStep(bundleRoot),
        new MkdirStep(metadataPath),
        // TODO(user): This is only appropriate for .app bundles.
        new WriteFileStep("APPLWRUN", metadataPath.resolve("PkgInfo"), /* executable */ false),
        new FindAndReplaceStep(
            infoPlistInputPath,
            infoPlistSubstitutionTempPath,
            InfoPlistSubstitution.createVariableExpansionFunction(
                withDefaults(
                    infoPlistSubstitutions,
                    ImmutableMap.of(
                        "EXECUTABLE_NAME", binaryName,
                        "PRODUCT_NAME", binaryName)))),
        new PlistProcessStep(
            infoPlistSubstitutionTempPath,
            infoPlistOutputPath,
            getInfoPlistAdditionalKeys(platformName, sdkName),
            getInfoPlistOverrideKeys(platformName),
            PlistProcessStep.OutputFormat.BINARY));

    if (binary.isPresent() && binary.get().getPathToOutput() != null) {
      stepsBuilder.add(new MkdirStep(bundleRoot.resolve(this.destinations.getExecutablesPath())));
      Path bundleBinaryPath = bundleRoot.resolve(binaryPath);
      stepsBuilder.add(CopyStep.forFile(binary.get().getPathToOutput(), bundleBinaryPath));
      stepsBuilder.add(
          new DsymStep(
              dsymutil.getCommandPrefix(getResolver()),
              bundleBinaryPath,
              bundleBinaryPath.resolveSibling(
                  bundleBinaryPath.getFileName().toString() + ".dSYM")));
      stepsBuilder.add(
          new DefaultShellStep(
              ImmutableList.<String>builder()
                  .addAll(strip.getCommandPrefix(getResolver()))
                  .add("-S")
                  .add(getProjectFilesystem().resolve(bundleBinaryPath).toString())
                  .build()));
    }

    Path bundleDestinationPath = bundleRoot.resolve(this.destinations.getResourcesPath());
    for (SourcePath dir : resourceDirs) {
      stepsBuilder.add(new MkdirStep(bundleDestinationPath));
      stepsBuilder.add(
          CopyStep.forDirectory(
              getResolver().getPath(dir),
              bundleDestinationPath,
              CopyStep.DirectoryMode.DIRECTORY_AND_CONTENTS));
    }
    for (SourcePath dir : dirsContainingResourceDirs) {
      stepsBuilder.add(new MkdirStep(bundleDestinationPath));
      stepsBuilder.add(
          CopyStep.forDirectory(
              getResolver().getPath(dir),
              bundleDestinationPath,
              CopyStep.DirectoryMode.CONTENTS_ONLY));
    }
    for (SourcePath file : resourceFiles) {
      stepsBuilder.add(new MkdirStep(bundleDestinationPath));
      Path resolvedFilePath = getResolver().getPath(file);
      Path destinationPath = bundleDestinationPath.resolve(resolvedFilePath.getFileName());
      addResourceProcessingSteps(resolvedFilePath, destinationPath, stepsBuilder);
    }

    addStepsToCopyExtensionBundlesDependencies(stepsBuilder);

    if (resourceVariantFiles.isPresent()) {
      for (SourcePath variantSourcePath : resourceVariantFiles.get()) {
        Path variantFilePath = getResolver().getPath(variantSourcePath);

        Path variantDirectory = variantFilePath.getParent();
        if (variantDirectory == null || !variantDirectory.toString().endsWith(".lproj")) {
          throw new HumanReadableException(
              "Variant files have to be in a directory with name ending in '.lproj', "
                  + "but '%s' is not.",
              variantFilePath);
        }

        Path bundleVariantDestinationPath =
            bundleDestinationPath.resolve(variantDirectory.getFileName());
        stepsBuilder.add(new MkdirStep(bundleVariantDestinationPath));

        Path destinationPath = bundleVariantDestinationPath.resolve(variantFilePath.getFileName());
        addResourceProcessingSteps(variantFilePath, destinationPath, stepsBuilder);
      }
    }

    if (assetCatalog.isPresent()) {
      Path bundleDir = assetCatalog.get().getOutputDir();
      stepsBuilder.add(
          CopyStep.forDirectory(bundleDir, bundleRoot, CopyStep.DirectoryMode.CONTENTS_ONLY));
    }

    // Copy the .mobileprovision file if the platform requires it.
    if (provisioningProfiles.isPresent()) {
      Optional<Path> entitlementsPlist = Optional.absent();
      final String srcRoot =
          context.getProjectRoot().resolve(getBuildTarget().getBasePath()).toString();
      Optional<String> entitlementsPlistString =
          InfoPlistSubstitution.getVariableExpansionForPlatform(
              CODE_SIGN_ENTITLEMENTS,
              platformName,
              withDefaults(
                  infoPlistSubstitutions,
                  ImmutableMap.of(
                      "SOURCE_ROOT", srcRoot,
                      "SRCROOT", srcRoot)));
      if (entitlementsPlistString.isPresent()) {
        entitlementsPlist = Optional.of(Paths.get(entitlementsPlistString.get()));
      }

      final Path signingEntitlementsTempPath =
          BuildTargets.getScratchPath(getBuildTarget(), "%s.xcent");

      stepsBuilder.add(
          new ProvisioningProfileCopyStep(
              infoPlistOutputPath,
              Optional.<String>absent(), // Provisioning profile UUID -- find automatically.
              entitlementsPlist,
              provisioningProfiles.get(),
              bundleDestinationPath.resolve("embedded.mobileprovision"),
              signingEntitlementsTempPath));

      stepsBuilder.add(
          new CodeSignStep(
              bundleDestinationPath,
              signingEntitlementsTempPath,
              codeSignIdentity.get().getHash()));
    }

    // Ensure the bundle directory is archived so we can fetch it later.
    buildableContext.recordArtifact(getPathToOutput());

    return stepsBuilder.build();
  }
예제 #5
0
  @Override
  public ImmutableList<Step> getBuildSteps(
      BuildContext context, BuildableContext buildableContext) {
    ImmutableList.Builder<Step> commands = ImmutableList.builder();

    // Create temp folder to store the files going to be zipped
    commands.add(new MakeCleanDirectoryStep(getProjectFilesystem(), temp));

    // Remove the output .aar file
    commands.add(new RmStep(getProjectFilesystem(), pathToOutputFile, /* force delete */ true));

    // put manifest into tmp folder
    commands.add(
        CopyStep.forFile(
            getProjectFilesystem(),
            manifest.getPathToOutput(),
            temp.resolve("AndroidManifest.xml")));

    // put R.txt into tmp folder
    commands.add(
        CopyStep.forFile(
            getProjectFilesystem(),
            Preconditions.checkNotNull(androidResource.getPathToOutput()),
            temp.resolve("R.txt")));

    // put res/ and assets/ into tmp folder
    commands.add(
        CopyStep.forDirectory(
            getProjectFilesystem(),
            assembledResourceDirectory,
            temp.resolve("res"),
            CopyStep.DirectoryMode.CONTENTS_ONLY));
    commands.add(
        CopyStep.forDirectory(
            getProjectFilesystem(),
            assembledAssetsDirectory,
            temp.resolve("assets"),
            CopyStep.DirectoryMode.CONTENTS_ONLY));

    // Create our Uber-jar, and place it in the tmp folder.
    commands.add(
        new JarDirectoryStep(
            getProjectFilesystem(),
            temp.resolve("classes.jar"),
            ImmutableSet.copyOf(getTransitiveClasspathEntries().values()),
            null,
            null));

    // move native libs into tmp folder under jni/
    if (assembledNativeLibs.isPresent()) {
      commands.add(
          CopyStep.forDirectory(
              getProjectFilesystem(),
              assembledNativeLibs.get(),
              temp.resolve("jni"),
              CopyStep.DirectoryMode.CONTENTS_ONLY));
    }

    // move native assets into tmp folder under assets/lib/
    for (SourcePath dir : nativeLibAssetsDirectories) {
      CopyNativeLibraries.copyNativeLibrary(
          getProjectFilesystem(),
          getResolver().getPath(dir),
          temp.resolve("assets").resolve("lib"),
          ImmutableSet.<TargetCpuType>of(),
          commands);
    }

    // do the zipping
    commands.add(
        new ZipStep(
            getProjectFilesystem(),
            pathToOutputFile,
            ImmutableSet.<Path>of(),
            false,
            ZipStep.DEFAULT_COMPRESSION_LEVEL,
            temp));

    return commands.build();
  }
예제 #6
0
  public static void copyNativeLibrary(
      final ProjectFilesystem filesystem,
      Path sourceDir,
      final Path destinationDir,
      ImmutableSet<TargetCpuType> cpuFilters,
      ImmutableList.Builder<Step> steps) {

    if (cpuFilters.isEmpty()) {
      steps.add(
          CopyStep.forDirectory(sourceDir, destinationDir, CopyStep.DirectoryMode.CONTENTS_ONLY));
    } else {
      for (TargetCpuType cpuType : cpuFilters) {
        Optional<String> abiDirectoryComponent = getAbiDirectoryComponent(cpuType);
        Preconditions.checkState(abiDirectoryComponent.isPresent());

        final Path libSourceDir = sourceDir.resolve(abiDirectoryComponent.get());
        Path libDestinationDir = destinationDir.resolve(abiDirectoryComponent.get());

        final MkdirStep mkDirStep = new MkdirStep(libDestinationDir);
        final CopyStep copyStep =
            CopyStep.forDirectory(
                libSourceDir, libDestinationDir, CopyStep.DirectoryMode.CONTENTS_ONLY);
        steps.add(
            new Step() {
              @Override
              public int execute(ExecutionContext context) {
                // TODO(simons): Using a projectfilesystem here is almost definitely wrong.
                // This is because each library may come from different build rules, which may be in
                // different repos --- this check works by coincidence.
                if (!filesystem.exists(libSourceDir)) {
                  return 0;
                }
                if (mkDirStep.execute(context) == 0 && copyStep.execute(context) == 0) {
                  return 0;
                }
                return 1;
              }

              @Override
              public String getShortName() {
                return "copy_native_libraries";
              }

              @Override
              public String getDescription(ExecutionContext context) {
                ImmutableList.Builder<String> stringBuilder = ImmutableList.builder();
                stringBuilder.add(String.format("[ -d %s ]", libSourceDir.toString()));
                stringBuilder.add(mkDirStep.getDescription(context));
                stringBuilder.add(copyStep.getDescription(context));
                return Joiner.on(" && ").join(stringBuilder.build());
              }
            });
      }
    }

    // Rename native files named like "*-disguised-exe" to "lib*.so" so they will be unpacked
    // by the Android package installer.  Then they can be executed like normal binaries
    // on the device.
    steps.add(
        new AbstractExecutionStep("rename_native_executables") {
          @Override
          public int execute(ExecutionContext context) {

            ProjectFilesystem filesystem = context.getProjectFilesystem();
            final ImmutableSet.Builder<Path> executablesBuilder = ImmutableSet.builder();
            try {
              filesystem.walkRelativeFileTree(
                  destinationDir,
                  new SimpleFileVisitor<Path>() {
                    @Override
                    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
                        throws IOException {
                      if (file.toString().endsWith("-disguised-exe")) {
                        executablesBuilder.add(file);
                      }
                      return FileVisitResult.CONTINUE;
                    }
                  });
              for (Path exePath : executablesBuilder.build()) {
                Path fakeSoPath =
                    Paths.get(
                        MorePaths.pathWithUnixSeparators(exePath)
                            .replaceAll("/([^/]+)-disguised-exe$", "/lib$1.so"));
                filesystem.move(exePath, fakeSoPath);
              }
            } catch (IOException e) {
              context.logError(e, "Renaming native executables failed.");
              return 1;
            }
            return 0;
          }
        });
  }