diff --git a/Meta/gn/build/install_vcpkg.py b/Meta/gn/build/install_vcpkg.py new file mode 100644 index 00000000000..151a132f8e8 --- /dev/null +++ b/Meta/gn/build/install_vcpkg.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 + +import argparse +import os +import pathlib +import subprocess +import sys + + +def main(): + parser = argparse.ArgumentParser(description='Install vcpkg dependencies') + parser.add_argument('--cc', type=str, required=True, help='The C compiler to use') + parser.add_argument('--cxx', type=str, required=True, help='The C++ compiler to use') + parser.add_argument('--manifest', type=str, required=True, help='The vcpkg manifest to install') + parser.add_argument('--vcpkg', type=str, required=True, help='The path to the vcpkg executable') + parser.add_argument('--vcpkg-root', type=str, required=True, help='The path to the vcpkg root directory') + parser.add_argument('--vcpkg-triplet', type=str, required=True, help='The vcpkg triplet to use') + parser.add_argument('--vcpkg-overlay-triplets', type=str, help='Path to a vcpkg overlay triplets directory') + parser.add_argument('--vcpkg-binary-cache-dir', type=str, help='Path to a vcpkg binary cache directory') + parser.add_argument('--stamp-file', type=str, help='Path to a file to touch after installation') + parser.add_argument('install_directory', type=str, help='The directory to install vcpkg deps into') + args = parser.parse_args() + + manifest_directory = pathlib.Path(args.manifest).parent + + env = os.environ.copy() + env['CC'] = args.cc + env['CXX'] = args.cxx + + vcpkg_arguments = [ + args.vcpkg, + 'install', + '--no-print-usage', + '--x-wait-for-lock', + f'--triplet={args.vcpkg_triplet}', + f'--vcpkg-root={args.vcpkg_root}', + f'--x-manifest-root={manifest_directory}', + f'--x-install-root={args.install_directory}' + ] + + if args.vcpkg_overlay_triplets: + vcpkg_arguments += [f'--overlay-triplets={args.vcpkg_overlay_triplets}'] + if args.vcpkg_binary_cache_dir: + binary_cache_dir = pathlib.Path(args.vcpkg_binary_cache_dir).absolute() + vcpkg_arguments += [f'--binarysource=clear;files,{binary_cache_dir},readwrite'] + + subprocess.run(vcpkg_arguments, env=env, check=True) + + if args.stamp_file: + pathlib.Path(args.stamp_file).touch() + + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/Meta/gn/build/libs/BUILD.gn b/Meta/gn/build/libs/BUILD.gn new file mode 100644 index 00000000000..768ccdc059a --- /dev/null +++ b/Meta/gn/build/libs/BUILD.gn @@ -0,0 +1,43 @@ +import("//Meta/gn/build/buildflags.gni") +import("//Meta/gn/build/toolchain/compiler.gni") +import("//Meta/gn/build/vcpkg.gni") + +action("install_vcpkg_manifest") { + script = "//Meta/gn/build/install_vcpkg.py" + + overlay_triplet_root = "//Meta/CMake/vcpkg" + config_name = "release" + if (is_debug) { + config_name = "debug" + } + + # FIXME: if (is_sanitizer) vcpkg_config_name = "sanitizer" + overlay_triplet_path = "${overlay_triplet_root}/${config_name}-triplets" + + stamp_file = "${vcpkg_install_root}/.vcpkg_installed-${vcpkg_triplet}-${config_name}.stamp" + + sources = [ vcpkg_manifest ] + outputs = [ stamp_file ] + + args = [ + "--cc", + "${host_cc}", + "--cxx", + "${host_cxx}", + "--manifest", + rebase_path(vcpkg_manifest, root_build_dir), + "--vcpkg", + rebase_path(vcpkg_binary, root_build_dir), + "--vcpkg-root", + rebase_path(vcpkg_root, root_build_dir), + "--vcpkg-triplet", + vcpkg_triplet, + "--vcpkg-overlay-triplets", + rebase_path(overlay_triplet_path, root_build_dir), + "--vcpkg-binary-cache", + rebase_path(vcpkg_binary_cache, root_build_dir), + "--stamp-file", + rebase_path(stamp_file, root_build_dir), + rebase_path(vcpkg_install_root, root_build_dir), + ] +} diff --git a/Meta/gn/build/libs/avif/BUILD.gn b/Meta/gn/build/libs/avif/BUILD.gn new file mode 100644 index 00000000000..2b351e949a9 --- /dev/null +++ b/Meta/gn/build/libs/avif/BUILD.gn @@ -0,0 +1,9 @@ +import("//Meta/gn/build/libs/third_party.gni") + +third_party_dependency("avif") { + libs = [ + "avif", + "dav1d", + "yuv", + ] +} diff --git a/Meta/gn/build/libs/curl/BUILD.gn b/Meta/gn/build/libs/curl/BUILD.gn new file mode 100644 index 00000000000..d09df9d3f66 --- /dev/null +++ b/Meta/gn/build/libs/curl/BUILD.gn @@ -0,0 +1,24 @@ +import("//Meta/gn/build/libs/third_party.gni") + +third_party_dependency("curl") { + libs = [ + "curl", + "z", + "brotlidec", + "brotlicommon", + "nghttp2", + ] + if (current_os == "mac") { + frameworks = [ + "SystemConfiguration.framework", + "Security.framework", + "CoreFoundation.framework", + "CoreServices.framework", + ] + } else { + libs += [ + "ssl", + "crypto", + ] + } +} diff --git a/Meta/gn/build/libs/ffmpeg/BUILD.gn b/Meta/gn/build/libs/ffmpeg/BUILD.gn new file mode 100644 index 00000000000..6eb87aaa351 --- /dev/null +++ b/Meta/gn/build/libs/ffmpeg/BUILD.gn @@ -0,0 +1,37 @@ +import("//Meta/gn/build/libs/ffmpeg/enable.gni") + +declare_args() { + # Select whether to look for ffmpeg in the homebrew installation + ffmpeg_homebrew = current_os == "mac" + + # Root directory for the homebrew installation + homebrew_prefix = "/opt/homebrew" +} + +declare_args() { + # Root directory for the ffmpeg installation, e.g. from brew --prefix ffmpeg + ffmpeg_prefix = "/usr" + if (ffmpeg_homebrew) { + ffmpeg_prefix = "${homebrew_prefix}/opt/ffmpeg" + } +} + +# FIXME: We don't build this, we pull it from the user's system +# So it doesn't follow the usual third_party_dependency pattern +config("ffmpeg_config") { + visibility = [ ":ffmpeg" ] + include_dirs = [ "${ffmpeg_prefix}/include" ] + lib_dirs = [ "${ffmpeg_prefix}/lib" ] + libs = [ + "avcodec", + "avformat", + "avutil", + ] + defines = [ "USE_FFMPEG" ] +} + +group("ffmpeg") { + if (enable_ffmpeg) { + public_configs = [ ":ffmpeg_config" ] + } +} diff --git a/Meta/gn/build/libs/ffmpeg/enable.gni b/Meta/gn/build/libs/ffmpeg/enable.gni new file mode 100644 index 00000000000..b2dbbf6a2eb --- /dev/null +++ b/Meta/gn/build/libs/ffmpeg/enable.gni @@ -0,0 +1,4 @@ +declare_args() { + # Select whether to build with ffmpeg support in LibMedia + enable_ffmpeg = true +} diff --git a/Meta/gn/build/libs/fontconfig/BUILD.gn b/Meta/gn/build/libs/fontconfig/BUILD.gn new file mode 100644 index 00000000000..67e58869d87 --- /dev/null +++ b/Meta/gn/build/libs/fontconfig/BUILD.gn @@ -0,0 +1,5 @@ +import("//Meta/gn/build/libs/third_party.gni") + +third_party_dependency("fontconfig") { + libs = [ "fontconfig" ] +} diff --git a/Meta/gn/build/libs/harfbuzz/BUILD.gn b/Meta/gn/build/libs/harfbuzz/BUILD.gn new file mode 100644 index 00000000000..0e36bbe7081 --- /dev/null +++ b/Meta/gn/build/libs/harfbuzz/BUILD.gn @@ -0,0 +1,16 @@ +import("//Meta/gn/build/libs/third_party.gni") + +third_party_dependency("harfbuzz") { + libs = [ + "harfbuzz", + "freetype", + "z", + "bz2", + "png16", + "brotlidec", + "brotlicommon", + ] + if (current_os == "mac") { + frameworks = [ "ApplicationServices.framework" ] + } +} diff --git a/Meta/gn/build/libs/icu/BUILD.gn b/Meta/gn/build/libs/icu/BUILD.gn new file mode 100644 index 00000000000..de65b1b9a0f --- /dev/null +++ b/Meta/gn/build/libs/icu/BUILD.gn @@ -0,0 +1,9 @@ +import("//Meta/gn/build/libs/third_party.gni") + +third_party_dependency("icu") { + libs = [ + "icui18n", + "icuuc", + "icudata", + ] +} diff --git a/Meta/gn/build/libs/jpeg/BUILD.gn b/Meta/gn/build/libs/jpeg/BUILD.gn new file mode 100644 index 00000000000..dc3fe1a106c --- /dev/null +++ b/Meta/gn/build/libs/jpeg/BUILD.gn @@ -0,0 +1,5 @@ +import("//Meta/gn/build/libs/third_party.gni") + +third_party_dependency("jpeg") { + libs = [ "jpeg" ] +} diff --git a/Meta/gn/build/libs/jxl/BUILD.gn b/Meta/gn/build/libs/jxl/BUILD.gn new file mode 100644 index 00000000000..bc071f02587 --- /dev/null +++ b/Meta/gn/build/libs/jxl/BUILD.gn @@ -0,0 +1,20 @@ +import("//Meta/gn/build/libs/third_party.gni") + +third_party_dependency("jxl") { + libs = [ + "jxl", + "hwy", + "brotlienc", + "brotlidec", + "brotlicommon", + "jxl_cms", + "lcms2", + ] + defines = [ + # FIXME: These static defines depend on whether you built jxl as static or not... + "JXL_STATIC_DEFINE", + "JXL_CMS_STATIC_DEFINE", + "HWY_STATIC_DEFINE", + "CMS_NO_REGISTER_KEYWORD", + ] +} diff --git a/Meta/gn/build/libs/png/BUILD.gn b/Meta/gn/build/libs/png/BUILD.gn new file mode 100644 index 00000000000..375219120b1 --- /dev/null +++ b/Meta/gn/build/libs/png/BUILD.gn @@ -0,0 +1,9 @@ +import("//Meta/gn/build/libs/third_party.gni") + +third_party_dependency("png") { + third_party_includes = [ "libpng16" ] + libs = [ + "png16", + "z", + ] +} diff --git a/Meta/gn/build/libs/simdutf/BUILD.gn b/Meta/gn/build/libs/simdutf/BUILD.gn new file mode 100644 index 00000000000..bb76497dc50 --- /dev/null +++ b/Meta/gn/build/libs/simdutf/BUILD.gn @@ -0,0 +1,6 @@ +import("//Meta/gn/build/libs/third_party.gni") + +third_party_dependency("simdutf") { + libs = [ "simdutf" ] + extra_public_configs = [ "//Meta/gn/build:pic" ] +} diff --git a/Meta/gn/build/libs/skia/BUILD.gn b/Meta/gn/build/libs/skia/BUILD.gn new file mode 100644 index 00000000000..0a8365962e6 --- /dev/null +++ b/Meta/gn/build/libs/skia/BUILD.gn @@ -0,0 +1,79 @@ +import("//Meta/gn/build/libs/third_party.gni") + +third_party_dependency("skia") { + third_party_includes = [ "skia" ] + libs = [ + "skia", + "fontconfig", + "expat", + "turbojpeg", + "jpeg", + "harfbuzz-subset", + "harfbuzz", + "freetype", + "bz2", + "brotlidec", + "brotlicommon", + "png16", + "z", + "webpdecoder", + "webpdemux", + "webpmux", + "webp", + "sharpyuv", + ] + if (current_os == "mac") { + frameworks = [ + "ApplicationServices.framework", + "OpenGL.framework", + "AppKit.framework", + "Metal.framework", + "Foundation.framework", + ] + } else { + libs += [ "GL" ] + } + + defines = [ + "SK_CODEC_DECODES_BMP", + "SK_CODEC_DECODES_WBMP", + "SK_ENABLE_PRECOMPILE", + "SK_GANESH", + "SK_DISABLE_TRACING", + "SK_USE_PERFETTO", + "SK_GAMMA_APPLY_TO_A8", + "SK_ENABLE_AVX512_OPTS", + "SK_TYPEFACE_FACTORY_FREETYPE", + "SK_FONTMGR_ANDROID_AVAILABLE", + "SK_FONTMGR_FREETYPE_DIRECTORY_AVAILABLE", + "SK_FONTMGR_FREETYPE_EMBEDDED_AVAILABLE", + "SK_FONTMGR_FREETYPE_EMPTY_AVAILABLE", + "SK_FONTMGR_FONTCONFIG_AVAILABLE", + "SK_GL", + "SK_SUPPORT_PDF", + "SK_CODEC_DECODES_JPEG", + "SK_CODEC_DECODES_ICO", + "SK_CODEC_DECODES_PNG", + "SK_CODEC_DECODES_RAW", + "SK_CODEC_DECODES_WEBP", + "SK_HAS_WUFFS_LIBRARY", + "SK_CODEC_DECODES_GIF", + "SK_XML", + ] + + if (current_os == "mac") { + defines += [ + "SK_ASSUME_GL=1", + "SK_ENABLE_API_AVAILABLE", + "SK_TYPEFACE_FACTORY_CORETEX", + "SK_FONTMGR_CORETEXT_AVAILABLE", + "SK_METAL", + ] + } else if (current_os == "linux") { + defines += [ + "SK_R32_SHIFT=16", + "SK_USE_VMA", + "SK_VULKAN", + ] + } +} diff --git a/Meta/gn/build/libs/sqlite3/BUILD.gn b/Meta/gn/build/libs/sqlite3/BUILD.gn new file mode 100644 index 00000000000..a0948218c2e --- /dev/null +++ b/Meta/gn/build/libs/sqlite3/BUILD.gn @@ -0,0 +1,5 @@ +import("//Meta/gn/build/libs/third_party.gni") + +third_party_dependency("sqlite3") { + libs = [ "sqlite3" ] +} diff --git a/Meta/gn/build/libs/third_party.gni b/Meta/gn/build/libs/third_party.gni new file mode 100644 index 00000000000..340add9b8a3 --- /dev/null +++ b/Meta/gn/build/libs/third_party.gni @@ -0,0 +1,57 @@ +import("//Meta/gn/build/vcpkg.gni") + +declare_args() { + # Whether to use vcpkg for dependency management + use_vcpkg = true +} + +declare_args() { + # Location to find installed third_party headers and libraries + third_party_prefix = "/usr" + if (use_vcpkg) { + third_party_prefix = "${vcpkg_install_root}/${vcpkg_triplet}" + } +} + +declare_args() { + # Library directory for third_party libraries + third_party_lib_dir = third_party_prefix + "/lib" + + # Include directory for third_party headers + third_party_include_dir = third_party_prefix + "/include" +} + +template("third_party_dependency") { + config("${target_name}_config") { + forward_variables_from(invoker, "*") + visibility = [ ":${target_name}" ] + include_dirs = [ "$third_party_include_dir" ] + if (defined(third_party_includes)) { + foreach(dir, third_party_includes) { + include_dirs += [ "$third_party_include_dir/$dir" ] + } + } + lib_dirs = [ "$third_party_lib_dir" ] + not_needed([ + "enable", + "extra_public_configs", + ]) + } + + group(target_name) { + forward_variables_from(invoker, + [ + "enable", + "extra_public_configs", + ]) + if (!defined(enable) || enable) { + public_configs = [ ":${target_name}_config" ] + if (use_vcpkg) { + deps = [ "//Meta/gn/build/libs:install_vcpkg_manifest" ] + } + } + if (defined(extra_public_configs)) { + public_configs += extra_public_configs + } + } +} diff --git a/Meta/gn/build/libs/vulkan/BUILD.gn b/Meta/gn/build/libs/vulkan/BUILD.gn new file mode 100644 index 00000000000..895629a4d54 --- /dev/null +++ b/Meta/gn/build/libs/vulkan/BUILD.gn @@ -0,0 +1,8 @@ +import("//Meta/gn/build/libs/third_party.gni") +import("//Meta/gn/build/libs/vulkan/enable.gni") + +third_party_dependency("vulkan") { + libs = [ "vulkan" ] + defines = [ "USE_VULKAN=1" ] + enable = enable_vulkan +} diff --git a/Meta/gn/build/libs/vulkan/enable.gni b/Meta/gn/build/libs/vulkan/enable.gni new file mode 100644 index 00000000000..929a0983011 --- /dev/null +++ b/Meta/gn/build/libs/vulkan/enable.gni @@ -0,0 +1,4 @@ +declare_args() { + # Select whether to build with Vulkan support + enable_vulkan = current_os == "linux" +} diff --git a/Meta/gn/build/libs/webp/BUILD.gn b/Meta/gn/build/libs/webp/BUILD.gn new file mode 100644 index 00000000000..240987029aa --- /dev/null +++ b/Meta/gn/build/libs/webp/BUILD.gn @@ -0,0 +1,12 @@ +import("//Meta/gn/build/libs/third_party.gni") + +third_party_dependency("webp") { + third_party_includes = [ "webp" ] + libs = [ + "webp", + "sharpyuv", + "webpdecoder", + "webpdemux", + "webpmux", + ] +} diff --git a/Meta/gn/build/libs/woff2/BUILD.gn b/Meta/gn/build/libs/woff2/BUILD.gn new file mode 100644 index 00000000000..4c38ddb0db9 --- /dev/null +++ b/Meta/gn/build/libs/woff2/BUILD.gn @@ -0,0 +1,11 @@ +import("//Meta/gn/build/libs/third_party.gni") + +third_party_dependency("woff2") { + third_party_includes = [ "woff2" ] + libs = [ + "woff2common", + "brotlidec", + "brotlicommon", + "woff2dec", + ] +} diff --git a/Meta/gn/build/toolchain/BUILD.gn b/Meta/gn/build/toolchain/BUILD.gn index 5b06349bb06..863a27ca27f 100644 --- a/Meta/gn/build/toolchain/BUILD.gn +++ b/Meta/gn/build/toolchain/BUILD.gn @@ -155,14 +155,6 @@ template("unix_toolchain") { } } -declare_args() { - # C compiler for native builds - host_cc = "cc" - - # C++ compiler for native builds - host_cxx = "c++" -} - unix_toolchain("unix") { toolchain_args = { current_os = host_os diff --git a/Meta/gn/build/toolchain/compiler.gni b/Meta/gn/build/toolchain/compiler.gni index b63399ecb8f..8e7ea8c023c 100644 --- a/Meta/gn/build/toolchain/compiler.gni +++ b/Meta/gn/build/toolchain/compiler.gni @@ -8,4 +8,10 @@ declare_args() { # Use ccache as a compiler launcher for compile and link jobs enable_ccache = true + + # C compiler for native builds + host_cc = "cc" + + # C++ compiler for native builds + host_cxx = "c++" } diff --git a/Meta/gn/build/vcpkg.gni b/Meta/gn/build/vcpkg.gni new file mode 100644 index 00000000000..72384094107 --- /dev/null +++ b/Meta/gn/build/vcpkg.gni @@ -0,0 +1,32 @@ +declare_args() { + # Root directory for vcpkg port files. Should be a checkout of microsoft/vcpkg. + vcpkg_root = "//Toolchain/Tarballs/vcpkg" + + # The os name to use for the default vcpkg triplet. + # If vcpkg_triplet is explicitly set, this is ignored. + vcpkg_os = current_os + if (current_os == "mac") { + vcpkg_os = "osx" + } else if (current_os == "win") { + vcpkg_os = "windows" + } + + # Location to cache vcpkg build artifacts. + vcpkg_binary_cache = "//Toolchain/Build/vcpkg-binary-cache" + + # Path to the vcpkg manifest file that describes all the vcpkg dependencies of the project + vcpkg_manifest = "//vcpkg.json" + + # The directory to install vcpkg dependencies into. + vcpkg_install_root = "${root_build_dir}/vcpkg_installed" +} + +declare_args() { + # Path to the vcpkg-tool binary, as bootstrapped in the vcpkg root directory. + vcpkg_binary = "${vcpkg_root}/vcpkg" +} + +declare_args() { + # The vcpkg triplet to use. If not set, it is derived from the current_os and current_cpu. + vcpkg_triplet = "${current_cpu}-${vcpkg_os}" +}