native/wasm/build.cake (131 lines of code) (raw):

DirectoryPath ROOT_PATH = MakeAbsolute(Directory("../..")); DirectoryPath OUTPUT_PATH = MakeAbsolute(ROOT_PATH.Combine("output/native")); #load "../../scripts/cake/native-shared.cake" string SUPPORT_GPU_VAR = Argument("supportGpu", EnvironmentVariable("SUPPORT_GPU") ?? "true").ToLower(); string EMSCRIPTEN_ROOT = Argument("emscripten", EnvironmentVariable("EMSCRIPTEN_SDK_ROOT") ?? EnvironmentVariable("EMSDK") ?? ""); string EMSCRIPTEN_VERSION = Argument("emscriptenVersion", EnvironmentVariable("EMSCRIPTEN_VERSION") ?? "").ToLower(); string[] EMSCRIPTEN_FEATURES = Argument("emscriptenFeatures", EnvironmentVariable("EMSCRIPTEN_FEATURES") ?? "").ToLower() .Split(",").Where(f => f != "none").ToArray(); bool SUPPORT_GPU = SUPPORT_GPU_VAR == "1" || SUPPORT_GPU_VAR == "true"; string CC = Argument("cc", "emcc"); string CXX = Argument("cxx", "em++"); string AR = Argument("ar", "emar"); string COMPILERS = $"cc='{CC}' cxx='{CXX}' ar='{AR}' "; Task("libSkiaSharp") .IsDependentOn("git-sync-deps") .WithCriteria(IsRunningOnLinux()) .Does(() => { bool hasSimdEnabled = EMSCRIPTEN_FEATURES.Contains("simd") || EMSCRIPTEN_FEATURES.Contains("_simd"); bool hasThreadingEnabled = EMSCRIPTEN_FEATURES.Contains("mt"); bool hasWasmEH = EMSCRIPTEN_FEATURES.Contains("_wasmeh"); var emscriptenFeaturesModifiers = EMSCRIPTEN_FEATURES .Where(f => !f.StartsWith("_")) .ToArray(); GnNinja($"wasm", "SkiaSharp", $"target_os='linux' " + $"target_cpu='wasm' " + $"is_static_skiasharp=true " + $"skia_enable_fontmgr_custom_directory=false " + $"skia_enable_fontmgr_custom_empty=false " + $"skia_enable_fontmgr_custom_embedded=true " + $"skia_enable_fontmgr_empty=false " + $"skia_enable_ganesh={(SUPPORT_GPU ? "true" : "false")} " + (SUPPORT_GPU ? "skia_gl_standard='webgl'" : "") + $"skia_enable_pdf=true " + $"skia_use_dng_sdk=false " + $"skia_use_webgl=true " + $"skia_use_fontconfig=false " + $"skia_use_freetype=true " + $"skia_use_harfbuzz=false " + $"skia_use_icu=false " + $"skia_use_piex=false " + $"skia_use_sfntly=false " + $"skia_use_expat=true " + $"skia_use_libwebp_encode=true " + $"skia_use_system_expat=false " + $"skia_use_system_freetype2=false " + $"skia_use_system_libjpeg_turbo=false " + $"skia_use_system_libpng=false " + $"skia_use_system_libwebp=false " + $"skia_use_system_zlib=false " + $"skia_use_vulkan=false " + $"skia_use_wuffs=true " + $"skia_enable_skottie=true " + $"use_PIC=false " + $"extra_cflags=[ " + $" '-DSKIA_C_DLL', '-DXML_POOR_ENTROPY', " + $" {(!hasSimdEnabled ? "'-DSKNX_NO_SIMD', " : "")} '-DSK_DISABLE_AAA', '-DGR_GL_CHECK_ALLOC_WITH_GET_ERROR=0', " + $" '-s', 'WARN_UNALIGNED=1' " + // '-s', 'USE_WEBGL2=1' (experimental) $" { (hasSimdEnabled ? ", '-msimd128'" : "") } " + $" { (hasThreadingEnabled ? ", '-pthread'" : "") } " + $" { (hasWasmEH ? ", '-fwasm-exceptions'" : "") } " + $"] " + // SIMD support is based on https://github.com/google/skia/blob/1f193df9b393d50da39570dab77a0bb5d28ec8ef/modules/canvaskit/compile.sh#L57 $"extra_cflags_cc=[ '-frtti' { (hasSimdEnabled ? ", '-msimd128'" : "") } { (hasThreadingEnabled ? ", '-pthread'" : "") } { (hasWasmEH ? ", '-fwasm-exceptions'" : "") } ] " + $"skia_emsdk_dir='{EMSCRIPTEN_ROOT}'" + COMPILERS + ADDITIONAL_GN_ARGS); var a = SKIA_PATH.CombineWithFilePath($"out/wasm/libSkiaSharp.a"); // separate all the .a files into .o files var skiaOut = SKIA_PATH.Combine("out/wasm"); var mergeDir = skiaOut.Combine("obj/merge"); EnsureDirectoryExists(mergeDir); CleanDirectories(mergeDir.FullPath); foreach (var file in GetFiles($"{skiaOut}/*.a")) { RunProcess(AR, new ProcessSettings { Arguments = $"x \"{file}\"", WorkingDirectory = mergeDir.FullPath, }); } // add the default font var input = SKIA_PATH.CombineWithFilePath("modules/canvaskit/fonts/NotoMono-Regular.ttf"); var embed_resources = SKIA_PATH.CombineWithFilePath("tools/embed_resources.py"); RunProcess(PYTHON_EXE, new ProcessSettings { Arguments = $"{embed_resources} --name SK_EMBEDDED_FONTS --input {input} --output {input}.cpp --align 4", WorkingDirectory = SKIA_PATH.FullPath, }); RunProcess(CC, $"-std=c++17 -I. {input}.cpp -r -o {mergeDir}/NotoMonoRegularttf.o"); // merge all the .o files into the final .a file var oFiles = GetFiles($"{mergeDir}/*.o"); RunProcess(AR, $"-crs {a} {string.Join(" ", oFiles)}"); var outDir = OUTPUT_PATH.Combine($"wasm"); if (!string.IsNullOrEmpty(EMSCRIPTEN_VERSION)) outDir = outDir.Combine("libSkiaSharp.a").Combine(EMSCRIPTEN_VERSION); if (emscriptenFeaturesModifiers.Length != 0) outDir = outDir.Combine(string.Join(",", emscriptenFeaturesModifiers)); EnsureDirectoryExists(outDir); CopyFileToDirectory(a, outDir); }); Task("libHarfBuzzSharp") .WithCriteria(IsRunningOnLinux()) .Does(() => { bool hasSimdEnabled = EMSCRIPTEN_FEATURES.Contains("simd") || EMSCRIPTEN_FEATURES.Contains("_simd"); bool hasThreadingEnabled = EMSCRIPTEN_FEATURES.Contains("mt"); bool hasWasmEH = EMSCRIPTEN_FEATURES.Contains("_wasmeh"); var emscriptenFeaturesModifiers = EMSCRIPTEN_FEATURES .Where(f => !f.StartsWith("_")) .ToArray(); GnNinja($"wasm", "HarfBuzzSharp", $"target_os='linux' " + $"target_cpu='wasm' " + $"is_static_skiasharp=true " + $"visibility_hidden=false " + $"extra_cflags=[ '-s', 'WARN_UNALIGNED=1' { (hasSimdEnabled ? ", '-msimd128'" : "") } { (hasThreadingEnabled ? ", '-pthread'" : "") } { (hasWasmEH ? ", '-fwasm-exceptions'" : "") } ] " + $"extra_cflags_cc=[ '-frtti' { (hasSimdEnabled ? ", '-msimd128'" : "") } { (hasThreadingEnabled ? ", '-pthread'" : "") } { (hasWasmEH ? ", '-fwasm-exceptions'" : "") } ] " + $"skia_emsdk_dir='{EMSCRIPTEN_ROOT}'" + COMPILERS + ADDITIONAL_GN_ARGS); var outDir = OUTPUT_PATH.Combine($"wasm"); if (!string.IsNullOrEmpty(EMSCRIPTEN_VERSION)) outDir = outDir.Combine("libHarfBuzzSharp.a").Combine(EMSCRIPTEN_VERSION); if (emscriptenFeaturesModifiers.Length != 0) outDir = outDir.Combine(string.Join(",", emscriptenFeaturesModifiers)); EnsureDirectoryExists(outDir); var so = SKIA_PATH.CombineWithFilePath($"out/wasm/libHarfBuzzSharp.a"); CopyFileToDirectory(so, outDir); CopyFile(so, outDir.CombineWithFilePath("libHarfBuzzSharp.a")); }); Task("Default") .IsDependentOn("libSkiaSharp") .IsDependentOn("libHarfBuzzSharp"); RunTarget(TARGET);