@Override
  public <A extends Arg> AppleBundle createBuildRule(
      TargetGraph targetGraph, BuildRuleParams params, BuildRuleResolver resolver, A args) {
    AppleCxxPlatform appleCxxPlatform = getAppleCxxPlatformForBuildTarget(params.getBuildTarget());
    AppleBundleDestinations destinations =
        AppleBundleDestinations.platformDestinations(
            appleCxxPlatform.getAppleSdk().getApplePlatform());

    ImmutableSet.Builder<SourcePath> bundleDirsBuilder = ImmutableSet.builder();
    ImmutableSet.Builder<SourcePath> dirsContainingResourceDirsBuilder = ImmutableSet.builder();
    ImmutableSet.Builder<SourcePath> bundleFilesBuilder = ImmutableSet.builder();
    ImmutableSet.Builder<SourcePath> bundleVariantFilesBuilder = ImmutableSet.builder();
    AppleResources.collectResourceDirsAndFiles(
        targetGraph,
        Preconditions.checkNotNull(targetGraph.get(params.getBuildTarget())),
        bundleDirsBuilder,
        dirsContainingResourceDirsBuilder,
        bundleFilesBuilder,
        bundleVariantFilesBuilder);
    ImmutableSet<SourcePath> bundleDirs = bundleDirsBuilder.build();
    ImmutableSet<SourcePath> dirsContainingResourceDirs = dirsContainingResourceDirsBuilder.build();
    ImmutableSet<SourcePath> bundleFiles = bundleFilesBuilder.build();
    ImmutableSet<SourcePath> bundleVariantFiles = bundleVariantFilesBuilder.build();

    SourcePathResolver sourcePathResolver = new SourcePathResolver(resolver);

    Optional<AppleAssetCatalog> assetCatalog =
        AppleDescriptions.createBuildRuleForTransitiveAssetCatalogDependencies(
            targetGraph,
            params,
            sourcePathResolver,
            appleCxxPlatform.getAppleSdk().getApplePlatform(),
            appleCxxPlatform.getActool());

    // TODO(user): Sort through the changes needed to make project generation work with
    // binary being optional.
    BuildRule flavoredBinaryRule = getFlavoredBinaryRule(targetGraph, params, resolver, args);
    BuildRuleParams bundleParamsWithFlavoredBinaryDep =
        getBundleParamsWithUpdatedDeps(
            params,
            args.binary,
            ImmutableSet.<BuildRule>builder()
                .add(flavoredBinaryRule)
                .addAll(assetCatalog.asSet())
                .addAll(
                    BuildRules.toBuildRulesFor(
                        params.getBuildTarget(),
                        resolver,
                        SourcePaths.filterBuildTargetSourcePaths(
                            Iterables.concat(
                                bundleFiles,
                                bundleDirs,
                                dirsContainingResourceDirs,
                                bundleVariantFiles))))
                .build());

    ImmutableMap<SourcePath, String> extensionBundlePaths =
        collectFirstLevelAppleDependencyBundles(params.getDeps(), destinations);

    return new AppleBundle(
        bundleParamsWithFlavoredBinaryDep,
        sourcePathResolver,
        args.extension,
        args.productName,
        args.infoPlist,
        args.infoPlistSubstitutions.get(),
        Optional.of(flavoredBinaryRule),
        destinations,
        bundleDirs,
        bundleFiles,
        dirsContainingResourceDirs,
        extensionBundlePaths,
        Optional.of(bundleVariantFiles),
        appleCxxPlatform.getIbtool(),
        appleCxxPlatform.getDsymutil(),
        appleCxxPlatform.getCxxPlatform().getStrip(),
        assetCatalog,
        args.getTests(),
        appleCxxPlatform.getAppleSdk(),
        codeSignIdentityStore,
        provisioningProfileStore,
        AppleBundle.DebugInfoFormat.DSYM);
  }
  /** Propagate the bundle's platform flavors to its dependents. */
  @Override
  public ImmutableSet<BuildTarget> findDepsForTargetFromConstructorArgs(
      BuildTarget buildTarget,
      Function<Optional<String>, Path> cellRoots,
      AppleBundleDescription.Arg constructorArg) {
    if (!constructorArg.deps.isPresent()) {
      return ImmutableSet.of();
    }

    if (!cxxPlatformFlavorDomain.containsAnyOf(buildTarget.getFlavors())) {
      buildTarget =
          BuildTarget.builder(buildTarget)
              .addAllFlavors(ImmutableSet.of(defaultCxxPlatform.getFlavor()))
              .build();
    }

    Optional<FatBinaryInfo> fatBinaryInfo =
        FatBinaryInfo.create(platformFlavorsToAppleCxxPlatforms, buildTarget);
    CxxPlatform cxxPlatform;
    if (fatBinaryInfo.isPresent()) {
      AppleCxxPlatform appleCxxPlatform = fatBinaryInfo.get().getRepresentativePlatform();
      cxxPlatform = appleCxxPlatform.getCxxPlatform();
    } else {
      cxxPlatform = getCxxPlatformForBuildTarget(buildTarget);
    }

    String platformName = cxxPlatform.getFlavor().getName();
    final Flavor actualWatchFlavor;
    if (ApplePlatform.isSimulator(platformName)) {
      actualWatchFlavor = ImmutableFlavor.builder().name("watchsimulator-i386").build();
    } else if (platformName.startsWith(ApplePlatform.Name.IPHONEOS)
        || platformName.startsWith(ApplePlatform.Name.WATCHOS)) {
      actualWatchFlavor = ImmutableFlavor.builder().name("watchos-armv7k").build();
    } else {
      actualWatchFlavor = ImmutableFlavor.builder().name(platformName).build();
    }

    FluentIterable<BuildTarget> depsExcludingBinary =
        FluentIterable.from(constructorArg.deps.get())
            .filter(Predicates.not(Predicates.equalTo(constructorArg.binary)));

    FluentIterable<BuildTarget> targetsWithPlatformFlavors =
        depsExcludingBinary.filter(BuildTargets.containsFlavors(cxxPlatformFlavorDomain));

    FluentIterable<BuildTarget> targetsWithoutPlatformFlavors =
        depsExcludingBinary.filter(
            Predicates.not(BuildTargets.containsFlavors(cxxPlatformFlavorDomain)));

    FluentIterable<BuildTarget> watchTargets =
        targetsWithoutPlatformFlavors
            .filter(BuildTargets.containsFlavor(WATCH))
            .transform(
                new Function<BuildTarget, BuildTarget>() {
                  @Override
                  public BuildTarget apply(BuildTarget input) {
                    return BuildTarget.builder(input.withoutFlavors(ImmutableSet.of(WATCH)))
                        .addFlavors(actualWatchFlavor)
                        .build();
                  }
                });

    targetsWithoutPlatformFlavors =
        targetsWithoutPlatformFlavors.filter(Predicates.not(BuildTargets.containsFlavor(WATCH)));

    return ImmutableSet.<BuildTarget>builder()
        .addAll(targetsWithPlatformFlavors)
        .addAll(watchTargets)
        .addAll(
            BuildTargets.propagateFlavorDomains(
                buildTarget,
                ImmutableSet.<FlavorDomain<?>>of(cxxPlatformFlavorDomain),
                targetsWithoutPlatformFlavors))
        .build();
  }
Beispiel #3
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();
  }