Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions .github/workflows/microsoft-build-spm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: Build SPM

on:
workflow_call:

jobs:
build-hermes:
name: "Build Hermes"
runs-on: macos-15
timeout-minutes: 90
steps:
- uses: actions/checkout@v4
with:
filter: blob:none
fetch-depth: 0

- name: Set up Xcode
run: sudo xcode-select --switch /Applications/Xcode.app

- name: Set up Node.js
uses: actions/setup-node@v4.4.0
with:
node-version: '22'
cache: yarn
registry-url: https://registry.npmjs.org

- name: Install npm dependencies
run: yarn install

- name: Build Hermes from source
working-directory: packages/react-native
run: node scripts/ios-prebuild.js -s -f Debug

- name: Upload Hermes artifacts
uses: actions/upload-artifact@v4
with:
name: hermes-artifacts
path: packages/react-native/.build/artifacts/hermes
retention-days: 1

build-spm:
name: "${{ matrix.platform }}"
needs: build-hermes
runs-on: macos-26
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
platform: [ios, macos, visionos]
steps:
- uses: actions/checkout@v4
with:
filter: blob:none
fetch-depth: 0

- name: Setup toolchain
uses: ./.github/actions/microsoft-setup-toolchain
with:
node-version: '22'
platform: ${{ matrix.platform }}

- name: Install npm dependencies
run: yarn install

- name: Download Hermes artifacts
uses: actions/download-artifact@v4
with:
name: hermes-artifacts
path: packages/react-native/.build/artifacts/hermes

- name: Setup SPM workspace (using prebuilt Hermes)
working-directory: packages/react-native
run: node scripts/ios-prebuild.js -s -f Debug

- name: Build SPM (${{ matrix.platform }})
working-directory: packages/react-native
run: node scripts/ios-prebuild.js -b -f Debug -p ${{ matrix.platform }}
6 changes: 6 additions & 0 deletions .github/workflows/microsoft-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ jobs:
permissions: {}
uses: ./.github/workflows/microsoft-build-rntester.yml

build-spm:
name: "Build SPM"
permissions: {}
uses: ./.github/workflows/microsoft-build-spm.yml

test-react-native-macos-init:
name: "Test react-native-macos init"
permissions: {}
Expand All @@ -156,6 +161,7 @@ jobs:
- yarn-constraints
- javascript-tests
- build-rntester
- build-spm
- test-react-native-macos-init
# - react-native-test-app-integration
steps:
Expand Down
34 changes: 25 additions & 9 deletions packages/react-native/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ let reactJsErrorHandler = RNTarget(
let reactGraphicsApple = RNTarget(
name: .reactGraphicsApple,
path: "ReactCommon/react/renderer/graphics/platform/ios",
linkedFrameworks: ["UIKit", "CoreGraphics"],
linkedFrameworks: ["CoreGraphics"],
dependencies: [.reactDebug, .jsi, .reactUtils, .reactNativeDependencies]
)

Expand Down Expand Up @@ -360,8 +360,8 @@ let reactCore = RNTarget(
"ReactCommon/react/runtime/platform/ios", // explicit header search path to break circular dependency. RCTHost imports `RCTDefines.h` in ReactCore, ReacCore needs to import RCTHost
],
linkedFrameworks: ["CoreServices"],
excludedPaths: ["Fabric", "Tests", "Resources", "Runtime/RCTJscInstanceFactory.mm", "I18n/strings", "CxxBridge/JSCExecutorFactory.mm", "CoreModules"],
dependencies: [.reactNativeDependencies, .reactCxxReact, .reactPerfLogger, .jsi, .reactJsiExecutor, .reactUtils, .reactFeatureFlags, .reactRuntimeScheduler, .yoga, .reactJsInspector, .reactJsiTooling, .rctDeprecation, .reactCoreRCTWebsocket, .reactRCTImage, .reactTurboModuleCore, .reactRCTText, .reactRCTBlob, .reactRCTAnimation, .reactRCTNetwork, .reactFabric, .hermesPrebuilt],
excludedPaths: ["Fabric", "Tests", "Resources", "Runtime/RCTJscInstanceFactory.mm", "I18n/strings", "CxxBridge/JSCExecutorFactory.mm", "CoreModules", "RCTUIKit"],
dependencies: [.reactNativeDependencies, .reactCxxReact, .reactPerfLogger, .jsi, .reactJsiExecutor, .reactUtils, .reactFeatureFlags, .reactRuntimeScheduler, .yoga, .reactJsInspector, .reactJsiTooling, .rctDeprecation, .reactCoreRCTWebsocket, .reactRCTImage, .reactTurboModuleCore, .reactRCTText, .reactRCTBlob, .reactRCTAnimation, .reactRCTNetwork, .reactFabric, .hermesPrebuilt, .reactRCTUIKit],
sources: [".", "Runtime/RCTHermesInstanceFactory.mm"]
)

