Fixes for Xcode 10's new build system

- Create a Run Script phase to write out dummy files for Objective-C sources
  in test targets. This silences some Xcode 10 warnings about .d files not
  being present, as well as issues with <target>_dependency_info.dat files.
- Add the Xcode processed Info.plist file as an input to the bazel_build.py
  script to ensure it is processed before our script. This allows our script
  to safely overwrite it.

PiperOrigin-RevId: 213950894
diff --git a/src/TulsiGenerator/PBXTargetGenerator.swift b/src/TulsiGenerator/PBXTargetGenerator.swift
index 092d4ac..4bf101d 100644
--- a/src/TulsiGenerator/PBXTargetGenerator.swift
+++ b/src/TulsiGenerator/PBXTargetGenerator.swift
@@ -1162,6 +1162,11 @@
       target.buildPhases.append(testBuildPhase)
     }
     if !testSourceFileInfos.isEmpty || !testNonArcSourceFileInfos.isEmpty {
+      if !containsSwift {
+        let allSources = testSourceFileInfos + testNonArcSourceFileInfos
+        let testBuildPhase = createGenerateDummyDependencyFilesTestBuildPhase(allSources)
+        target.buildPhases.append(testBuildPhase)
+      }
       var fileReferences = generateFileReferencesForFileInfos(testSourceFileInfos)
       let (nonARCFiles, nonARCSettings) =
           generateFileReferencesAndSettingsForNonARCFileInfos(testNonArcSourceFileInfos)
@@ -1584,6 +1589,30 @@
     return buildPhase
   }
 
+  private func createGenerateDummyDependencyFilesTestBuildPhase(_ sources: [BazelFileInfo]) -> PBXShellScriptBuildPhase {
+    let files = sources.map { ($0.subPath as NSString).deletingPathExtension.pbPathLastComponent }
+    let shellScript = """
+# Script to generate dependency files Xcode expects when running tests.
+set -eu
+ARCH_ARRAY=($ARCHS)
+FILES=(\(files.map { $0.escapingForShell }.joined(separator: " ")))
+for ARCH in "${ARCH_ARRAY[@]}"
+do
+  mkdir -p "$OBJECT_FILE_DIR_normal/$ARCH/"
+  rm -f "$OBJECT_FILE_DIR_normal/$ARCH/${PRODUCT_NAME}_dependency_info.dat"
+  printf '\\x00\\x31\\x00' >"$OBJECT_FILE_DIR_normal/$ARCH/${PRODUCT_NAME}_dependency_info.dat"
+  for FILE in "${FILES[@]}"
+  do
+    touch "$OBJECT_FILE_DIR_normal/$ARCH/$FILE.d"
+  done
+done
+"""
+    let buildPhase = PBXShellScriptBuildPhase(shellScript: shellScript, shellPath: "/bin/bash")
+    buildPhase.showEnvVarsInLog = true
+    buildPhase.mnemonic = "ObjcDummy"
+    return buildPhase
+  }
+
   private func createBuildPhaseForRuleEntry(_ entry: RuleEntry)
       -> PBXShellScriptBuildPhase? {
     let buildLabel = entry.label.value
@@ -1599,7 +1628,14 @@
         "\(changeDirectoryAction)\n" +
         "exec \(commandLine)"
 
-    let buildPhase = PBXShellScriptBuildPhase(shellScript: shellScript, shellPath: "/bin/bash")
+    // Using the Info.plist as an input forces Xcode to run this after processing the Info.plist,
+    // allowing our script to safely overwrite the Info.plist after Xcode does its processing.
+    let inputPaths = ["$(TARGET_BUILD_DIR)/$(INFOPLIST_PATH)"]
+    let buildPhase = PBXShellScriptBuildPhase(
+      shellScript: shellScript,
+      shellPath: "/bin/bash",
+      inputPaths: inputPaths
+    )
     buildPhase.showEnvVarsInLog = true
     buildPhase.mnemonic = "BazelBuild"
     return buildPhase
diff --git a/src/TulsiGenerator/XcodeProjectGenerator.swift b/src/TulsiGenerator/XcodeProjectGenerator.swift
index f5c8323..3785341 100644
--- a/src/TulsiGenerator/XcodeProjectGenerator.swift
+++ b/src/TulsiGenerator/XcodeProjectGenerator.swift
@@ -559,7 +559,6 @@
 
     let workspaceSharedDataURL = projectURL.appendingPathComponent("project.xcworkspace/xcshareddata")
     let sharedWorkspaceSettings: [String: Any] = [
-      "BuildSystemType": "Original",
       "IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded": false as AnyObject,
     ]
     try writeWorkspaceSettings(sharedWorkspaceSettings,
diff --git a/src/TulsiGeneratorTests/PBXTargetGeneratorTests.swift b/src/TulsiGeneratorTests/PBXTargetGeneratorTests.swift
index c6eeec0..58f0679 100644
--- a/src/TulsiGeneratorTests/PBXTargetGeneratorTests.swift
+++ b/src/TulsiGeneratorTests/PBXTargetGeneratorTests.swift
@@ -995,6 +995,7 @@
         expectedBuildPhases: [
           BazelShellScriptBuildPhaseDefinition(bazelPath: bazelPath, buildTarget: rule1BuildTarget),
           SourcesBuildPhaseDefinition(files: testSources, mainGroup: project.mainGroup),
+          ObjcDummyShellScriptBuildPhaseDefinition(),
         ]
       )
       assertTarget(expectedTarget, inTargets: targets)
@@ -1113,7 +1114,8 @@
           expectedBuildPhases: [
               SourcesBuildPhaseDefinition(files: testSources, mainGroup: project.mainGroup),
               BazelShellScriptBuildPhaseDefinition(bazelPath: bazelPath,
-                                              buildTarget: testRuleBuildTarget)
+                                              buildTarget: testRuleBuildTarget),
+              ObjcDummyShellScriptBuildPhaseDefinition(),
           ]
       )
       assertTarget(expectedTarget, inTargets: targets)
