diff --git a/.bazelrc b/.bazelrc index bff0e9eb..adaf2fca 100644 --- a/.bazelrc +++ b/.bazelrc @@ -7,8 +7,6 @@ build --spawn_strategy=local # Setup Xcode configuration. build --xcode_version_config=//:host_xcodes -build --experimental_strict_conflict_checks - build --verbose_failures # Print the full command line for commands that failed build --test_output=errors # Prints log file output to the console on failure diff --git a/.bazelversion b/.bazelversion index a3fcc712..ae9a76b9 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1 +1 @@ -7.1.0 +8.0.0 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e80ff1f6..be1fb3b4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,7 +20,7 @@ jobs: strategy: fail-fast: false matrix: - bazel_version: [7.1.0] + bazel_version: [7.1.0, 8.0.0] xcode_version: [15.2] virtual_frameworks: [true, false] sandbox: [true, false] @@ -85,7 +85,7 @@ jobs: strategy: fail-fast: false matrix: - bazel_version: [7.1.0] + bazel_version: [7.1.0, 8.0.0] sandbox: [true, false] xcode_version: [15.2] env: @@ -131,7 +131,7 @@ jobs: strategy: fail-fast: false matrix: - bazel_version: [7.1.0] # Only run on latest Bazel version as stardoc changes between versions and produces different results + bazel_version: [7.1.0, 8.0.0] # Only run on latest Bazel version as stardoc changes between versions and produces different results xcode_version: [15.2] env: XCODE_VERSION: ${{ matrix.xcode_version }} @@ -164,7 +164,7 @@ jobs: strategy: fail-fast: false matrix: - bazel_version: [7.1.0] + bazel_version: [7.1.0, 8.0.0] xcode_version: [15.2] env: XCODE_VERSION: ${{ matrix.xcode_version }} diff --git a/BUILD.bazel b/BUILD.bazel index f5194203..2c176653 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -1,8 +1,9 @@ +load("@bazel_skylib//lib:selects.bzl", "selects") + # Pull buildifer.mac as an http_file, then depend on the file group to make an # executable load("@build_bazel_rules_swift//swift/internal:feature_names.bzl", "SWIFT_FEATURE_USE_GLOBAL_INDEX_STORE") load("//rules:features.bzl", "feature_names") -load("@bazel_skylib//lib:selects.bzl", "selects") alias( name = "buildifier", @@ -135,34 +136,32 @@ selects.config_setting_group( ) xcode_version( - name = "version15_2_0_15C500b", + name = "version16_4_0_16F6", aliases = [ - "15.2", - "15.2.0", - "15.2.0.15C500b", - "15C500b", + "16.4", + "16.4.0", ], - default_ios_sdk_version = "17.2", - default_macos_sdk_version = "14.2", - default_tvos_sdk_version = "17.2", - default_visionos_sdk_version = "1.0", - default_watchos_sdk_version = "10.2", - version = "15.2.0.15C500b", + default_ios_sdk_version = "18.5", + default_macos_sdk_version = "15.5", + default_tvos_sdk_version = "18.5", + default_visionos_sdk_version = "2.5", + default_watchos_sdk_version = "11.5", + version = "16.4.0.16F6", ) xcode_config( name = "host_xcodes", - default = ":version15_2_0_15C500b", + default = ":version16_4_0_16F6", versions = [ - ":version15_2_0_15C500b", + ":version16_4_0_16F6", ], visibility = ["//visibility:public"], ) available_xcodes( name = "host_available_xcodes", - default = ":version15_2_0_15C500b", + default = ":version16_4_0_16F6", versions = [ - ":version15_2_0_15C500b", + ":version16_4_0_16F6", ], ) diff --git a/MODULE.bazel b/MODULE.bazel index f91016e6..dedc4514 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -9,6 +9,7 @@ module( version = "0", bazel_compatibility = [ ">=7.0.0", + "<9.0.0", ], compatibility_level = 1, repo_name = "build_bazel_rules_ios", @@ -17,7 +18,7 @@ module( # Declare the bzlmod dependencies needed by rules_ios and users of rules_ios bazel_dep( name = "apple_support", - version = "1.15.1", + version = "1.21.1", repo_name = "build_bazel_apple_support", ) bazel_dep( @@ -27,7 +28,7 @@ bazel_dep( ) bazel_dep( name = "rules_cc", - version = "0.0.10", + version = "0.0.16", ) bazel_dep( name = "rules_swift", @@ -37,7 +38,7 @@ bazel_dep( ) bazel_dep( name = "bazel_skylib", - version = "1.4.2", + version = "1.7.1", ) # Declare the development dependencies needed for rules_ios development @@ -48,12 +49,12 @@ bazel_dep( ) bazel_dep( name = "rules_pkg", - version = "0.9.1", + version = "1.0.1", dev_dependency = True, ) bazel_dep( name = "stardoc", - version = "0.6.2", + version = "0.7.2", dev_dependency = True, repo_name = "io_bazel_stardoc", ) diff --git a/README.md b/README.md index 19902fe7..b7e0489b 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ See the following table for supported release versions. | Bazel release | Minimum supported rules version | Final supported rules version |:-------------------:|:-------------------------:|:-------------------------: +| 8.* | 5.4.0 | current | 7.* | 4.4.0 | current | 6.* | 2.0.0 | 5.3.0 | 5.* | 1.0.0 | 3.2.2 @@ -49,6 +50,29 @@ See the following table for supported rules_apple release versions. | 2.* | 2.* | 3.2.2 | 1.* | 1.0.0 | 3.2.2 +## Bazel 8 Migration Guide + +If you're upgrading from Bazel 7 to Bazel 8, please note the following changes: + +### Important Changes +- The `apple_common.AppleDynamicFramework` provider has been removed in Bazel 8 +- Several ObjcInfo provider fields have been removed, including: + - `force_load_library` + - `imported_library` + - `library` + - `static_framework_file` + - And others related to linking + +### Required Updates +1. Update rules_ios to version 5.4.0 or later +2. Update your dependencies in MODULE.bazel: + - `apple_support` to 1.21.1 or later + - `rules_cc` to 0.0.16 or later + - `bazel_skylib` to 1.7.1 or later + +### Compatibility +rules_ios 5.4.0+ maintains compatibility with both Bazel 7 and Bazel 8, so you can safely update before migrating to Bazel 8. + ## Getting started ### Bzlmod setup diff --git a/rules/framework.bzl b/rules/framework.bzl index 5e9753ac..371692fb 100644 --- a/rules/framework.bzl +++ b/rules/framework.bzl @@ -1,36 +1,36 @@ """Framework rules""" -load("//rules/framework:vfs_overlay.bzl", "VFSOverlayInfo", "make_vfsoverlay") -load("//rules:features.bzl", "feature_names") -load("//rules:library.bzl", "PrivateHeadersInfo", "apple_library") -load("//rules:plists.bzl", "process_infoplists") -load("//rules:providers.bzl", "AvoidDepsInfo", "FrameworkInfo") -load("//rules:transition_support.bzl", "transition_support") -load("//rules:utils.bzl", "is_bazel_7") -load("//rules/internal:objc_provider_utils.bzl", "objc_provider_utils") load("@bazel_skylib//lib:partial.bzl", "partial") load("@bazel_skylib//lib:paths.bzl", "paths") load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain", "use_cpp_toolchain") load("@build_bazel_rules_apple//apple/internal:apple_product_type.bzl", "apple_product_type") +load("@build_bazel_rules_apple//apple/internal:apple_toolchains.bzl", "AppleMacToolsToolchainInfo", "AppleXPlatToolsToolchainInfo") load("@build_bazel_rules_apple//apple/internal:features_support.bzl", "features_support") load("@build_bazel_rules_apple//apple/internal:linking_support.bzl", "linking_support") load("@build_bazel_rules_apple//apple/internal:outputs.bzl", "outputs") load("@build_bazel_rules_apple//apple/internal:partials.bzl", "partials") load("@build_bazel_rules_apple//apple/internal:platform_support.bzl", "platform_support") load("@build_bazel_rules_apple//apple/internal:processor.bzl", "processor") +load("@build_bazel_rules_apple//apple/internal:providers.bzl", "AppleBundleInfo", "ApplePlatformInfo", "IosFrameworkBundleInfo", "new_applebundleinfo", "new_iosframeworkbundleinfo") load("@build_bazel_rules_apple//apple/internal:resource_actions.bzl", "resource_actions") load("@build_bazel_rules_apple//apple/internal:resources.bzl", "resources") load("@build_bazel_rules_apple//apple/internal:rule_support.bzl", "rule_support") -load("@build_bazel_rules_apple//apple/internal:apple_toolchains.bzl", "AppleMacToolsToolchainInfo", "AppleXPlatToolsToolchainInfo") load("@build_bazel_rules_apple//apple/internal:swift_support.bzl", "swift_support") -load("@build_bazel_rules_apple//apple/internal/utils:clang_rt_dylibs.bzl", "clang_rt_dylibs") -load("@build_bazel_rules_apple//apple/internal:providers.bzl", "AppleBundleInfo", "ApplePlatformInfo", "IosFrameworkBundleInfo", "new_applebundleinfo", "new_iosframeworkbundleinfo") -load("@build_bazel_rules_swift//swift:providers.bzl", "SwiftInfo", "create_clang_module_inputs", "create_swift_module_context", "create_swift_module_inputs") -load("@build_bazel_rules_swift//swift:swift.bzl", "swift_clang_module_aspect") load( "@build_bazel_rules_apple//apple/internal/aspects:resource_aspect.bzl", "apple_resource_aspect", ) +load("@build_bazel_rules_apple//apple/internal/utils:clang_rt_dylibs.bzl", "clang_rt_dylibs") +load("@build_bazel_rules_swift//swift:providers.bzl", "SwiftInfo", "create_clang_module_inputs", "create_swift_module_context", "create_swift_module_inputs") +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_clang_module_aspect") +load("//rules:features.bzl", "feature_names") +load("//rules:library.bzl", "PrivateHeadersInfo", "apple_library") +load("//rules:plists.bzl", "process_infoplists") +load("//rules:providers.bzl", "AvoidDepsInfo", "FrameworkInfo") +load("//rules:transition_support.bzl", "transition_support") +load("//rules:utils.bzl", "is_bazel_7") +load("//rules/framework:vfs_overlay.bzl", "VFSOverlayInfo", "make_vfsoverlay") +load("//rules/internal:objc_provider_utils.bzl", "objc_provider_utils") _APPLE_FRAMEWORK_PACKAGING_KWARGS = [ "visibility", @@ -1153,7 +1153,7 @@ apple_framework_packaging = rule( implementation = _apple_framework_packaging_impl, toolchains = use_cpp_toolchain(), cfg = transition_support.apple_rule_transition, - fragments = ["apple", "cpp", "objc"], + fragments = ["apple", "cpp", "objc", "j2objc"], output_to_genfiles = True, attrs = { "framework_name": attr.string( diff --git a/rules/internal/bazel_version.bzl b/rules/internal/bazel_version.bzl new file mode 100644 index 00000000..97f6ffc6 --- /dev/null +++ b/rules/internal/bazel_version.bzl @@ -0,0 +1,72 @@ +"""Utilities for detecting and handling Bazel version differences.""" + +def _parse_bazel_version(bazel_version): + """Parse Bazel version string into major, minor, patch components. + + Args: + bazel_version: String like "8.0.0" or "7.1.0" + + Returns: + Tuple of (major, minor, patch) as integers + """ + # Handle development versions like "8.0.0-pre.20240101.1" + parts = bazel_version.split("-")[0].split(".") + major = int(parts[0]) if len(parts) > 0 else 0 + minor = int(parts[1]) if len(parts) > 1 else 0 + patch = int(parts[2]) if len(parts) > 2 else 0 + return (major, minor, patch) + +def _is_bazel_8_or_higher(): + """Check if running Bazel 8 or higher. + + Returns: + True if Bazel version is 8.0.0 or higher, False otherwise + """ + if hasattr(native, "bazel_version"): + major, _, _ = _parse_bazel_version(native.bazel_version) + return major >= 8 + return False + +def _has_apple_dynamic_framework_provider(): + """Check if apple_common.AppleDynamicFramework provider is available. + + Returns: + True if the provider exists, False otherwise (Bazel 8+) + """ + return hasattr(apple_common, "AppleDynamicFramework") + +def _has_objc_provider_field(field_name): + """Check if a specific ObjcInfo provider field is available. + + Args: + field_name: Name of the field to check + + Returns: + True if the field is available in ObjcInfo + """ + # In Bazel 8, many ObjcInfo fields were removed + # Available fields: direct_module_maps, direct_sources, j2objc_library, + # module_map, source, strict_include, umbrella_header + removed_in_bazel_8 = [ + "force_load_library", + "imported_library", + "library", + "link_inputs", + "linkopt", + "sdk_dylib", + "sdk_framework", + "static_framework_file", + "weak_sdk_framework", + "dynamic_framework_file", + ] + + if _is_bazel_8_or_higher() and field_name in removed_in_bazel_8: + return False + return True + +bazel_version = struct( + parse = _parse_bazel_version, + is_bazel_8_or_higher = _is_bazel_8_or_higher, + has_apple_dynamic_framework_provider = _has_apple_dynamic_framework_provider, + has_objc_provider_field = _has_objc_provider_field, +) \ No newline at end of file diff --git a/rules/internal/framework_middleman.bzl b/rules/internal/framework_middleman.bzl index b8fa1673..cdc7ab4d 100644 --- a/rules/internal/framework_middleman.bzl +++ b/rules/internal/framework_middleman.bzl @@ -1,5 +1,6 @@ load("@bazel_skylib//lib:partial.bzl", "partial") load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain", "use_cpp_toolchain") +load("@build_bazel_rules_swift//swift:swift.bzl", "SwiftInfo") load( "@build_bazel_rules_apple//apple/internal:providers.bzl", "AppleResourceInfo", @@ -41,6 +42,7 @@ def _framework_middleman(ctx): dynamic_framework_providers = [] apple_embeddable_infos = [] cc_providers = [] + swift_infos = [] cc_toolchain = find_cpp_toolchain(ctx) cc_features = cc_common.configure_features( ctx = ctx, @@ -64,9 +66,16 @@ def _framework_middleman(ctx): resource_providers.append(lib_dep[AppleResourceInfo]) if apple_common.Objc in lib_dep: objc_providers.append(lib_dep[apple_common.Objc]) - if apple_common.AppleDynamicFramework in lib_dep: + if SwiftInfo in lib_dep: + swift_infos.append(lib_dep[SwiftInfo]) + # Also ensure Swift's CcInfo is collected + if CcInfo in lib_dep and lib_dep not in cc_providers: + cc_providers.append(lib_dep[CcInfo]) + # Bazel 8 compatibility: Try both old and potential new provider names + if hasattr(apple_common, "AppleDynamicFramework") and apple_common.AppleDynamicFramework in lib_dep: dynamic_frameworks.append(lib_dep) dynamic_framework_providers.append(lib_dep[apple_common.AppleDynamicFramework]) + # Note: In Bazel 8, dynamic framework info might be in CcInfo instead for dep in ctx.attr.framework_deps: _process_dep(dep) @@ -77,40 +86,91 @@ def _framework_middleman(ctx): _process_dep(lib_dep) # Here we only need to loop a subset of the keys - objc_provider_fields = objc_provider_utils.merge_objc_providers_dict(providers = objc_providers, merge_keys = [ - "dynamic_framework_file", - ]) + # In Bazel 8, dynamic_framework_file is not supported in ObjcInfo + # We'll handle it through CcInfo instead + objc_provider_fields = objc_provider_utils.merge_objc_providers_dict(providers = objc_providers, merge_keys = []) # Add the frameworks to the objc provider for Bazel <= 6 dynamic_framework_provider = objc_provider_utils.merge_dynamic_framework_providers(dynamic_framework_providers) - objc_provider_fields["dynamic_framework_file"] = depset( - transitive = [dynamic_framework_provider.framework_files, objc_provider_fields.get("dynamic_framework_file", depset([]))], - ) + # Don't add dynamic_framework_file to ObjcInfo in Bazel 8 - it will be handled via CcInfo + objc_provider = apple_common.new_objc_provider(**objc_provider_fields) # Add the framework info to the cc info linking context for Bazel >= 7 - framework_cc_info = CcInfo( - linking_context = cc_common.create_linking_context( - linker_inputs = depset([ - cc_common.create_linker_input( - owner = ctx.label, - libraries = depset([ - cc_common.create_library_to_link( - actions = ctx.actions, - cc_toolchain = cc_toolchain, - feature_configuration = cc_features, - dynamic_library = dynamic_library, - ) - for dynamic_library in dynamic_framework_provider.framework_files.to_list() + if dynamic_framework_provider and hasattr(dynamic_framework_provider, "framework_files"): + framework_cc_info = CcInfo( + linking_context = cc_common.create_linking_context( + linker_inputs = depset([ + cc_common.create_linker_input( + owner = ctx.label, + libraries = depset([ + cc_common.create_library_to_link( + actions = ctx.actions, + cc_toolchain = cc_toolchain, + feature_configuration = cc_features, + dynamic_library = dynamic_library, + ) + for dynamic_library in dynamic_framework_provider.framework_files.to_list() + ]), + ), + ]), + ), + ) + cc_info_provider = cc_common.merge_cc_infos(direct_cc_infos = [framework_cc_info], cc_infos = cc_providers) + else: + cc_info_provider = cc_common.merge_cc_infos(cc_infos = cc_providers) + + # Bazel 8 compatibility: Collect libraries from ObjcInfo and add to CcInfo + # This ensures all libraries (including .lo files) are properly linked + additional_libraries = [] + for objc_p in objc_providers: + # Collect regular libraries + if hasattr(objc_p, "library"): + additional_libraries.extend(objc_p.library.to_list()) + # Collect force_load libraries (critical for alwayslink) + if hasattr(objc_p, "force_load_library"): + additional_libraries.extend(objc_p.force_load_library.to_list()) + # Collect imported libraries + if hasattr(objc_p, "imported_library"): + additional_libraries.extend(objc_p.imported_library.to_list()) + # Collect static framework files + if hasattr(objc_p, "static_framework_file"): + additional_libraries.extend(objc_p.static_framework_file.to_list()) + + # If we found additional libraries not in CcInfo, add them + if additional_libraries: + # Create library_to_link for each additional library + libraries_to_link = [] + for lib in additional_libraries: + # Check if it's a static library (.a or .lo) + if lib.path.endswith(".a") or lib.path.endswith(".lo"): + libraries_to_link.append( + cc_common.create_library_to_link( + actions = ctx.actions, + cc_toolchain = cc_toolchain, + feature_configuration = cc_features, + static_library = lib, + alwayslink = lib.path.endswith(".lo"), # .lo files are alwayslink + ) + ) + + if libraries_to_link: + additional_cc_info = CcInfo( + linking_context = cc_common.create_linking_context( + linker_inputs = depset([ + cc_common.create_linker_input( + owner = ctx.label, + libraries = depset(libraries_to_link), + ), ]), ), - ]), - ), - ) - cc_info_provider = cc_common.merge_cc_infos(direct_cc_infos = [framework_cc_info], cc_infos = cc_providers) + ) + cc_info_provider = cc_common.merge_cc_infos( + direct_cc_infos = [additional_cc_info], + cc_infos = [cc_info_provider], + ) providers = [ - dynamic_framework_provider, cc_info_provider, objc_provider, new_iosframeworkbundleinfo(), @@ -126,6 +186,17 @@ def _framework_middleman(ctx): ), ] + # Add dynamic framework provider if it exists (Bazel < 8) + if dynamic_framework_provider: + providers.append(dynamic_framework_provider) + + # Add SwiftInfo if there are Swift dependencies + if swift_infos: + # For now, just pass through the first SwiftInfo if it exists + # Proper merging of SwiftInfo is complex and would require swift_common.merge_swift_info + if len(swift_infos) > 0: + providers.append(swift_infos[0]) + embed_info_provider = embeddable_info.merge_providers(apple_embeddable_infos) if embed_info_provider: providers.append(embed_info_provider) @@ -229,6 +300,7 @@ def _get_lib_name(name): def _dep_middleman(ctx): objc_providers = [] cc_providers = [] + swift_infos = [] avoid_libraries = {} def _collect_providers(lib_dep): @@ -236,18 +308,28 @@ def _dep_middleman(ctx): objc_providers.append(lib_dep[apple_common.Objc]) if CcInfo in lib_dep: cc_providers.append(lib_dep[CcInfo]) + if SwiftInfo in lib_dep: + swift_infos.append(lib_dep[SwiftInfo]) + # Ensure Swift's CcInfo is also collected + if CcInfo in lib_dep and lib_dep[CcInfo] not in cc_providers: + cc_providers.append(lib_dep[CcInfo]) def _process_avoid_deps(avoid_dep_libs): for dep in avoid_dep_libs: if apple_common.Objc in dep: - for lib in dep[apple_common.Objc].library.to_list(): - avoid_libraries[lib] = True - for lib in dep[apple_common.Objc].force_load_library.to_list(): - avoid_libraries[lib] = True - for lib in dep[apple_common.Objc].imported_library.to_list(): - avoid_libraries[lib.basename] = True - for lib in dep[apple_common.Objc].static_framework_file.to_list(): - avoid_libraries[lib.basename] = True + objc_provider = dep[apple_common.Objc] + if hasattr(objc_provider, "library"): + for lib in objc_provider.library.to_list(): + avoid_libraries[lib] = True + if hasattr(objc_provider, "force_load_library"): + for lib in objc_provider.force_load_library.to_list(): + avoid_libraries[lib] = True + if hasattr(objc_provider, "imported_library"): + for lib in objc_provider.imported_library.to_list(): + avoid_libraries[lib.basename] = True + if hasattr(objc_provider, "static_framework_file"): + for lib in objc_provider.static_framework_file.to_list(): + avoid_libraries[lib.basename] = True if CcInfo in dep: for linker_input in dep[CcInfo].linking_context.linker_inputs.to_list(): for library_to_link in linker_input.libraries: @@ -278,10 +360,14 @@ def _dep_middleman(ctx): ]) # Ensure to strip out static link inputs - _dedupe_key("library", avoid_libraries, objc_provider_fields) - _dedupe_key("force_load_library", avoid_libraries, objc_provider_fields) - _dedupe_key("imported_library", avoid_libraries, objc_provider_fields, check_name = True) - _dedupe_key("static_framework_file", avoid_libraries, objc_provider_fields, check_name = True) + if "library" in objc_provider_fields: + _dedupe_key("library", avoid_libraries, objc_provider_fields) + if "force_load_library" in objc_provider_fields: + _dedupe_key("force_load_library", avoid_libraries, objc_provider_fields) + if "imported_library" in objc_provider_fields: + _dedupe_key("imported_library", avoid_libraries, objc_provider_fields, check_name = True) + if "static_framework_file" in objc_provider_fields: + _dedupe_key("static_framework_file", avoid_libraries, objc_provider_fields, check_name = True) if "sdk_dylib" in objc_provider_fields: # Put sdk_dylib at _end_ of the linker invocation. Apple's linkers have @@ -299,14 +385,72 @@ def _dep_middleman(ctx): # Construct the CcInfo provider, the linking information is used in Bazel >= 7. cc_info_provider = cc_common.merge_cc_infos(cc_infos = cc_providers) + + # Bazel 8 compatibility: Ensure all libraries from ObjcInfo are in CcInfo + # Collect libraries that might not be in CcInfo yet + all_libraries = [] + for key in ["library", "force_load_library", "imported_library", "static_framework_file"]: + if key in objc_provider_fields: + libs = objc_provider_fields[key].to_list() + for lib in libs: + # Only add files, not basenames + if hasattr(lib, "path"): + all_libraries.append(lib) + + # Add any missing libraries to CcInfo + if all_libraries: + cc_toolchain = find_cpp_toolchain(ctx) + cc_features = cc_common.configure_features( + ctx = ctx, + cc_toolchain = cc_toolchain, + requested_features = ctx.features, + unsupported_features = ctx.disabled_features, + ) + + libraries_to_link = [] + for lib in all_libraries: + if lib.path.endswith(".a") or lib.path.endswith(".lo"): + libraries_to_link.append( + cc_common.create_library_to_link( + actions = ctx.actions, + cc_toolchain = cc_toolchain, + feature_configuration = cc_features, + static_library = lib, + alwayslink = lib.path.endswith(".lo"), + ) + ) + + if libraries_to_link: + additional_cc_info = CcInfo( + linking_context = cc_common.create_linking_context( + linker_inputs = depset([ + cc_common.create_linker_input( + owner = ctx.label, + libraries = depset(libraries_to_link), + ), + ]), + ), + ) + cc_info_provider = cc_common.merge_cc_infos( + direct_cc_infos = [additional_cc_info], + cc_infos = [cc_info_provider], + ) - return [ + providers = [ cc_info_provider, objc_provider, ] + + # Add SwiftInfo if there are Swift dependencies + if swift_infos and len(swift_infos) > 0: + # Pass through the first SwiftInfo (simplified - may need proper merging) + providers.append(swift_infos[0]) + + return providers dep_middleman = rule( implementation = _dep_middleman, + toolchains = use_cpp_toolchain(), attrs = { "deps": attr.label_list( cfg = transition_support.apple_platform_split_transition, diff --git a/rules/internal/objc_provider_utils.bzl b/rules/internal/objc_provider_utils.bzl index 2fa7cfeb..f298e847 100644 --- a/rules/internal/objc_provider_utils.bzl +++ b/rules/internal/objc_provider_utils.bzl @@ -22,12 +22,18 @@ def _merge_objc_providers_dict(providers, transitive = [], merge_keys = objc_mer "providers": transitive, } for key in merge_keys: - set = depset( - direct = [], - # Note: we may want to merge this with the below inputs? - transitive = [getattr(provider, key) for provider in providers], - ) - _add_to_dict_if_present(fields, key, set) + provider_values = [] + for provider in providers: + # Check if the provider has this attribute (Bazel 8 compatibility) + if hasattr(provider, key): + provider_values.append(getattr(provider, key)) + if provider_values: + set = depset( + direct = [], + # Note: we may want to merge this with the below inputs? + transitive = provider_values, + ) + _add_to_dict_if_present(fields, key, set) return fields def _merge_objc_providers(providers, transitive = []): @@ -38,18 +44,43 @@ def _merge_objc_providers(providers, transitive = []): return apple_common.new_objc_provider(**objc_provider_fields) def _merge_dynamic_framework_providers(dynamic_framework_providers): + # Bazel 8 compatibility: Check if new_dynamic_framework_provider exists + if not hasattr(apple_common, "new_dynamic_framework_provider"): + # In Bazel 8, create a struct to carry framework information + # This will be used to pass framework files through the build + framework_files = [] + framework_dirs = [] + + for dep in dynamic_framework_providers: + if hasattr(dep, "framework_files"): + framework_files.extend(dep.framework_files.to_list()) + if hasattr(dep, "framework_dirs"): + framework_dirs.extend(dep.framework_dirs.to_list()) + + return struct( + framework_files = depset(framework_files), + framework_dirs = depset(framework_dirs), + objc = apple_common.new_objc_provider(), + cc_info = CcInfo(), + ) + fields = {} merge_keys = [ "framework_dirs", "framework_files", ] for key in merge_keys: - set = depset( - direct = [], - # Note: we may want to merge this with the below inputs? - transitive = [getattr(dep, key) for dep in dynamic_framework_providers], - ) - _add_to_dict_if_present(fields, key, set) + provider_values = [] + for dep in dynamic_framework_providers: + if hasattr(dep, key): + provider_values.append(getattr(dep, key)) + if provider_values: + set = depset( + direct = [], + # Note: we may want to merge this with the below inputs? + transitive = provider_values, + ) + _add_to_dict_if_present(fields, key, set) fields["objc"] = apple_common.new_objc_provider() fields["cc_info"] = CcInfo() diff --git a/tests/framework/platforms/versions.bzl b/tests/framework/platforms/versions.bzl index c625a107..7392557c 100644 --- a/tests/framework/platforms/versions.bzl +++ b/tests/framework/platforms/versions.bzl @@ -2,7 +2,7 @@ load("//rules:framework.bzl", "apple_framework") load("//rules:app.bzl", "ios_application") _VERSIONS = { - "macos": ["10.13", "14.0"], + "macos": ["10.13", "15.2"], "ios": ["12.0", "16.2", "17.2"], "tvos": ["12.0", "16.2", "17.2"], "watchos": ["3.2"], diff --git a/tests/ios/unit-test/BUILD.bazel b/tests/ios/unit-test/BUILD.bazel index eaabd137..22967472 100644 --- a/tests/ios/unit-test/BUILD.bazel +++ b/tests/ios/unit-test/BUILD.bazel @@ -53,7 +53,7 @@ ios_unit_test( minimum_os_version = "12.0", test_host = select({ "//tests/ios/unit-test:use_other_test_host": "//rules/test_host_app:iOS-12.0-AppHost", - "//conditions:default": "//rules/test_host_app:iOS-14.0-AppHost", + "//conditions:default": "//rules/test_host_app:iOS-15.2-AppHost", }), ) diff --git a/tests/ios/xcframeworks/StaticLib/BUILD.bazel b/tests/ios/xcframeworks/StaticLib/BUILD.bazel index e642d870..35f15bff 100644 --- a/tests/ios/xcframeworks/StaticLib/BUILD.bazel +++ b/tests/ios/xcframeworks/StaticLib/BUILD.bazel @@ -5,7 +5,7 @@ ios_application( name = "StaticLibApp", srcs = ["App/main.m"], bundle_id = "com.example.app", - minimum_os_version = "12.0", + minimum_os_version = "15.2", provisioning_profile = "@build_bazel_rules_ios//tests/ios:integration-test.mobileprovision", visibility = ["//visibility:public"], deps = [ @@ -16,7 +16,7 @@ ios_application( apple_framework( name = "StaticLibFW", srcs = glob(["StaticLibFW/*"]), - platforms = {"ios": "12.0"}, + platforms = {"ios": "15.2"}, visibility = ["//visibility:public"], deps = [ "//tests/ios/xcframeworks/StaticLib/ObjcLib",