diff --git a/packages/skia/android/cpp/jni/include/JniSkiaBaseView.h b/packages/skia/android/cpp/jni/include/JniSkiaBaseView.h index 434b330df4..fad912d7b9 100644 --- a/packages/skia/android/cpp/jni/include/JniSkiaBaseView.h +++ b/packages/skia/android/cpp/jni/include/JniSkiaBaseView.h @@ -29,7 +29,6 @@ class JniSkiaBaseView { } protected: - virtual void surfaceAvailable(jobject surface, int width, int height) { _skiaAndroidView->surfaceAvailable(surface, width, height); } diff --git a/packages/skia/android/cpp/jni/include/JniSkiaPictureView.h b/packages/skia/android/cpp/jni/include/JniSkiaPictureView.h index dc5d265b93..a3aaef90a3 100644 --- a/packages/skia/android/cpp/jni/include/JniSkiaPictureView.h +++ b/packages/skia/android/cpp/jni/include/JniSkiaPictureView.h @@ -49,7 +49,6 @@ class JniSkiaPictureView : public jni::HybridClass, } protected: - void surfaceAvailable(jobject surface, int width, int height) override { JniSkiaBaseView::surfaceAvailable(surface, width, height); } diff --git a/packages/skia/package.json b/packages/skia/package.json index e24a6d8041..26795992c1 100644 --- a/packages/skia/package.json +++ b/packages/skia/package.json @@ -41,12 +41,9 @@ "e2e": "E2E=true yarn test -i e2e", "release": "semantic-release", "build": "bob build && merge-dirs lib/typescript/src lib/commonjs && merge-dirs lib/typescript/src lib/module", - "build-skia-ios-framework": "ts-node ./scripts/build-skia-ios-framework.ts", - "build-skia-ios": "ts-node ./scripts/build-skia-ios.ts && yarn build-skia-ios-framework", - "build-skia-android": "ts-node ./scripts/build-skia-android.ts", "clean-skia": "yarn rimraf ./libs && yarn rimraf ../../externals/skia/out", - "copy-skia-headers": "ts-node ./scripts/copy-skia-module-headers.ts", - "build-skia": "yarn rimraf ./libs && yarn build-skia-ios && yarn build-skia-android && yarn copy-skia-headers", + "build-skia": "ts-node ./scripts/build-skia.ts", + "copy-skia-headers": "ts-node ./scripts/copy-skia-headers.ts", "clang-format": "yarn clang-format-ios && yarn clang-format-android && yarn clang-format-common", "clang-format-ios": "find ios/ -iname '*.h' -o -iname '*.mm' -o -iname '*.cpp' | xargs clang-format -i", "clang-format-android": "find android/cpp/ -iname '*.h' -o -iname '*.m' -o -iname '*.cpp' | xargs clang-format -i", diff --git a/packages/skia/scripts/build-skia-android.ts b/packages/skia/scripts/build-skia-android.ts deleted file mode 100644 index 3591effc95..0000000000 --- a/packages/skia/scripts/build-skia-android.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { configurations } from "./skia-configuration"; -import { executeCmd } from "./utils"; - -const configuration = configurations.android; - -console.log("Building skia for Android..."); -let command = ""; - -Object.keys(configuration.targets).forEach((targetKey) => { - command += - (command !== "" ? " && " : "") + - `yarn ts-node ./scripts/build-skia.ts android ${targetKey}`; -}); - -executeCmd(command, "Android", () => { - console.log("Done building skia for Android."); -}); diff --git a/packages/skia/scripts/build-skia-ios-framework.ts b/packages/skia/scripts/build-skia-ios-framework.ts deleted file mode 100644 index 2bc4732760..0000000000 --- a/packages/skia/scripts/build-skia-ios-framework.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { configurations } from "./skia-configuration"; -import { executeCmdSync, checkFileExists } from "./utils"; - -/** - * This build script takes the prebuilt Skia Binaries and creates - * iOS Fat Libraries (archives with all archs inside of one file). - * - * Requirements: Requires and tests that all Skia Binaries for the iOS - * archs are built and available in the libs folder. - * - * This build script is run after the Skia Binaries are built. - */ - -console.log("Building iOS Fat Libraries from Skia Binaries"); -console.log(""); - -console.log("Checking prerequisites..."); - -// Check deps -Object.keys(configurations.ios.targets).forEach((targetKey) => { - configurations.ios.outputNames.forEach((out) => { - checkFileExists( - `libs/ios/${targetKey}/${out}`, - `libs/ios/${targetKey}/${out}`, - `libs/ios/${targetKey}/${out} not found` - ); - }); -}); - -console.log(""); -console.log("Prerequisites met. Starting build."); -console.log(""); - -console.log("Building fat binary for iphone simulator"); -configurations.ios.outputNames.forEach((out) => { - console.log(`Building fat binary for simulator for file ${out}`); - executeCmdSync( - `lipo -create libs/ios/x64/${out} libs/ios/arm64-iphonesimulator/${out} -output libs/ios/${ - out.split(".")[0] - }.a` - ); -}); - -console.log(""); -console.log("Building xcframeworks..."); - -configurations.ios.outputNames.forEach((out) => { - const libName = out.split(".")[0]; - console.log(`Building ${libName}.xcframework`); - executeCmdSync(`rm -rf ./package/libs/ios/${libName}.xcframework`); - executeCmdSync( - "xcodebuild -create-xcframework " + - `-library libs/ios/${libName}.a ` + - `-library libs/ios/arm64-iphoneos/${libName}.a ` + - ` -output libs/ios/${libName}.xcframework ` - ); -}); - -console.log("Frameworks successfully built."); diff --git a/packages/skia/scripts/build-skia-ios.ts b/packages/skia/scripts/build-skia-ios.ts deleted file mode 100644 index 6166000d76..0000000000 --- a/packages/skia/scripts/build-skia-ios.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { configurations } from "./skia-configuration"; -import { executeCmd } from "./utils"; - -const configuration = configurations.ios; - -console.log("Building skia for iOS..."); -let command = ""; - -Object.keys(configuration.targets).forEach((targetKey) => { - command += - (command !== "" ? " && " : "") + - `yarn ts-node ./scripts/build-skia.ts ios ${targetKey}`; -}); - -executeCmd(command, "iOS", () => { - console.log("Done building skia for iOS."); -}); diff --git a/packages/skia/scripts/build-skia.ts b/packages/skia/scripts/build-skia.ts index a4c5a7b7a0..96789c4907 100644 --- a/packages/skia/scripts/build-skia.ts +++ b/packages/skia/scripts/build-skia.ts @@ -1,82 +1,43 @@ import { exit } from "process"; -import { existsSync, mkdirSync } from "fs"; - -import { executeCmd, executeCmdSync } from "./utils"; -import type { PlatformName } from "./skia-configuration"; -import { commonArgs, configurations } from "./skia-configuration"; - -const typedKeys = (obj: T) => Object.keys(obj) as (keyof T)[]; - -/** - * This build script builds the Skia Binaries from the Skia repositories - * that are added as submodules to this repo. Both the Skia repo and - * the depottools (build tools) for building is included. - * - * The build script does not have any other requirements than that the - * Android NDK should be installed. - * - * This build script is run by the build-skia.yml github workflow - * - * Arguments: - * @param platform the current platform as defined in the file skia-configuration.ts - * @param cpu the cpu platform as defined in the file skia-configuration.ts - * - */ - -console.log("Starting SKIA Build."); -console.log(""); - -// Test for existence of Android SDK -if (!process.env.ANDROID_NDK) { - console.log("ANDROID_NDK not set."); - exit(1); -} else { - console.log("☑ ANDROID_NDK"); -} - -console.log(""); -console.log("Requirements met. Starting build."); -console.log(""); - -if (process.argv.length !== 4) { - console.log("Missing platform/target arguments"); - console.log("Available platforms/targets:"); - console.log(""); - typedKeys(configurations).forEach((platform) => { - console.log(platform); - const config = configurations[platform]; - Object.keys(config.targets).forEach((target) => console.log(" " + target)); - }); - exit(1); -} - -const currentDir = process.cwd(); -const SkiaDir = "../../externals/skia"; -const SelectedPlatform = (process.argv[2] as PlatformName) ?? ""; -const SelectedTarget = process.argv[3] ?? ""; -if (SkiaDir === undefined) { - throw new Error("No Skia root directory specified."); -} +import type { Platform, PlatformName } from "./skia-configuration"; +import { + commonArgs, + configurations, + copyHeaders, + OutFolder, + PackageRoot, + ProjectRoot, + SkiaSrc, +} from "./skia-configuration"; +import { $, mapKeys, runAsync } from "./utils"; const getOutDir = (platform: PlatformName, targetName: string) => { - return `out/${platform}/${targetName}`; + return `${OutFolder}/${platform}/${targetName}`; }; -const configurePlatform = (platform: PlatformName, targetName: string) => { - console.log(`Configuring platform "${platform}" for target "${targetName}"`); +const configurePlatform = ( + platformName: PlatformName, + configuration: Platform, + targetName: string +) => { + process.chdir(SkiaSrc); + console.log( + `Configuring platform "${platformName}" for target "${targetName}"` + ); console.log("Current directory", process.cwd()); - const configuration = configurations[platform]; if (configuration) { const target = configuration.targets[targetName]; if (!target) { - console.log(`Target ${targetName} not found for platform ${platform}`); + console.log( + `Target ${targetName} not found for platform ${platformName}` + ); exit(1); } const commandline = `PATH=../depot_tools/:$PATH gn gen ${getOutDir( - platform, + platformName, targetName )}`; @@ -105,25 +66,25 @@ const configurePlatform = (platform: PlatformName, targetName: string) => { ""; // eslint-disable-next-line max-len - const command = `${commandline} ${options} ${targetOptions} --script-executable=python3 --args='target_os="${platform}" target_cpu="${target.cpu}" ${common}${args}${targetArgs}'`; + const command = `${commandline} ${options} ${targetOptions} --script-executable=python3 --args='target_os="${platformName}" target_cpu="${target.cpu}" ${common}${args}${targetArgs}'`; console.log("Command:"); console.log(command); console.log("==============================="); - executeCmdSync(command); + $(command); return true; } else { console.log( - `Could not find platform "${platform}" for target "${targetName}" ` + `Could not find platform "${platformName}" for target "${targetName}" ` ); return false; } }; -const buildPlatform = ( +export const buildPlatform = async ( platform: PlatformName, - targetName: string, - callback: () => void + targetName: string ) => { + process.chdir(SkiaSrc); console.log(`Building platform "${platform}" for target "${targetName}"`); // We need to include the path to our custom python2 -> python3 mapping script // to make sure we can run all scripts that uses #!/usr/bin/env python as shebang @@ -132,87 +93,88 @@ const buildPlatform = ( platform, targetName )}`; - console.log(command); - executeCmd(command, `${platform}/${targetName}`, callback); + await runAsync(command, `${platform}/${targetName}`); }; -const processOutput = (platformName: PlatformName, targetName: string) => { - console.log( - `Copying output for platform "${platformName}" and cpu "${targetName}"` - ); - const source = getOutDir(platformName, targetName); - const configuration = configurations[platformName]; - if (configuration) { - const libNames = configuration.outputNames; - let targetDir = `${currentDir}/${configurations[platformName].outputRoot}/${targetName}`; - // Check if we have any output mappings here - const target = configuration.targets[targetName]; - if (target.output) { - targetDir = `${currentDir}/${configurations[platformName].outputRoot}/${target.output}`; - } - - if (!existsSync(targetDir)) { - console.log(`Creating directory '${targetDir}'...`); - mkdirSync(targetDir + "/", { recursive: true }); - } - - libNames.forEach((libName) => { - console.log(`Copying ${source}/${libName} to ${targetDir}/`); - console.log(`cp ${source}/${libName} ${targetDir}/.`); - executeCmdSync(`cp ${source}/${libName} ${targetDir}/.`); +export const copyLib = ( + os: PlatformName, + cpu: string, + platform: string, + outputNames: string[] +) => { + const dstPath = `${PackageRoot}/libs/${os}/${platform}/`; + $(`mkdir -p ${dstPath}`); + + outputNames + .map((name) => `${OutFolder}/${os}/${cpu}/${name}`) + .forEach((lib) => { + const libPath = lib; + console.log(`Copying ${libPath} to ${dstPath}`); + console.log(`cp ${libPath} ${dstPath}`); + $(`cp ${libPath} ${dstPath}`); }); - } else { - throw new Error( - `Could not find platform "${platformName}" for tagetCpu "${targetName}" ` - ); - } }; -try { - console.log(`Entering directory ${SkiaDir}`); - process.chdir(SkiaDir); - - // Find platform/target - const platform = configurations[SelectedPlatform]; - if (!platform) { - console.log(`Could not find platform ${SelectedPlatform}`); - exit(1); - } - const target = platform.targets[SelectedTarget]; - if (!target) { - console.log( - `Could not find target ${SelectedTarget} for platform ${SelectedPlatform}` +const buildXCFrameworks = () => { + const os: PlatformName = "ios"; + const { outputNames } = configurations.ios; + process.chdir(SkiaSrc); + outputNames.forEach((name) => { + console.log("Building XCFramework for " + name); + const prefix = `${OutFolder}/${os}`; + $(`mkdir -p ${OutFolder}/${os}/iphonesimulator`); + $(`rm -rf ${OutFolder}/${os}/iphonesimulator/${name}`); + $( + // eslint-disable-next-line max-len + `lipo -create ${OutFolder}/${os}/x64/${name} ${OutFolder}/${os}/arm64-iphonesimulator/${name} -output ${OutFolder}/${os}/iphonesimulator/${name}` ); + const [lib] = name.split("."); + const dstPath = `${PackageRoot}/libs/${os}/${lib}.xcframework`; + $( + "xcodebuild -create-xcframework " + + `-library ${prefix}/arm64-iphoneos/${name} ` + + `-library ${prefix}/iphonesimulator/${name} ` + + ` -output ${dstPath}` + ); + }); +}; + +(async () => { + // Test for existence of Android SDK + if (!process.env.ANDROID_NDK) { + console.log("ANDROID_NDK not set."); exit(1); + } else { + console.log("☑ ANDROID_NDK"); } // Run glient sync console.log("Running gclient sync..."); - // Start by running sync - executeCmdSync("PATH=../depot_tools/:$PATH python3 tools/git-sync-deps"); + process.chdir(SkiaSrc); + $("PATH=../depot_tools/:$PATH python3 tools/git-sync-deps"); console.log("gclient sync done"); - - try { - // Configure the platform - if (!configurePlatform(SelectedPlatform, SelectedTarget)) { - throw Error( - `Error configuring platform "${SelectedPlatform}" for cpu "${SelectedTarget}"` - ); + $(`rm -rf ${PackageRoot}/libs`); + for (const key of mapKeys(configurations)) { + const configuration = configurations[key]; + for (const target of mapKeys(configuration.targets)) { + if (!configurePlatform(key as PlatformName, configuration, target)) { + throw Error(`Error configuring platform "${key}" for cpu "${target}"`); + } + await buildPlatform(key as PlatformName, target); + process.chdir(ProjectRoot); + if (key === "android") { + copyLib( + key, + target, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + configuration.targets[target].output, + configuration.outputNames + ); + } } - // Spawn build - buildPlatform(SelectedPlatform, SelectedTarget, () => { - process.chdir(SkiaDir); - // Copy the output - processOutput(SelectedPlatform, SelectedTarget); - // Revert back to original directory - process.chdir(currentDir); - }); - } catch (err) { - console.log(`ERROR ${SelectedPlatform}/${SelectedTarget}: ${err}`); } - - process.chdir(currentDir); -} catch (err) { - console.log(err); -} + buildXCFrameworks(); + copyHeaders(); +})(); diff --git a/packages/skia/scripts/copy-skia-headers.ts b/packages/skia/scripts/copy-skia-headers.ts new file mode 100644 index 0000000000..1469c43b65 --- /dev/null +++ b/packages/skia/scripts/copy-skia-headers.ts @@ -0,0 +1,3 @@ +import { copyHeaders } from "./skia-configuration"; + +copyHeaders(); diff --git a/packages/skia/scripts/copy-skia-module-headers.ts b/packages/skia/scripts/copy-skia-module-headers.ts deleted file mode 100644 index 7e6fcb4a47..0000000000 --- a/packages/skia/scripts/copy-skia-module-headers.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { executeCmdSync } from "./utils"; - -const copyModule = (module: string) => [ - `mkdir -p ./cpp/skia/modules/${module}/include`, - `cp -a ../../externals/skia/modules/${module}/include/. ./cpp/skia/modules/${module}/include`, -]; - -[ - "rm -rf ./cpp/skia", - - "mkdir -p ./cpp/skia", - "mkdir -p ./cpp/skia/include", - "mkdir -p ./cpp/skia/modules", - "mkdir -p ./cpp/skia/src", - - "cp -a ../../externals/skia/include/. ./cpp/skia/include", - ...copyModule("svg"), - ...copyModule("skresources"), - ...copyModule("skparagraph"), - ...copyModule("skshaper"), - "cp -a ../../externals/skia/modules/skcms/. ./cpp/skia/modules/skcms", - "mkdir -p ./cpp/skia/src/", - "mkdir -p ./cpp/skia/src/core/", - "cp -a ../../externals/skia/src/core/SkChecksum.h ./cpp/skia/src/core/.", - "cp -a ../../externals/skia/src/core/SkTHash.h ./cpp/skia/src/core/.", - - "mkdir -p ./cpp/skia/src/gpu/ganesh/gl", - "cp -a ../../externals/skia/src/gpu/ganesh/gl/GrGLDefines.h ./cpp/skia/src/gpu/ganesh/gl/.", - - "cp -a ../../externals/skia/src/core/SkLRUCache.h ./cpp/skia/src/core/.", - - "mkdir -p ./cpp/skia/src/base", - "cp -a ../../externals/skia/src/base/SkTLazy.h ./cpp/skia/src/base/.", - "cp -a ../../externals/skia/src/base/SkMathPriv.h ./cpp/skia/src/base/.", - "cp -a ../../externals/skia/src/base/SkTInternalLList.h ./cpp/skia/src/base/.", - "cp -a ../../externals/skia/src/base/SkUTF.h ./cpp/skia/src/base/.", - - "mkdir -p ./cpp/skia/modules/skunicode/include/", - "cp -a ../../externals/skia/modules/skunicode/include/SkUnicode.h ./cpp/skia/modules/skunicode/include/.", - - // Remove migrated headers - //grep -R "Delete this after migrating clients" cpp - "rm -rf ./cpp/skia/include/gpu/GrContextThreadSafeProxy.h", - "rm -rf ./cpp/skia/include/gpu/GrDirectContext.h", - "rm -rf ./cpp/skia/include/gpu/GrBackendSemaphore.h", - "rm -rf ./cpp/skia/include/gpu/mock/GrMockTypes.h", - "rm -rf ./cpp/skia/include/gpu/GrDriverBugWorkaroundsAutogen.h", - "rm -rf ./cpp/skia/include/gpu/GrTypes.h", - "rm -rf ./cpp/skia/include/gpu/vk/GrVkTypes.h", - "rm -rf ./cpp/skia/include/gpu/GrDriverBugWorkarounds.h", - "rm -rf ./cpp/skia/include/gpu/GrContextOptions.h", - "rm -rf ./cpp/skia/include/gpu/gl/GrGLExtensions.h", - "rm -rf ./cpp/skia/include/gpu/gl/GrGLAssembleInterface.h", - "rm -rf ./cpp/skia/include/gpu/gl/GrGLTypes.h", - "rm -rf ./cpp/skia/include/gpu/gl/GrGLConfig.h", - "rm -rf ./cpp/skia/include/gpu/gl/GrGLFunctions.h", - "rm -rf ./cpp/skia/include/gpu/gl/GrGLAssembleHelpers.h", - "rm -rf ./cpp/skia/include/gpu/gl/GrGLInterface.h", - "rm -rf ./cpp/skia/include/gpu/GrYUVABackendTextures.h", - "rm -rf ./cpp/skia/include/gpu/GrRecordingContext.h", - "rm -rf ./cpp/skia/include/gpu/GrBackendSurface.h", - "rm -rf ./cpp/skia/include/gpu/d3d/GrD3DBackendContext.h", - "rm -rf ./cpp/skia/include/gpu/d3d/GrD3DTypes.h", -].map((cmd) => { - console.log(cmd); - executeCmdSync(cmd); -}); diff --git a/packages/skia/scripts/skia-configuration.ts b/packages/skia/scripts/skia-configuration.ts index 554a4f69b0..e76699afc9 100644 --- a/packages/skia/scripts/skia-configuration.ts +++ b/packages/skia/scripts/skia-configuration.ts @@ -1,3 +1,12 @@ +import path from "path"; + +import { $ } from "./utils"; + +export const SkiaSrc = path.join(__dirname, "../../../externals/skia"); +export const ProjectRoot = path.join(__dirname, "../../.."); +export const PackageRoot = path.join(__dirname, ".."); +export const OutFolder = path.join(SkiaSrc, "out"); + const NdkDir: string = process.env.ANDROID_NDK ?? ""; export const BUILD_WITH_PARAGRAPH = true; @@ -56,6 +65,7 @@ export const commonArgs = [ ["skia_enable_flutter_defines", true], ["paragraph_tests_enabled", false], ["is_component_build", false], + // ["skia_enable_graphite", true], ]; export type PlatformName = "ios" | "android"; @@ -67,7 +77,7 @@ export type Target = { output?: string; options?: Arg[]; }; -export type Configuration = { [K in PlatformName]: Platform }; + export type Platform = { targets: { [key: string]: Target }; args: Arg[]; @@ -76,7 +86,7 @@ export type Platform = { options?: Arg[]; }; -export const configurations: Configuration = { +export const configurations = { android: { targets: { arm: { @@ -166,3 +176,72 @@ export const configurations: Configuration = { ], }, }; + +const copyModule = (module: string) => [ + `mkdir -p ./cpp/skia/modules/${module}/include`, + `cp -a ../../externals/skia/modules/${module}/include/. ./cpp/skia/modules/${module}/include`, +]; + +export const copyHeaders = () => { + process.chdir(PackageRoot); + [ + "rm -rf ./cpp/skia", + + "mkdir -p ./cpp/skia", + "mkdir -p ./cpp/skia/include", + "mkdir -p ./cpp/skia/modules", + "mkdir -p ./cpp/skia/src", + + "cp -a ../../externals/skia/include/. ./cpp/skia/include", + ...copyModule("svg"), + ...copyModule("skresources"), + ...copyModule("skparagraph"), + ...copyModule("skshaper"), + "cp -a ../../externals/skia/modules/skcms/. ./cpp/skia/modules/skcms", + "mkdir -p ./cpp/skia/src/", + "mkdir -p ./cpp/skia/src/core/", + "cp -a ../../externals/skia/src/core/SkChecksum.h ./cpp/skia/src/core/.", + "cp -a ../../externals/skia/src/core/SkTHash.h ./cpp/skia/src/core/.", + + "mkdir -p ./cpp/skia/src/gpu/ganesh/gl", + "cp -a ../../externals/skia/src/gpu/ganesh/gl/GrGLDefines.h ./cpp/skia/src/gpu/ganesh/gl/.", + + "cp -a ../../externals/skia/src/core/SkLRUCache.h ./cpp/skia/src/core/.", + + "mkdir -p ./cpp/skia/src/base", + "cp -a ../../externals/skia/src/base/SkTLazy.h ./cpp/skia/src/base/.", + "cp -a ../../externals/skia/src/base/SkMathPriv.h ./cpp/skia/src/base/.", + "cp -a ../../externals/skia/src/base/SkTInternalLList.h ./cpp/skia/src/base/.", + "cp -a ../../externals/skia/src/base/SkUTF.h ./cpp/skia/src/base/.", + + "mkdir -p ./cpp/skia/modules/skunicode/include/", + "cp -a ../../externals/skia/modules/skunicode/include/SkUnicode.h ./cpp/skia/modules/skunicode/include/.", + + // Remove migrated headers + //grep -R "Delete this after migrating clients" cpp + "rm -rf ./cpp/skia/include/gpu/GrContextThreadSafeProxy.h", + "rm -rf ./cpp/skia/include/gpu/GrDirectContext.h", + "rm -rf ./cpp/skia/include/gpu/GrBackendSemaphore.h", + "rm -rf ./cpp/skia/include/gpu/mock/GrMockTypes.h", + "rm -rf ./cpp/skia/include/gpu/GrDriverBugWorkaroundsAutogen.h", + "rm -rf ./cpp/skia/include/gpu/GrTypes.h", + "rm -rf ./cpp/skia/include/gpu/vk/GrVkTypes.h", + "rm -rf ./cpp/skia/include/gpu/GrDriverBugWorkarounds.h", + "rm -rf ./cpp/skia/include/gpu/GrContextOptions.h", + "rm -rf ./cpp/skia/include/gpu/gl/GrGLExtensions.h", + "rm -rf ./cpp/skia/include/gpu/gl/GrGLAssembleInterface.h", + "rm -rf ./cpp/skia/include/gpu/gl/GrGLTypes.h", + "rm -rf ./cpp/skia/include/gpu/gl/GrGLConfig.h", + "rm -rf ./cpp/skia/include/gpu/gl/GrGLFunctions.h", + "rm -rf ./cpp/skia/include/gpu/gl/GrGLAssembleHelpers.h", + "rm -rf ./cpp/skia/include/gpu/gl/GrGLInterface.h", + "rm -rf ./cpp/skia/include/gpu/GrYUVABackendTextures.h", + "rm -rf ./cpp/skia/include/gpu/GrRecordingContext.h", + "rm -rf ./cpp/skia/include/gpu/GrBackendSurface.h", + "rm -rf ./cpp/skia/include/gpu/d3d/GrD3DBackendContext.h", + "rm -rf ./cpp/skia/include/gpu/d3d/GrD3DTypes.h", + ].map((cmd) => { + console.log(cmd); + $(cmd); + }); +}; diff --git a/packages/skia/scripts/utils.ts b/packages/skia/scripts/utils.ts index 11777d187c..6a96cab4d0 100644 --- a/packages/skia/scripts/utils.ts +++ b/packages/skia/scripts/utils.ts @@ -1,44 +1,12 @@ -import { exec, execSync } from "child_process"; +import { spawn, execSync } from "child_process"; +import { copyFileSync, existsSync, mkdirSync, readdirSync, statSync } from "fs"; import { exit } from "process"; import path from "path"; -import fs from "fs"; - -export const executeCmdSync = (command: string) => { - try { - return execSync(command); - } catch (e) { - exit(1); - } -}; - -export const executeCmd = ( - command: string, - label: string, - callback: () => void -) => { - const proc = exec(command, { env: process.env }, callback); - if (proc) { - proc.stdout?.on("data", function (data) { - console.log(`[${label}]:`, data.trim()); - }); - proc.stderr?.on("data", function (data) { - console.error(`[${label}]:`, data.trim()); - }); - proc.on("close", function (code) { - if (code) { - console.log(`[${label}] exited with code ${code}`); - exit(code); - } - }); - } -}; - -export const getDistFolder = () => "./dist"; export const ensureFolderExists = (dirPath: string) => { try { console.log(`Ensuring that ${dirPath} exists...`); - fs.mkdirSync(dirPath, { recursive: true }); + mkdirSync(dirPath, { recursive: true }); } catch (err) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore @@ -48,68 +16,98 @@ export const ensureFolderExists = (dirPath: string) => { } }; -export const checkFileExists = ( - filePath: string, - message: string, - error: string -) => { - const exists = fs.existsSync(filePath); +export const runAsync = (command: string, label: string): Promise => { + return new Promise((resolve, reject) => { + const [cmd, ...args] = command.split(" "); + console.log({ cmd, args }); + const childProcess = spawn(cmd, args, { + shell: true, + }); + + childProcess.stdout.on("data", (data) => { + process.stdout.write(`${label} ${data}`); + }); + + childProcess.stderr.on("data", (data) => { + console.error(`${label} ${data}`); + }); + + childProcess.on("close", (code) => { + if (code === 0) { + resolve(); + } else { + reject(new Error(`${label} exited with code ${code}`)); + } + }); + + childProcess.on("error", (error) => { + reject(new Error(`${label} ${error.message}`)); + }); + }); +}; + +export const mapKeys = (obj: T) => + Object.keys(obj) as (keyof T)[]; + +export const checkFileExists = (filePath: string) => { + const exists = existsSync(filePath); if (!exists) { console.log(""); console.log("Failed:"); - console.log(message + " not found. (" + filePath + ")"); - console.log(error); + console.log(filePath + " not found. (" + filePath + ")"); console.log(""); exit(1); } else { - console.log("☑ " + message); + console.log("✅ " + filePath); } }; -const getBackupFilename = (filePath: string) => filePath + ".bak"; - -export const backupAndCopyFile = ( - filePathToBeReplacedAndBackedUp: string, - filePathToCopy: string -) => { - // Back up and replace - console.log(`Backing up and replacing ${filePathToBeReplacedAndBackedUp}...`); - const backupFilePath = getBackupFilename(filePathToBeReplacedAndBackedUp); - fs.renameSync(filePathToBeReplacedAndBackedUp, backupFilePath); +export const $ = (command: string) => { + try { + return execSync(command); + } catch (e) { + exit(1); + } +}; - // Copy the Package file from the npm folder - fs.copyFileSync(filePathToCopy, filePathToBeReplacedAndBackedUp); +const serializeCMakeArgs = (args: Record) => { + return Object.keys(args) + .map((key) => `-D${key}=${args[key]}`) + .join(" "); }; -export const restoreFile = (filePathToBeRestored: string) => { - console.log(`Restoring ${getBackupFilename(filePathToBeRestored)}...`); - fs.unlinkSync(filePathToBeRestored); - fs.renameSync(getBackupFilename(filePathToBeRestored), filePathToBeRestored); +export const build = async ( + label: string, + args: Record, + debugLabel: string +) => { + console.log(`🔨 Building ${label}`); + $(`mkdir -p externals/dawn/out/${label}`); + process.chdir(`externals/dawn/out/${label}`); + const cmd = `cmake ../.. -G Ninja ${serializeCMakeArgs(args)}`; + await runAsync(cmd, debugLabel); + await runAsync("ninja", debugLabel); + process.chdir("../../../.."); }; -/** - * Look ma, it's cp -R. - * @param {string} src The path to the thing to copy. - * @param {string} dest The path to the new copy. - */ export var copyRecursiveSync = function (src: string, dest: string) { - var exists = fs.existsSync(src); + var exists = existsSync(src); if (!exists) { return; } - var stats = fs.statSync(src); + var stats = statSync(src); var isDirectory = stats.isDirectory(); if (isDirectory) { - if (!fs.existsSync(dest)) { - fs.mkdirSync(dest); + if (!existsSync(dest)) { + mkdirSync(dest); } - fs.readdirSync(src).forEach((childItemName) => { + readdirSync(src).forEach((childItemName) => { copyRecursiveSync( path.join(src, childItemName), path.join(dest, childItemName) ); }); } else { - fs.copyFileSync(src, dest); + copyFileSync(src, dest); } }; diff --git a/packages/skia/scripts/workflow-copy-libs.ts b/packages/skia/scripts/workflow-copy-libs.ts index b29e41b338..ca4d0465eb 100644 --- a/packages/skia/scripts/workflow-copy-libs.ts +++ b/packages/skia/scripts/workflow-copy-libs.ts @@ -1,4 +1,4 @@ -import fs from "fs"; +import { existsSync } from "fs"; import { ensureFolderExists, copyRecursiveSync } from "./utils"; /** @@ -45,7 +45,7 @@ const copyFiles = (from: string, to: string, files: string[]) => { files.forEach((f) => { const source = "./artifacts/" + from + "/" + f; const target = to + "/" + f; - if (!fs.existsSync(source)) { + if (!existsSync(source)) { console.log( "Copying failed, the artifact source", source, @@ -54,7 +54,7 @@ const copyFiles = (from: string, to: string, files: string[]) => { ); process.exit(1); } - if (!fs.existsSync(to)) { + if (!existsSync(to)) { console.log( "Copying failed, the destination", to,