Search in sources :

Example 16 with SourceTreePath

use of com.facebook.buck.apple.xcode.xcodeproj.SourceTreePath in project buck by facebook.

the class ProjectGenerator method addSceneKitAssetsIntoTarget.

private void addSceneKitAssetsIntoTarget(TargetNode<? extends CxxLibraryDescription.Arg, ?> targetNode, PBXGroup targetGroup) throws IOException {
    ImmutableSet<AppleWrapperResourceArg> allSceneKitAssets = AppleBuildRules.collectTransitiveBuildRules(targetGraph, Optional.of(dependenciesCache), AppleBuildRules.SCENEKIT_ASSETS_DESCRIPTION_CLASSES, ImmutableList.of(targetNode));
    for (final AppleWrapperResourceArg sceneKitAssets : allSceneKitAssets) {
        PBXGroup resourcesGroup = targetGroup.getOrCreateChildGroupByName("Resources");
        resourcesGroup.getOrCreateFileReferenceBySourceTreePath(new SourceTreePath(PBXReference.SourceTree.SOURCE_ROOT, pathRelativizer.outputDirToRootRelative(sceneKitAssets.path), Optional.empty()));
    }
}
Also used : SourceTreePath(com.facebook.buck.apple.xcode.xcodeproj.SourceTreePath) PBXGroup(com.facebook.buck.apple.xcode.xcodeproj.PBXGroup) AppleWrapperResourceArg(com.facebook.buck.apple.AppleWrapperResourceArg)

Example 17 with SourceTreePath

use of com.facebook.buck.apple.xcode.xcodeproj.SourceTreePath in project buck by facebook.

the class ProjectGenerator method addCoreDataModelBuildPhase.

private void addCoreDataModelBuildPhase(PBXGroup targetGroup, Iterable<AppleWrapperResourceArg> dataModels) throws IOException {
    for (final AppleWrapperResourceArg dataModel : dataModels) {
        // Core data models go in the resources group also.
        PBXGroup resourcesGroup = targetGroup.getOrCreateChildGroupByName("Resources");
        if (CoreDataModelDescription.isVersionedDataModel(dataModel)) {
            // It's safe to do I/O here to figure out the current version because we're returning all
            // the versions and the file pointing to the current version from
            // getInputsToCompareToOutput(), so the rule will be correctly detected as stale if any of
            // them change.
            final String currentVersionFileName = ".xccurrentversion";
            final String currentVersionKey = "_XCCurrentVersionName";
            final XCVersionGroup versionGroup = resourcesGroup.getOrCreateChildVersionGroupsBySourceTreePath(new SourceTreePath(PBXReference.SourceTree.SOURCE_ROOT, pathRelativizer.outputDirToRootRelative(dataModel.path), Optional.empty()));
            projectFilesystem.walkRelativeFileTree(dataModel.path, new SimpleFileVisitor<Path>() {

                @Override
                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
                    if (dir.equals(dataModel.path)) {
                        return FileVisitResult.CONTINUE;
                    }
                    versionGroup.getOrCreateFileReferenceBySourceTreePath(new SourceTreePath(PBXReference.SourceTree.SOURCE_ROOT, pathRelativizer.outputDirToRootRelative(dir), Optional.empty()));
                    return FileVisitResult.SKIP_SUBTREE;
                }
            });
            Path currentVersionPath = dataModel.path.resolve(currentVersionFileName);
            try (InputStream in = projectFilesystem.newFileInputStream(currentVersionPath)) {
                NSObject rootObject;
                try {
                    rootObject = PropertyListParser.parse(in);
                } catch (IOException e) {
                    throw e;
                } catch (Exception e) {
                    rootObject = null;
                }
                if (!(rootObject instanceof NSDictionary)) {
                    throw new HumanReadableException("Malformed %s file.", currentVersionFileName);
                }
                NSDictionary rootDictionary = (NSDictionary) rootObject;
                NSObject currentVersionName = rootDictionary.objectForKey(currentVersionKey);
                if (!(currentVersionName instanceof NSString)) {
                    throw new HumanReadableException("Malformed %s file.", currentVersionFileName);
                }
                PBXFileReference ref = versionGroup.getOrCreateFileReferenceBySourceTreePath(new SourceTreePath(PBXReference.SourceTree.SOURCE_ROOT, pathRelativizer.outputDirToRootRelative(dataModel.path.resolve(currentVersionName.toString())), Optional.empty()));
                versionGroup.setCurrentVersion(Optional.of(ref));
            } catch (NoSuchFileException e) {
                if (versionGroup.getChildren().size() == 1) {
                    versionGroup.setCurrentVersion(Optional.of(Iterables.get(versionGroup.getChildren(), 0)));
                }
            }
        } else {
            resourcesGroup.getOrCreateFileReferenceBySourceTreePath(new SourceTreePath(PBXReference.SourceTree.SOURCE_ROOT, pathRelativizer.outputDirToRootRelative(dataModel.path), Optional.empty()));
        }
    }
}
Also used : SourceTreePath(com.facebook.buck.apple.xcode.xcodeproj.SourceTreePath) SourceTreePath(com.facebook.buck.apple.xcode.xcodeproj.SourceTreePath) Path(java.nio.file.Path) SourcePath(com.facebook.buck.rules.SourcePath) BuildTargetSourcePath(com.facebook.buck.rules.BuildTargetSourcePath) PathSourcePath(com.facebook.buck.rules.PathSourcePath) FrameworkPath(com.facebook.buck.rules.coercer.FrameworkPath) NSObject(com.dd.plist.NSObject) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) NSDictionary(com.dd.plist.NSDictionary) NoSuchFileException(java.nio.file.NoSuchFileException) FileVisitResult(java.nio.file.FileVisitResult) NSString(com.dd.plist.NSString) IOException(java.io.IOException) NSString(com.dd.plist.NSString) MacroException(com.facebook.buck.model.MacroException) NoSuchBuildTargetException(com.facebook.buck.parser.NoSuchBuildTargetException) IOException(java.io.IOException) NoSuchFileException(java.nio.file.NoSuchFileException) UncheckedExecutionException(com.google.common.util.concurrent.UncheckedExecutionException) HumanReadableException(com.facebook.buck.util.HumanReadableException) XCVersionGroup(com.facebook.buck.apple.xcode.xcodeproj.XCVersionGroup) HumanReadableException(com.facebook.buck.util.HumanReadableException) PBXGroup(com.facebook.buck.apple.xcode.xcodeproj.PBXGroup) AppleWrapperResourceArg(com.facebook.buck.apple.AppleWrapperResourceArg) BasicFileAttributes(java.nio.file.attribute.BasicFileAttributes) PBXFileReference(com.facebook.buck.apple.xcode.xcodeproj.PBXFileReference)

