diff --git a/packages/skia/package.json b/packages/skia/package.json index 3f5dbf961d..fc8f6f05a7 100644 --- a/packages/skia/package.json +++ b/packages/skia/package.json @@ -26,7 +26,7 @@ "android-arm64-v8a": "6be2711ca4c31523d381420e98cabfe7e7939e246975c7b427968d5dd3b62be9", "android-x86": "888934ddc34f431c7fac5628f633dc11a4e84d68c41adb33307ae7586cc7b0b5", "android-x86_64": "2180a5be52d51bbf1dabaf95051ed0ce422b047157bcda6e486657c2c7b87ceb", - "apple-xcframeworks": "cb50d9c85c9f02389ecc433912145e4a7ce2277bfe26a69dd7f7a9db74c9e276" + "apple-xcframeworks": "6c9e4c565977acaf9d4f4b113050cfe8f9804602fd3cd4ec982c605fa7b040e6" } }, "description": "High-performance React Native Graphics using Skia", diff --git a/packages/skia/scripts/install-skia.mjs b/packages/skia/scripts/install-skia.mjs index e6f2a19ea1..df248d2f61 100644 --- a/packages/skia/scripts/install-skia.mjs +++ b/packages/skia/scripts/install-skia.mjs @@ -59,10 +59,11 @@ console.log( `📦 Downloading Skia prebuilt binaries for ${releaseTag}` ); -const runCommand = (command, args) => { +const runCommand = (command, args, options = {}) => { return new Promise((resolve, reject) => { const child = spawn(command, args, { stdio: ["ignore", "inherit", "inherit"], + ...options, }); child.on("error", (error) => { reject(error); @@ -77,6 +78,75 @@ const runCommand = (command, args) => { }); }; +const runCommandWithOutput = (command, args, options = {}) => { + return new Promise((resolve, reject) => { + const child = spawn(command, args, { + stdio: ["ignore", "pipe", "pipe"], + ...options, + }); + let stdout = ""; + let stderr = ""; + child.stdout.on("data", (data) => { + stdout += data.toString(); + }); + child.stderr.on("data", (data) => { + stderr += data.toString(); + }); + child.on("error", (error) => { + reject(error); + }); + child.on("close", (code) => { + if (code === 0) { + resolve(stdout.trim()); + } else { + reject(new Error(`Command ${command} exited with code ${code}: ${stderr}`)); + } + }); + }); +}; + +const skiaDir = path.resolve(__dirname, "../../../externals/skia"); + +const checkoutSkiaBranch = async (version) => { + const branchName = `chrome/${version}`; + + // Check if the skia directory exists and is a git repo + // (won't exist when installed via npm - submodule is not included in the package) + if (!fs.existsSync(skiaDir) || !fs.existsSync(path.join(skiaDir, ".git"))) { + return; + } + + console.log(`🔀 Checking out Skia branch: ${branchName}`); + + try { + // Get current branch/commit + const currentRef = await runCommandWithOutput("git", ["rev-parse", "--abbrev-ref", "HEAD"], { cwd: skiaDir }); + + if (currentRef === branchName) { + console.log(` ✓ Already on branch ${branchName}`); + return; + } + + // Fetch the branch from origin + console.log(` Fetching branch ${branchName} from origin...`); + try { + await runCommand("git", ["fetch", "origin", `${branchName}:${branchName}`], { cwd: skiaDir }); + } catch (e) { + // Branch might already exist locally, try to update it + await runCommand("git", ["fetch", "origin", branchName], { cwd: skiaDir }); + } + + // Checkout the branch (use -f to discard local changes in the submodule) + console.log(` Checking out ${branchName}...`); + await runCommand("git", ["checkout", "-f", branchName], { cwd: skiaDir }); + + console.log(` ✓ Successfully checked out ${branchName}`); + } catch (error) { + console.error(` ⚠️ Failed to checkout branch ${branchName}: ${error.message}`); + console.error(" Headers may not match the prebuilt binaries!"); + } +}; + const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms)); const downloadToFile = (url, destPath, maxRetries = 5) => { @@ -359,6 +429,9 @@ const clearDirectory = (directory) => { }; const main = async () => { + // Ensure the skia submodule is on the correct branch for copying headers + await checkoutSkiaBranch(skiaVersion); + // Check if binaries are installed and checksums match if (areBinariesInstalled() && verifyChecksums()) { console.log("✅ Prebuilt binaries already installed with matching checksums, skipping download");