From 7747a5f2efd9ff5ae82eb4bfe4408e608e8f4234 Mon Sep 17 00:00:00 2001 From: Antonio Caggiano Date: Mon, 27 May 2024 15:54:00 +0200 Subject: [PATCH] angle: Patches Add ANGLE patches for installing libraries and headers with pkgconfig files. Then add a patch for allowing generation of brew bottle. Signed-off-by: Antonio Caggiano --- Patches/0001-gn-Add-install-target.patch | 255 +++++++++++++++++++++++ Patches/0002-gn-Headerpad-config.patch | 58 ++++++ 2 files changed, 313 insertions(+) create mode 100644 Patches/0001-gn-Add-install-target.patch create mode 100644 Patches/0002-gn-Headerpad-config.patch diff --git a/Patches/0001-gn-Add-install-target.patch b/Patches/0001-gn-Add-install-target.patch new file mode 100644 index 0000000..319e3e5 --- /dev/null +++ b/Patches/0001-gn-Add-install-target.patch @@ -0,0 +1,255 @@ +From 9533f9908edae528c9a0ac22e4266f702f625685 Mon Sep 17 00:00:00 2001 +From: Antonio Caggiano +Date: Tue, 30 Apr 2024 17:47:36 +0200 +Subject: [PATCH] gn: Add install target + +Define an install_target GN template which installs include directories +and a predefined list of libraries to a given prefix. The template is +taking advantage of an install_target.py script which generates package +config files for every named target. + +Bug: angleproject:8110 +Change-Id: I6deb40fe9c54f11da7caf4fb5df59d3ce522df29 +--- + AUTHORS | 1 + + BUILD.gn | 55 +++++++++++++++ + scripts/install_target.py | 145 ++++++++++++++++++++++++++++++++++++++ + 3 files changed, 201 insertions(+) + create mode 100644 scripts/install_target.py + +diff --git a/AUTHORS b/AUTHORS +index 43ea79d17..6c17098fb 100644 +--- a/AUTHORS ++++ b/AUTHORS +@@ -43,6 +43,7 @@ Yandex LLC + Rive + Institute of Software, Chinese Academy of Sciences + Guangdong OPPO Mobile Telecommunications Corp., Ltd ++Qualcomm Innovation Center, Inc. + + Jacek Caban + Mark Callow +diff --git a/BUILD.gn b/BUILD.gn +index e9c3a3e79..4a0029b7a 100644 +--- a/BUILD.gn ++++ b/BUILD.gn +@@ -86,6 +86,9 @@ declare_args() { + is_android && !build_with_chromium + + angle_enable_context_mutex = true ++ ++ # Prefix where the artifacts should be installed on the system ++ install_prefix = "" + } + + declare_args() { +@@ -1849,3 +1852,55 @@ group("angle_static") { + ":translator", + ] + } ++ ++template("install_target") { ++ install_deps = [] ++ ++ foreach(_lib, invoker.libs) { ++ install_deps += [ ":install_${_lib}" ] ++ ++ source = "${root_build_dir}/${_lib}${angle_libs_suffix}${shlib_extension}" ++ ++ action("install_${_lib}") { ++ deps = [ ":${_lib}" ] ++ script = "scripts/install_target.py" ++ sources = [ source ] ++ ++ outputs = [ "${target_gen_dir}/install_${_lib}.stamp" ] ++ args = [ ++ "--name", ++ _lib, ++ "--prefix", ++ "$install_prefix", ++ "--libs", ++ rebase_path(source), ++ ] ++ } ++ } ++ ++ install_deps += [ ":install_includes" ] ++ action("install_includes") { ++ script = "scripts/install_target.py" ++ configs = invoker.configs ++ ++ outputs = [ "${target_gen_dir}/install_${target_name}.stamp" ] ++ args = [ ++ "--prefix", ++ "$install_prefix", ++ "{{include_dirs}}", ++ ] ++ } ++ ++ group("install_${target_name}") { ++ deps = install_deps ++ } ++} ++ ++install_target("angle") { ++ libs = [ ++ "libEGL", ++ "libGLESv1_CM", ++ "libGLESv2", ++ ] ++ configs = [ ":includes_config" ] ++} +diff --git a/scripts/install_target.py b/scripts/install_target.py +new file mode 100644 +index 000000000..7582b1860 +--- /dev/null ++++ b/scripts/install_target.py +@@ -0,0 +1,145 @@ ++#! /usr/bin/env python3 ++# Copyright 2024 Google Inc. All rights reserved. ++# Use of this source code is governed by a BSD-style license that can be ++# found in the LICENSE file. ++"""Install script for ANGLE targets ++ ++1. Suppose this is your custom prefix: ++ `export CUSTOM_PREFIX=/custom/prefix ++2. Configure the install prefix with gn: ++ `gn gen --args="install_prefix=$CUSTOM_PREFIX" out` ++3. Then install ANGLE: ++ `ninja -C out install_angle` ++ ++This will copy all needed include directories under $CUSTOM_PREFIX/include and the ++libraries will be copied to $CUSTOM_PREFIX/lib. A package config file is generated for ++each library under $CUSTOM_PREFIX/lib/pkgconfig, therefore ANGLE libraries can be ++discovered by package config making sure this path is listed in the PKG_CONFIG_PATH ++environment variable. ++``` ++export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$CUSTOM_PREFIX/lib/pkgconfig ++pkg-config --libs EGL ++pkg-config --cflags EGL ++``` ++""" ++ ++import argparse ++import os ++import shutil ++import sys ++ ++ ++def install2(src_list: list, dst_dir: str): ++ """Installs a list of files or directories in `src_list` to `dst_dir`""" ++ os.makedirs(dst_dir, exist_ok=True) ++ for src in src_list: ++ if not os.path.exists(src): ++ raise FileNotFoundError("Failed to find {}".format(src)) ++ basename = os.path.basename(src) ++ dst = os.path.join(dst_dir, basename) ++ print("Installing {} to {}".format(src, dst)) ++ if os.path.isdir(src): ++ shutil.copytree(src, dst, dirs_exist_ok=True) ++ else: ++ shutil.copy2(src, dst) ++ ++ ++PC_TEMPLATE = """prefix={prefix} ++libdir=${{prefix}}/lib ++includedir=${{prefix}}/include ++ ++Name: {name} ++Description: {description} ++Version: {version} ++Libs: -L${{libdir}} {link_libraries} ++Cflags: -I${{includedir}} ++""" ++ ++ ++def gen_link_libraries(libs: list): ++ """Generates a string that can be used for the `Libs:` entry of a pkgconfig file""" ++ link_libraries = "" ++ for lib in libs: ++ # Absolute paths to file names only -> libEGL.dylib ++ basename = os.path.basename(lib) ++ # lib name only -> libEGL ++ libname: str = os.path.splitext(basename)[0] ++ # name only -> EGL ++ name = libname.strip('lib') ++ link_libraries += '-l{}'.format(name) ++ return link_libraries ++ ++ ++def gen_pkgconfig(name: str, version: str, prefix: os.path.abspath, libs: list): ++ """Generates a pkgconfig file for the current target""" ++ # Remove lib from name -> EGL ++ no_lib_name = name.strip('lib') ++ description = "ANGLE's {}".format(no_lib_name) ++ name_lowercase = no_lib_name.lower() ++ link_libraries = gen_link_libraries(libs) ++ pc_content = PC_TEMPLATE.format( ++ name=name_lowercase, ++ prefix=prefix, ++ description=description, ++ version=version, ++ link_libraries=link_libraries) ++ ++ lib_pkgconfig_path = os.path.join(prefix, 'lib/pkgconfig') ++ if not os.path.exists(lib_pkgconfig_path): ++ os.makedirs(lib_pkgconfig_path) ++ ++ pc_path = os.path.join(lib_pkgconfig_path, '{}.pc'.format(name_lowercase)) ++ print("Generating {}".format(pc_path)) ++ with open(pc_path, 'w+') as pc_file: ++ pc_file.write(pc_content) ++ ++ ++def install(name, version, prefix: os.path.abspath, libs: list, includes: list): ++ """Installs under `prefix` ++ - the libraries in the `libs` list ++ - the include directories in the `includes` list ++ - the pkgconfig file for current target if name is set""" ++ install2(libs, os.path.join(prefix, "lib")) ++ ++ for include in includes: ++ assert (os.path.isdir(include)) ++ incs = [inc.path for inc in os.scandir(include)] ++ install2(incs, os.path.join(prefix, "include")) ++ ++ if name: ++ gen_pkgconfig(name, version, prefix, libs) ++ ++ ++def main(): ++ parser = argparse.ArgumentParser(description='Install script for ANGLE targets') ++ parser.add_argument( ++ '--name', ++ help='Name of the target (e.g., EGL or GLESv2). Set it to generate a pkgconfig file', ++ ) ++ parser.add_argument( ++ '--version', help='SemVer of the target (e.g., 0.1.0 or 2.1)', default='0.0.0') ++ parser.add_argument( ++ '--prefix', ++ help='Install prefix to use (e.g., out/install or /usr/local/)', ++ default='', ++ type=os.path.abspath) ++ parser.add_argument( ++ '--libs', ++ help='List of libraries to install (e.g., libEGL.dylib or libGLESv2.so)', ++ default=[], ++ nargs='+', ++ type=os.path.abspath) ++ parser.add_argument( ++ '-I', ++ '--includes', ++ help='List of include directories to install (e.g., include or ../include)', ++ default=[], ++ nargs='+', ++ type=os.path.abspath) ++ ++ args = parser.parse_args() ++ install(args.name, args.version, args.prefix, args.libs, args.includes) ++ ++ ++if __name__ == '__main__': ++ sys.exit(main()) +-- +2.45.1 + diff --git a/Patches/0002-gn-Headerpad-config.patch b/Patches/0002-gn-Headerpad-config.patch new file mode 100644 index 0000000..1b00a41 --- /dev/null +++ b/Patches/0002-gn-Headerpad-config.patch @@ -0,0 +1,58 @@ +From 60e4ddc20c55b872c05892553000074efda0ecd7 Mon Sep 17 00:00:00 2001 +From: Antonio Caggiano +Date: Tue, 28 May 2024 16:35:28 +0200 +Subject: [PATCH] gn: Headerpad config + +Use -headerpad_max_install_names in the build, otherwise updated load +commands won't fit in Mach-O header. This is a requirement for +generating a bottle for homebrew. + +Change-Id: I5c82d03e21f9e5b1adc1c9dba571634132d32276 +--- + BUILD.gn | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/BUILD.gn b/BUILD.gn +index 4a0029b7a..f242f5c4b 100644 +--- a/BUILD.gn ++++ b/BUILD.gn +@@ -607,6 +607,12 @@ config("angle_gl_visibility_config") { + } + } + ++config("headerpad_config") { ++ if (is_mac) { ++ ldflags = [ "-headerpad_max_install_names" ] ++ } ++} ++ + config("angle_vulkan_wayland_config") { + if (angle_enable_vulkan && angle_use_wayland && + defined(vulkan_wayland_include_dirs)) { +@@ -1432,6 +1438,7 @@ template("angle_libGLESv2") { + ":angle_gl_visibility_config", + ":debug_annotations_config", + ":gl_prototypes", ++ ":headerpad_config", + ] + + if (angle_enable_gl_desktop_frontend) { +@@ -1559,6 +1566,7 @@ angle_shared_library("libGLESv1_CM") { + ":angle_gl_visibility_config", + ":debug_annotations_config", + ":gl_prototypes", ++ ":headerpad_config", + ] + + defines = [] +@@ -1605,6 +1613,7 @@ template("libEGL_template") { + configs += [ + ":debug_annotations_config", + ":library_name_config", ++ ":headerpad_config", + ] + deps += [ ":includes" ] + } +-- +2.45.1 +