Example 18 with SourceTreePath

use of com.facebook.buck.apple.xcode.xcodeproj.SourceTreePath in project buck by facebook.

the class ProjectGenerator method generateBinaryTarget.

private PBXNativeTarget generateBinaryTarget(PBXProject project, Optional<? extends TargetNode<? extends HasAppleBundleFields, ?>> bundle, TargetNode<? extends CxxLibraryDescription.Arg, ?> targetNode, ProductType productType, String productOutputFormat, Optional<Path> infoPlistOptional, boolean includeFrameworks, ImmutableSet<AppleResourceDescription.Arg> recursiveResources, ImmutableSet<AppleResourceDescription.Arg> directResources, ImmutableSet<AppleAssetCatalogDescription.Arg> recursiveAssetCatalogs, ImmutableSet<AppleAssetCatalogDescription.Arg> directAssetCatalogs, ImmutableSet<AppleWrapperResourceArg> wrapperResources, Optional<Iterable<PBXBuildPhase>> copyFilesPhases, Optional<TargetNode<AppleBundleDescription.Arg, ?>> bundleLoaderNode) throws IOException {
    LOG.debug("Generating binary target for node %s", targetNode);
    TargetNode<?, ?> buildTargetNode = bundle.isPresent() ? bundle.get() : targetNode;
    final BuildTarget buildTarget = buildTargetNode.getBuildTarget();
    String buildTargetName = getProductNameForBuildTarget(buildTarget);
    CxxLibraryDescription.Arg arg = targetNode.getConstructorArg();
    NewNativeTargetProjectMutator mutator = new NewNativeTargetProjectMutator(pathRelativizer, this::resolveSourcePath);
    ImmutableSet<SourcePath> exportedHeaders = ImmutableSet.copyOf(getHeaderSourcePaths(arg.exportedHeaders));
    ImmutableSet<SourcePath> headers = ImmutableSet.copyOf(getHeaderSourcePaths(arg.headers));
    ImmutableMap<CxxSource.Type, ImmutableList<String>> langPreprocessorFlags = targetNode.getConstructorArg().langPreprocessorFlags;
    mutator.setTargetName(getXcodeTargetName(buildTarget)).setProduct(productType, buildTargetName, Paths.get(String.format(productOutputFormat, buildTargetName)));
    boolean isFocusedOnTarget = buildTarget.matchesUnflavoredTargets(focusModules);
    Optional<TargetNode<AppleNativeTargetDescriptionArg, ?>> appleTargetNode = targetNode.castArg(AppleNativeTargetDescriptionArg.class);
    if (!shouldGenerateHeaderSymlinkTreesOnly()) {
        if (isFocusedOnTarget) {
            mutator.setLangPreprocessorFlags(langPreprocessorFlags).setPublicHeaders(exportedHeaders).setPrefixHeader(arg.prefixHeader).setSourcesWithFlags(ImmutableSet.copyOf(arg.srcs)).setPrivateHeaders(headers).setRecursiveResources(recursiveResources).setDirectResources(directResources).setWrapperResources(wrapperResources);
        }
        if (bundle.isPresent() && isFocusedOnTarget) {
            HasAppleBundleFields bundleArg = bundle.get().getConstructorArg();
            mutator.setInfoPlist(Optional.of(bundleArg.getInfoPlist()));
        }
        mutator.setBridgingHeader(arg.bridgingHeader);
        if (appleTargetNode.isPresent() && isFocusedOnTarget) {
            AppleNativeTargetDescriptionArg appleArg = appleTargetNode.get().getConstructorArg();
            mutator = mutator.setExtraXcodeSources(ImmutableSet.copyOf(appleArg.extraXcodeSources));
        }
        if (options.contains(Option.CREATE_DIRECTORY_STRUCTURE) && isFocusedOnTarget) {
            mutator.setTargetGroupPath(StreamSupport.stream(buildTarget.getBasePath().spliterator(), false).map(Object::toString).collect(MoreCollectors.toImmutableList()));
        }
        if (!recursiveAssetCatalogs.isEmpty() && isFocusedOnTarget) {
            mutator.setRecursiveAssetCatalogs(recursiveAssetCatalogs);
        }
        if (!directAssetCatalogs.isEmpty() && isFocusedOnTarget) {
            mutator.setDirectAssetCatalogs(directAssetCatalogs);
        }
        if (includeFrameworks && isFocusedOnTarget) {
            ImmutableSet.Builder<FrameworkPath> frameworksBuilder = ImmutableSet.builder();
            frameworksBuilder.addAll(targetNode.getConstructorArg().frameworks);
            frameworksBuilder.addAll(targetNode.getConstructorArg().libraries);
            frameworksBuilder.addAll(collectRecursiveFrameworkDependencies(ImmutableList.of(targetNode)));
            mutator.setFrameworks(frameworksBuilder.build());
            mutator.setArchives(collectRecursiveLibraryDependencies(ImmutableList.of(targetNode)));
        }
        // TODO(Task #3772930): Go through all dependencies of the rule
        // and add any shell script rules here
        ImmutableList.Builder<TargetNode<?, ?>> preScriptPhases = ImmutableList.builder();
        ImmutableList.Builder<TargetNode<?, ?>> postScriptPhases = ImmutableList.builder();
        if (bundle.isPresent() && targetNode != bundle.get() && isFocusedOnTarget) {
            collectBuildScriptDependencies(targetGraph.getAll(bundle.get().getDeclaredDeps()), preScriptPhases, postScriptPhases);
        }
        collectBuildScriptDependencies(targetGraph.getAll(targetNode.getDeclaredDeps()), preScriptPhases, postScriptPhases);
        if (isFocusedOnTarget) {
            mutator.setPreBuildRunScriptPhasesFromTargetNodes(preScriptPhases.build());
            if (copyFilesPhases.isPresent()) {
                mutator.setCopyFilesPhases(copyFilesPhases.get());
            }
            mutator.setPostBuildRunScriptPhasesFromTargetNodes(postScriptPhases.build());
        }
    }
    NewNativeTargetProjectMutator.Result targetBuilderResult = mutator.buildTargetAndAddToProject(project, isFocusedOnTarget);
    PBXNativeTarget target = targetBuilderResult.target;
    Optional<PBXGroup> targetGroup = targetBuilderResult.targetGroup;
    ImmutableMap.Builder<String, String> extraSettingsBuilder = ImmutableMap.builder();
    ImmutableMap.Builder<String, String> defaultSettingsBuilder = ImmutableMap.builder();
    if (!shouldGenerateHeaderSymlinkTreesOnly()) {
        if (isFocusedOnTarget) {
            SourceTreePath buckFilePath = new SourceTreePath(PBXReference.SourceTree.SOURCE_ROOT, pathRelativizer.outputPathToBuildTargetPath(buildTarget).resolve(buildFileName), Optional.empty());
            PBXFileReference buckReference = targetGroup.get().getOrCreateFileReferenceBySourceTreePath(buckFilePath);
            buckReference.setExplicitFileType(Optional.of("text.script.python"));
        }
        // -- configurations
        extraSettingsBuilder.put("TARGET_NAME", buildTargetName).put("SRCROOT", pathRelativizer.outputPathToBuildTargetPath(buildTarget).toString());
        if (productType == ProductType.UI_TEST && isFocusedOnTarget) {
            if (bundleLoaderNode.isPresent()) {
                BuildTarget testTarget = bundleLoaderNode.get().getBuildTarget();
                extraSettingsBuilder.put("TEST_TARGET_NAME", getXcodeTargetName(testTarget));
            } else {
                throw new HumanReadableException("The test rule '%s' is configured with 'is_ui_test' but has no test_host_app", buildTargetName);
            }
        } else if (bundleLoaderNode.isPresent() && isFocusedOnTarget) {
            TargetNode<AppleBundleDescription.Arg, ?> bundleLoader = bundleLoaderNode.get();
            String bundleLoaderProductName = getProductNameForBuildTarget(bundleLoader.getBuildTarget());
            String bundleLoaderBundleName = bundleLoaderProductName + "." + getExtensionString(bundleLoader.getConstructorArg().getExtension());
            // NOTE(grp): This is a hack. We need to support both deep (OS X) and flat (iOS)
            // style bundles for the bundle loader, but at this point we don't know what platform
            // the bundle loader (or current target) is going to be built for. However, we can be
            // sure that it's the same as the target (presumably a test) we're building right now.
            //
            // Using that knowledge, we can do build setting tricks to defer choosing the bundle
            // loader path until Xcode build time, when the platform is known. There's no build
            // setting that conclusively says whether the current platform uses deep bundles:
            // that would be too easy. But in the cases we care about (unit test bundles), the
            // current bundle will have a style matching the style of the bundle loader app, so
            // we can take advantage of that to do the determination.
            //
            // Unfortunately, the build setting for the bundle structure (CONTENTS_FOLDER_PATH)
            // includes the WRAPPER_NAME, so we can't just interpolate that in. Instead, we have
            // to use another trick with build setting operations and evaluation. By using the
            // $(:file) operation, we can extract the last component of the contents path: either
            // "Contents" or the current bundle name. Then, we can interpolate with that expected
            // result in the build setting name to conditionally choose a different loader path.
            // The conditional that decides which path is used. This is a complex Xcode build setting
            // expression that expands to one of two values, depending on the last path component of
            // the CONTENTS_FOLDER_PATH variable. As described above, this will be either "Contents"
            // for deep bundles or the bundle file name itself for flat bundles. Finally, to santiize
            // the potentially invalid build setting names from the bundle file name, it converts that
            // to an identifier. We rely on BUNDLE_LOADER_BUNDLE_STYLE_CONDITIONAL_<bundle file name>
            // being undefined (and thus expanding to nothing) for the path resolution to work.
            //
            // The operations on the CONTENTS_FOLDER_PATH are documented here:
            // http://codeworkshop.net/posts/xcode-build-setting-transformations
            String bundleLoaderOutputPathConditional = "$(BUNDLE_LOADER_BUNDLE_STYLE_CONDITIONAL_$(CONTENTS_FOLDER_PATH:file:identifier))";
            // If the $(CONTENTS_FOLDER_PATH:file:identifier) expands to this, we add the deep bundle
            // path into the bundle loader. See above for the case when it will expand to this value.
            String bundleLoaderOutputPathDeepSetting = "BUNDLE_LOADER_BUNDLE_STYLE_CONDITIONAL_Contents";
            String bundleLoaderOutputPathDeepValue = "Contents/MacOS/";
            String bundleLoaderOutputPathValue = Joiner.on('/').join(getTargetOutputPath(bundleLoader), bundleLoaderBundleName, bundleLoaderOutputPathConditional, bundleLoaderProductName);
            extraSettingsBuilder.put(bundleLoaderOutputPathDeepSetting, bundleLoaderOutputPathDeepValue).put("BUNDLE_LOADER", bundleLoaderOutputPathValue).put("TEST_HOST", "$(BUNDLE_LOADER)");
        }
        if (infoPlistOptional.isPresent()) {
            Path infoPlistPath = pathRelativizer.outputDirToRootRelative(infoPlistOptional.get());
            extraSettingsBuilder.put("INFOPLIST_FILE", infoPlistPath.toString());
        }
        if (arg.bridgingHeader.isPresent()) {
            Path bridgingHeaderPath = pathRelativizer.outputDirToRootRelative(resolveSourcePath(arg.bridgingHeader.get()));
            extraSettingsBuilder.put("SWIFT_OBJC_BRIDGING_HEADER", Joiner.on('/').join("$(SRCROOT)", bridgingHeaderPath.toString()));
        }
        Optional<String> swiftVersion = swiftBuckConfig.getVersion();
        if (swiftVersion.isPresent()) {
            extraSettingsBuilder.put("SWIFT_VERSION", swiftVersion.get());
        }
        Optional<SourcePath> prefixHeaderOptional = targetNode.getConstructorArg().prefixHeader;
        if (prefixHeaderOptional.isPresent()) {
            Path prefixHeaderRelative = resolveSourcePath(prefixHeaderOptional.get());
            Path prefixHeaderPath = pathRelativizer.outputDirToRootRelative(prefixHeaderRelative);
            extraSettingsBuilder.put("GCC_PREFIX_HEADER", prefixHeaderPath.toString());
            extraSettingsBuilder.put("GCC_PRECOMPILE_PREFIX_HEADER", "YES");
        }
        extraSettingsBuilder.put("USE_HEADERMAP", "NO");
        defaultSettingsBuilder.put("REPO_ROOT", projectFilesystem.getRootPath().toAbsolutePath().normalize().toString());
        defaultSettingsBuilder.put(PRODUCT_NAME, getProductName(buildTargetNode, buildTarget));
        if (bundle.isPresent()) {
            defaultSettingsBuilder.put("WRAPPER_EXTENSION", getExtensionString(bundle.get().getConstructorArg().getExtension()));
        }
        // We use BUILT_PRODUCTS_DIR as the root for the everything being built. Target-
        // specific output is placed within CONFIGURATION_BUILD_DIR, inside BUILT_PRODUCTS_DIR.
        // That allows Copy Files build phases to reference files in the CONFIGURATION_BUILD_DIR
        // of other targets by using paths relative to the target-independent BUILT_PRODUCTS_DIR.
        defaultSettingsBuilder.put("BUILT_PRODUCTS_DIR", // $SYMROOT/Debug-iphonesimulator
        Joiner.on('/').join("$SYMROOT", "$CONFIGURATION$EFFECTIVE_PLATFORM_NAME"));
        defaultSettingsBuilder.put("CONFIGURATION_BUILD_DIR", "$BUILT_PRODUCTS_DIR");
        boolean nodeIsAppleLibrary = targetNode.getDescription() instanceof AppleLibraryDescription;
        boolean nodeIsCxxLibrary = targetNode.getDescription() instanceof CxxLibraryDescription;
        if (!bundle.isPresent() && (nodeIsAppleLibrary || nodeIsCxxLibrary)) {
            defaultSettingsBuilder.put("EXECUTABLE_PREFIX", "lib");
        }
        if (isFocusedOnTarget) {
            ImmutableSet<Path> recursiveHeaderSearchPaths = collectRecursiveHeaderSearchPaths(targetNode);
            ImmutableSet<Path> headerMapBases = recursiveHeaderSearchPaths.isEmpty() ? ImmutableSet.of() : ImmutableSet.of(pathRelativizer.outputDirToRootRelative(buildTargetNode.getFilesystem().getBuckPaths().getBuckOut()));
            ImmutableMap.Builder<String, String> appendConfigsBuilder = ImmutableMap.builder();
            appendConfigsBuilder.put("HEADER_SEARCH_PATHS", Joiner.on(' ').join(Iterables.concat(recursiveHeaderSearchPaths, headerMapBases))).put("LIBRARY_SEARCH_PATHS", Joiner.on(' ').join(collectRecursiveLibrarySearchPaths(ImmutableSet.of(targetNode)))).put("FRAMEWORK_SEARCH_PATHS", Joiner.on(' ').join(collectRecursiveFrameworkSearchPaths(ImmutableList.of(targetNode))));
            Iterable<String> otherCFlags = Iterables.concat(cxxBuckConfig.getFlags("cflags").orElse(DEFAULT_CFLAGS), collectRecursiveExportedPreprocessorFlags(ImmutableList.of(targetNode)), targetNode.getConstructorArg().compilerFlags, targetNode.getConstructorArg().preprocessorFlags);
            Iterable<String> otherCxxFlags = Iterables.concat(cxxBuckConfig.getFlags("cxxflags").orElse(DEFAULT_CXXFLAGS), collectRecursiveExportedPreprocessorFlags(ImmutableList.of(targetNode)), targetNode.getConstructorArg().compilerFlags, targetNode.getConstructorArg().preprocessorFlags);
            ImmutableList<String> otherLdFlags = convertStringWithMacros(targetNode, Iterables.concat(targetNode.getConstructorArg().linkerFlags, collectRecursiveExportedLinkerFlags(ImmutableList.of(targetNode))));
            appendConfigsBuilder.put("OTHER_CFLAGS", Joiner.on(' ').join(Iterables.transform(otherCFlags, Escaper.BASH_ESCAPER))).put("OTHER_CPLUSPLUSFLAGS", Joiner.on(' ').join(Iterables.transform(otherCxxFlags, Escaper.BASH_ESCAPER))).put("OTHER_LDFLAGS", Joiner.on(' ').join(Iterables.transform(otherLdFlags, Escaper.BASH_ESCAPER)));
            ImmutableMultimap.Builder<String, ImmutableList<String>> platformFlagsBuilder = ImmutableMultimap.builder();
            for (Pair<Pattern, ImmutableList<String>> flags : Iterables.concat(targetNode.getConstructorArg().platformCompilerFlags.getPatternsAndValues(), targetNode.getConstructorArg().platformPreprocessorFlags.getPatternsAndValues(), collectRecursiveExportedPlatformPreprocessorFlags(ImmutableList.of(targetNode)))) {
                String sdk = flags.getFirst().pattern().replaceAll("[*.]", "");
                platformFlagsBuilder.put(sdk, flags.getSecond());
            }
            ImmutableMultimap<String, ImmutableList<String>> platformFlags = platformFlagsBuilder.build();
            for (String sdk : platformFlags.keySet()) {
                appendConfigsBuilder.put(String.format("OTHER_CFLAGS[sdk=*%s*]", sdk), Joiner.on(' ').join(Iterables.transform(Iterables.concat(otherCFlags, Iterables.concat(platformFlags.get(sdk))), Escaper.BASH_ESCAPER))).put(String.format("OTHER_CPLUSPLUSFLAGS[sdk=*%s*]", sdk), Joiner.on(' ').join(Iterables.transform(Iterables.concat(otherCxxFlags, Iterables.concat(platformFlags.get(sdk))), Escaper.BASH_ESCAPER)));
            }
            ImmutableMultimap.Builder<String, ImmutableList<String>> platformLinkerFlagsBuilder = ImmutableMultimap.builder();
            for (Pair<Pattern, ImmutableList<StringWithMacros>> flags : Iterables.concat(targetNode.getConstructorArg().platformLinkerFlags.getPatternsAndValues(), collectRecursiveExportedPlatformLinkerFlags(ImmutableList.of(targetNode)))) {
                String sdk = flags.getFirst().pattern().replaceAll("[*.]", "");
                platformLinkerFlagsBuilder.put(sdk, convertStringWithMacros(targetNode, flags.getSecond()));
            }
            ImmutableMultimap<String, ImmutableList<String>> platformLinkerFlags = platformLinkerFlagsBuilder.build();
            for (String sdk : platformLinkerFlags.keySet()) {
                appendConfigsBuilder.put(String.format("OTHER_LDFLAGS[sdk=*%s*]", sdk), Joiner.on(' ').join(Iterables.transform(Iterables.concat(otherLdFlags, Iterables.concat(platformLinkerFlags.get(sdk))), Escaper.BASH_ESCAPER)));
            }
            ImmutableMap<String, String> appendedConfig = appendConfigsBuilder.build();
            Optional<ImmutableSortedMap<String, ImmutableMap<String, String>>> configs = getXcodeBuildConfigurationsForTargetNode(targetNode, appendedConfig);
            setTargetBuildConfigurations(getConfigurationNameToXcconfigPath(buildTarget), target, project.getMainGroup(), configs.get(), extraSettingsBuilder.build(), defaultSettingsBuilder.build(), appendedConfig);
        }
    }
    // -- phases
    createHeaderSymlinkTree(getPublicCxxHeaders(targetNode), getPathToHeaderSymlinkTree(targetNode, HeaderVisibility.PUBLIC), arg.xcodePublicHeadersSymlinks.orElse(true) || isHeaderMapDisabled(), !shouldMergeHeaderMaps());
    if (isFocusedOnTarget) {
        createHeaderSymlinkTree(getPrivateCxxHeaders(targetNode), getPathToHeaderSymlinkTree(targetNode, HeaderVisibility.PRIVATE), arg.xcodePrivateHeadersSymlinks.orElse(true) || isHeaderMapDisabled(), !isHeaderMapDisabled());
    }
    if (shouldMergeHeaderMaps() && isMainProject) {
        createMergedHeaderMap();
    }
    if (appleTargetNode.isPresent() && isFocusedOnTarget && !shouldGenerateHeaderSymlinkTreesOnly()) {
        // Use Core Data models from immediate dependencies only.
        addCoreDataModelsIntoTarget(appleTargetNode.get(), targetGroup.get());
        addSceneKitAssetsIntoTarget(appleTargetNode.get(), targetGroup.get());
    }
    return target;
}
Also used : TargetNode(com.facebook.buck.rules.TargetNode) ImmutableList(com.google.common.collect.ImmutableList) AppleNativeTargetDescriptionArg(com.facebook.buck.apple.AppleNativeTargetDescriptionArg) NSString(com.dd.plist.NSString) FrameworkPath(com.facebook.buck.rules.coercer.FrameworkPath) SourcePath(com.facebook.buck.rules.SourcePath) BuildTargetSourcePath(com.facebook.buck.rules.BuildTargetSourcePath) PathSourcePath(com.facebook.buck.rules.PathSourcePath) HasAppleBundleFields(com.facebook.buck.apple.HasAppleBundleFields) ImmutableSet(com.google.common.collect.ImmutableSet) BuildTarget(com.facebook.buck.model.BuildTarget) UnflavoredBuildTarget(com.facebook.buck.model.UnflavoredBuildTarget) ImmutableMultimap(com.google.common.collect.ImmutableMultimap) AppleLibraryDescription(com.facebook.buck.apple.AppleLibraryDescription) SourceTreePath(com.facebook.buck.apple.xcode.xcodeproj.SourceTreePath) SourceTreePath(com.facebook.buck.apple.xcode.xcodeproj.SourceTreePath) Path(java.nio.file.Path) SourcePath(com.facebook.buck.rules.SourcePath) BuildTargetSourcePath(com.facebook.buck.rules.BuildTargetSourcePath) PathSourcePath(com.facebook.buck.rules.PathSourcePath) FrameworkPath(com.facebook.buck.rules.coercer.FrameworkPath) Pattern(java.util.regex.Pattern) PBXNativeTarget(com.facebook.buck.apple.xcode.xcodeproj.PBXNativeTarget) CxxLibraryDescription(com.facebook.buck.cxx.CxxLibraryDescription) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) ImmutableMap(com.google.common.collect.ImmutableMap) ProductType(com.facebook.buck.apple.xcode.xcodeproj.ProductType) HumanReadableException(com.facebook.buck.util.HumanReadableException) PBXGroup(com.facebook.buck.apple.xcode.xcodeproj.PBXGroup) AppleBundleDescription(com.facebook.buck.apple.AppleBundleDescription) NSObject(com.dd.plist.NSObject) PBXFileReference(com.facebook.buck.apple.xcode.xcodeproj.PBXFileReference)

