Ejemplo n.º 1
0
  @VisibleForTesting
  static AppleCxxPlatform buildWithExecutableChecker(
      AppleSdk targetSdk,
      String minVersion,
      String targetArchitecture,
      AppleSdkPaths sdkPaths,
      BuckConfig buckConfig,
      ExecutableFinder executableFinder) {

    ImmutableList.Builder<Path> toolSearchPathsBuilder = ImmutableList.builder();
    // Search for tools from most specific to least specific.
    toolSearchPathsBuilder
        .add(sdkPaths.getSdkPath().resolve(USR_BIN))
        .add(sdkPaths.getSdkPath().resolve("Developer").resolve(USR_BIN))
        .add(sdkPaths.getPlatformPath().resolve("Developer").resolve(USR_BIN));
    for (Path toolchainPath : sdkPaths.getToolchainPaths()) {
      toolSearchPathsBuilder.add(toolchainPath.resolve(USR_BIN));
    }
    if (sdkPaths.getDeveloperPath().isPresent()) {
      toolSearchPathsBuilder.add(sdkPaths.getDeveloperPath().get().resolve(USR_BIN));
      toolSearchPathsBuilder.add(sdkPaths.getDeveloperPath().get().resolve("Tools"));
    }
    ImmutableList<Path> toolSearchPaths = toolSearchPathsBuilder.build();

    // TODO(user): Add more and better cflags.
    ImmutableList.Builder<String> cflagsBuilder = ImmutableList.builder();
    cflagsBuilder.add("-isysroot", sdkPaths.getSdkPath().toString());
    cflagsBuilder.add("-arch", targetArchitecture);
    switch (targetSdk.getApplePlatform().getName()) {
      case ApplePlatform.Name.IPHONEOS:
        cflagsBuilder.add("-mios-version-min=" + minVersion);
        break;
      case ApplePlatform.Name.IPHONESIMULATOR:
        cflagsBuilder.add("-mios-simulator-version-min=" + minVersion);
        break;
      default:
        // For Mac builds, -mmacosx-version-min=<version>.
        cflagsBuilder.add(
            "-m" + targetSdk.getApplePlatform().getName() + "-version-min=" + minVersion);
        break;
    }

    ImmutableList<String> ldflags = ImmutableList.of("-sdk_version", targetSdk.getVersion());

    ImmutableList.Builder<String> versionsBuilder = ImmutableList.builder();
    versionsBuilder.add(targetSdk.getVersion());
    for (AppleToolchain toolchain : targetSdk.getToolchains()) {
      versionsBuilder.add(toolchain.getVersion());
    }
    String version = Joiner.on(':').join(versionsBuilder.build());

    Tool clangPath =
        new VersionedTool(
            getToolPath("clang", toolSearchPaths, executableFinder),
            ImmutableList.<String>of(),
            "apple-clang",
            version);

    Tool clangXxPath =
        new VersionedTool(
            getToolPath("clang++", toolSearchPaths, executableFinder),
            ImmutableList.<String>of(),
            "apple-clang++",
            version);

    Tool ar =
        new VersionedTool(
            getToolPath("ar", toolSearchPaths, executableFinder),
            ImmutableList.<String>of(),
            "apple-ar",
            version);

    Tool actool =
        new VersionedTool(
            getToolPath("actool", toolSearchPaths, executableFinder),
            ImmutableList.<String>of(),
            "apple-actool",
            version);

    Tool ibtool =
        new VersionedTool(
            getToolPath("ibtool", toolSearchPaths, executableFinder),
            ImmutableList.<String>of(),
            "apple-ibtool",
            version);

    Tool xctest =
        new VersionedTool(
            getToolPath("xctest", toolSearchPaths, executableFinder),
            ImmutableList.<String>of(),
            "apple-xctest",
            version);

    Optional<Tool> otest = getOptionalTool("otest", toolSearchPaths, executableFinder, version);

    Tool dsymutil =
        new VersionedTool(
            getToolPath("dsymutil", toolSearchPaths, executableFinder),
            ImmutableList.<String>of(),
            "apple-dsymutil",
            version);

    CxxBuckConfig config = new CxxBuckConfig(buckConfig);

    ImmutableFlavor targetFlavor =
        ImmutableFlavor.of(
            ImmutableFlavor.replaceInvalidCharacters(
                targetSdk.getName() + "-" + targetArchitecture));

    ImmutableBiMap.Builder<Path, Path> sanitizerPaths = ImmutableBiMap.builder();
    sanitizerPaths.put(sdkPaths.getSdkPath(), Paths.get("APPLE_SDKROOT"));
    sanitizerPaths.put(sdkPaths.getPlatformPath(), Paths.get("APPLE_PLATFORM_DIR"));
    if (sdkPaths.getDeveloperPath().isPresent()) {
      sanitizerPaths.put(sdkPaths.getDeveloperPath().get(), Paths.get("APPLE_DEVELOPER_DIR"));
    }

    DebugPathSanitizer debugPathSanitizer =
        new DebugPathSanitizer(250, File.separatorChar, Paths.get("."), sanitizerPaths.build());

    ImmutableList<String> cflags = cflagsBuilder.build();

    CxxPlatform cxxPlatform =
        CxxPlatforms.build(
            targetFlavor,
            Platform.MACOS,
            config,
            clangPath,
            clangPath,
            new ClangCompiler(clangPath),
            new ClangCompiler(clangXxPath),
            clangPath,
            clangXxPath,
            clangXxPath,
            Optional.of(CxxPlatform.LinkerType.DARWIN),
            clangXxPath,
            ldflags,
            new BsdArchiver(ar),
            cflags,
            ImmutableList.<String>of(),
            getOptionalTool("lex", toolSearchPaths, executableFinder, version),
            getOptionalTool("yacc", toolSearchPaths, executableFinder, version),
            Optional.of(debugPathSanitizer));

    return AppleCxxPlatform.builder()
        .setCxxPlatform(cxxPlatform)
        .setAppleSdk(targetSdk)
        .setAppleSdkPaths(sdkPaths)
        .setActool(actool)
        .setIbtool(ibtool)
        .setXctest(xctest)
        .setOtest(otest)
        .setDsymutil(dsymutil)
        .build();
  }
