From 683fb751523c17d1dd7d3b4f775e8928087b9404 Mon Sep 17 00:00:00 2001 From: Luis Padron Date: Fri, 4 Apr 2025 21:57:26 -0400 Subject: [PATCH] Support index-import on all Xcode 16.x versions Similar to: bazelbuild/rules_swift#1504 Part of #3160 This PR updates the index-import dependency to include both version 5.8 and 6.1 as the hash algorithm changed in Swift 6.1. To make this change backwards compatible we switch to the 5.8 version on Xcode 16.2 and under. Signed-off-by: Luis Padron --- MODULE.bazel | 9 ++---- .../fixtures/bwb.xcodeproj/project.pbxproj | 2 ++ .../test/fixtures/bwb_project_spec.json | 3 +- examples/rules_ios/MODULE.bazel | 2 +- examples/rules_ios/WORKSPACE | 4 +-- .../fixtures/bwb.xcodeproj/project.pbxproj | 1 + .../test/fixtures/bwb_project_spec.json | 3 +- .../write_pbxproj_prefix_tests.bzl | 10 +++++++ tools/BUILD | 2 ++ tools/generators/legacy/src/DTO/Project.swift | 6 +++- .../legacy/src/Generator/CreateProject.swift | 2 ++ .../legacy/src/Generator/Environment.swift | 1 + .../legacy/src/Generator/Generator.swift | 1 + .../legacy/test/CreateProjectTests.swift | 4 +++ tools/generators/legacy/test/Fixtures.swift | 1 + .../legacy/test/GeneratorTests.swift | 5 ++++ tools/generators/pbxproj_prefix/README.md | 3 +- .../src/Generator/Arguments.swift | 3 ++ .../src/Generator/Environment.swift | 1 + .../src/Generator/Generator.swift | 1 + .../Generator/PBXProjectBuildSettings.swift | 11 +++++++- .../test/PBXProjectBuildSettingsTests.swift | 3 ++ .../ImportIndexstores.swift | 13 ++++++++- .../internal/files/legacy_input_files.bzl | 8 ++++-- .../internal/files/legacy_output_files.bzl | 8 ++++-- xcodeproj/internal/pbxproj_partials.bzl | 6 ++++ .../internal/xcodeproj_incremental_rule.bzl | 12 +++++++- xcodeproj/internal/xcodeproj_legacy_rule.bzl | 22 +++++++++++++-- xcodeproj/repositories.bzl | 28 ++++++++++++++----- 29 files changed, 145 insertions(+), 30 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index c2693e10c2..b604345f0d 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -10,7 +10,7 @@ bazel_dep(name = "bazel_features", version = "1.3.0") bazel_dep(name = "bazel_skylib", version = "1.3.0") bazel_dep( name = "rules_swift", - version = "1.18.0", + version = "2.8.0", max_compatibility_level = 2, repo_name = "build_bazel_rules_swift", ) @@ -28,6 +28,7 @@ non_module_deps = use_extension("//xcodeproj:extensions.bzl", "non_module_deps") use_repo( non_module_deps, "rules_xcodeproj_index_import", + "rules_xcodeproj_legacy_index_import", ) # Non-release dependencies @@ -55,12 +56,6 @@ bazel_dep( repo_name = "io_bazel_stardoc", ) -# Use newer versions of deps in development -single_version_override( - module_name = "rules_swift", - version = "2.3.0", -) - # Some of our deps are forcing a new stardoc on us, so pinning for now single_version_override( module_name = "stardoc", diff --git a/examples/integration/test/fixtures/bwb.xcodeproj/project.pbxproj b/examples/integration/test/fixtures/bwb.xcodeproj/project.pbxproj index 657f678cfb..37a37fe815 100644 --- a/examples/integration/test/fixtures/bwb.xcodeproj/project.pbxproj +++ b/examples/integration/test/fixtures/bwb.xcodeproj/project.pbxproj @@ -15628,6 +15628,7 @@ LD_DYLIB_INSTALL_NAME = ""; LD_OBJC_ABI_VERSION = ""; LD_RUNPATH_SEARCH_PATHS = ""; + LEGACY_INDEX_IMPORT = "fixture-legacy-index-import-path"; LIBTOOL = "$(BAZEL_INTEGRATION_DIR)/libtool"; ONLY_ACTIVE_ARCH = YES; PROJECT_DIR = "../../../../../bazel-output-base/rules_xcodeproj.noindex/build_output_base/execroot/_main"; @@ -18220,6 +18221,7 @@ LD_DYLIB_INSTALL_NAME = ""; LD_OBJC_ABI_VERSION = ""; LD_RUNPATH_SEARCH_PATHS = ""; + LEGACY_INDEX_IMPORT = "fixture-legacy-index-import-path"; LIBTOOL = "$(BAZEL_INTEGRATION_DIR)/libtool"; ONLY_ACTIVE_ARCH = YES; PROJECT_DIR = "../../../../../bazel-output-base/rules_xcodeproj.noindex/build_output_base/execroot/_main"; diff --git a/examples/integration/test/fixtures/bwb_project_spec.json b/examples/integration/test/fixtures/bwb_project_spec.json index 1da549cf06..c6c68815d6 100644 --- a/examples/integration/test/fixtures/bwb_project_spec.json +++ b/examples/integration/test/fixtures/bwb_project_spec.json @@ -482,7 +482,8 @@ "watchOSAppExtension/Info.plist", "watchOSAppExtension/Test/UnitTests/BUILD" ], - "i": "fixture-index-import-path", + "i": "fixture-legacy-index-import-path", + "j": "fixture-index-import-path", "m": "13.0", "n": "bwb", "o": { diff --git a/examples/rules_ios/MODULE.bazel b/examples/rules_ios/MODULE.bazel index ca97d6afa0..8ef4496535 100644 --- a/examples/rules_ios/MODULE.bazel +++ b/examples/rules_ios/MODULE.bazel @@ -20,7 +20,7 @@ bazel_dep( ) bazel_dep( name = "rules_ios", - version = "5.5.1", + version = "5.6.0", repo_name = "build_bazel_rules_ios", ) diff --git a/examples/rules_ios/WORKSPACE b/examples/rules_ios/WORKSPACE index edeef6aa23..a5292bc1fe 100644 --- a/examples/rules_ios/WORKSPACE +++ b/examples/rules_ios/WORKSPACE @@ -2,8 +2,8 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "build_bazel_rules_ios", - sha256 = "c417b69639a737eb44e2af13309f1b00950d6d0c48f67c64ee36d3ea750f687e", - url = "https://github.com/bazel-ios/rules_ios/releases/download/4.6.0/rules_ios.4.6.0.tar.gz", + sha256 = "e0dbd18f1d7a48a4b98e97dbdc45dfc7f0b1cf902afe86c442614db17f560611", + url = "https://github.com/bazel-ios/rules_ios/releases/download/5.6.0/rules_ios.5.6.0.tar.gz", ) load( diff --git a/examples/rules_ios/test/fixtures/bwb.xcodeproj/project.pbxproj b/examples/rules_ios/test/fixtures/bwb.xcodeproj/project.pbxproj index e6dc08353c..d4ae1835ce 100644 --- a/examples/rules_ios/test/fixtures/bwb.xcodeproj/project.pbxproj +++ b/examples/rules_ios/test/fixtures/bwb.xcodeproj/project.pbxproj @@ -5016,6 +5016,7 @@ LD_DYLIB_INSTALL_NAME = ""; LD_OBJC_ABI_VERSION = ""; LD_RUNPATH_SEARCH_PATHS = ""; + LEGACY_INDEX_IMPORT = "fixture-legacy-index-import-path"; LIBTOOL = "$(BAZEL_INTEGRATION_DIR)/libtool"; ONLY_ACTIVE_ARCH = YES; PROJECT_DIR = "../../../../../bazel-output-base/rules_xcodeproj.noindex/build_output_base/execroot/_main"; diff --git a/examples/rules_ios/test/fixtures/bwb_project_spec.json b/examples/rules_ios/test/fixtures/bwb_project_spec.json index 2b5c98ba41..3d349a0d14 100644 --- a/examples/rules_ios/test/fixtures/bwb_project_spec.json +++ b/examples/rules_ios/test/fixtures/bwb_project_spec.json @@ -214,7 +214,8 @@ "iOSApp/Test/UITests/BUILD", "test/fixtures/BUILD" ], - "i": "fixture-index-import-path", + "i": "fixture-legacy-index-import-path", + "j": "fixture-index-import-path", "m": "13.0", "n": "bwb", "o": { diff --git a/test/internal/pbxproj_partials/write_pbxproj_prefix_tests.bzl b/test/internal/pbxproj_partials/write_pbxproj_prefix_tests.bzl index e416fdb56c..c9470c5959 100644 --- a/test/internal/pbxproj_partials/write_pbxproj_prefix_tests.bzl +++ b/test/internal/pbxproj_partials/write_pbxproj_prefix_tests.bzl @@ -55,6 +55,7 @@ def _write_pbxproj_prefix_test_impl(ctx): ), index_import = ctx.attr.index_import, install_path = "a/project.xcodeproj", + legacy_index_import = ctx.attr.legacy_index_import, minimum_xcode_version = ctx.attr.minimum_xcode_version, platforms = ctx.attr.platforms, post_build_script = ctx.attr.post_build_script, @@ -145,6 +146,7 @@ write_pbxproj_prefix_test = unittest.make( "execution_root_file": attr.string(mandatory = True), "import_index_build_indexstores": attr.bool(mandatory = True), "index_import": attr.string(mandatory = True), + "legacy_index_import": attr.string(mandatory = True), "minimum_xcode_version": attr.string(mandatory = True), "platforms": attr.string_list(mandatory = True), "post_build_script": attr.string(), @@ -181,6 +183,7 @@ def write_pbxproj_prefix_test_suite(name): execution_root_file, import_index_build_indexstores, index_import, + legacy_index_import, minimum_xcode_version, platforms, post_build_script = None, @@ -205,6 +208,7 @@ def write_pbxproj_prefix_test_suite(name): execution_root_file = execution_root_file, import_index_build_indexstores = import_index_build_indexstores, index_import = index_import, + legacy_index_import = legacy_index_import, minimum_xcode_version = minimum_xcode_version, platforms = platforms, post_build_script = post_build_script, @@ -234,6 +238,7 @@ def write_pbxproj_prefix_test_suite(name): execution_root_file = "an/execution/root/file", import_index_build_indexstores = True, index_import = "some/path/to/index_import", + legacy_index_import = "some/path/to/legacy/index_import", minimum_xcode_version = "14.2.1", platforms = [ "MACOS", @@ -262,6 +267,8 @@ def write_pbxproj_prefix_test_suite(name): "an/execution/root/file", # targetIdsFile "a/path/to/target_ids_list", + # legacyIndexImport + "some/path/to/legacy/index_import", # indexImport "some/path/to/index_import", # resolvedRepositoriesFile @@ -297,6 +304,7 @@ def write_pbxproj_prefix_test_suite(name): execution_root_file = "an/execution/root/file", import_index_build_indexstores = False, index_import = "some/path/to/index_import", + legacy_index_import = "some/path/to/legacy/index_import", platforms = [ "MACOS", "IOS_DEVICE", @@ -328,6 +336,8 @@ def write_pbxproj_prefix_test_suite(name): "an/execution/root/file", # targetIdsFile "a/path/to/target_ids_list", + # legacyIndexImport + "some/path/to/legacy/index_import", # indexImport "some/path/to/index_import", # resolvedRepositoriesFile diff --git a/tools/BUILD b/tools/BUILD index a25ef9c38b..ba99c3f68b 100644 --- a/tools/BUILD +++ b/tools/BUILD @@ -175,6 +175,8 @@ _XCSCHEMES = [ "bazel-output-base/rules_xcodeproj.noindex/build_output_base/execroot/_main/bazel-out/darwin_arm64-dbg/bin/external/_main~internal~rules_xcodeproj_generated/generator/tools/xcodeproj/xcodeproj_execution_root_file", # targetIdsFile "bazel-out/darwin_arm64-dbg/bin/external/_main~internal~rules_xcodeproj_generated/generator/tools/xcodeproj/xcodeproj_target_ids", + # legacyIndexImport + "bazel-out/darwin_arm64-opt-exec-2B5CBBC6/bin/external/_main~non_module_deps~rules_xcodeproj_legacy_index_import/index-import", # indexImport "bazel-out/darwin_arm64-opt-exec-2B5CBBC6/bin/external/_main~non_module_deps~rules_xcodeproj_index_import/index-import", # resolvedRepositoriesFile diff --git a/tools/generators/legacy/src/DTO/Project.swift b/tools/generators/legacy/src/DTO/Project.swift index 7935135108..55148c349e 100644 --- a/tools/generators/legacy/src/DTO/Project.swift +++ b/tools/generators/legacy/src/DTO/Project.swift @@ -39,6 +39,7 @@ struct Project: Equatable { var customXcodeSchemes: [XcodeScheme] = [] let targetIdsFile: String let targetNameMode: TargetNameMode + let legacyIndexImport: String let indexImport: String let preBuildScript: String? let postBuildScript: String? @@ -61,7 +62,8 @@ extension Project: Decodable { case schemeAutogenerationMode = "s" case targetIdsFile = "T" case targetNameMode = "N" - case indexImport = "i" + case legacyIndexImport = "i" + case indexImport = "j" case preBuildScript = "p" case postBuildScript = "P" } @@ -107,6 +109,8 @@ extension Project: Decodable { TargetNameMode.self, forKey: .targetNameMode ) ?? .auto + legacyIndexImport = try container + .decode(String.self, forKey: .legacyIndexImport) indexImport = try container .decode(String.self, forKey: .indexImport) preBuildScript = try container diff --git a/tools/generators/legacy/src/Generator/CreateProject.swift b/tools/generators/legacy/src/Generator/CreateProject.swift index 11e23b1567..548705e416 100644 --- a/tools/generators/legacy/src/Generator/CreateProject.swift +++ b/tools/generators/legacy/src/Generator/CreateProject.swift @@ -12,6 +12,7 @@ extension Generator { forFixtures: Bool, project: Project, directories: Directories, + legacyIndexImport: String, indexImport: String, minimumXcodeVersion: SemanticVersion ) -> PBXProj { @@ -104,6 +105,7 @@ $(PROJECT_FILE_PATH)/\(directories.internalDirectoryName) // We don't want Xcode to set any search paths, since we set them in // `link.params` "LD_RUNPATH_SEARCH_PATHS": "", + "LEGACY_INDEX_IMPORT": legacyIndexImport, "ONLY_ACTIVE_ARCH": true, "PROJECT_DIR": absoluteProjectDirPath, "RULES_XCODEPROJ_BUILD_MODE": buildMode.rawValue, diff --git a/tools/generators/legacy/src/Generator/Environment.swift b/tools/generators/legacy/src/Generator/Environment.swift index 051e292122..00b4d5f145 100644 --- a/tools/generators/legacy/src/Generator/Environment.swift +++ b/tools/generators/legacy/src/Generator/Environment.swift @@ -12,6 +12,7 @@ struct Environment { _ forFixtures: Bool, _ project: Project, _ directories: Directories, + _ legacyIndexImport: String, _ indexImport: String, _ minimumXcodeVersion: SemanticVersion ) -> PBXProj diff --git a/tools/generators/legacy/src/Generator/Generator.swift b/tools/generators/legacy/src/Generator/Generator.swift index e72953d9f6..ec94343184 100644 --- a/tools/generators/legacy/src/Generator/Generator.swift +++ b/tools/generators/legacy/src/Generator/Generator.swift @@ -57,6 +57,7 @@ class Generator { forFixtures, project, directories, + project.legacyIndexImport, project.indexImport, project.minimumXcodeVersion ) diff --git a/tools/generators/legacy/test/CreateProjectTests.swift b/tools/generators/legacy/test/CreateProjectTests.swift index 56cc72128f..81e8eb3c32 100644 --- a/tools/generators/legacy/test/CreateProjectTests.swift +++ b/tools/generators/legacy/test/CreateProjectTests.swift @@ -86,6 +86,7 @@ $(INDEXING_DEPLOYMENT_LOCATION__NO) "LD_OBJC_ABI_VERSION": "", "LD_DYLIB_INSTALL_NAME": "", "LD_RUNPATH_SEARCH_PATHS": "", + "LEGACY_INDEX_IMPORT": "/tmp/legacy-index-import", "ONLY_ACTIVE_ARCH": true, "PROJECT_DIR": """ /tmp/bazel-output-base/rules_xcodeproj/build_output_base/execroot/rules_xcodeproj @@ -144,6 +145,7 @@ $(PROJECT_TEMP_DIR)/$(BAZEL_PACKAGE_BIN_DIR)/$(COMPILE_TARGET_NAME) forFixtures: false, project: project, directories: directories, + legacyIndexImport: project.legacyIndexImport, indexImport: project.indexImport, minimumXcodeVersion: project.minimumXcodeVersion ) @@ -215,6 +217,7 @@ $(BUILD_DIR)/$(BAZEL_PACKAGE_BIN_DIR) "GCC_OPTIMIZATION_LEVEL": "0", "LD": "$(BAZEL_INTEGRATION_DIR)/ld", "LDPLUSPLUS": "$(BAZEL_INTEGRATION_DIR)/ld", + "LEGACY_INDEX_IMPORT": "/tmp/legacy-index-import", "LIBTOOL": "$(BAZEL_INTEGRATION_DIR)/libtool", "IMPORT_INDEX_BUILD_INDEXSTORES": true, "INDEX_DATA_STORE_DIR": "$(INDEX_DATA_STORE_DIR)", @@ -286,6 +289,7 @@ $(PROJECT_TEMP_DIR)/$(BAZEL_PACKAGE_BIN_DIR)/$(COMPILE_TARGET_NAME) forFixtures: false, project: project, directories: directories, + legacyIndexImport: project.legacyIndexImport, indexImport: project.indexImport, minimumXcodeVersion: project.minimumXcodeVersion ) diff --git a/tools/generators/legacy/test/Fixtures.swift b/tools/generators/legacy/test/Fixtures.swift index 945e68a8e4..fabf7faac8 100644 --- a/tools/generators/legacy/test/Fixtures.swift +++ b/tools/generators/legacy/test/Fixtures.swift @@ -43,6 +43,7 @@ enum Fixtures { customXcodeSchemes: [], targetIdsFile: "/tmp/target_ids", targetNameMode: .auto, + legacyIndexImport: "/tmp/legacy-index-import", indexImport: "/tmp/index-import", preBuildScript: "./pre-build.sh", postBuildScript: "./post-build.sh" diff --git a/tools/generators/legacy/test/GeneratorTests.swift b/tools/generators/legacy/test/GeneratorTests.swift index 49bb091301..ac4225ad6d 100644 --- a/tools/generators/legacy/test/GeneratorTests.swift +++ b/tools/generators/legacy/test/GeneratorTests.swift @@ -66,6 +66,7 @@ final class GeneratorTests: XCTestCase { customXcodeSchemes: [], targetIdsFile: "/tmp/target_ids", targetNameMode: .auto, + legacyIndexImport: "/tmp/legacy-index-import", indexImport: "/tmp/index-import", preBuildScript: "./pre-build.sh", postBuildScript: "./post-build.sh" @@ -265,6 +266,7 @@ final class GeneratorTests: XCTestCase { let buildMode: BuildMode let project: Project let directories: Directories + let legacyIndexImport: String let indexImport: String let minimumXcodeVersion: SemanticVersion } @@ -275,6 +277,7 @@ final class GeneratorTests: XCTestCase { _forFixtures _: Bool, project: Project, directories: Directories, + legacyIndexImport: String, indexImport: String, minimumXcodeVersion: SemanticVersion ) -> PBXProj { @@ -282,6 +285,7 @@ final class GeneratorTests: XCTestCase { buildMode: buildMode, project: project, directories: directories, + legacyIndexImport: legacyIndexImport, indexImport: indexImport, minimumXcodeVersion: minimumXcodeVersion )) @@ -292,6 +296,7 @@ final class GeneratorTests: XCTestCase { buildMode: buildMode, project: project, directories: directories, + legacyIndexImport: project.legacyIndexImport, indexImport: project.indexImport, minimumXcodeVersion: project.minimumXcodeVersion )] diff --git a/tools/generators/pbxproj_prefix/README.md b/tools/generators/pbxproj_prefix/README.md index 6c87afac2e..95408d5c26 100644 --- a/tools/generators/pbxproj_prefix/README.md +++ b/tools/generators/pbxproj_prefix/README.md @@ -216,7 +216,7 @@ Here is an example output: GCC_OPTIMIZATION_LEVEL = 0; IMPORT_INDEX_BUILD_INDEXSTORES = YES; INDEX_DATA_STORE_DIR = "$(INDEX_DATA_STORE_DIR)"; - INDEX_IMPORT = "$(BAZEL_OUT)/darwin_arm64-opt-exec-2B5CBBC6/bin/external/_main~non_module_deps~rules_xcodeproj_index_import/index-import"; + INDEX_IMPORT = "$(BAZEL_OUT)/darwin_arm64-opt-exec-2B5CBBC6/bin/external/_main~non_module_deps~rules_xcodeproj_index_import/index-import_legacy"; INDEX_FORCE_SCRIPT_EXECUTION = YES; INSTALL_PATH = "$(BAZEL_PACKAGE_BIN_DIR)/$(TARGET_NAME)/bin"; INTERNAL_DIR = "$(PROJECT_FILE_PATH)/rules_xcodeproj"; @@ -285,6 +285,7 @@ Here is an example output: LD_DYLIB_INSTALL_NAME = ""; LD_OBJC_ABI_VERSION = ""; LD_RUNPATH_SEARCH_PATHS = ""; + LEGACY_INDEX_IMPORT = "$(BAZEL_OUT)/darwin_arm64-opt-exec-2B5CBBC6/bin/external/_main~non_module_deps~rules_xcodeproj_index_import/index-import_legacy"; LIBTOOL = "$(BAZEL_INTEGRATION_DIR)/libtool"; ONLY_ACTIVE_ARCH = YES; PROJECT_DIR = "/tmp/workspace/bazel-output-base/rules_xcodeproj.noindex/build_output_base/execroot/_main"; diff --git a/tools/generators/pbxproj_prefix/src/Generator/Arguments.swift b/tools/generators/pbxproj_prefix/src/Generator/Arguments.swift index 4dd7238ab2..d8d252feba 100644 --- a/tools/generators/pbxproj_prefix/src/Generator/Arguments.swift +++ b/tools/generators/pbxproj_prefix/src/Generator/Arguments.swift @@ -30,6 +30,9 @@ Path to a file that contains the absolute path to the Bazel execution root. @Argument(help: "Path to the target IDs list file.") var targetIdsFile: String + @Argument(help: "Path to the legacy index_import executable.") + var legacyIndexImport: String + @Argument(help: "Path to the index_import executable.") var indexImport: String diff --git a/tools/generators/pbxproj_prefix/src/Generator/Environment.swift b/tools/generators/pbxproj_prefix/src/Generator/Environment.swift index 2ba7edd366..15d675f129 100644 --- a/tools/generators/pbxproj_prefix/src/Generator/Environment.swift +++ b/tools/generators/pbxproj_prefix/src/Generator/Environment.swift @@ -32,6 +32,7 @@ extension Generator { let pbxProjectBuildSettings: ( _ config: String, _ importIndexBuildIndexstores: Bool, + _ legacyIndexImport: String, _ indexImport: String, _ indexingProjectDir: String, _ projectDir: String, diff --git a/tools/generators/pbxproj_prefix/src/Generator/Generator.swift b/tools/generators/pbxproj_prefix/src/Generator/Generator.swift index 871eb10deb..3417eb169c 100644 --- a/tools/generators/pbxproj_prefix/src/Generator/Generator.swift +++ b/tools/generators/pbxproj_prefix/src/Generator/Generator.swift @@ -51,6 +51,7 @@ struct Generator { /*config:*/ arguments.config, /*importIndexBuildIndexstores:*/ arguments .importIndexBuildIndexstores, + /*legacyIndexImport:*/ arguments.legacyIndexImport, /*indexImport:*/ arguments.indexImport, /*indexingProjectDir:*/ environment.indexingProjectDir( /*projectDir:*/ projectDir diff --git a/tools/generators/pbxproj_prefix/src/Generator/PBXProjectBuildSettings.swift b/tools/generators/pbxproj_prefix/src/Generator/PBXProjectBuildSettings.swift index a5561af959..cb4feff0f0 100644 --- a/tools/generators/pbxproj_prefix/src/Generator/PBXProjectBuildSettings.swift +++ b/tools/generators/pbxproj_prefix/src/Generator/PBXProjectBuildSettings.swift @@ -9,8 +9,10 @@ extension Generator { /// - config: The value to be used for the `BAZEL_CONFIG` build setting. /// - importIndexBuildIndexstores: Whether to import index build /// indexstores. + /// - legacyIndexImport: The Bazel execution root relative path to the + /// `index_import` (version 5.8) executable. /// - indexImport: The Bazel execution root relative path to the - /// `index_import` executable. + /// `index_import` (version 6.1+) executable. /// - indexingProjectDir: The value returned from /// `Generator.indexingProjectDir()`. /// - projectDir: The value returned from `Generator.projectDir()`. @@ -20,6 +22,7 @@ extension Generator { static func pbxProjectBuildSettings( config: String, importIndexBuildIndexstores: Bool, + legacyIndexImport: String, indexImport: String, indexingProjectDir: String, projectDir: String, @@ -123,6 +126,12 @@ extension Generator { .init(key: "LD_DYLIB_INSTALL_NAME", value: #""""#), .init(key: "LD_OBJC_ABI_VERSION", value: #""""#), .init(key: "LD_RUNPATH_SEARCH_PATHS", value: #""""#), + .init( + key: "LEGACY_INDEX_IMPORT", + value: legacyIndexImport + .executionRootBasedBuildSettingPath + .pbxProjEscaped + ), .init(key: "ONLY_ACTIVE_ARCH", value: "YES"), .init( key: "PROJECT_DIR", diff --git a/tools/generators/pbxproj_prefix/test/PBXProjectBuildSettingsTests.swift b/tools/generators/pbxproj_prefix/test/PBXProjectBuildSettingsTests.swift index 46b81a6d7f..5f8ab08b05 100644 --- a/tools/generators/pbxproj_prefix/test/PBXProjectBuildSettingsTests.swift +++ b/tools/generators/pbxproj_prefix/test/PBXProjectBuildSettingsTests.swift @@ -11,6 +11,7 @@ class PBXProjectBuildSettingsTests: XCTestCase { let config = "rxcp_custom_config" let importIndexBuildIndexstores = false + let legacyIndexImport = "external/legacy-index-import" let indexImport = "external/index-import" let indexingProjectDir = "/some/indexing/project dir" let projectDir = "/some/project dir" @@ -58,6 +59,7 @@ class PBXProjectBuildSettingsTests: XCTestCase { LD_DYLIB_INSTALL_NAME = ""; LD_OBJC_ABI_VERSION = ""; LD_RUNPATH_SEARCH_PATHS = ""; + LEGACY_INDEX_IMPORT = "$(BAZEL_EXTERNAL)/legacy-index-import"; LIBTOOL = "$(BAZEL_INTEGRATION_DIR)/libtool"; ONLY_ACTIVE_ARCH = YES; PROJECT_DIR = "/some/project dir"; @@ -83,6 +85,7 @@ class PBXProjectBuildSettingsTests: XCTestCase { let buildSettings = Generator.pbxProjectBuildSettings( config: config, importIndexBuildIndexstores: importIndexBuildIndexstores, + legacyIndexImport: legacyIndexImport, indexImport: indexImport, indexingProjectDir: indexingProjectDir, projectDir: projectDir, diff --git a/tools/import_indexstores/ImportIndexstores.swift b/tools/import_indexstores/ImportIndexstores.swift index 845081ec2a..09ac782fd3 100644 --- a/tools/import_indexstores/ImportIndexstores.swift +++ b/tools/import_indexstores/ImportIndexstores.swift @@ -135,9 +135,20 @@ Intermediates\.noindex/Previews/[^/]*/Intermediates\.noindex let arch = String(archs.split(separator: " ", maxSplits: 1).first!) let developerDir = try getEnvironmentVariable("DEVELOPER_DIR") - let indexImport = try getEnvironmentVariable("INDEX_IMPORT") let srcRoot = try getEnvironmentVariable("SRCROOT") + // TODO: Remove 5.8 when support for Xcode 16.2.x is dropped. + // For now, we must support two index-import versions: 5.8.x and 6.1.x + // In Swift 6.1 (Xcode 16.3+) the hash algorithm was changed making index imports + // incompatible with 5.8.x. Fallback to the latest version. + let indexImport: String + if let xcodeVersion = Int(try getEnvironmentVariable("XCODE_VERSION_ACTUAL")), + xcodeVersion < 1630 { + indexImport = try getEnvironmentVariable("LEGACY_INDEX_IMPORT") + } else { + indexImport = try getEnvironmentVariable("INDEX_IMPORT") + } + try await withThrowingTaskGroup(of: Void.self) { group in for (targetPathOverride, indexstores) in indexstores { group.addTask { diff --git a/xcodeproj/internal/files/legacy_input_files.bzl b/xcodeproj/internal/files/legacy_input_files.bzl index 030934d595..2cbdab9348 100644 --- a/xcodeproj/internal/files/legacy_input_files.bzl +++ b/xcodeproj/internal/files/legacy_input_files.bzl @@ -958,6 +958,7 @@ def _process_output_group_files( is_indexstores, output_group_name, additional_bwx_generated, + legacy_index_import, index_import): # `list` copy is needed for some reason to prevent depset from changing # underneath us. Without this it's nondeterministic which files are in it. @@ -966,7 +967,7 @@ def _process_output_group_files( ) if is_indexstores: - direct = [index_import] + direct = [legacy_index_import, index_import] else: direct = None @@ -979,6 +980,7 @@ def _to_output_groups_fields( *, inputs, additional_bwx_generated = {}, + legacy_index_import, index_import): """Generates a dictionary to be splatted into `OutputGroupInfo`. @@ -987,7 +989,8 @@ def _to_output_groups_fields( additional_bwx_generated: A `dict` that maps the output group name of targets to a `list` of `depset`s of `File`s that should be merged into the output group map for that output group name. - index_import: A `File` for `index-import`. + legacy_index_import: A `File` for `index-import` version 5.8.x. + index_import: A `File` for `index-import` version 6.1.x.+. Returns: A `dict` where the keys are output group names and the values are @@ -999,6 +1002,7 @@ def _to_output_groups_fields( is_indexstores = is_indexstores, output_group_name = name, additional_bwx_generated = additional_bwx_generated, + legacy_index_import = legacy_index_import, index_import = index_import, ) for name, is_indexstores, files in inputs._output_group_list.to_list() diff --git a/xcodeproj/internal/files/legacy_output_files.bzl b/xcodeproj/internal/files/legacy_output_files.bzl index dd076e27e5..69dfe8082c 100644 --- a/xcodeproj/internal/files/legacy_output_files.bzl +++ b/xcodeproj/internal/files/legacy_output_files.bzl @@ -356,13 +356,14 @@ def _process_output_group_files( is_indexstores, output_group_name, additional_bwb_outputs, + legacy_index_import, index_import): # `list` copy is needed for some reason to prevent depset from changing # underneath us. Without this it's nondeterministic which files are in it. outputs_depsets = list(additional_bwb_outputs.get(output_group_name, [])) if is_indexstores: - direct = [index_import] + direct = [legacy_index_import, index_import] else: direct = None @@ -375,6 +376,7 @@ def _to_output_groups_fields( *, outputs, additional_bwb_outputs = {}, + legacy_index_import, index_import): """Generates a dictionary to be splatted into `OutputGroupInfo`. @@ -383,7 +385,8 @@ def _to_output_groups_fields( additional_bwb_outputs: A `dict` that maps the output group name of targets to a `list` of `depset`s of `File`s that should be merged into the output group map for that output group name. - index_import: A `File` for `index-import`. + legacy_index_import: A `File` for `index-import` version 5.8.x. + index_import: A `File` for `index-import` version 6.1.x.+. Returns: A `dict` where the keys are output group names and the values are @@ -395,6 +398,7 @@ def _to_output_groups_fields( is_indexstores = is_indexstores, output_group_name = name, additional_bwb_outputs = additional_bwb_outputs, + legacy_index_import = legacy_index_import, index_import = index_import, ) for name, is_indexstores, files in outputs._output_group_list.to_list() diff --git a/xcodeproj/internal/pbxproj_partials.bzl b/xcodeproj/internal/pbxproj_partials.bzl index 9247c9c0f4..6cf4b0d756 100644 --- a/xcodeproj/internal/pbxproj_partials.bzl +++ b/xcodeproj/internal/pbxproj_partials.bzl @@ -662,6 +662,7 @@ def _write_pbxproj_prefix( execution_root_file, generator_name, import_index_build_indexstores, + legacy_index_import, index_import, install_path, minimum_xcode_version, @@ -688,6 +689,8 @@ def _write_pbxproj_prefix( generator_name: The name of the `xcodeproj` generator target. import_index_build_indexstores: Whether to import index build indexstores. + legacy_index_import: The executable `File` for the + `legacy_index_import` tool. index_import: The executable `File` for the `index_import` tool. install_path: The workspace relative path to where the final `.xcodeproj` will be written. @@ -734,6 +737,9 @@ def _write_pbxproj_prefix( # targetIdsFile args.add(target_ids_list) + # legacyIndexImport + args.add(legacy_index_import) + # indexImport args.add(index_import) diff --git a/xcodeproj/internal/xcodeproj_incremental_rule.bzl b/xcodeproj/internal/xcodeproj_incremental_rule.bzl index 0a87d0b428..a70fb53e97 100644 --- a/xcodeproj/internal/xcodeproj_incremental_rule.bzl +++ b/xcodeproj/internal/xcodeproj_incremental_rule.bzl @@ -325,6 +325,7 @@ def _write_project_contents( files_and_groups_generator, generation_shard_count, import_index_build_indexstores, + legacy_index_import, index_import, install_path, minimum_xcode_version, @@ -448,6 +449,7 @@ def _write_project_contents( execution_root_file = execution_root_file, generator_name = name, import_index_build_indexstores = import_index_build_indexstores, + legacy_index_import = legacy_index_import, index_import = index_import, install_path = install_path, minimum_xcode_version = minimum_xcode_version, @@ -622,6 +624,7 @@ Are you using an `alias`? `xcodeproj.focused_targets` and \ actions = ctx.actions colorize = ctx.attr.colorize config = ctx.attr.config + legacy_index_import = ctx.executable._legacy_index_import index_import = ctx.executable._index_import install_path = ctx.attr.install_path is_fixture = ctx.attr._is_fixture @@ -654,6 +657,7 @@ Are you using an `alias`? `xcodeproj.focused_targets` and \ import_index_build_indexstores = ( ctx.attr.import_index_build_indexstores ), + legacy_index_import = legacy_index_import, index_import = index_import, install_path = install_path, minimum_xcode_version = ( @@ -780,7 +784,7 @@ Are you using an `alias`? `xcodeproj.focused_targets` and \ ), OutputGroupInfo( all_targets = output_groups_fields["all_b"], - index_import = depset([index_import]), + index_import = depset([legacy_index_import, index_import]), target_ids_list = depset([target_ids_list]), **output_groups_fields ), @@ -883,6 +887,12 @@ def _xcodeproj_incremental_attrs( ), ), "_is_fixture": attr.bool(default = is_fixture), + # TODO: Remove 5.8 when support for Xcode 16.x is dropped. + "_legacy_index_import": attr.label( + cfg = "exec", + default = Label("@rules_xcodeproj_legacy_index_import//:index_import"), + executable = True, + ), "_pbxnativetargets_generator": attr.label( cfg = "exec", default = Label( diff --git a/xcodeproj/internal/xcodeproj_legacy_rule.bzl b/xcodeproj/internal/xcodeproj_legacy_rule.bzl index e51acf0a5c..2afef05dc7 100644 --- a/xcodeproj/internal/xcodeproj_legacy_rule.bzl +++ b/xcodeproj/internal/xcodeproj_legacy_rule.bzl @@ -1161,6 +1161,7 @@ def _write_spec( extra_files, extra_folders, infos, + legacy_index_import, index_import, is_fixture, minimum_xcode_version, @@ -1194,7 +1195,10 @@ def _write_spec( "T": "fixture-target-ids-file" if is_fixture else build_setting_path( file = target_ids_list, ), - "i": "fixture-index-import-path" if is_fixture else build_setting_path( + "i": "fixture-legacy-index-import-path" if is_fixture else build_setting_path( + file = legacy_index_import, + ), + "j": "fixture-index-import-path" if is_fixture else build_setting_path( file = index_import, ), "m": minimum_xcode_version, @@ -1338,6 +1342,7 @@ def _write_xcodeproj( execution_root_file, extension_point_identifiers_file, generator, + legacy_index_import, index_import, install_path, is_fixture, @@ -1372,7 +1377,10 @@ def _write_xcodeproj( extension_point_identifiers_file, ], outputs = [xcodeproj], - tools = [index_import], + tools = [ + legacy_index_import, + index_import, + ], execution_requirements = { # Projects can be rather large, and take almost no time to generate # This also works around any RBC tree artifact issues @@ -1592,6 +1600,7 @@ configurations: {}""".format(", ".join(xcode_configurations))) envs = envs, extra_files = extra_files, extra_folders = extra_folders, + legacy_index_import = ctx.executable._legacy_index_import, index_import = ctx.executable._index_import, infos = infos, is_fixture = is_fixture, @@ -1735,6 +1744,7 @@ done execution_root_file = execution_root_file, extension_point_identifiers_file = extension_point_identifiers_file, generator = ctx.attr._generator[DefaultInfo].files_to_run, + legacy_index_import = ctx.attr._legacy_index_import[DefaultInfo].files_to_run, index_import = ctx.attr._index_import[DefaultInfo].files_to_run, install_path = install_path, is_fixture = is_fixture, @@ -1760,6 +1770,7 @@ done input_files_output_groups = input_files.to_output_groups_fields( inputs = inputs, additional_bwx_generated = additional_bwx_generated, + legacy_index_import = ctx.executable._legacy_index_import, index_import = ctx.executable._index_import, ) output_files_output_groups = {} @@ -1773,6 +1784,7 @@ done output_files_output_groups = output_files.to_output_groups_fields( outputs = provider_outputs, additional_bwb_outputs = additional_bwb_outputs, + legacy_index_import = ctx.executable._legacy_index_import, index_import = ctx.executable._index_import, ) all_targets_files = [output_files_output_groups["all_b"]] @@ -1903,6 +1915,12 @@ def _xcodeproj_legacy_attrs( ), ), "_is_fixture": attr.bool(default = is_fixture), + # TODO: Remove 5.8 when support for Xcode 16.x is dropped. + "_legacy_index_import": attr.label( + cfg = "exec", + default = Label("@rules_xcodeproj_legacy_index_import//:index_import"), + executable = True, + ), "_link_params_processor": attr.label( cfg = "exec", default = Label( diff --git a/xcodeproj/repositories.bzl b/xcodeproj/repositories.bzl index 06d4dabc73..6f5b64083b 100644 --- a/xcodeproj/repositories.bzl +++ b/xcodeproj/repositories.bzl @@ -121,8 +121,8 @@ def xcodeproj_rules_dependencies( _maybe( http_archive, name = "build_bazel_rules_swift", - sha256 = "bb01097c7c7a1407f8ad49a1a0b1960655cf823c26ad2782d0b7d15b323838e2", - url = "https://github.com/bazelbuild/rules_swift/releases/download/1.18.0/rules_swift.1.18.0.tar.gz", + sha256 = "68290c747eab415d924a3e2a8d2d32a4686dd1e0b091a6b4db4892d1bc0e8308", + url = "https://github.com/bazelbuild/rules_swift/releases/download/2.8.0/rules_swift.2.8.0.tar.gz", ignore_version_differences = ignore_version_differences, ) @@ -148,10 +148,10 @@ def xcodeproj_rules_dependencies( # here in order to reuse it, and in case `rules_swift` stops depending on it # in the future. We don't though, because we need 5.5.3.1 or higher, and the # current lowest version of rules_swift we support uses 5.3.2.6. - _maybe( - http_archive, - name = "rules_xcodeproj_index_import", - build_file_content = """\ + # TODO: we must depend on two versions of index-import to support backwards + # compatibility between Xcode 16.3+ and older versions, we can remove the older + # version once we drop support for Xcode 16.x. + index_import_build_file_content = """\ load("@bazel_skylib//rules:native_binary.bzl", "native_binary") native_binary( @@ -160,11 +160,25 @@ native_binary( out = "index-import", visibility = ["//visibility:public"], ) -""", +""" + _maybe( + http_archive, + name = "rules_xcodeproj_legacy_index_import", + build_file_content = index_import_build_file_content, + canonical_id = "index-import-5.8.0.1", sha256 = "28c1ffa39d99e74ed70623899b207b41f79214c498c603915aef55972a851a15", url = "https://github.com/MobileNativeFoundation/index-import/releases/download/5.8.0.1/index-import.tar.gz", ignore_version_differences = ignore_version_differences, ) + _maybe( + http_archive, + name = "rules_xcodeproj_index_import", + build_file_content = index_import_build_file_content, + canonical_id = "index-import-6.1.0", + sha256 = "54d0477526bba0dc1560189dfc4f02d90aea536e9cb329e911f32b2a564b66f1", + url = "https://github.com/MobileNativeFoundation/index-import/releases/download/6.1.0/index-import.tar.gz", + ignore_version_differences = ignore_version_differences, + ) # Source dependencies _xcodeproj_rules_source_dependencies(ignore_version_differences)