diff options
author | schmitt <schmitt@google.com> | 2017-06-26 15:35:06 +0200 |
---|---|---|
committer | Marcel Hlopko <hlopko@google.com> | 2017-06-26 18:42:44 +0200 |
commit | 0507fd5eaa0b30fcabe39db02ef9fb090ef7edc6 (patch) | |
tree | 8c71f09a5388db96e6122ca160ef5b8397cfa6d3 /src/objc_tools | |
parent | 8f6549fcca1838e2bbb0ec0dc52fc8b83c923c8e (diff) |
Remove remaining xcodegen references.
Deletes last code references to xcodegen tool as well as tool itself.
RELNOTES: None.
PiperOrigin-RevId: 160137807
Diffstat (limited to 'src/objc_tools')
21 files changed, 0 insertions, 2289 deletions
diff --git a/src/objc_tools/xcodegen/BUILD b/src/objc_tools/xcodegen/BUILD deleted file mode 100644 index 606bb160da..0000000000 --- a/src/objc_tools/xcodegen/BUILD +++ /dev/null @@ -1,44 +0,0 @@ -package(default_visibility = ["//src:__subpackages__"]) - -java_binary( - name = "xcodegen", - srcs = glob(["java/**/XcodeGen.java"]), - main_class = "com.google.devtools.build.xcode.xcodegen.XcodeGen", - visibility = ["//visibility:public"], - deps = [ - ":xcodegen_lib", - "//src/main/java/com/google/devtools/common/options", - "//src/main/protobuf:xcodegen_java_proto", - "//third_party:guava", - "//third_party/java/buck-ios-support", - "//third_party/protobuf:protobuf_java", - ], -) - -java_library( - name = "xcodegen_lib", - srcs = glob( - ["java/**/*.java"], - exclude = [ - "java/**/XcodeGen.java", - "java/**/testing/*.java", - ], - ), - deps = [ - "//src/main/protobuf:xcodegen_java_proto", - "//src/objc_tools/plmerge:plmerge_lib", - "//src/tools/xcode-common/java/com/google/devtools/build/xcode/common", - "//src/tools/xcode-common/java/com/google/devtools/build/xcode/util", - "//third_party:guava", - "//third_party:jsr305", - "//third_party/java/buck-ios-support", - "//third_party/java/dd_plist", - "//third_party/protobuf:protobuf_java", - ], -) - -filegroup( - name = "srcs", - srcs = glob(["**"]), - visibility = ["//src:__pkg__"], -) diff --git a/src/objc_tools/xcodegen/README b/src/objc_tools/xcodegen/README deleted file mode 100644 index c91dea7d9f..0000000000 --- a/src/objc_tools/xcodegen/README +++ /dev/null @@ -1,2 +0,0 @@ -xcodegen generates xcode project files for metadata about a given set of -targets. diff --git a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/AggregateKey.java b/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/AggregateKey.java deleted file mode 100644 index 49d0546dc3..0000000000 --- a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/AggregateKey.java +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.xcode.xcodegen; - -import com.google.common.base.Optional; -import com.google.devtools.build.xcode.util.Value; - -import java.nio.file.Path; - -/** - * Data used to as a key when assigning items to aggregate references - * (see {@link AggregateReferenceType}). All items sharing a single key value should belong to the - * same group. - * <p> - * Note that the information in the grouping key is also the information that is used to create a - * new group, minus the actual list of files in the group. See - * {@link AggregateReferenceType#create(AggregateKey, Iterable)}. - */ -public class AggregateKey extends Value<AggregateKey> { - private final Optional<String> name; - private final Optional<Path> path; - - public AggregateKey(Optional<String> name, Optional<Path> path) { - super(name, path); - this.name = name; - this.path = path; - } - - public Optional<String> name() { - return name; - } - - public Optional<Path> path() { - return path; - } - - /** - * Returns an instance that indicates any item assigned to it should not belong to a group. - */ - public static AggregateKey standalone() { - return new AggregateKey(Optional.<String>absent(), Optional.<Path>absent()); - } - - /** - * Indicates that this grouping key means an item should not belong to any group. - */ - public boolean isStandalone() { - return !path().isPresent() && !name().isPresent(); - } -} diff --git a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/AggregateReferenceType.java b/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/AggregateReferenceType.java deleted file mode 100644 index b945184ce0..0000000000 --- a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/AggregateReferenceType.java +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.xcode.xcodegen; - -import com.facebook.buck.apple.xcode.xcodeproj.PBXFileReference; -import com.facebook.buck.apple.xcode.xcodeproj.PBXReference; -import com.facebook.buck.apple.xcode.xcodeproj.PBXReference.SourceTree; -import com.facebook.buck.apple.xcode.xcodeproj.PBXVariantGroup; -import com.facebook.buck.apple.xcode.xcodeproj.XCVersionGroup; -import com.google.common.base.Optional; -import com.google.common.collect.ImmutableSetMultimap; -import com.google.common.collect.Iterables; -import com.google.common.collect.SetMultimap; -import java.nio.file.Path; -import java.util.Collection; - -/** - * An aggregate reference is a kind of PBXReference that contains one or more files, grouped by some - * criteria, and appearing as a group in the Xcode project navigator, and often handled as a single - * file during the build phase and in other situations. - */ -public enum AggregateReferenceType { - /** - * A group which contains multiple .xcdatamodel directories where each is a different version of - * the same schema. We may have to support other files besides .xcdatamodel in the future. - * Instances of this group are represented by {@link XCVersionGroup} and are grouped by the - * relative path of the containing .xcdatamodeld directory. - */ - XCVersionGroup { - @Override - public PBXReference create(AggregateKey key, Iterable<PBXFileReference> children) { - XCVersionGroup result = new XCVersionGroup( - key.name().orNull(), - key.path().isPresent() ? key.path().get().toString() : null, - SourceTree.GROUP); - Iterables.addAll(result.getChildren(), children); - return result; - } - - @Override - public AggregateKey aggregateKey(Path path) { - Path parent = path.getParent(); - if (parent.getFileName().toString().endsWith(".xcdatamodeld")) { - return new AggregateKey( - Optional.of(parent.getFileName().toString()), Optional.of(parent)); - } else { - return AggregateKey.standalone(); - } - } - - @Override - public Path pathInAggregate(Path path) { - return path.getFileName(); - } - }, - - /** - * A group which contains the same content in multiple languages, each language belonging to a - * different file. Instances of this group are represented by {@link PBXVariantGroup} and are - * grouped by the base name of the file (e.g. "foo" in "/usr/bar/foo"). - */ - PBXVariantGroup { - @Override - public PBXReference create(AggregateKey key, Iterable<PBXFileReference> children) { - PBXVariantGroup result = new PBXVariantGroup( - key.name().orNull(), - key.path().isPresent() ? key.path().get().toString() : null, - SourceTree.GROUP); - Iterables.addAll(result.getChildren(), children); - return result; - } - - @Override - public AggregateKey aggregateKey(Path path) { - if (Resources.languageOfLprojDir(path).isPresent()) { - return new AggregateKey( - Optional.of(path.getFileName().toString()), Optional.<Path>absent()); - } else { - return AggregateKey.standalone(); - } - } - - @Override - public Path pathInAggregate(Path path) { - return path; - } - }; - - /** - * Creates a new instance of this group with the group information and children. - */ - public abstract PBXReference create(AggregateKey key, Iterable<PBXFileReference> children); - - /** - * Returns the value by which this item should be grouped. All items sharing the same key should - * belong to the same group. An {@link AggregateKey#standalone()} return here indicates that the - * item should not belong to a group and should be built and treated as a standalone file. - */ - public abstract AggregateKey aggregateKey(Path path); - - public abstract Path pathInAggregate(Path path); - - /** Groups a sequence of items according to their {@link #aggregateKey(Path)}. */ - public SetMultimap<AggregateKey, Path> aggregates(Collection<Path> paths) { - ImmutableSetMultimap.Builder<AggregateKey, Path> result = - new ImmutableSetMultimap.Builder<>(); - for (Path path : paths) { - AggregateKey key = aggregateKey(path); - Path referencePath = key.isStandalone() ? path : pathInAggregate(path); - result.put(key, referencePath); - } - return result.build(); - } -} diff --git a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/CurrentVersionSetter.java b/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/CurrentVersionSetter.java deleted file mode 100644 index 861abfc2f7..0000000000 --- a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/CurrentVersionSetter.java +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2015 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.xcode.xcodegen; - -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.devtools.build.xcode.plmerge.PlistMerging; - -import com.dd.plist.NSDictionary; -import com.dd.plist.NSString; -import com.facebook.buck.apple.xcode.xcodeproj.PBXFileReference; -import com.facebook.buck.apple.xcode.xcodeproj.PBXReference; -import com.facebook.buck.apple.xcode.xcodeproj.PBXReference.SourceTree; -import com.facebook.buck.apple.xcode.xcodeproj.XCVersionGroup; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -/** - * Processes the {@link XCVersionGroup} instances in a sequence of {@link PBXReference}s to have - * the {@code currentVersion} field set properly according to the {@code .xccurrentversion} file, if - * available. - * - * <p>This will NOT set the current version for any group where one of the following is true: - * <ul> - * <li>the sourceTree of the group is not GROUP (meaning it is not relative to the workspace root) - * <li>the {@code .xccurrentversion} file does not exist or is not accessible - * <li>the plist in the file does not contain the correct entry - * <li>the {@link XCVersionGroup} does not have a child that matches the version in the - * {@code .xccurrentversion} file - * </ul> - */ -public final class CurrentVersionSetter implements PbxReferencesProcessor { - private final Path workspaceRoot; - - public CurrentVersionSetter(Path workspaceRoot) { - this.workspaceRoot = Preconditions.checkNotNull(workspaceRoot); - } - - @Override - public Iterable<PBXReference> process(Iterable<PBXReference> references) { - for (PBXReference reference : references) { - if ((reference instanceof XCVersionGroup) && (reference.getPath() != null)) { - trySetCurrentVersion((XCVersionGroup) reference); - } - } - return references; - } - - private void trySetCurrentVersion(XCVersionGroup group) { - if (group.getSourceTree() != SourceTree.GROUP) { - return; - } - - Path groupPath = workspaceRoot.resolve(group.getPath()); - Path currentVersionPlist = groupPath.resolve(".xccurrentversion"); - if (!Files.isReadable(currentVersionPlist)) { - return; - } - - NSDictionary plist; - try { - plist = PlistMerging.readPlistFile(currentVersionPlist); - } catch (IOException e) { - return; - } - NSString currentVersion = (NSString) plist.get("_XCCurrentVersionName"); - if (currentVersion == null) { - return; - } - - for (PBXFileReference child : group.getChildren()) { - child.setExplicitFileType(Optional.of("wrapper.xcdatamodel")); - if (child.getName().equals(currentVersion.getContent())) { - group.setCurrentVersion(Optional.of(child)); - } - } - } -} diff --git a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/FileReference.java b/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/FileReference.java deleted file mode 100644 index 64f156440d..0000000000 --- a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/FileReference.java +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.xcode.xcodegen; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.devtools.build.xcode.util.Value; - -import com.facebook.buck.apple.xcode.xcodeproj.PBXFileReference; -import com.facebook.buck.apple.xcode.xcodeproj.PBXReference.SourceTree; - -import java.io.File; - -/** - * Contains data similar to {@link PBXFileReference}, but is actually a value type, with working - * {@link #equals(Object)} and {@link #hashCode()} methods. - * <p> - * TODO(bazel-team): Consider just adding equals and hashCode methods to PBXFileReference. This may - * not be as straight-forward as it sounds, since the Xcodeproj serialization logic and all related - * classes are based on identity equality semantics. - */ -public class FileReference extends Value<FileReference> { - private final String name; - private final Optional<String> path; - private final SourceTree sourceTree; - private final Optional<String> explicitFileType; - - @VisibleForTesting - FileReference( - String name, - Optional<String> path, - SourceTree sourceTree, - Optional<String> explicitFileType) { - super(name, path, sourceTree, explicitFileType); - this.name = name; - this.path = path; - this.sourceTree = sourceTree; - this.explicitFileType = explicitFileType; - } - - public String name() { - return name; - } - - public Optional<String> path() { - return path; - } - - public SourceTree sourceTree() { - return sourceTree; - } - - public Optional<String> explicitFileType() { - return explicitFileType; - } - - /** - * Returns an instance whose name is the base name of the path. - */ - public static FileReference of(String path, SourceTree sourceTree) { - return new FileReference( - new File(path).getName(), - Optional.of(path), - sourceTree, - Optional.<String>absent()); - } - - /** - * Returns an instance with a path and without an {@link #explicitFileType()}. - */ - public static FileReference of(String name, String path, SourceTree sourceTree) { - return new FileReference( - name, Optional.of(path), sourceTree, Optional.<String>absent()); - } - - /** - * Returns an instance equivalent to this one, but with {@link #explicitFileType()} set to the - * given value. This instance should not already have a value set for {@link #explicitFileType()}. - */ - public FileReference withExplicitFileType(String explicitFileType) { - Preconditions.checkState(!explicitFileType().isPresent(), - "should not already have explicitFileType: %s", this); - return new FileReference(name(), path(), sourceTree(), Optional.of(explicitFileType)); - } -} diff --git a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/HasProjectNavigatorFiles.java b/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/HasProjectNavigatorFiles.java deleted file mode 100644 index 1e22c49b93..0000000000 --- a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/HasProjectNavigatorFiles.java +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.xcode.xcodegen; - -import com.facebook.buck.apple.xcode.xcodeproj.PBXReference; - -/** - * An object that knows some references that should be added to the main group so they appear in the - * project navigator view in Xcode. - */ -public interface HasProjectNavigatorFiles { - /** - * Returns all references known by this object that should be added to the main group. - */ - public Iterable<PBXReference> mainGroupReferences(); -} diff --git a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/LibraryObjects.java b/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/LibraryObjects.java deleted file mode 100644 index 3547ab9fc2..0000000000 --- a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/LibraryObjects.java +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.xcode.xcodegen; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.VisibleForTesting; - -import com.facebook.buck.apple.xcode.xcodeproj.PBXBuildFile; -import com.facebook.buck.apple.xcode.xcodeproj.PBXFileReference; -import com.facebook.buck.apple.xcode.xcodeproj.PBXFrameworksBuildPhase; -import com.facebook.buck.apple.xcode.xcodeproj.PBXReference; -import com.facebook.buck.apple.xcode.xcodeproj.PBXReference.SourceTree; - -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; - -/** - * Collector that gathers references to libraries and frameworks when generating {@linkplain - * PBXFrameworksBuildPhase framework build phases} for later display in XCode. - * - * <p>Use this class to {@link #newBuildPhase() generate} a framework build phase for each target, - * by adding things that are linked with the final binary: - * {@link BuildPhaseBuilder#addFramework frameworks} ("v1_6/GoogleMaps.framework"), - * {@link BuildPhaseBuilder#addSdkFramework SDK frameworks} ("XCTest.framework", - * "Foundation.framework") or {@link BuildPhaseBuilder#addDylib dylibs} ("libz.dylib"). Anything - * added here will also be returned by {@link #mainGroupReferences}. - * - * <p>File references used by this class are de-duplicated against a global cache. - */ -public final class LibraryObjects implements HasProjectNavigatorFiles { - - @VisibleForTesting static final String FRAMEWORK_FILE_TYPE = "wrapper.framework"; - - private final LinkedHashMap<FileReference, PBXReference> fileToMainGroupReferences = - new LinkedHashMap<>(); - private final PBXFileReferences fileReferenceCache; - - /** - * @param fileReferenceCache global file reference repository used to avoid creating the same - * file reference twice - */ - public LibraryObjects(PBXFileReferences fileReferenceCache) { - this.fileReferenceCache = checkNotNull(fileReferenceCache); - } - - /** - * Builder that assembles information required to generate a {@link PBXFrameworksBuildPhase}. - */ - public final class BuildPhaseBuilder { - - private final LinkedHashSet<FileReference> fileReferences = new LinkedHashSet<>(); - - private BuildPhaseBuilder() {} // Don't allow instantiation from outside the enclosing class. - - /** - * Creates a new SDK framework based on the passed name. - * - * @param name simple framework name without ".framework" suffix, e.g. "Foundation" - */ - public BuildPhaseBuilder addSdkFramework(String name) { - String location = String.format("System/Library/Frameworks/%s.framework", name); - FileReference reference = - FileReference.of(location, SourceTree.SDKROOT).withExplicitFileType(FRAMEWORK_FILE_TYPE); - fileReferences.add(reference); - return this; - } - - /** - * Creates a new (non-SDK) framework based on the given path. - * - * @param execPath path to the framework's folder, relative to the xcodeproject's path root, - * e.g. "v1_6/GoogleMaps.framework" - */ - public BuildPhaseBuilder addFramework(String execPath) { - FileReference reference = - FileReference.of(execPath, SourceTree.GROUP).withExplicitFileType(FRAMEWORK_FILE_TYPE); - fileReferences.add(reference); - return this; - } - - /** - * Returns a new build phase containing the added libraries. - */ - public PBXFrameworksBuildPhase build() { - PBXFrameworksBuildPhase buildPhase = new PBXFrameworksBuildPhase(); - for (FileReference reference : fileReferences) { - PBXFileReference fileRef = fileReferenceCache.get(reference); - buildPhase.getFiles().add(new PBXBuildFile(fileRef)); - fileToMainGroupReferences.put(reference, fileRef); - } - return buildPhase; - } - } - - /** - * Returns a builder for a new build phase. - */ - public BuildPhaseBuilder newBuildPhase() { - return new BuildPhaseBuilder(); - } - - @Override - public Iterable<PBXReference> mainGroupReferences() { - return fileToMainGroupReferences.values(); - } -} diff --git a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/LocalPBXContainerItemProxy.java b/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/LocalPBXContainerItemProxy.java deleted file mode 100644 index 5726775518..0000000000 --- a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/LocalPBXContainerItemProxy.java +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.xcode.xcodegen; - -import com.google.common.base.Preconditions; - -import com.facebook.buck.apple.xcode.XcodeprojSerializer; -import com.facebook.buck.apple.xcode.xcodeproj.PBXContainerItemProxy; -import com.facebook.buck.apple.xcode.xcodeproj.PBXFileReference; -import com.facebook.buck.apple.xcode.xcodeproj.PBXObject; -import com.facebook.buck.apple.xcode.xcodeproj.PBXProject; -import com.facebook.buck.apple.xcode.xcodeproj.PBXReference.SourceTree; - -/** - * Represents a PBXContainerItemProxy object that does not reference a remote (other project file) - * object. - * <p> - * TODO(bazel-team): Upstream this to Buck. - */ -public class LocalPBXContainerItemProxy extends PBXContainerItemProxy { - private static final PBXFileReference DUMMY_FILE_REFERENCE = - new PBXFileReference("", "", SourceTree.ABSOLUTE); - - private final PBXProject containerPortalAsProject; - private final PBXObject remoteGlobalIdHolder; - - public LocalPBXContainerItemProxy( - PBXProject containerPortalAsProject, PBXObject remoteGlobalIdHolder, ProxyType proxyType) { - super(DUMMY_FILE_REFERENCE, "" /* remoteGlobalIDString */, proxyType); - this.containerPortalAsProject = Preconditions.checkNotNull(containerPortalAsProject); - this.remoteGlobalIdHolder = Preconditions.checkNotNull(remoteGlobalIdHolder); - } - - public PBXProject getContainerPortalAsProject() { - return containerPortalAsProject; - } - - public PBXObject getRemoteGlobalIdHolder() { - return remoteGlobalIdHolder; - } - - @Override - public void serializeInto(XcodeprojSerializer s) { - // Note we don't call super.serializeInto because we don't want the DUMMY_FILE_REFERENCE to - // get saved to the project file (even though it is probably harmless). - s.addField("containerPortal", containerPortalAsProject.getGlobalID()); - s.addField("remoteGlobalIDString", remoteGlobalIdHolder); - s.addField("proxyType", getProxyType().getIntValue()); - } -} diff --git a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/LocalPBXTargetDependency.java b/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/LocalPBXTargetDependency.java deleted file mode 100644 index fb31c9fb18..0000000000 --- a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/LocalPBXTargetDependency.java +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.xcode.xcodegen; - -import com.facebook.buck.apple.xcode.XcodeprojSerializer; -import com.facebook.buck.apple.xcode.xcodeproj.PBXTargetDependency; - -/** - * A target dependency that is not remote, which is similar to the normal Buck PBXTargetDependency, - * but includes a {@code target} field. - * <p> - * TODO(bazel-team): Upstream this to Buck. - */ -public class LocalPBXTargetDependency extends PBXTargetDependency { - public LocalPBXTargetDependency(LocalPBXContainerItemProxy targetProxy) { - super(targetProxy); - } - - @Override - public void serializeInto(XcodeprojSerializer s) { - super.serializeInto(s); - s.addField("target", getTargetProxy().getRemoteGlobalIDString()); - } -} diff --git a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/PBXBuildFiles.java b/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/PBXBuildFiles.java deleted file mode 100644 index 4fd27518f4..0000000000 --- a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/PBXBuildFiles.java +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.xcode.xcodegen; - -import com.facebook.buck.apple.xcode.xcodeproj.PBXBuildFile; -import com.facebook.buck.apple.xcode.xcodeproj.PBXFileReference; -import com.facebook.buck.apple.xcode.xcodeproj.PBXReference; -import com.facebook.buck.apple.xcode.xcodeproj.PBXReference.SourceTree; -import com.facebook.buck.apple.xcode.xcodeproj.PBXVariantGroup; -import com.facebook.buck.apple.xcode.xcodeproj.XCVersionGroup; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.SetMultimap; -import com.google.devtools.build.xcode.util.Mapping; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * A kind of cache which makes it easier to collect and manage PBXBuildFile and PBXReference - * objects. It knows how to create new PBXBuildFile, PBXVariantGroup, and PBXFileReference objects - * from {@link Path} objects and sequences thereof. - * <p> - * A PBXFileReference specifies a path to a file and its <em>name</em>. The name is confusingly - * defined as the real file name for non-localized files (e.g. "foo" in "bar/foo"), and the language - * name for localized files (e.g. "en" in "bar/en.lproj/foo"). - * <p> - * A PBXVariantGroup is a set of PBXFileReferences with the same file name (the virtual name). Each - * file is in some directory named *.lproj. For instance, the following files would belong to the - * same PBXVariantGroup: - * - * <ul> - * <li>foo1/en.lproj/file.strings - * <li>foo2/ru.lproj/file.strings - * </ul> - * - * Where the virtual name is "file.strings". Note that because of the way PBXVariantGroups are named - * and specified in .xcodeproj files, it is possible Xcode does or will use it for groups not - * defined by localization, but we currently ignore that possibility. - * <p> - * A PBXBuildFile is the simplest object - it is simply a reference to a PBXReference, which can be - * either a PBXFileReference or PBXVariantGroup. The fact that PBXFileReference and PBXVariantGroup - * are considered kinds of PBXReference is reflected in the Java inheritance hierarchy for the - * classes that model these Xcode objects. - * <p> - * The PBXBuildFile is the object referred to in the build phases of targets, so it is seen as a - * buildable or compilable unit. The PBXFileReference and PBXVariantGroup objects are referred to - * by the PBXGroups, which define what is visible in the Project Navigator view in Xcode. - * <p> - * This class assumes that all paths given through the public API are specified relative to the - * Xcodegen root, and creates PBXFileReferences that should be added to a group whose path is the - * root. - * TODO(bazel-team): Make this an immutable type, of which multiple instances are created as new - * references and build files are added. The current API is side-effect-based and confusing. - */ -final class PBXBuildFiles implements HasProjectNavigatorFiles { - /** - * Map from Paths to the PBXBuildFile that encompasses all and only those Paths. Because the - * {@link PBXBuildFile}s in this map encompass multiple files, their - * {@link PBXBuildFile#getFileRef()} value is a {@link PBXVariantGroup} or {@link XCVersionGroup}. - * <p> - * Note that this Map reflects the intention of the API, namely that {"a"} does not map to the - * same thing as {"a", "b"}, and you cannot get a build file with only one of the corresponding - * files - you need the whole set. - */ - private Map<ImmutableSet<Path>, PBXBuildFile> aggregateBuildFiles; - - private Map<FileReference, PBXBuildFile> standaloneBuildFiles; - private PBXFileReferences pbxReferences; - private List<PBXReference> mainGroupReferences; - - public PBXBuildFiles(PBXFileReferences pbxFileReferences) { - this.aggregateBuildFiles = new HashMap<>(); - this.standaloneBuildFiles = new HashMap<>(); - this.pbxReferences = Preconditions.checkNotNull(pbxFileReferences); - this.mainGroupReferences = new ArrayList<>(); - } - - private PBXBuildFile aggregateBuildFile(ImmutableSet<Path> paths, PBXReference reference) { - Preconditions.checkArgument(!paths.isEmpty(), "paths must be non-empty"); - for (PBXBuildFile cached : Mapping.of(aggregateBuildFiles, paths).asSet()) { - return cached; - } - PBXBuildFile buildFile = new PBXBuildFile(reference); - mainGroupReferences.add(reference); - aggregateBuildFiles.put(paths, buildFile); - return buildFile; - } - - /** - * Returns new or cached instances of PBXBuildFiles corresponding to files that may or may not - * belong to an aggregate reference (see {@link AggregateReferenceType}). Files specified by the - * {@code paths} argument are grouped into individual PBXBuildFiles using the given {@link - * AggregateReferenceType}. Files that are standalone are not put in an aggregate reference, but - * are put in a standalone PBXBuildFile in the returned sequence. - */ - public Iterable<PBXBuildFile> get(AggregateReferenceType type, Collection<Path> paths) { - ImmutableList.Builder<PBXBuildFile> result = new ImmutableList.Builder<>(); - SetMultimap<AggregateKey, Path> keyedPaths = type.aggregates(paths); - for (Map.Entry<AggregateKey, Collection<Path>> aggregation : keyedPaths.asMap().entrySet()) { - if (!aggregation.getKey().isStandalone()) { - ImmutableSet<Path> itemPaths = ImmutableSet.copyOf(aggregation.getValue()); - result.add(aggregateBuildFile( - itemPaths, type.create(aggregation.getKey(), fileReferences(itemPaths)))); - } - } - for (Path generalResource : keyedPaths.get(AggregateKey.standalone())) { - result.add(getStandalone(FileReference.of(generalResource.toString(), SourceTree.GROUP))); - } - - return result.build(); - } - - /** - * Returns a new or cached instance of a PBXBuildFile for a file that is not part of a variant - * group. - */ - public PBXBuildFile getStandalone(FileReference file) { - for (PBXBuildFile cached : Mapping.of(standaloneBuildFiles, file).asSet()) { - return cached; - } - PBXBuildFile buildFile = new PBXBuildFile(pbxReferences.get(file)); - mainGroupReferences.add(pbxReferences.get(file)); - standaloneBuildFiles.put(file, buildFile); - return buildFile; - } - - /** Applies {@link #fileReference(Path)} to each item in the sequence. */ - private final Iterable<PBXFileReference> fileReferences(Collection<Path> paths) { - ImmutableList.Builder<PBXFileReference> result = new ImmutableList.Builder<>(); - for (Path path : paths) { - result.add(fileReference(path)); - } - return result.build(); - } - - /** - * Returns a new or cached PBXFileReference for the given file. The name of the reference depends - * on whether the file is in a localized (*.lproj) directory. If it is localized, then the name - * of the reference is the name of the language (the text before ".lproj"). Otherwise, the name is - * the same as the file name (e.g. Localizable.strings). This is confusing, but it is how Xcode - * creates PBXFileReferences. - */ - private PBXFileReference fileReference(Path path) { - Optional<String> language = Resources.languageOfLprojDir(path); - String name = language.isPresent() ? language.get() : path.getFileName().toString(); - return pbxReferences.get(FileReference.of(name, path.toString(), SourceTree.GROUP)); - } - - @Override - public Iterable<PBXReference> mainGroupReferences() { - return mainGroupReferences; - } -} diff --git a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/PBXFileReferences.java b/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/PBXFileReferences.java deleted file mode 100644 index c7181e75cf..0000000000 --- a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/PBXFileReferences.java +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.xcode.xcodegen; - -import com.google.devtools.build.xcode.util.Mapping; - -import com.facebook.buck.apple.xcode.xcodeproj.PBXFileReference; - -import java.util.HashMap; -import java.util.Map; - -/** - * A factory for {@link PBXFileReference}s. {@link PBXFileReference}s are inherently non-value - * types, in that each created instance appears in the serialized Xcodeproj file, even if some of - * the instances are equivalent. This serves as a cache so that a value type ({@link FileReference}) - * can be converted to a canonical, cached {@link PBXFileReference} which is equivalent to it. - */ -final class PBXFileReferences { - private final Map<FileReference, PBXFileReference> cache = new HashMap<>(); - - /** - * Supplies a reference, containing values for fields specified in {@code reference}. - */ - public PBXFileReference get(FileReference reference) { - for (PBXFileReference existing : Mapping.of(cache, reference).asSet()) { - return existing; - } - - PBXFileReference result = new PBXFileReference( - reference.name(), reference.path().orNull(), reference.sourceTree()); - result.setExplicitFileType(reference.explicitFileType()); - - cache.put(reference, result); - return result; - } -} diff --git a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/PbxReferencesGrouper.java b/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/PbxReferencesGrouper.java deleted file mode 100644 index aee29508e8..0000000000 --- a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/PbxReferencesGrouper.java +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.xcode.xcodegen; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.devtools.build.xcode.util.Containing; -import com.google.devtools.build.xcode.util.Equaling; -import com.google.devtools.build.xcode.util.Mapping; - -import com.facebook.buck.apple.xcode.xcodeproj.PBXGroup; -import com.facebook.buck.apple.xcode.xcodeproj.PBXReference; -import com.facebook.buck.apple.xcode.xcodeproj.PBXReference.SourceTree; -import com.facebook.buck.apple.xcode.xcodeproj.PBXVariantGroup; - -import java.nio.file.FileSystem; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.Map; - -/** - * A {@link PBXReference} processor to group self-contained PBXReferences into PBXGroups. Grouping - * is done to make it easier to navigate the files of the project in Xcode's Project Navigator. - * - * <p>A <em>self-contained</em> reference is one that is not a member of a PBXVariantGroup or other - * aggregate group, although a self-contained reference may contain such a reference as a child. - * - * <p>This implementation arranges the {@code PBXFileReference}s into a hierarchy of - * {@code PBXGroup}s that mirrors the actual location of the files on disk. - * - * <p>When using this grouper, the top-level items are the following: - * <ul> - * <li>BUILT_PRODUCTS_DIR - a group containing items in the SourceRoot of this name - * <li>SDKROOT - a group containing items that are part of the Xcode install, such as SDK - * frameworks - * <li>workspace_root - a group containing items within the root of the workspace of the client - * <li>miscellaneous - anything that does not belong in one of the above groups is placed directly - * in the main group. - * </ul> - */ -public class PbxReferencesGrouper implements PbxReferencesProcessor { - private final FileSystem fileSystem; - - public PbxReferencesGrouper(FileSystem fileSystem) { - this.fileSystem = Preconditions.checkNotNull(fileSystem, "fileSystem"); - } - - /** - * Converts a {@code String} to a {@code Path} using this instance's file system. - */ - private Path path(String pathString) { - return RelativePaths.fromString(fileSystem, pathString); - } - - /** - * Returns the deepest directory that contains both paths. - */ - private Path deepestCommonContainer(Path path1, Path path2) { - Path container = path(""); - int nameIndex = 0; - while ((nameIndex < Math.min(path1.getNameCount(), path2.getNameCount())) - && Equaling.of(path1.getName(nameIndex), path2.getName(nameIndex))) { - container = container.resolve(path1.getName(nameIndex)); - nameIndex++; - } - return container; - } - - /** - * Returns the parent of the given path. This is similar to {@link Path#getParent()}, but is - * nullable-phobic. {@link Path#getParent()} considers the root of the filesystem to be the null - * Path. This method uses {@code path("")} for the root. This is also how the implementation of - * {@link PbxReferencesGrouper} expresses <em>root</em> in general. - */ - private Path parent(Path path) { - return (path.getNameCount() == 1) ? path("") : path.getParent(); - } - - /** - * The directory of the PBXGroup that will contain the given reference. For most references, this - * is just the actual parent directory. For {@code PBXVariantGroup}s, whose children are not - * guaranteed to be in any common directory except the client root, this returns the deepest - * common container of each child in the group. - */ - private Path dirOfContainingPbxGroup(PBXReference reference) { - if (reference instanceof PBXVariantGroup) { - PBXVariantGroup variantGroup = (PBXVariantGroup) reference; - Path path = Paths.get(variantGroup.getChildren().get(0).getPath()); - for (PBXReference child : variantGroup.getChildren()) { - path = deepestCommonContainer(path, path(child.getPath())); - } - return path; - } else { - return parent(path(reference.getPath())); - } - } - - /** - * Contains the populated PBXGroups for a certain source tree. - */ - private class Groups { - /** - * Map of paths to the PBXGroup that is used to contain all files and groups in that path. - */ - final Map<Path, PBXGroup> groupCache; - - Groups(String rootGroupName, SourceTree sourceTree) { - groupCache = new HashMap<>(); - groupCache.put(path(""), new PBXGroup(rootGroupName, "" /* path */, sourceTree)); - } - - PBXGroup rootGroup() { - return Mapping.of(groupCache, path("")).get(); - } - - void add(Path dirOfContainingPbxGroup, PBXReference reference) { - for (PBXGroup container : Mapping.of(groupCache, dirOfContainingPbxGroup).asSet()) { - container.getChildren().add(reference); - return; - } - PBXGroup newGroup = new PBXGroup(dirOfContainingPbxGroup.getFileName().toString(), - null /* path */, SourceTree.GROUP); - newGroup.getChildren().add(reference); - add(parent(dirOfContainingPbxGroup), newGroup); - groupCache.put(dirOfContainingPbxGroup, newGroup); - } - } - - @Override - public Iterable<PBXReference> process(Iterable<PBXReference> references) { - Map<SourceTree, Groups> groupsBySourceTree = ImmutableMap.of( - SourceTree.GROUP, new Groups("workspace_root", SourceTree.GROUP), - SourceTree.SDKROOT, new Groups("SDKROOT", SourceTree.SDKROOT), - SourceTree.BUILT_PRODUCTS_DIR, - new Groups("BUILT_PRODUCTS_DIR", SourceTree.BUILT_PRODUCTS_DIR)); - ImmutableList.Builder<PBXReference> result = new ImmutableList.Builder<>(); - - for (PBXReference reference : references) { - if (Containing.key(groupsBySourceTree, reference.getSourceTree())) { - Path containingDir = dirOfContainingPbxGroup(reference); - Mapping.of(groupsBySourceTree, reference.getSourceTree()) - .get() - .add(containingDir, reference); - } else { - // The reference is not inside any expected source tree, so don't try anything clever. Just - // add it to the main group directly (not in a nested PBXGroup). - result.add(reference); - } - } - - for (Groups groupsRoot : groupsBySourceTree.values()) { - if (!groupsRoot.rootGroup().getChildren().isEmpty()) { - result.add(groupsRoot.rootGroup()); - } - } - - return result.build(); - } -} diff --git a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/PbxReferencesProcessor.java b/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/PbxReferencesProcessor.java deleted file mode 100644 index 9f743dbe56..0000000000 --- a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/PbxReferencesProcessor.java +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.xcode.xcodegen; - -import com.facebook.buck.apple.xcode.xcodeproj.PBXReference; -import com.facebook.buck.apple.xcode.xcodeproj.PBXReference.SourceTree; - -/** - * Processes a sequence of self-contained references in some manner before they are added to a - * project. - * - * <p>A <em>self-contained</em> reference is one that is not a member of a PBXVariantGroup or other - * aggregate group, although a self-contained reference may contain such a reference as a child. - */ -public interface PbxReferencesProcessor { - /** - * Processes the references of the main group to generate another sequence of references, which - * may or may not reuse the input references. - * - * <p>The on-disk path of the main group is assumed to point to workspace root. This is important - * when the {@code sourceRoot} property of the references in the input or output arguments are - * {@link SourceTree#GROUP}. - */ - Iterable<PBXReference> process(Iterable<PBXReference> references); -} diff --git a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/RelativePaths.java b/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/RelativePaths.java deleted file mode 100644 index 1652fd7b64..0000000000 --- a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/RelativePaths.java +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.xcode.xcodegen; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.google.common.collect.ImmutableList; - -import java.nio.file.FileSystem; -import java.nio.file.Path; -import java.util.List; - -/** - * Utility methods for working with relative {@link Path} objects. - */ -class RelativePaths { - private RelativePaths() { - throw new UnsupportedOperationException("static-only"); - } - - /** - * Converts the given string to a {@code Path}, confirming it is relative. - */ - static Path fromString(FileSystem fileSystem, String pathString) { - Path path = fileSystem.getPath(pathString); - checkArgument(!path.isAbsolute(), "Expected relative path but got: %s", path); - return path; - } - - /** - * Converts each item in {@code pathStrings} using {@link #fromString(FileSystem, String)}. - */ - static List<Path> fromStrings(FileSystem fileSystem, Iterable<String> pathStrings) { - ImmutableList.Builder<Path> result = new ImmutableList.Builder<>(); - for (String pathString : pathStrings) { - result.add(fromString(fileSystem, pathString)); - } - return result.build(); - } -} diff --git a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/Resources.java b/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/Resources.java deleted file mode 100644 index 65cea40f7c..0000000000 --- a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/Resources.java +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.xcode.xcodegen; - -import com.google.common.base.Optional; -import com.google.common.collect.ImmutableSetMultimap; -import com.google.common.collect.Iterables; -import com.google.devtools.build.xcode.util.Equaling; -import com.google.devtools.build.xcode.util.Value; -import com.google.devtools.build.xcode.xcodegen.proto.XcodeGenProtos.TargetControl; - -import com.facebook.buck.apple.xcode.xcodeproj.PBXBuildFile; -import com.facebook.buck.apple.xcode.xcodeproj.PBXReference.SourceTree; -import com.facebook.buck.apple.xcode.xcodeproj.PBXResourcesBuildPhase; -import com.facebook.buck.apple.xcode.xcodeproj.PBXTarget.ProductType; - -import java.nio.file.FileSystem; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; - -/** - * Contains information about resources in an Xcode project. - */ -public class Resources extends Value<Resources> { - - private final ImmutableSetMultimap<TargetControl, PBXBuildFile> buildFiles; - - private Resources(ImmutableSetMultimap<TargetControl, PBXBuildFile> buildFiles) { - super(buildFiles); - this.buildFiles = buildFiles; - } - - /** - * Build files that should be added to the PBXResourcesBuildPhase for the given target. - */ - public ImmutableSetMultimap<TargetControl, PBXBuildFile> buildFiles() { - return buildFiles; - } - - /** - * Returns the PBXResourcesBuildPhase for the given target, if applicable. It will return an - * absent {@code Optional} if the target is a library or there are no resources to compile. - */ - public PBXResourcesBuildPhase resourcesBuildPhase(TargetControl targetControl) { - PBXResourcesBuildPhase resourcesPhase = new PBXResourcesBuildPhase(); - resourcesPhase.getFiles().addAll(buildFiles().get(targetControl)); - return resourcesPhase; - } - - public static Optional<String> languageOfLprojDir(Path child) { - Path parent = child.getParent(); - if (parent == null) { - return Optional.absent(); - } - String dirName = parent.getFileName().toString(); - String lprojSuffix = ".lproj"; - if (dirName.endsWith(lprojSuffix)) { - return Optional.of(dirName.substring(0, dirName.length() - lprojSuffix.length())); - } else { - return Optional.absent(); - } - } - - public static Resources fromTargetControls( - FileSystem fileSystem, PBXBuildFiles pbxBuildFiles, Iterable<TargetControl> targetControls) { - ImmutableSetMultimap.Builder<TargetControl, PBXBuildFile> buildFiles = - new ImmutableSetMultimap.Builder<>(); - - for (TargetControl targetControl : targetControls) { - List<PBXBuildFile> targetBuildFiles = new ArrayList<>(); - - Iterable<String> simpleImports = - Iterables.concat(targetControl.getXcassetsDirList(), targetControl.getBundleImportList()); - // Add .bundle, .xcassets directories to the Project Navigator so they are visible from within - // Xcode. - // Bundle imports are handled very similarly to asset catalogs, so we just add them with the - // same logic. Xcode's automatic file type detection logic is smart enough to see it is a - // bundle and link it properly, and add the {@code lastKnownFileType} property. - for (String simpleImport : simpleImports) { - targetBuildFiles.add( - pbxBuildFiles.getStandalone(FileReference.of(simpleImport, SourceTree.GROUP))); - } - - Iterables.addAll( - targetBuildFiles, - pbxBuildFiles.get( - AggregateReferenceType.PBXVariantGroup, - RelativePaths.fromStrings(fileSystem, targetControl.getGeneralResourceFileList()))); - - // If this target is a binary, save the build files. Otherwise, we don't need them. The file - // references we generated with fileObjects will be added to the main group later. - if (!Equaling.of( - ProductType.STATIC_LIBRARY, XcodeprojGeneration.productType(targetControl))) { - buildFiles.putAll(targetControl, targetBuildFiles); - } - } - - return new Resources(buildFiles.build()); - } -} diff --git a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/SourceFile.java b/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/SourceFile.java deleted file mode 100644 index a0ef5c8e92..0000000000 --- a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/SourceFile.java +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.xcode.xcodegen; - -import com.google.common.collect.ImmutableList; -import com.google.devtools.build.xcode.util.Value; -import com.google.devtools.build.xcode.xcodegen.proto.XcodeGenProtos.TargetControl; - -import java.nio.file.FileSystem; -import java.nio.file.Path; - -/** - * Source file path with information on how to build it. - */ -public class SourceFile extends Value<SourceFile> { - /** Indicates how a source file is built or not built. */ - public enum BuildType { - NO_BUILD, BUILD, NON_ARC_BUILD; - } - - private final BuildType buildType; - private final Path path; - - private SourceFile(BuildType buildType, Path path) { - super(buildType, path); - this.buildType = buildType; - this.path = path; - } - - public BuildType buildType() { - return buildType; - } - - public Path path() { - return path; - } - - /** - * Returns information on all source files in a target. In particular, this includes: - * <ul> - * <li>arc-compiled source files - * <li>non-arc-compiled source files - * <li>support files, such as BUILD and header files - * <li>Info.plist file - * </ul> - */ - public static Iterable<SourceFile> allSourceFiles(FileSystem fileSystem, TargetControl control) { - ImmutableList.Builder<SourceFile> result = new ImmutableList.Builder<>(); - for (Path plainSource : RelativePaths.fromStrings(fileSystem, control.getSourceFileList())) { - result.add(new SourceFile(BuildType.BUILD, plainSource)); - } - for (Path nonArcSource - : RelativePaths.fromStrings(fileSystem, control.getNonArcSourceFileList())) { - result.add(new SourceFile(BuildType.NON_ARC_BUILD, nonArcSource)); - } - for (Path supportSource : RelativePaths.fromStrings(fileSystem, control.getSupportFileList())) { - result.add(new SourceFile(BuildType.NO_BUILD, supportSource)); - } - if (control.hasInfoplist()) { - result.add(new SourceFile( - BuildType.NO_BUILD, RelativePaths.fromString(fileSystem, control.getInfoplist()))); - } - return result.build(); - } -} diff --git a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/Xcdatamodels.java b/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/Xcdatamodels.java deleted file mode 100644 index 5e4c00629b..0000000000 --- a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/Xcdatamodels.java +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.xcode.xcodegen; - -import com.google.common.collect.ImmutableSetMultimap; -import com.google.devtools.build.xcode.util.Equaling; -import com.google.devtools.build.xcode.util.Value; -import com.google.devtools.build.xcode.xcodegen.proto.XcodeGenProtos.TargetControl; - -import com.facebook.buck.apple.xcode.xcodeproj.PBXBuildFile; -import com.facebook.buck.apple.xcode.xcodeproj.PBXTarget.ProductType; - -import java.nio.file.FileSystem; - -/** - * Contains information about .xcdatamodel directories in an Xcode project. - */ -public class Xcdatamodels extends Value<Xcdatamodels> { - - private final ImmutableSetMultimap<TargetControl, PBXBuildFile> buildFiles; - - private Xcdatamodels(ImmutableSetMultimap<TargetControl, PBXBuildFile> buildFiles) { - super(buildFiles); - this.buildFiles = buildFiles; - } - - /** - * Map of each build file that should be added to the sources build phase for each target, given - * the target's control data. - */ - public ImmutableSetMultimap<TargetControl, PBXBuildFile> buildFiles() { - return buildFiles; - } - - public static Xcdatamodels fromTargetControls( - FileSystem fileSystem, PBXBuildFiles pbxBuildFiles, Iterable<TargetControl> targetControls) { - ImmutableSetMultimap.Builder<TargetControl, PBXBuildFile> targetLabelToBuildFiles = - new ImmutableSetMultimap.Builder<>(); - for (TargetControl targetControl : targetControls) { - Iterable<PBXBuildFile> targetBuildFiles = - pbxBuildFiles.get( - AggregateReferenceType.XCVersionGroup, - RelativePaths.fromStrings(fileSystem, targetControl.getXcdatamodelList())); - - // If this target is not a static library, save the build files. If it's a static lib, we - // don't need them. The file references we generated with fileObjects will be added to the - // main group later. - if (!Equaling.of( - ProductType.STATIC_LIBRARY, XcodeprojGeneration.productType(targetControl))) { - targetLabelToBuildFiles.putAll(targetControl, targetBuildFiles); - } - } - return new Xcdatamodels(targetLabelToBuildFiles.build()); - } -} diff --git a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/XcodeGen.java b/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/XcodeGen.java deleted file mode 100644 index e3576c226f..0000000000 --- a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/XcodeGen.java +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.xcode.xcodegen; - -import com.google.common.base.Function; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import com.google.devtools.build.xcode.xcodegen.proto.XcodeGenProtos.Control; -import com.google.devtools.build.xcode.xcodegen.proto.XcodeGenProtos.TargetControl; -import com.google.devtools.common.options.Option; -import com.google.devtools.common.options.Options; -import com.google.devtools.common.options.OptionsBase; -import com.google.devtools.common.options.OptionsParser; -import com.google.devtools.common.options.OptionsParsingException; - -import com.facebook.buck.apple.xcode.xcodeproj.PBXProject; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Iterator; -import java.util.List; - -/** - * Entry-point for the command-line Xcode project generator. - */ -public class XcodeGen { - /** - * Options for {@link XcodeGen}. - */ - public static class XcodeGenOptions extends OptionsBase { - @Option( - name = "control", - help = "Path to a control file, which contains only a binary serialized instance of " - + "the Control protocol buffer. Required.", - defaultValue = "null") - public String control; - } - - public static void main(String[] args) throws IOException, OptionsParsingException { - OptionsParser parser = OptionsParser.newOptionsParser(XcodeGenOptions.class); - parser.parse(args); - XcodeGenOptions options = parser.getOptions(XcodeGenOptions.class); - if (options.control == null) { - throw new IllegalArgumentException("--control must be specified\n" - + Options.getUsage(XcodeGenOptions.class)); - } - FileSystem fileSystem = FileSystems.getDefault(); - - Control controlPb; - try (InputStream in = Files.newInputStream(fileSystem.getPath(options.control))) { - controlPb = Control.parseFrom(in); - } - Path pbxprojPath = fileSystem.getPath(controlPb.getPbxproj()); - - Iterator<String> srcList = allSourceFilePaths(controlPb).iterator(); - Path workspaceRoot; - - // TODO(bazel-team): Remove this if-else clause once Bazel passes in the workspace root. - if (controlPb.hasWorkspaceRoot()) { - workspaceRoot = fileSystem.getPath(controlPb.getWorkspaceRoot()); - } else if (!srcList.hasNext()) { - workspaceRoot = XcodeprojGeneration.relativeWorkspaceRoot(pbxprojPath); - } else { - // Get the absolute path to the workspace root. - - // TODO(bazel-team): Remove this hack, possibly by converting Xcodegen to be run with - // "bazel run" and using RUNFILES to get the workspace root. For now, this is needed to work - // around Xcode's handling of symlinks not playing nicely with how Bazel stores output - // artifacts in /private/var/tmp. This means a relative path from .xcodeproj in bazel-out to - // the workspace root in .xcodeproj will not work properly at certain times during - // Xcode/xcodebuild execution. Walking up the path of a known source file prevents having - // to reason about a file that might only be accessible through a symlink, like a tools jar. - Path relSourceFilePath = fileSystem.getPath(srcList.next()); - Path absSourceFilePath = relSourceFilePath.toAbsolutePath(); - workspaceRoot = absSourceFilePath; - for (int i = 0; i < relSourceFilePath.getNameCount(); i++) { - workspaceRoot = workspaceRoot.getParent(); - } - } - - try (OutputStream out = Files.newOutputStream(pbxprojPath)) { - // This workspace root here is relative to the PWD, so that the .xccurrentversion - // files can actually be read. The other workspaceRoot is relative to the .xcodeproj - // root or is absolute. - Path relativeWorkspaceRoot = fileSystem.getPath("."); - PBXProject project = XcodeprojGeneration.xcodeproj( - workspaceRoot, controlPb, - ImmutableList.of( - new CurrentVersionSetter(relativeWorkspaceRoot), - new PbxReferencesGrouper(fileSystem))); - XcodeprojGeneration.write(out, project); - } - } - - private static Iterable<String> allSourceFilePaths(Control control) { - return Iterables.concat( - Iterables.transform(control.getTargetList(), - new Function<TargetControl, List<String>>() { - public List<String> apply(TargetControl tc) { - return tc.getSourceFileList(); - } - })); - } -} diff --git a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/XcodeprojGeneration.java b/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/XcodeprojGeneration.java deleted file mode 100644 index c3f70725e4..0000000000 --- a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/XcodeprojGeneration.java +++ /dev/null @@ -1,661 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.xcode.xcodegen; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Joiner; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import com.google.common.escape.Escaper; -import com.google.common.escape.Escapers; -import com.google.devtools.build.xcode.common.XcodeprojPath; -import com.google.devtools.build.xcode.util.Containing; -import com.google.devtools.build.xcode.util.Equaling; -import com.google.devtools.build.xcode.util.Mapping; -import com.google.devtools.build.xcode.xcodegen.LibraryObjects.BuildPhaseBuilder; -import com.google.devtools.build.xcode.xcodegen.SourceFile.BuildType; -import com.google.devtools.build.xcode.xcodegen.proto.XcodeGenProtos.Control; -import com.google.devtools.build.xcode.xcodegen.proto.XcodeGenProtos.DependencyControl; -import com.google.devtools.build.xcode.xcodegen.proto.XcodeGenProtos.TargetControl; -import com.google.devtools.build.xcode.xcodegen.proto.XcodeGenProtos.XcodeprojBuildSetting; - -import com.dd.plist.NSArray; -import com.dd.plist.NSDictionary; -import com.dd.plist.NSObject; -import com.dd.plist.NSString; -import com.facebook.buck.apple.xcode.GidGenerator; -import com.facebook.buck.apple.xcode.XcodeprojSerializer; -import com.facebook.buck.apple.xcode.xcodeproj.PBXBuildFile; -import com.facebook.buck.apple.xcode.xcodeproj.PBXContainerItemProxy.ProxyType; -import com.facebook.buck.apple.xcode.xcodeproj.PBXCopyFilesBuildPhase; -import com.facebook.buck.apple.xcode.xcodeproj.PBXFileReference; -import com.facebook.buck.apple.xcode.xcodeproj.PBXFrameworksBuildPhase; -import com.facebook.buck.apple.xcode.xcodeproj.PBXNativeTarget; -import com.facebook.buck.apple.xcode.xcodeproj.PBXProject; -import com.facebook.buck.apple.xcode.xcodeproj.PBXReference; -import com.facebook.buck.apple.xcode.xcodeproj.PBXReference.SourceTree; -import com.facebook.buck.apple.xcode.xcodeproj.PBXResourcesBuildPhase; -import com.facebook.buck.apple.xcode.xcodeproj.PBXShellScriptBuildPhase; -import com.facebook.buck.apple.xcode.xcodeproj.PBXSourcesBuildPhase; -import com.facebook.buck.apple.xcode.xcodeproj.PBXTarget.ProductType; -import com.facebook.buck.apple.xcode.xcodeproj.PBXTargetDependency; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.nio.charset.StandardCharsets; -import java.nio.file.FileSystem; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ExecutionException; - -/** - * Utility code for generating Xcode project files. - */ -public class XcodeprojGeneration { - public static final String FILE_TYPE_ARCHIVE_LIBRARY = "archive.ar"; - public static final String FILE_TYPE_WRAPPER_APPLICATION = "wrapper.application"; - public static final String FILE_TYPE_WRAPPER_BUNDLE = "wrapper.cfbundle"; - public static final String FILE_TYPE_APP_EXTENSION = "wrapper.app-extension"; - public static final String FILE_TYPE_FRAMEWORK = "wrapper.frawework"; - private static final String DEFAULT_OPTIONS_NAME = "Debug"; - private static final Escaper QUOTE_ESCAPER = Escapers.builder().addEscape('"', "\\\"").build(); - - @VisibleForTesting - static final String APP_NEEDS_SOURCE_ERROR = - "Due to limitations in Xcode, application projects must have at least one source file."; - - private XcodeprojGeneration() { - throw new UnsupportedOperationException("static-only"); - } - - /** - * Determines the relative path to the workspace root from the path of the project.pbxproj output - * file. An absolute path is preferred if available. - */ - static Path relativeWorkspaceRoot(Path pbxproj) { - int levelsToExecRoot = pbxproj.getParent().getParent().getNameCount(); - return pbxproj.getFileSystem().getPath(Joiner - .on('/') - .join(Collections.nCopies(levelsToExecRoot, ".."))); - } - - /** - * Writes a project to an {@code OutputStream} in the correct encoding. - */ - public static void write(OutputStream out, PBXProject project) throws IOException { - XcodeprojSerializer ser = new XcodeprojSerializer( - new GidGenerator(ImmutableSet.<String>of()), project); - Writer outWriter = new OutputStreamWriter(out, StandardCharsets.UTF_8); - // toXMLPropertyList includes an XML encoding specification (UTF-8), which we specify above. - // Standard Xcodeproj files use the toASCIIPropertyList format, but Xcode will rewrite - // XML-encoded project files automatically when first opening them. We use XML to prevent - // encoding issues, since toASCIIPropertyList does not include the UTF-8 encoding comment, and - // Xcode by default apparently uses MacRoman. - // This encoding concern is probably why Buck also generates XML project files as well. - outWriter.write(ser.toPlist().toXMLPropertyList()); - outWriter.flush(); - } - - private static final EnumSet<ProductType> SUPPORTED_PRODUCT_TYPES = EnumSet.of( - ProductType.STATIC_LIBRARY, - ProductType.APPLICATION, - ProductType.BUNDLE, - ProductType.UNIT_TEST, - ProductType.APP_EXTENSION, - ProductType.FRAMEWORK, - ProductType.WATCH_OS1_APPLICATION, - ProductType.WATCH_OS1_EXTENSION); - - private static final EnumSet<ProductType> PRODUCT_TYPES_THAT_HAVE_A_BINARY = EnumSet.of( - ProductType.APPLICATION, - ProductType.BUNDLE, - ProductType.UNIT_TEST, - ProductType.APP_EXTENSION, - ProductType.FRAMEWORK, - ProductType.WATCH_OS1_APPLICATION, - ProductType.WATCH_OS1_EXTENSION); - - /** - * Detects the product type of the given target based on multiple fields in {@code targetControl}. - * {@code productType} is set as a field on {@code PBXNativeTarget} objects in Xcode project - * files, and we support three values: {@link ProductType#APPLICATION}, - * {@link ProductType#STATIC_LIBRARY}, and {@link ProductType#BUNDLE}. The product type is not - * only what xcodegen sets the {@code productType} field to - it also dictates what can be built - * with this target (e.g. a library cannot be built with resources), what build phase it should be - * added to of its dependers, and the name and shape of its build output. - */ - public static ProductType productType(TargetControl targetControl) { - if (targetControl.hasProductType()) { - for (ProductType supportedType : SUPPORTED_PRODUCT_TYPES) { - if (targetControl.getProductType().equals(supportedType.identifier)) { - return supportedType; - } - } - throw new IllegalArgumentException( - "Unsupported product type: " + targetControl.getProductType()); - } - - return targetControl.hasInfoplist() ? ProductType.APPLICATION : ProductType.STATIC_LIBRARY; - } - - private static String productName(TargetControl targetControl) { - if (Equaling.of(ProductType.STATIC_LIBRARY, productType(targetControl))) { - // The product names for static libraries must be unique since the final - // binary is linked with "clang -l${LIBRARY_PRODUCT_NAME}" for each static library. - // Unlike other product types, a full application may have dozens of static libraries, - // so rather than just use the target name, we use the full label to generate the product - // name. - return targetControl.getLabel(); - } else { - return targetControl.getName(); - } - } - - /** - * Returns the file reference corresponding to the {@code productReference} of the given target. - * The {@code productReference} is the build output of a target, and its name and file type - * (stored in the {@link FileReference}) change based on the product type. - */ - private static FileReference productReference(TargetControl targetControl) { - ProductType type = productType(targetControl); - String productName = productName(targetControl); - - switch (type) { - case APPLICATION: - case WATCH_OS1_APPLICATION: - return FileReference.of(String.format("%s.app", productName), SourceTree.BUILT_PRODUCTS_DIR) - .withExplicitFileType(FILE_TYPE_WRAPPER_APPLICATION); - case STATIC_LIBRARY: - return FileReference.of( - String.format("lib%s.a", productName), SourceTree.BUILT_PRODUCTS_DIR) - .withExplicitFileType(FILE_TYPE_ARCHIVE_LIBRARY); - case BUNDLE: - return FileReference.of( - String.format("%s.bundle", productName), SourceTree.BUILT_PRODUCTS_DIR) - .withExplicitFileType(FILE_TYPE_WRAPPER_BUNDLE); - case UNIT_TEST: - return FileReference.of( - String.format("%s.xctest", productName), SourceTree.BUILT_PRODUCTS_DIR) - .withExplicitFileType(FILE_TYPE_WRAPPER_BUNDLE); - case APP_EXTENSION: - case WATCH_OS1_EXTENSION: - return FileReference.of( - String.format("%s.appex", productName), SourceTree.BUILT_PRODUCTS_DIR) - .withExplicitFileType(FILE_TYPE_APP_EXTENSION); - case FRAMEWORK: - return FileReference.of( - String.format("%s.framework", productName), SourceTree.BUILT_PRODUCTS_DIR) - .withExplicitFileType(FILE_TYPE_FRAMEWORK); - - default: - throw new IllegalArgumentException("unknown: " + type); - } - } - - private static class TargetInfo { - final TargetControl control; - final PBXNativeTarget nativeTarget; - final PBXFrameworksBuildPhase frameworksPhase; - final PBXResourcesBuildPhase resourcesPhase; - final PBXBuildFile productBuildFile; - final PBXTargetDependency targetDependency; - final NSDictionary buildConfig; - - TargetInfo(TargetControl control, - PBXNativeTarget nativeTarget, - PBXFrameworksBuildPhase frameworksPhase, - PBXResourcesBuildPhase resourcesPhase, - PBXBuildFile productBuildFile, - PBXTargetDependency targetDependency, - NSDictionary buildConfig) { - this.control = control; - this.nativeTarget = nativeTarget; - this.frameworksPhase = frameworksPhase; - this.resourcesPhase = resourcesPhase; - this.productBuildFile = productBuildFile; - this.targetDependency = targetDependency; - this.buildConfig = buildConfig; - } - - /** - * Returns the path to the built, statically-linked binary for this target. The path contains - * build-setting variables and may be used in a build setting such as {@code TEST_HOST}. - * - * <p>One example return value is {@code $(BUILT_PRODUCTS_DIR)/Foo.app/Foo}. - */ - String staticallyLinkedBinary() { - ProductType type = productType(control); - Preconditions.checkArgument( - Containing.item(PRODUCT_TYPES_THAT_HAVE_A_BINARY, type), - "This product type (%s) is not known to have a binary.", type); - FileReference productReference = productReference(control); - return String.format("$(%s)/%s/%s", - productReference.sourceTree().name(), - productReference.path().or(productReference.name()), - control.getName()); - } - - /** - * Adds the given dependency to the list of dependencies, the - * appropriate build phase if applicable, and the appropriate build setting values if - * applicable, of this target. - */ - void addDependencyInfo( - DependencyControl dependencyControl, Map<String, TargetInfo> targetInfoByLabel) { - TargetInfo dependencyInfo = - Mapping.of(targetInfoByLabel, dependencyControl.getTargetLabel()).get(); - if (dependencyControl.getTestHost()) { - buildConfig.put("TEST_HOST", dependencyInfo.staticallyLinkedBinary()); - buildConfig.put("BUNDLE_LOADER", dependencyInfo.staticallyLinkedBinary()); - } else if (productType(dependencyInfo.control) == ProductType.BUNDLE - || productType(dependencyInfo.control) == ProductType.WATCH_OS1_APPLICATION) { - resourcesPhase.getFiles().add(dependencyInfo.productBuildFile); - } else if (productType(dependencyInfo.control) == ProductType.APP_EXTENSION - || productType(dependencyInfo.control) == ProductType.WATCH_OS1_EXTENSION) { - PBXCopyFilesBuildPhase copyFilesPhase = new PBXCopyFilesBuildPhase( - PBXCopyFilesBuildPhase.Destination.PLUGINS, /*path=*/""); - copyFilesPhase.getFiles().add(dependencyInfo.productBuildFile); - nativeTarget.getBuildPhases().add(copyFilesPhase); - } else { - frameworksPhase.getFiles().add(dependencyInfo.productBuildFile); - } - nativeTarget.getDependencies().add(dependencyInfo.targetDependency); - } - } - - private static NSDictionary nonArcCompileSettings() { - NSDictionary result = new NSDictionary(); - result.put("COMPILER_FLAGS", "-fno-objc-arc"); - return result; - } - - private static boolean hasAtLeastOneCompilableSource(TargetControl control) { - return (control.getSourceFileCount() != 0) || (control.getNonArcSourceFileCount() != 0); - } - - private static <E> Iterable<E> plus(Iterable<E> before, E... rest) { - return Iterables.concat(before, ImmutableList.copyOf(rest)); - } - - /** - * Returns the final header search paths to be placed in a build configuration. - */ - private static NSArray headerSearchPaths(Iterable<String> paths) { - ImmutableList.Builder<String> result = new ImmutableList.Builder<>(); - for (String path : paths) { - // TODO(bazel-team): Remove this hack once the released version of Bazel is prepending - // "$(WORKSPACE_ROOT)/" to every "source rooted" path. - if (!path.startsWith("$")) { - path = "$(WORKSPACE_ROOT)/" + path; - } - result.add(path); - } - return (NSArray) NSObject.wrap(result.build()); - } - - /** - * Returns the {@code FRAMEWORK_SEARCH_PATHS} array for a target's build config given the list of - * {@code .framework} directory paths. - */ - private static NSArray frameworkSearchPaths(Iterable<String> frameworks) { - ImmutableSet.Builder<NSString> result = new ImmutableSet.Builder<>(); - for (String framework : frameworks) { - result.add(new NSString("$(WORKSPACE_ROOT)/" + Paths.get(framework).getParent())); - } - // This is needed by XcTest targets (and others, just in case) for SenTestingKit.framework. - result.add(new NSString("$(SDKROOT)/Developer/Library/Frameworks")); - // This is needed by non-XcTest targets that use XcTest.framework, for instance for test - // utility libraries packaged as an objc_library. - result.add(new NSString("$(PLATFORM_DIR)/Developer/Library/Frameworks")); - - return (NSArray) NSObject.wrap(result.build().asList()); - } - - /** - * Returns the {@code ARCHS} array for a target's build config given the list of architecture - * strings. If none is given, an array with default architectures "armv7" and "arm64" will be - * returned. - */ - private static NSArray cpuArchitectures(Iterable<String> architectures) { - if (Iterables.isEmpty(architectures)) { - return new NSArray(new NSString("armv7"), new NSString("arm64")); - } else { - ImmutableSet.Builder<NSString> result = new ImmutableSet.Builder<>(); - for (String architecture : architectures) { - result.add(new NSString(architecture)); - } - return (NSArray) NSObject.wrap(result.build().asList()); - } - } - - private static PBXFrameworksBuildPhase buildFrameworksInfo( - LibraryObjects libraryObjects, TargetControl target) { - BuildPhaseBuilder builder = libraryObjects.newBuildPhase(); - for (String sdkFramework : target.getSdkFrameworkList()) { - builder.addSdkFramework(sdkFramework); - } - for (String framework : target.getFrameworkList()) { - builder.addFramework(framework); - } - return builder.build(); - } - - private static ImmutableList<String> otherLdflags(TargetControl targetControl) { - Iterable<String> givenFlags = targetControl.getLinkoptList(); - ImmutableList.Builder<String> flags = new ImmutableList.Builder<>(); - flags.addAll(givenFlags); - if (Containing.item(PRODUCT_TYPES_THAT_HAVE_A_BINARY, productType(targetControl))) { - for (String dylib : targetControl.getSdkDylibList()) { - if (dylib.startsWith("lib")) { - dylib = dylib.substring(3); - } - flags.add("-l" + dylib); - } - } - - return flags.build(); - } - - /** - * Returns a unique name for the given imported library path, scoped by both the base name and - * the parent directories. For example, with "foo/bar/lib.a", "lib_bar_foo.a" will be returned. - */ - private static String uniqueImportedLibraryName(String importedLibrary) { - String extension = ""; - String pathWithoutExtension = ""; - int i = importedLibrary.lastIndexOf('.'); - if (i > 0) { - extension = importedLibrary.substring(i); - pathWithoutExtension = importedLibrary.substring(0, i); - } else { - pathWithoutExtension = importedLibrary; - } - - String[] pathFragments = pathWithoutExtension.replace("-", "_").split("/"); - return Joiner.on("_").join(Lists.reverse(Arrays.asList(pathFragments))) + extension; - } - - /** Generates a project file. */ - public static PBXProject xcodeproj(Path workspaceRoot, Control control, - Iterable<PbxReferencesProcessor> postProcessors) { - checkArgument(control.hasPbxproj(), "Must set pbxproj field on control proto."); - FileSystem fileSystem = workspaceRoot.getFileSystem(); - - XcodeprojPath<Path> outputPath = XcodeprojPath.converter().fromPath( - RelativePaths.fromString(fileSystem, control.getPbxproj())); - - NSDictionary projBuildConfigMap = new NSDictionary(); - projBuildConfigMap.put("ARCHS", cpuArchitectures(control.getCpuArchitectureList())); - projBuildConfigMap.put("VALID_ARCHS", - new NSArray( - new NSString("armv7"), - new NSString("armv7s"), - new NSString("arm64"), - new NSString("i386"), - new NSString("x86_64"))); - projBuildConfigMap.put("CLANG_ENABLE_OBJC_ARC", "YES"); - projBuildConfigMap.put("SDKROOT", "iphoneos"); - projBuildConfigMap.put("IPHONEOS_DEPLOYMENT_TARGET", "7.0"); - projBuildConfigMap.put("GCC_VERSION", "com.apple.compilers.llvm.clang.1_0"); - projBuildConfigMap.put("CODE_SIGN_IDENTITY[sdk=iphoneos*]", "iPhone Developer"); - - // Disable bitcode for now. - // TODO(bazel-team): Need to re-enable once we have real Xcode 7 support. - projBuildConfigMap.put("ENABLE_BITCODE", "NO"); - - for (XcodeprojBuildSetting projectSetting : control.getBuildSettingList()) { - projBuildConfigMap.put(projectSetting.getName(), projectSetting.getValue()); - } - - PBXProject project = new PBXProject(outputPath.getProjectName()); - project.getMainGroup().setPath(workspaceRoot.toString()); - if (workspaceRoot.isAbsolute()) { - project.getMainGroup().setSourceTree(SourceTree.ABSOLUTE); - } - try { - project - .getBuildConfigurationList() - .getBuildConfigurationsByName() - .get(DEFAULT_OPTIONS_NAME) - .setBuildSettings(projBuildConfigMap); - } catch (ExecutionException e) { - throw new RuntimeException(e); - } - - Map<String, TargetInfo> targetInfoByLabel = new HashMap<>(); - List<String> usedTargetNames = new ArrayList<>(); - PBXFileReferences fileReferences = new PBXFileReferences(); - LibraryObjects libraryObjects = new LibraryObjects(fileReferences); - PBXBuildFiles pbxBuildFiles = new PBXBuildFiles(fileReferences); - Resources resources = - Resources.fromTargetControls(fileSystem, pbxBuildFiles, control.getTargetList()); - Xcdatamodels xcdatamodels = - Xcdatamodels.fromTargetControls(fileSystem, pbxBuildFiles, control.getTargetList()); - // We use a hash set for the Project Navigator files so that the same PBXFileReference does not - // get added twice. Because PBXFileReference uses equality-by-identity semantics, this requires - // the PBXFileReferences cache to properly return the same reference for functionally-equivalent - // files. - Set<PBXReference> projectNavigatorFiles = new LinkedHashSet<>(); - for (TargetControl targetControl : control.getTargetList()) { - checkArgument(targetControl.hasName(), "TargetControl requires a name: %s", targetControl); - checkArgument(targetControl.hasLabel(), "TargetControl requires a label: %s", targetControl); - - ProductType productType = productType(targetControl); - Preconditions.checkArgument( - (productType != ProductType.APPLICATION) || hasAtLeastOneCompilableSource(targetControl), - APP_NEEDS_SOURCE_ERROR); - PBXSourcesBuildPhase sourcesBuildPhase = new PBXSourcesBuildPhase(); - - for (SourceFile source : SourceFile.allSourceFiles(fileSystem, targetControl)) { - PBXFileReference fileRef = - fileReferences.get(FileReference.of(source.path().toString(), SourceTree.GROUP)); - projectNavigatorFiles.add(fileRef); - if (Equaling.of(source.buildType(), BuildType.NO_BUILD)) { - continue; - } - PBXBuildFile buildFile = new PBXBuildFile(fileRef); - if (Equaling.of(source.buildType(), BuildType.NON_ARC_BUILD)) { - buildFile.setSettings(Optional.of(nonArcCompileSettings())); - } - sourcesBuildPhase.getFiles().add(buildFile); - } - sourcesBuildPhase.getFiles().addAll(xcdatamodels.buildFiles().get(targetControl)); - - PBXFileReference productReference = fileReferences.get(productReference(targetControl)); - projectNavigatorFiles.add(productReference); - - NSDictionary targetBuildConfigMap = new NSDictionary(); - // TODO(bazel-team): Stop adding the workspace root automatically once the - // released version of Bazel starts passing it. - targetBuildConfigMap.put("USER_HEADER_SEARCH_PATHS", - headerSearchPaths( - plus(targetControl.getUserHeaderSearchPathList(), "$(WORKSPACE_ROOT)"))); - targetBuildConfigMap.put( - "HEADER_SEARCH_PATHS", - headerSearchPaths(plus(targetControl.getHeaderSearchPathList(), "$(inherited)"))); - targetBuildConfigMap.put( - "FRAMEWORK_SEARCH_PATHS", - frameworkSearchPaths( - Iterables.concat( - targetControl.getFrameworkList(), - targetControl.getFrameworkSearchPathOnlyList()))); - - targetBuildConfigMap.put("WORKSPACE_ROOT", workspaceRoot.toString()); - - if (targetControl.hasPchPath()) { - targetBuildConfigMap.put( - "GCC_PREFIX_HEADER", "$(WORKSPACE_ROOT)/" + targetControl.getPchPath()); - } - - targetBuildConfigMap.put("PRODUCT_NAME", productName(targetControl)); - if (targetControl.hasInfoplist()) { - targetBuildConfigMap.put( - "INFOPLIST_FILE", "$(WORKSPACE_ROOT)/" + targetControl.getInfoplist()); - } - - - // Double-quotes in copt strings need to be escaped for XCode. - if (targetControl.getCoptCount() > 0) { - List<String> escapedCopts = Lists.transform( - targetControl.getCoptList(), QUOTE_ESCAPER.asFunction()); - targetBuildConfigMap.put("OTHER_CFLAGS", NSObject.wrap(escapedCopts)); - } - targetBuildConfigMap.put("OTHER_LDFLAGS", NSObject.wrap(otherLdflags(targetControl))); - for (XcodeprojBuildSetting setting : targetControl.getBuildSettingList()) { - String name = setting.getName(); - String value = setting.getValue(); - // TODO(bazel-team): Remove this hack after next Bazel release. - if (name.equals("CODE_SIGN_ENTITLEMENTS") && !value.startsWith("$")) { - value = "$(WORKSPACE_ROOT)/" + value; - } - targetBuildConfigMap.put(name, value); - } - - // Note that HFS+ (the Mac filesystem) is usually case insensitive, so we cast all target - // names to lower case before checking for duplication because otherwise users may end up - // having duplicated intermediate build directories that can interfere with the build. - String targetName = targetControl.getName(); - String targetNameInLowerCase = targetName.toLowerCase(); - if (usedTargetNames.contains(targetNameInLowerCase)) { - // Use the label in the odd case where we have two targets with the same name. - targetName = targetControl.getLabel(); - targetNameInLowerCase = targetName.toLowerCase(); - } - checkState(!usedTargetNames.contains(targetNameInLowerCase), - "Name (case-insensitive) already exists for target with label/name %s/%s in list: %s", - targetControl.getLabel(), targetControl.getName(), usedTargetNames); - usedTargetNames.add(targetNameInLowerCase); - PBXNativeTarget target = new PBXNativeTarget(targetName, productType); - try { - target - .getBuildConfigurationList() - .getBuildConfigurationsByName() - .get(DEFAULT_OPTIONS_NAME) - .setBuildSettings(targetBuildConfigMap); - } catch (ExecutionException e) { - throw new RuntimeException(e); - } - target.setProductReference(productReference); - - // We only add frameworks here and not dylibs because of differences in how - // Xcode 6 and Xcode 7 specify dylibs in the project organizer. - // (Xcode 6 -> *.dylib, Xcode 7 -> *.tbd) - PBXFrameworksBuildPhase frameworksPhase = buildFrameworksInfo(libraryObjects, targetControl); - PBXResourcesBuildPhase resourcesPhase = resources.resourcesBuildPhase(targetControl); - - for (String importedArchive : targetControl.getImportedLibraryList()) { - PBXFileReference fileReference = fileReferences.get( - FileReference.of(importedArchive, SourceTree.GROUP) - .withExplicitFileType(FILE_TYPE_ARCHIVE_LIBRARY)); - projectNavigatorFiles.add(fileReference); - } - - project.getTargets().add(target); - - target.getBuildPhases().add(frameworksPhase); - target.getBuildPhases().add(sourcesBuildPhase); - target.getBuildPhases().add(resourcesPhase); - - checkState(!Mapping.of(targetInfoByLabel, targetControl.getLabel()).isPresent(), - "Mapping already exists for target with label %s in map: %s", - targetControl.getLabel(), targetInfoByLabel); - targetInfoByLabel.put( - targetControl.getLabel(), - new TargetInfo( - targetControl, - target, - frameworksPhase, - resourcesPhase, - new PBXBuildFile(productReference), - new LocalPBXTargetDependency( - new LocalPBXContainerItemProxy( - project, target, ProxyType.TARGET_REFERENCE)), - targetBuildConfigMap)); - } - - for (HasProjectNavigatorFiles references : ImmutableList.of(pbxBuildFiles, libraryObjects)) { - Iterables.addAll(projectNavigatorFiles, references.mainGroupReferences()); - } - - Iterable<PBXReference> processedProjectFiles = projectNavigatorFiles; - for (PbxReferencesProcessor postProcessor : postProcessors) { - processedProjectFiles = postProcessor.process(processedProjectFiles); - } - - Iterables.addAll(project.getMainGroup().getChildren(), processedProjectFiles); - for (TargetInfo targetInfo : targetInfoByLabel.values()) { - TargetControl targetControl = targetInfo.control; - for (DependencyControl dependency : targetControl.getDependencyList()) { - targetInfo.addDependencyInfo(dependency, targetInfoByLabel); - } - - if (!Equaling.of(ProductType.STATIC_LIBRARY, productType(targetControl)) - && !targetControl.getImportedLibraryList().isEmpty()) { - // We add a script build phase to copy the imported libraries to BUILT_PRODUCT_DIR with - // unique names before linking them to work around an Xcode issue where imported libraries - // with duplicated names lead to link errors. - // - // Internally Xcode uses linker flag -l{LIBRARY_NAME} to link a particular library and - // delegates to the linker to locate the actual library using library search paths. So given - // two imported libraries with the same name: a/b/libfoo.a, c/d/libfoo.a, Xcode uses - // duplicate linker flag -lfoo to link both of the libraries. Depending on the order of - // the library search paths, the linker will only be able to locate and link one of the - // libraries. - // - // With this workaround using a script build phase, all imported libraries to link have - // unique names. For the previous example with a/b/libfoo.a and c/d/libfoo.a, the script - // build phase will copy them to BUILT_PRODUCTS_DIR with unique names libfoo_b_a.a and - // libfoo_d_c.a, respectively. The linker flags Xcode uses to link them will be - // -lfoo_d_c and -lfoo_b_a, with no duplication. - PBXShellScriptBuildPhase scriptBuildPhase = new PBXShellScriptBuildPhase(); - scriptBuildPhase.setShellScript( - "for ((i=0; i < ${SCRIPT_INPUT_FILE_COUNT}; i++)) do\n" - + " INPUT_FILE=\"SCRIPT_INPUT_FILE_${i}\"\n" - + " OUTPUT_FILE=\"SCRIPT_OUTPUT_FILE_${i}\"\n" - + " cp -v -f \"${!INPUT_FILE}\" \"${!OUTPUT_FILE}\"\n" - + "done"); - for (String importedLibrary : targetControl.getImportedLibraryList()) { - String uniqueImportedLibrary = uniqueImportedLibraryName(importedLibrary); - scriptBuildPhase.getInputPaths().add("$(WORKSPACE_ROOT)/" + importedLibrary); - scriptBuildPhase.getOutputPaths().add("$(BUILT_PRODUCTS_DIR)/" + uniqueImportedLibrary); - FileReference fileReference = FileReference.of(uniqueImportedLibrary, - SourceTree.BUILT_PRODUCTS_DIR).withExplicitFileType(FILE_TYPE_ARCHIVE_LIBRARY); - targetInfo.frameworksPhase.getFiles().add(pbxBuildFiles.getStandalone(fileReference)); - } - targetInfo.nativeTarget.getBuildPhases().add(scriptBuildPhase); - } - } - - return project; - } -} diff --git a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/testing/PbxTypes.java b/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/testing/PbxTypes.java deleted file mode 100644 index 7c409148b8..0000000000 --- a/src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/testing/PbxTypes.java +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.xcode.xcodegen.testing; - -import com.google.common.base.Optional; -import com.google.common.collect.ImmutableList; -import com.google.devtools.build.xcode.xcodegen.FileReference; - -import com.facebook.buck.apple.xcode.xcodeproj.PBXBuildFile; -import com.facebook.buck.apple.xcode.xcodeproj.PBXFileReference; -import com.facebook.buck.apple.xcode.xcodeproj.PBXFrameworksBuildPhase; -import com.facebook.buck.apple.xcode.xcodeproj.PBXReference; - -/** - * Collection of static utility methods for PBX type transformations, either to other - * representations of the same or our domain objects. - */ -public class PbxTypes { - - private PbxTypes() {} - - /** - * Returns all file references the {@code phase} depends on in - * {@link PBXFrameworksBuildPhase#getFiles()}. - */ - public static ImmutableList<FileReference> fileReferences(PBXFrameworksBuildPhase phase) { - return fileReferences(pbxFileReferences(phase)); - } - - /** - * Transforms the given list of PBX references to file references. - */ - public static ImmutableList<FileReference> fileReferences( - Iterable<? extends PBXReference> references) { - ImmutableList.Builder<FileReference> fileReferences = ImmutableList.builder(); - for (PBXReference reference : references) { - fileReferences.add(fileReference(reference)); - } - return fileReferences.build(); - } - - /** - * Extracts the list of PBX references {@code phase} depends on through - * {@link PBXFrameworksBuildPhase#getFiles()}. - */ - public static ImmutableList<PBXReference> pbxFileReferences(PBXFrameworksBuildPhase phase) { - ImmutableList.Builder<PBXReference> phaseFileReferences = ImmutableList.builder(); - for (PBXBuildFile buildFile : phase.getFiles()) { - phaseFileReferences.add(buildFile.getFileRef()); - } - return phaseFileReferences.build(); - } - - /** - * Converts a PBX file reference to its domain equivalent. - */ - public static FileReference fileReference(PBXReference reference) { - FileReference fileReference = - FileReference.of(reference.getName(), reference.getPath(), reference.getSourceTree()); - if (reference instanceof PBXFileReference) { - Optional<String> explicitFileType = ((PBXFileReference) reference).getExplicitFileType(); - if (explicitFileType.isPresent()) { - return fileReference.withExplicitFileType(explicitFileType.get()); - } - } - return fileReference; - } - - /** - * Returns the string representation of all references the {@code phase} depends on in - * {@link PBXFrameworksBuildPhase#getFiles()}. - * - */ - public static ImmutableList<String> referencePaths(PBXFrameworksBuildPhase phase) { - return paths(pbxFileReferences(phase)); - } - - /** - * Transforms the given list of references into their string path representations. - */ - public static ImmutableList<String> paths(Iterable<? extends PBXReference> references) { - ImmutableList.Builder<String> paths = ImmutableList.builder(); - for (PBXReference reference : references) { - paths.add(reference.getPath()); - } - return paths.build(); - } -} |