Ejemplo n.º 2
0
  AppleBundle(
      BuildRuleParams params,
      SourcePathResolver resolver,
      Either<AppleBundleExtension, String> extension,
      SourcePath infoPlist,
      Map<String, String> infoPlistSubstitutions,
      Optional<BuildRule> binary,
      AppleBundleDestinations destinations,
      Set<SourcePath> resourceDirs,
      Set<SourcePath> resourceFiles,
      Set<SourcePath> dirsContainingResourceDirs,
      ImmutableSet<SourcePath> extensionBundlePaths,
      Optional<ImmutableSet<SourcePath>> resourceVariantFiles,
      Tool ibtool,
      Tool dsymutil,
      Tool strip,
      Optional<AppleAssetCatalog> assetCatalog,
      Set<BuildTarget> tests,
      AppleSdk sdk,
      ImmutableSet<CodeSignIdentity> allValidCodeSignIdentities,
      Optional<SourcePath> provisioningProfileSearchPath) {
    super(params, resolver);
    this.extension =
        extension.isLeft() ? extension.getLeft().toFileExtension() : extension.getRight();
    this.infoPlist = infoPlist;
    this.infoPlistSubstitutions = ImmutableMap.copyOf(infoPlistSubstitutions);
    this.binary = binary;
    this.destinations = destinations;
    this.resourceDirs = resourceDirs;
    this.resourceFiles = resourceFiles;
    this.dirsContainingResourceDirs = dirsContainingResourceDirs;
    this.extensionBundlePaths = extensionBundlePaths;
    this.resourceVariantFiles = resourceVariantFiles;
    this.ibtool = ibtool;
    this.dsymutil = dsymutil;
    this.strip = strip;
    this.assetCatalog = assetCatalog;
    this.binaryName = getBinaryName(getBuildTarget());
    this.bundleRoot = getBundleRoot(getBuildTarget(), this.extension);
    this.binaryPath = this.destinations.getExecutablesPath().resolve(this.binaryName);
    this.tests = ImmutableSortedSet.copyOf(tests);
    this.platformName = sdk.getApplePlatform().getName();
    this.sdkName = sdk.getName();

    // We need to resolve the possible set of profiles and code sign identity at construction time
    // because they form part of the rule key.
    if (binary.isPresent() && ApplePlatform.needsCodeSign(this.platformName)) {
      final Path searchPath;
      if (provisioningProfileSearchPath.isPresent()) {
        searchPath = resolver.getResolvedPath(provisioningProfileSearchPath.get());
      } else {
        searchPath =
            Paths.get(
                System.getProperty("user.home") + "/Library/MobileDevice/Provisioning Profiles");
      }

      Optional<ImmutableSet<ProvisioningProfileMetadata>> provisioningProfiles;
      try {
        provisioningProfiles =
            Optional.of(ProvisioningProfileCopyStep.findProfilesInPath(searchPath));
      } catch (InterruptedException e) {
        // We get here if the user pressed Ctrl-C during the profile discovery step.
        // In this case, we'll fail anyway since the set of profiles will be empty.
        provisioningProfiles = Optional.of(ImmutableSet.<ProvisioningProfileMetadata>of());
      }
      this.provisioningProfiles = provisioningProfiles;

      Optional<CodeSignIdentity> foundIdentity = Optional.absent();
      Optional<String> customIdentity =
          InfoPlistSubstitution.getVariableExpansionForPlatform(
              CODE_SIGN_IDENTITY, this.platformName, this.infoPlistSubstitutions);
      if (customIdentity.isPresent()) {
        LOG.debug("Bundle specifies custom code signing identity: " + customIdentity.get());
        if (CodeSignIdentity.isHash(customIdentity.get())) {
          for (CodeSignIdentity identity : allValidCodeSignIdentities) {
            if (identity.getHash().equals(customIdentity.get())) {
              foundIdentity = Optional.of(identity);
              break;
            }
          }
        } else {
          for (CodeSignIdentity identity : allValidCodeSignIdentities) {
            if (identity.getFullName().startsWith(customIdentity.get())) {
              foundIdentity = Optional.of(identity);
              break;
            }
          }
        }
      } else if (!allValidCodeSignIdentities.isEmpty()) {
        LOG.debug("Using default code signing identity");
        Iterator<CodeSignIdentity> it = allValidCodeSignIdentities.iterator();
        foundIdentity = Optional.of(it.next());
      }
      if (!foundIdentity.isPresent()) {
        throw new HumanReadableException(
            "The platform "
                + platformName
                + " for this target "
                + "requires code signing but couldn't find a compatible code signing identity to use.");
      }
      LOG.debug("Code signing identity is " + foundIdentity.toString());
      this.codeSignIdentity = foundIdentity;
    } else {
      this.provisioningProfiles = Optional.absent();
      this.codeSignIdentity = Optional.absent();
    }
  }