Meta: Add third-party libraries to gn build with vcpkg install script

The vcpkg install is handled through an action to run vcpkg install with
the private --x-install-root flag that their CMake toolchain file uses
to install dependencies into a build-time directory.
This commit is contained in:
Andrew Kaster 2024-09-25 12:27:23 -06:00 committed by Andrew Kaster
parent aa1bf3e8a4
commit 6ee1afc9c0
Notes: github-actions[bot] 2024-09-27 16:17:09 +00:00
23 changed files with 457 additions and 8 deletions

View file

@ -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())

View file

@ -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),
]
}

View file

@ -0,0 +1,9 @@
import("//Meta/gn/build/libs/third_party.gni")
third_party_dependency("avif") {
libs = [
"avif",
"dav1d",
"yuv",
]
}

View file

@ -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",
]
}
}

View file

@ -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" ]
}
}

View file

@ -0,0 +1,4 @@
declare_args() {
# Select whether to build with ffmpeg support in LibMedia
enable_ffmpeg = true
}

View file

@ -0,0 +1,5 @@
import("//Meta/gn/build/libs/third_party.gni")
third_party_dependency("fontconfig") {
libs = [ "fontconfig" ]
}

View file

@ -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" ]
}
}

View file

@ -0,0 +1,9 @@
import("//Meta/gn/build/libs/third_party.gni")
third_party_dependency("icu") {
libs = [
"icui18n",
"icuuc",
"icudata",
]
}

View file

@ -0,0 +1,5 @@
import("//Meta/gn/build/libs/third_party.gni")
third_party_dependency("jpeg") {
libs = [ "jpeg" ]
}

View file

@ -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",
]
}

View file

@ -0,0 +1,9 @@
import("//Meta/gn/build/libs/third_party.gni")
third_party_dependency("png") {
third_party_includes = [ "libpng16" ]
libs = [
"png16",
"z",
]
}

View file

@ -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" ]
}

View file

@ -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",
]
}
}

View file

@ -0,0 +1,5 @@
import("//Meta/gn/build/libs/third_party.gni")
third_party_dependency("sqlite3") {
libs = [ "sqlite3" ]
}

View file

@ -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
}
}
}

View file

@ -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
}

View file

@ -0,0 +1,4 @@
declare_args() {
# Select whether to build with Vulkan support
enable_vulkan = current_os == "linux"
}

View file

@ -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",
]
}

View file

@ -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",
]
}

View file

@ -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

View file

@ -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++"
}

32
Meta/gn/build/vcpkg.gni Normal file
View file

@ -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}"
}