aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/objc_tools
diff options
context:
space:
mode:
authorGravatar schmitt <schmitt@google.com>2017-06-26 15:35:06 +0200
committerGravatar Marcel Hlopko <hlopko@google.com>2017-06-26 18:42:44 +0200
commit0507fd5eaa0b30fcabe39db02ef9fb090ef7edc6 (patch)
tree8c71f09a5388db96e6122ca160ef5b8397cfa6d3 /src/objc_tools
parent8f6549fcca1838e2bbb0ec0dc52fc8b83c923c8e (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')
-rw-r--r--src/objc_tools/xcodegen/BUILD44
-rw-r--r--src/objc_tools/xcodegen/README2
-rw-r--r--src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/AggregateKey.java62
-rw-r--r--src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/AggregateReferenceType.java126
-rw-r--r--src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/CurrentVersionSetter.java92
-rw-r--r--src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/FileReference.java98
-rw-r--r--src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/HasProjectNavigatorFiles.java28
-rw-r--r--src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/LibraryObjects.java119
-rw-r--r--src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/LocalPBXContainerItemProxy.java62
-rw-r--r--src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/LocalPBXTargetDependency.java36
-rw-r--r--src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/PBXBuildFiles.java171
-rw-r--r--src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/PBXFileReferences.java48
-rw-r--r--src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/PbxReferencesGrouper.java173
-rw-r--r--src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/PbxReferencesProcessor.java37
-rw-r--r--src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/RelativePaths.java52
-rw-r--r--src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/Resources.java113
-rw-r--r--src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/SourceFile.java77
-rw-r--r--src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/Xcdatamodels.java67
-rw-r--r--src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/XcodeGen.java121
-rw-r--r--src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/XcodeprojGeneration.java661
-rw-r--r--src/objc_tools/xcodegen/java/com/google/devtools/build/xcode/xcodegen/testing/PbxTypes.java100
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();
- }
-}