@@ -1200,7 +1202,8 @@
       expectedBuildPhases: [
         SourcesBuildPhaseDefinition(files: testSources, mainGroup: project.mainGroup),
         BazelShellScriptBuildPhaseDefinition(bazelPath: bazelPath,
-                                             buildTarget: "\(testRulePackage):\(testRuleTargetName)")
+                                             buildTarget: "\(testRulePackage):\(testRuleTargetName)"),
+        ObjcDummyShellScriptBuildPhaseDefinition(),
       ]
     )
     assertTarget(expectedTarget, inTargets: targets)
@@ -1408,7 +1411,8 @@
         expectedBuildPhases: [
           SourcesBuildPhaseDefinition(files: testSources, mainGroup: project.mainGroup),
           BazelShellScriptBuildPhaseDefinition(bazelPath: bazelPath,
-                                          buildTarget: testRuleBuildTarget)
+                                          buildTarget: testRuleBuildTarget),
+          ObjcDummyShellScriptBuildPhaseDefinition(),
         ]
       )
       assertTarget(expectedTarget, inTargets: targets)
@@ -2850,6 +2854,24 @@
     }
   }
 
+  private class ObjcDummyShellScriptBuildPhaseDefinition: BuildPhaseDefinition {
+    init() {
+      super.init(isa: "PBXShellScriptBuildPhase", files: [], mnemonic: "ObjcDummy")
+    }
+
+    override func validate(_ phase: PBXBuildPhase, line: UInt = #line) {
+      super.validate(phase, line: line)
+
+      // Guaranteed by the test infrastructure below, failing this indicates a programming error in
+      // the test fixture, not in the code being tested.
+      let scriptBuildPhase = phase as! PBXShellScriptBuildPhase
+
+      let script = scriptBuildPhase.shellScript
+      XCTAssert(script.contains("touch"), "Build script does not contain 'touch'.",
+                line: line)
+    }
+  }
+
   private func fileRefForPath(_ path: String) -> PBXReference? {
     let components = path.components(separatedBy: "/")
     var node = project.mainGroup