Example 19 with SourceTreePath

use of com.facebook.buck.apple.xcode.xcodeproj.SourceTreePath in project buck by facebook.

the class ProjectGenerator method getProductsSourceTreePath.

private SourceTreePath getProductsSourceTreePath(TargetNode<?, ?> targetNode) {
    String productName = getProductNameForBuildTarget(targetNode.getBuildTarget());
    String productOutputName;
    if (targetNode.getDescription() instanceof AppleLibraryDescription || targetNode.getDescription() instanceof CxxLibraryDescription || targetNode.getDescription() instanceof HalideLibraryDescription) {
        String productOutputFormat = AppleBuildRules.getOutputFileNameFormatForLibrary(targetNode.getBuildTarget().getFlavors().contains(CxxDescriptionEnhancer.SHARED_FLAVOR));
        productOutputName = String.format(productOutputFormat, productName);
    } else if (targetNode.getDescription() instanceof AppleBundleDescription || targetNode.getDescription() instanceof AppleTestDescription) {
        HasAppleBundleFields arg = (HasAppleBundleFields) targetNode.getConstructorArg();
        productName = arg.getProductName().orElse(productName);
        productOutputName = productName + "." + getExtensionString(arg.getExtension());
    } else if (targetNode.getDescription() instanceof AppleBinaryDescription) {
        productOutputName = productName;
    } else {
        throw new RuntimeException("Unexpected type: " + targetNode.getDescription().getClass());
    }
    return new SourceTreePath(PBXReference.SourceTree.BUILT_PRODUCTS_DIR, Paths.get(productOutputName), Optional.empty());
}
Also used : SourceTreePath(com.facebook.buck.apple.xcode.xcodeproj.SourceTreePath) HasAppleBundleFields(com.facebook.buck.apple.HasAppleBundleFields) AppleTestDescription(com.facebook.buck.apple.AppleTestDescription) CxxLibraryDescription(com.facebook.buck.cxx.CxxLibraryDescription) AppleBundleDescription(com.facebook.buck.apple.AppleBundleDescription) NSString(com.dd.plist.NSString) HalideLibraryDescription(com.facebook.buck.halide.HalideLibraryDescription) AppleBinaryDescription(com.facebook.buck.apple.AppleBinaryDescription) AppleLibraryDescription(com.facebook.buck.apple.AppleLibraryDescription)

