diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 551c179b6f..74b5c158b6 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -13,7 +13,7 @@ on: env: CCACHE_DIR: ${{ github.workspace }}/ccache_dir GITHUB_TOKEN: ${{ github.token }} - xcodeVersion: "16.2" # Only affects Mac runners, and only for prerequisites. + xcodeVersion: "26.2" # Only affects Mac runners, and only for prerequisites. concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }} @@ -57,7 +57,7 @@ jobs: - os: ubuntu-22.04 architecture: arm64 # Do not attempt to use x64 on Mac. - - os: macos-14 + - os: macos-15 architecture: x64 steps: - uses: lukka/get-cmake@latest diff --git a/.github/workflows/cpp-packaging.yml b/.github/workflows/cpp-packaging.yml index 3016375392..fa5fd7d628 100644 --- a/.github/workflows/cpp-packaging.yml +++ b/.github/workflows/cpp-packaging.yml @@ -32,9 +32,9 @@ env: demumbleVer: "df938e45c2b0e064fb5323d88b692d03b451d271" # Use SHA256 for hashing files. hashCommand: "sha256sum" - # Xcode version 16.2 is the version we build the SDK with. + # Xcode version 26.2 is the version we build the SDK with. # Our MacOS runners will use the version in /Applications/Xcode_${xcodeVersion}.app - xcodeVersion: "16.2" + xcodeVersion: "26.2" # LLVM version with ARM MachO support has no version number yet. llvmVer: "5f187f0afaad33013ba03454c4749d99b1362534" GITHUB_TOKEN: ${{ github.token }} @@ -82,13 +82,13 @@ jobs: if: ${{ github.event.inputs.downloadPublicVersion == '' && github.event.inputs.downloadPreviousRun == '' }} strategy: matrix: - os: [ubuntu-22.04, macos-14] + os: [ubuntu-22.04, macos-15] include: - os: ubuntu-22.04 tools_platform: linux # Binutils 2.35.1 released Sep 19, 2020 binutils_version: "2.35.1" - - os: macos-14 + - os: macos-15 tools_platform: darwin # Binutils 2.35.1 released Sep 19, 2020 binutils_version: "2.35.1" @@ -191,7 +191,7 @@ jobs: build_and_package_ios_tvos: name: build-and-package-ios-tvos - runs-on: macos-14 + runs-on: macos-15 if: ${{ github.event.inputs.downloadPublicVersion == '' && github.event.inputs.downloadPreviousRun == '' }} steps: - uses: lukka/get-cmake@latest @@ -320,7 +320,7 @@ jobs: strategy: fail-fast: false matrix: - os: [windows-latest, ubuntu-22.04, macos-14] + os: [windows-latest, ubuntu-22.04, macos-15] build_type: ["Release", "Debug"] architecture: ["x64", "x86", "arm64"] msvc_runtime: ["static", "dynamic"] @@ -338,7 +338,7 @@ jobs: vcpkg_triplet_suffix: "linux" additional_build_flags: "" sdk_platform: "linux" - - os: macos-14 + - os: macos-15 vcpkg_triplet_suffix: "osx" additional_build_flags: "--target_format libraries" sdk_platform: "darwin" @@ -346,13 +346,13 @@ jobs: exclude: - os: windows-latest linux_abi: "c++11" - - os: macos-14 + - os: macos-15 architecture: "x86" - - os: macos-14 + - os: macos-15 msvc_runtime: "dynamic" - - os: macos-14 + - os: macos-15 linux_abi: "c++11" - - os: macos-14 + - os: macos-15 build_type: "Debug" - os: ubuntu-22.04 msvc_runtime: "dynamic" @@ -509,7 +509,7 @@ jobs: suffix: '-x64-Debug-dynamic' runs_on_platform: ubuntu-22.04 - sdk_platform: darwin - runs_on_platform: macos-14 + runs_on_platform: macos-15 exclude: - sdk_platform: windows suffix: '' diff --git a/.github/workflows/desktop.yml b/.github/workflows/desktop.yml index 06990f0a76..b45acf6155 100644 --- a/.github/workflows/desktop.yml +++ b/.github/workflows/desktop.yml @@ -72,12 +72,12 @@ jobs: # msvc_runtime excludes - os: ubuntu-22.04 msvc_runtime: "dynamic" - - os: macos-14 + - os: macos-15 msvc_runtime: "dynamic" # architecture excluees - - os: macos-14 + - os: macos-15 architecture: "x86" - - os: macos-14 + - os: macos-15 architecture: "x64" # Xcode excludes -- allow only one on osx and linux - os: ubuntu-22.04 diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml index 19f74f620d..9e9d5077e9 100644 --- a/.github/workflows/integration_tests.yml +++ b/.github/workflows/integration_tests.yml @@ -21,7 +21,7 @@ on: required: true operating_systems: description: 'CSV of VMs to run on' - default: 'ubuntu-22.04,windows-latest,macos-14' + default: 'ubuntu-22.04,windows-latest,macos-15' required: true desktop_ssl_variants: description: 'CSV of desktop SSL variants to use' @@ -49,7 +49,7 @@ env: triggerLabelFull: "tests-requested: full" triggerLabelQuick: "tests-requested: quick" pythonVersion: '3.9' - xcodeVersion: '16.2' + xcodeVersion: '26.2' logArtifactRetentionDays: 90 binaryArtifactRetentionDays: 7 GITHUB_TOKEN: ${{ github.token }} @@ -213,7 +213,7 @@ jobs: # at 3am PST/4am PDT. Running firestore desktop integration test aginst tip-of-tree ios repo echo "::warning ::Running against Firestore tip-of-tree" matrix_platform="Desktop" - matrix_os=$( python scripts/gha/print_matrix_configuration.py -w integration_tests ${TEST_MATRIX_PARAM} -k os -o "ubuntu-22.04,macos-14") + matrix_os=$( python scripts/gha/print_matrix_configuration.py -w integration_tests ${TEST_MATRIX_PARAM} -k os -o "ubuntu-22.04,macos-15") else matrix_platform=$( python scripts/gha/print_matrix_configuration.py -w integration_tests ${TEST_MATRIX_PARAM} -k platform -o "${GITHUB_EVENT_INPUTS_PLATFORMS}" --apis ${apis} ) matrix_os=$( python scripts/gha/print_matrix_configuration.py -w integration_tests ${TEST_MATRIX_PARAM} -k os -o "${GITHUB_EVENT_INPUTS_OPERATING_SYSTEMS}") @@ -283,7 +283,7 @@ jobs: - os: ubuntu-22.04 arch: arm64 # Do not attempt to use x86 on Mac. - - os: macos-14 + - os: macos-15 arch: x86 # Until we support building openssl from source, we can't use the # system's openssl when cross-compiling, except on Linux. Builds on Linux @@ -292,7 +292,7 @@ jobs: - os: windows-latest ssl_variant: openssl arch: x86 - - os: macos-14 + - os: macos-15 ssl_variant: openssl arch: x64 steps: @@ -605,7 +605,7 @@ jobs: strategy: fail-fast: false matrix: - os: [macos-14] + os: [macos-15] steps: - uses: lukka/get-cmake@latest with: @@ -724,7 +724,7 @@ jobs: strategy: fail-fast: false matrix: - os: [macos-14] + os: [macos-15] steps: - uses: lukka/get-cmake@latest with: @@ -853,7 +853,7 @@ jobs: - os: ubuntu-22.04 arch: arm64 # Do not attempt to use x86 on Mac. - - os: macos-14 + - os: macos-15 arch: x86 # Until we support building openssl from source, we can't use the # system's openssl when cross-compiling, except on Linux. Builds on Linux @@ -862,7 +862,7 @@ jobs: - os: windows-latest ssl_variant: openssl arch: x86 - - os: macos-14 + - os: macos-15 ssl_variant: openssl arch: x64 steps: @@ -1127,7 +1127,7 @@ jobs: test_ios: name: test-ios-${{ matrix.build_os }}-${{ matrix.ios_device }}-${{ matrix.test_type }} needs: [check_and_prepare, build_ios] - runs-on: macos-14 + runs-on: macos-15 if: contains(needs.check_and_prepare.outputs.matrix_platform, 'iOS') && needs.check_and_prepare.outputs.apis != '' && !cancelled() strategy: fail-fast: false @@ -1137,7 +1137,7 @@ jobs: exclude: - ios_device: "ios_target" test_type: "uitest" - build_os: [macos-14] + build_os: [macos-15] steps: - uses: actions/checkout@v3 with: @@ -1317,13 +1317,13 @@ jobs: test_tvos: name: test-tvos-${{ matrix.build_os }}-${{ matrix.tvos_device }} needs: [check_and_prepare, build_tvos] - runs-on: macos-14 + runs-on: macos-15 if: contains(needs.check_and_prepare.outputs.matrix_platform, 'tvOS') && needs.check_and_prepare.outputs.apis != '' && !cancelled() strategy: fail-fast: false matrix: tvos_device: ${{ fromJson(needs.check_and_prepare.outputs.tvos_device) }} - build_os: [macos-14] + build_os: [macos-15] steps: - uses: actions/checkout@v3 with: diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml index 0b24e536d2..c87c4b048a 100644 --- a/.github/workflows/ios.yml +++ b/.github/workflows/ios.yml @@ -41,7 +41,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ 'macos-14' ] + os: [ 'macos-15' ] xcode_version: ${{ fromJson(needs.prepare_matrix.outputs.matrix_xcode_version) }} steps: - uses: lukka/get-cmake@latest diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml index 2f2ea7fc99..07849f8513 100644 --- a/.github/workflows/update-dependencies.yml +++ b/.github/workflows/update-dependencies.yml @@ -27,7 +27,7 @@ env: jobs: update_dependencies: name: update-deps - runs-on: macos-14 + runs-on: macos-15 steps: - name: Get token for firebase-workflow-trigger uses: tibdex/github-app-token@v1 diff --git a/CMakeLists.txt b/CMakeLists.txt index 88f166f12c..68db39fd25 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -162,6 +162,9 @@ if(APPLE) # build output for our Objective-C++ files much too verbose. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-nullability-completeness") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-nullability-completeness") + # On Apple platforms, disable the target os macros, as they cause problems with zlib + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-define-target-os-macros") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-define-target-os-macros") if(DESKTOP) # Mac desktop Firestore build requires -Wno-deprecated-declarations set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-declarations") diff --git a/release_build_files/readme.md b/release_build_files/readme.md index 743834f9c7..c63c527a5e 100644 --- a/release_build_files/readme.md +++ b/release_build_files/readme.md @@ -408,7 +408,7 @@ Firebase Cloud Messaging (stub) | firebase_messaging.framework User Messaging Platform (stub) | libfirebase_ump.a | | libfirebase_app.a -The provided libraries have been tested using Xcode 16.2. When building C++ +The provided libraries have been tested using Xcode 26.2. When building C++ desktop apps on OS X, you will need to link the `gssapi_krb5` and `pthread` system libraries, as well as the `CoreFoundation`, `Foundation`, `GSS`, and `Security` OS X system frameworks (consult your compiler documentation for more @@ -613,6 +613,11 @@ workflow use only during the development of your app, not for publicly shipping code. ## Release Notes +### Upcoming +- Changes + - General (iOS, tvOS, Desktop): iOS, tvOS, and macOS SDKs are now built + using Xcode 26.2. + ### 13.7.0 - Changes - General (Android): Update to Firebase Android BoM version 34.13.0. diff --git a/scripts/gha/install_prereqs_desktop.py b/scripts/gha/install_prereqs_desktop.py index 65c01bc4f2..365e487666 100644 --- a/scripts/gha/install_prereqs_desktop.py +++ b/scripts/gha/install_prereqs_desktop.py @@ -83,6 +83,15 @@ def main(): # brew install protobuf utils.run_command(['brew', 'install', 'clang-format']) + # Install mono on linux/mac if its not installed already + if not utils.is_command_installed('mono'): + if utils.is_linux_os(): + # sudo apt install mono-complete + utils.run_command(['apt', 'install', '-y', 'mono-complete'], as_root=True) + elif utils.is_mac_os(): + # brew install mono + utils.run_command(['brew', 'install', 'mono']) + # On Linux, if gcc-10 isn't installed install it. Then make it the default. if utils.is_linux_os(): # Check if we have gcc 9 or gcc 10 as the default, if not, set gcc 10. diff --git a/scripts/gha/print_matrix_configuration.py b/scripts/gha/print_matrix_configuration.py index b968f103f9..f51e6a3163 100644 --- a/scripts/gha/print_matrix_configuration.py +++ b/scripts/gha/print_matrix_configuration.py @@ -73,35 +73,35 @@ PARAMETERS = { "desktop": { "matrix": { - "os": ["ubuntu-22.04", "macos-14"], + "os": ["ubuntu-22.04", "macos-15"], "build_type": ["Release", "Debug"], "architecture": ["x64", "x86", "arm64"], "msvc_runtime": ["static","dynamic"], - "xcode_version": ["16.2"], + "xcode_version": ["26.2"], "python_version": ["3.9"], EXPANDED_KEY: { - "os": ["ubuntu-22.04", "macos-14", "windows-latest"], - "xcode_version": ["16.2"], + "os": ["ubuntu-22.04", "macos-15", "windows-latest"], + "xcode_version": ["26.2"], } } }, "android": { "matrix": { - "os": ["ubuntu-22.04", "macos-14", "windows-latest"], + "os": ["ubuntu-22.04", "macos-15", "windows-latest"], "architecture": ["x64", "arm64"], "python_version": ["3.9"], EXPANDED_KEY: { - "os": ["ubuntu-22.04", "macos-14", "windows-latest"] + "os": ["ubuntu-22.04", "macos-15", "windows-latest"] } } }, "integration_tests": { "matrix": { - "os": ["ubuntu-22.04", "macos-14", "windows-latest"], + "os": ["ubuntu-22.04", "macos-15", "windows-latest"], "platform": ["Desktop", "Android", "iOS", "tvOS"], "ssl_lib": ["openssl"], "android_device": ["android_target", "emulator_ftl_target"], @@ -113,7 +113,7 @@ "msvc_runtime": ["dynamic"], "cpp_compiler_windows": ["VisualStudio2019"], "cpp_compiler_linux": ["clang-11.0"], - "xcode_version": ["16.2"], # only the first one is used + "xcode_version": ["26.2"], # only the first one is used "ndk_version": ["r22b"], "platform_version": ["28"], "build_tools_version": ["28.0.3"], @@ -141,10 +141,10 @@ "ios": { "matrix": { - "xcode_version": ["16.2"], + "xcode_version": ["26.2"], EXPANDED_KEY: { - "xcode_version": ["16.2"] + "xcode_version": ["26.2"] } } }, @@ -211,8 +211,8 @@ {"type": "ftl", "device": "model=iphone8,version=16.6"}, {"type": "ftl", "device": "model=ipad10,version=16.6"}, ], - "simulator_target": [ {"type": "virtual", "name":"iPhone 15 Pro Max", "version":"17.2"} ], - "tvos_simulator": [ {"type": "virtual", "name":"Apple TV", "version":"17.2"} ], + "simulator_target": [ {"type": "virtual", "name":"iPhone 16 Pro Max", "version":"26.2"} ], + "tvos_simulator": [ {"type": "virtual", "name":"Apple TV", "version":"26.2"} ], } # Easy accesssor for getting a TEST_DEVICES entry. Note that once a device model diff --git a/scripts/gha/test_simulator.py b/scripts/gha/test_simulator.py index 297d530b1c..2fb8f57c90 100644 --- a/scripts/gha/test_simulator.py +++ b/scripts/gha/test_simulator.py @@ -240,7 +240,7 @@ def main(argv): device_name = FLAGS.ios_name device_os = FLAGS.ios_version - device_id = _create_and_boot_simulator("iOS", device_name, device_os) + device_id, device_name, device_os = _create_and_boot_simulator("iOS", device_name, device_os) if not device_id: logging.error("simulator created fail") return 21 @@ -274,7 +274,7 @@ def main(argv): device_name = FLAGS.tvos_name device_os = FLAGS.tvos_version - device_id = _create_and_boot_simulator("tvOS", device_name, device_os) + device_id, device_name, device_os = _create_and_boot_simulator("tvOS", device_name, device_os) if not device_id: logging.error("simulator created fail") return 21 @@ -500,49 +500,113 @@ def _shutdown_simulator(): def _create_and_boot_simulator(apple_platform, device_name, device_os): - """Create a simulator locally. Will wait until this simulator booted.""" - _shutdown_simulator() - command = "xcrun xctrace list devices 2>&1 | grep \"%s Simulator (%s)\" | awk -F'[()]' '{print $4}'" % (device_name, device_os) - logging.info("Get test simulator: %s", command) - result = subprocess.Popen(command, universal_newlines=True, shell=True, stdout=subprocess.PIPE) - device_id = result.stdout.readline().strip() + """Create a simulator locally. Will wait until this simulator booted. - if not device_id: - # download and create device - args = ["brew", "install", "xcodesorg/made/xcodes"] - logging.info("Download xcodes: %s", " ".join(args)) - subprocess.run(args=args, check=True) + Returns a tuple of (device_id, device_name, device_os). + """ + _shutdown_simulator() - # Get the set of available versions for the given Apple platform - args = ["xcodes", "runtimes"] - runtimes = subprocess.run(args=args, capture_output=True, text=True, check=True) - available_versions = re.findall('{0} ([\d|.]+)'.format(apple_platform), runtimes.stdout.strip()) - logging.info("Found available versions for %s: %s", apple_platform, ", ".join(available_versions)) + # Find available runtimes using simctl + try: + runtimes_result = subprocess.run( + ["xcrun", "simctl", "list", "runtimes", "-j"], + capture_output=True, text=True, check=True) + runtimes_data = json.loads(runtimes_result.stdout) + except Exception: + logging.exception("Failed to get runtimes list from simctl") + return None, None, None + + # Filter runtimes by platform and availability + available_runtimes = [] + for r in runtimes_data.get("runtimes", []): + if r.get("isAvailable") and r.get("platform") == apple_platform: + available_runtimes.append(r) + + if not available_runtimes: + logging.error("No available runtimes found for platform: %s", apple_platform) + return None, None, None + + # Find matching runtime version + target_runtime = None + for r in available_runtimes: + version = r.get("version") + if version == device_os or version.startswith(device_os): + target_runtime = r + break - # If the requested version is available, use it, otherwise default to the latest - if (device_os not in available_versions): - logging.warning("Unable to find version %s, will fall back to %s", device_os, available_versions[-1]) - if FLAGS.ci: - print("::warning ::Unable to find %s version %s, will fall back to %s" % (apple_platform, device_os, available_versions[-1])) - device_os = available_versions[-1] + if not target_runtime: + # Fall back to the latest runtime version + def parse_version(version_str): + sanitized = re.sub(r'[^\d.]', '', version_str) + parts = [] + for x in sanitized.split('.'): + if x.isdigit(): + parts.append(int(x)) + return parts + + available_runtimes.sort(key=lambda r: parse_version(r.get("version"))) + target_runtime = available_runtimes[-1] + fallback_os = target_runtime.get("version") + logging.warning("Requested %s version %s is not available. Falling back to %s", + apple_platform, device_os, fallback_os) + if FLAGS.ci: + print("::warning ::Requested %s version %s is not available, falling back to %s" % + (apple_platform, device_os, fallback_os)) + device_os = fallback_os + + runtime_id = target_runtime.get("identifier") + logging.info("Using runtime: %s (ID: %s)", target_runtime.get("name"), runtime_id) + + # Check if a matching simulator device already exists + try: + devices_result = subprocess.run( + ["xcrun", "simctl", "list", "devices", "-j"], + capture_output=True, text=True, check=True) + devices_data = json.loads(devices_result.stdout) + except Exception: + logging.exception("Failed to get devices list from simctl") + return None, None, None + + devices_under_runtime = devices_data.get("devices", {}).get(runtime_id, []) + device_id = None + for d in devices_under_runtime: + if d.get("isAvailable") and d.get("name") == device_name: + device_id = d.get("udid") + logging.info("Found existing simulator device: %s (%s)", device_name, device_id) + break - args = ["sudo", "xcodes", "runtimes", "install", "%s %s" % (apple_platform, device_os)] - logging.info("Download simulator: %s", " ".join(args)) - subprocess.run(args=args, check=False) + if not device_id: + # Create new device if not found + args = ["xcrun", "simctl", "create", "test_simulator", device_name, runtime_id] + logging.info("Creating test simulator: %s", " ".join(args)) + try: + result = subprocess.run(args=args, capture_output=True, text=True, check=True) + device_id = result.stdout.strip() + logging.info("Created simulator: %s", device_id) + except subprocess.CalledProcessError as e: + logging.error("Failed to create simulator: %s", e.stderr) + # Fall back to the first available device under this runtime + for d in devices_under_runtime: + if d.get("isAvailable"): + device_id = d.get("udid") + device_name = d.get("name") + logging.info("Fallback to first available device: %s (%s)", device_name, device_id) + break - args = ["xcrun", "simctl", "create", "test_simulator", device_name, "%s%s" % (apple_platform, device_os)] - logging.info("Create test simulator: %s", " ".join(args)) - result = subprocess.run(args=args, capture_output=True, text=True, check=True) - device_id = result.stdout.strip() + if not device_id: + logging.error("No simulator device available or created") + return None, None, None + # Boot the simulator args = ["xcrun", "simctl", "boot", device_id] - logging.info("Boot my simulator: %s", " ".join(args)) + logging.info("Boot simulator: %s", " ".join(args)) subprocess.run(args=args, check=True) args = ["xcrun", "simctl", "bootstatus", device_id] logging.info("Wait for simulator to boot: %s", " ".join(args)) subprocess.run(args=args, check=True) - return device_id + + return device_id, device_name, device_os def _delete_simulator(device_id): diff --git a/testing/sample_framework/src/app_framework.cc b/testing/sample_framework/src/app_framework.cc index 929979d7df..96c0a6b21c 100644 --- a/testing/sample_framework/src/app_framework.cc +++ b/testing/sample_framework/src/app_framework.cc @@ -35,8 +35,10 @@ // In Xcode 16, libc++ removed the noexcept specifier from // __libcpp_verbose_abort. -#if defined(__apple_build_version__) && __apple_build_version__ >= 16000000 && \ - __apple_build_version__ < 20000000 +#if defined(_LIBCPP_VERBOSE_ABORT_NOEXCEPT) +#define FIREBASE_LIBCPP_VERBOSE_ABORT_NOEXCEPT _LIBCPP_VERBOSE_ABORT_NOEXCEPT +#elif defined(__apple_build_version__) && \ + __apple_build_version__ >= 16000000 && __apple_build_version__ < 20000000 #define FIREBASE_LIBCPP_VERBOSE_ABORT_NOEXCEPT #else #define FIREBASE_LIBCPP_VERBOSE_ABORT_NOEXCEPT noexcept