Expand All @@ -376,7 +376,6 @@ let reactFabric = RNTarget(
"components/view/tests",
"components/view/platform/android",
"components/view/platform/windows",
"components/view/platform/macos",
"components/scrollview/tests",
"components/scrollview/platform/android",
"mounting/tests",
Expand Down Expand Up @@ -420,16 +419,13 @@ let reactFabricComponents = RNTarget(
"components/modal/platform/cxx",
"components/view/platform/android",
"components/view/platform/windows",
"components/view/platform/macos",
"components/textinput/platform/android",
"components/text/platform/android",
"components/textinput/platform/macos",
"components/text/tests",
"textlayoutmanager/tests",
"textlayoutmanager/platform/android",
"textlayoutmanager/platform/cxx",
"textlayoutmanager/platform/windows",
"textlayoutmanager/platform/macos",
"conponents/rncore", // this was the old folder where RN Core Components were generated. If you ran codegen in the past, you might have some files in it that might make the build fail.
],
dependencies: [.reactNativeDependencies, .reactCore, .reactJsiExecutor, .reactTurboModuleCore, .jsi, .logger, .reactDebug, .reactFeatureFlags, .reactUtils, .reactRuntimeScheduler, .reactCxxReact, .yoga, .reactRendererDebug, .reactGraphics, .reactFabric, .reactTurboModuleBridging],
Expand Down Expand Up @@ -524,6 +520,16 @@ let reactSettings = RNTarget(
dependencies: [.reactTurboModuleCore, .yoga]
)

// [macOS
/// React-RCTUIKit.podspec
/// UIKit/AppKit compatibility layer for React Native macOS.
let reactRCTUIKit = RNTarget(
name: .reactRCTUIKit,
path: "React/RCTUIKit",
excludedPaths: ["README.md"]
)
// macOS]

// MARK: Target list
let targets = [
reactDebug,
Expand Down Expand Up @@ -581,13 +587,14 @@ let targets = [
reactAppDelegate,
reactSettings,
reactRuntimeExecutor,
reactRCTUIKit, // [macOS]
]

// MARK: Package object

let package = Package(
name: react,
platforms: [.iOS(.v15), .macCatalyst(SupportedPlatform.MacCatalystVersion.v13)],
platforms: [.iOS(.v15), .macOS(.v14), .macCatalyst(SupportedPlatform.MacCatalystVersion.v13)],
products: [
.library(
name: react,
Expand Down Expand Up @@ -753,6 +760,7 @@ extension String {
static let reactNativeModuleDom = "React-domnativemodule"
static let reactAppDelegate = "React-RCTAppDelegate"
static let reactSettings = "React-RCTSettings"
static let reactRCTUIKit = "React-RCTUIKit" // [macOS]
}

func relativeSearchPath(_ depth: Int, _ path: String) -> String {
Expand Down Expand Up @@ -792,6 +800,14 @@ extension Target {
.define("USE_HERMES", to: "1"),
] + defines + cxxCommonHeaderPaths

// [macOS] Platform-specific framework linking for targets that need UIKit (iOS/visionOS) vs AppKit (macOS)
var conditionalLinkerSettings: [LinkerSetting] = linkerSettings
if name == "React-graphics-Apple" || name == "React-RCTUIKit" {
conditionalLinkerSettings.append(.linkedFramework("UIKit", .when(platforms: [.iOS, .visionOS])))
conditionalLinkerSettings.append(.linkedFramework("AppKit", .when(platforms: [.macOS])))
}
// macOS]

return .target(
name: name,
dependencies: dependencies,
Expand All @@ -800,7 +816,7 @@ extension Target {
sources: sources,
publicHeadersPath: publicHeadersPath,
cxxSettings: cxxSettings,
linkerSettings: linkerSettings
linkerSettings: conditionalLinkerSettings
)
}
}
6 changes: 6 additions & 0 deletions packages/react-native/scripts/ios-prebuild/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,21 @@ import type {BuildFlavor, Destination, Platform} from './types';
const platforms /*: $ReadOnlyArray<Platform> */ = [
'ios',
'ios-simulator',
'macos', // [macOS]
'mac-catalyst',
'visionos', // [macOS]
'visionos-simulator', // [macOS]
];

// CI can't use commas in cache keys, so 'macOS,variant=Mac Catalyst' was creating troubles
// This map that converts from platforms to valid Xcodebuild destinations.
const platformToDestination /*: $ReadOnly<{|[Platform]: Destination|}> */ = {
ios: 'iOS',
'ios-simulator': 'iOS Simulator',
macos: 'macOS', // [macOS]
'mac-catalyst': 'macOS,variant=Mac Catalyst',
visionos: 'xrOS', // [macOS]
'visionos-simulator': 'xrOS Simulator', // [macOS]
};

const cli = yargs
Expand Down
Loading
Loading