Example 20 with SourceTreePath

use of com.facebook.buck.apple.xcode.xcodeproj.SourceTreePath in project buck by facebook.

the class NewNativeTargetProjectMutator method buildTargetAndAddToProject.

public Result buildTargetAndAddToProject(PBXProject project, boolean addBuildPhases) {
    PBXNativeTarget target = new PBXNativeTarget(targetName);
    Optional<PBXGroup> optTargetGroup;
    if (addBuildPhases) {
        PBXGroup targetGroup = project.getMainGroup().getOrCreateDescendantGroupByPath(targetGroupPath);
        targetGroup = targetGroup.getOrCreateChildGroupByName(targetName);
        // Phases
        addRunScriptBuildPhases(target, preBuildRunScriptPhases);
        addPhasesAndGroupsForSources(target, targetGroup);
        addFrameworksBuildPhase(project, target);
        addResourcesFileReference(targetGroup);
        addResourcesBuildPhase(target, targetGroup);
        target.getBuildPhases().addAll((Collection<? extends PBXBuildPhase>) copyFilesPhases);
        addRunScriptBuildPhases(target, postBuildRunScriptPhases);
        optTargetGroup = Optional.of(targetGroup);
    } else {
        optTargetGroup = Optional.empty();
    }
    // Product
    PBXGroup productsGroup = project.getMainGroup().getOrCreateChildGroupByName("Products");
    PBXFileReference productReference = productsGroup.getOrCreateFileReferenceBySourceTreePath(new SourceTreePath(PBXReference.SourceTree.BUILT_PRODUCTS_DIR, productOutputPath, Optional.empty()));
    target.setProductName(productName);
    target.setProductReference(productReference);
    target.setProductType(productType);
    project.getTargets().add(target);
    return new Result(target, optTargetGroup);
}
Also used : SourceTreePath(com.facebook.buck.apple.xcode.xcodeproj.SourceTreePath) PBXNativeTarget(com.facebook.buck.apple.xcode.xcodeproj.PBXNativeTarget) PBXGroup(com.facebook.buck.apple.xcode.xcodeproj.PBXGroup) PBXFileReference(com.facebook.buck.apple.xcode.xcodeproj.PBXFileReference)

Aggregations

SourceTreePath (com.facebook.buck.apple.xcode.xcodeproj.SourceTreePath)21 NSString (com.dd.plist.NSString)10 Test (org.junit.Test)10 PBXFileReference (com.facebook.buck.apple.xcode.xcodeproj.PBXFileReference)8 BuildTarget (com.facebook.buck.model.BuildTarget)8 PBXGroup (com.facebook.buck.apple.xcode.xcodeproj.PBXGroup)7 PBXTarget (com.facebook.buck.apple.xcode.xcodeproj.PBXTarget)7 FakeSourcePath (com.facebook.buck.rules.FakeSourcePath)7 ImmutableMap (com.google.common.collect.ImmutableMap)5 SourcePath (com.facebook.buck.rules.SourcePath)4 FrameworkPath (com.facebook.buck.rules.coercer.FrameworkPath)4 HumanReadableException (com.facebook.buck.util.HumanReadableException)4 Path (java.nio.file.Path)4 CoreMatchers.containsString (org.hamcrest.CoreMatchers.containsString)4 NSDictionary (com.dd.plist.NSDictionary)3 PBXBuildFile (com.facebook.buck.apple.xcode.xcodeproj.PBXBuildFile)3 PathSourcePath (com.facebook.buck.rules.PathSourcePath)3 NSObject (com.dd.plist.NSObject)2 AppleBundleDescription (com.facebook.buck.apple.AppleBundleDescription)2 AppleLibraryDescription (com.facebook.buck.apple.AppleLibraryDescription)2