xref: /aosp_15_r20/external/angle/scripts/install_target.py (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker#! /usr/bin/env python3
2*8975f5c5SAndroid Build Coastguard Worker# Copyright 2024 Google Inc.  All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker# found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker"""Install script for ANGLE targets
6*8975f5c5SAndroid Build Coastguard Worker
7*8975f5c5SAndroid Build Coastguard Worker1. Suppose this is your custom prefix:
8*8975f5c5SAndroid Build Coastguard Worker   `export CUSTOM_PREFIX=/custom/prefix
9*8975f5c5SAndroid Build Coastguard Worker2. Configure the install prefix with gn:
10*8975f5c5SAndroid Build Coastguard Worker   `gn gen --args="install_prefix=\"$CUSTOM_PREFIX\"" out`
11*8975f5c5SAndroid Build Coastguard Worker3. Then install ANGLE:
12*8975f5c5SAndroid Build Coastguard Worker   `ninja -C out install_angle`
13*8975f5c5SAndroid Build Coastguard Worker
14*8975f5c5SAndroid Build Coastguard WorkerThis will copy all needed include directories under $CUSTOM_PREFIX/include and the
15*8975f5c5SAndroid Build Coastguard Workerlibraries will be copied to $CUSTOM_PREFIX/lib. A package config file is generated for
16*8975f5c5SAndroid Build Coastguard Workereach library under $CUSTOM_PREFIX/lib/pkgconfig, therefore ANGLE libraries can be
17*8975f5c5SAndroid Build Coastguard Workerdiscovered by package config making sure this path is listed in the PKG_CONFIG_PATH
18*8975f5c5SAndroid Build Coastguard Workerenvironment variable.
19*8975f5c5SAndroid Build Coastguard Worker```
20*8975f5c5SAndroid Build Coastguard Workerexport PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$CUSTOM_PREFIX/lib/pkgconfig
21*8975f5c5SAndroid Build Coastguard Workerpkg-config --libs EGL
22*8975f5c5SAndroid Build Coastguard Workerpkg-config --cflags EGL
23*8975f5c5SAndroid Build Coastguard Worker```
24*8975f5c5SAndroid Build Coastguard Worker"""
25*8975f5c5SAndroid Build Coastguard Worker
26*8975f5c5SAndroid Build Coastguard Workerimport argparse
27*8975f5c5SAndroid Build Coastguard Workerimport os
28*8975f5c5SAndroid Build Coastguard Workerimport shutil
29*8975f5c5SAndroid Build Coastguard Workerimport sys
30*8975f5c5SAndroid Build Coastguard Worker
31*8975f5c5SAndroid Build Coastguard Worker
32*8975f5c5SAndroid Build Coastguard Workerdef install2(src_list: list, dst_dir: str):
33*8975f5c5SAndroid Build Coastguard Worker    """Installs a list of files or directories in `src_list` to `dst_dir`"""
34*8975f5c5SAndroid Build Coastguard Worker    os.makedirs(dst_dir, exist_ok=True)
35*8975f5c5SAndroid Build Coastguard Worker    for src in src_list:
36*8975f5c5SAndroid Build Coastguard Worker        if not os.path.exists(src):
37*8975f5c5SAndroid Build Coastguard Worker            raise FileNotFoundError("Failed to find {}".format(src))
38*8975f5c5SAndroid Build Coastguard Worker        basename = os.path.basename(src)
39*8975f5c5SAndroid Build Coastguard Worker        dst = os.path.join(dst_dir, basename)
40*8975f5c5SAndroid Build Coastguard Worker        print("Installing {} to {}".format(src, dst))
41*8975f5c5SAndroid Build Coastguard Worker        if os.path.isdir(src):
42*8975f5c5SAndroid Build Coastguard Worker            shutil.copytree(src, dst, dirs_exist_ok=True)
43*8975f5c5SAndroid Build Coastguard Worker        else:
44*8975f5c5SAndroid Build Coastguard Worker            shutil.copy2(src, dst)
45*8975f5c5SAndroid Build Coastguard Worker
46*8975f5c5SAndroid Build Coastguard Worker
47*8975f5c5SAndroid Build Coastguard WorkerPC_TEMPLATE = """prefix={prefix}
48*8975f5c5SAndroid Build Coastguard Workerlibdir=${{prefix}}/lib
49*8975f5c5SAndroid Build Coastguard Workerincludedir=${{prefix}}/include
50*8975f5c5SAndroid Build Coastguard Worker
51*8975f5c5SAndroid Build Coastguard WorkerName: {name}
52*8975f5c5SAndroid Build Coastguard WorkerDescription: {description}
53*8975f5c5SAndroid Build Coastguard WorkerVersion: {version}
54*8975f5c5SAndroid Build Coastguard WorkerLibs: -L${{libdir}} {link_libraries}
55*8975f5c5SAndroid Build Coastguard WorkerCflags: -I${{includedir}}
56*8975f5c5SAndroid Build Coastguard Worker"""
57*8975f5c5SAndroid Build Coastguard Worker
58*8975f5c5SAndroid Build Coastguard Worker
59*8975f5c5SAndroid Build Coastguard Workerdef gen_link_libraries(libs: list):
60*8975f5c5SAndroid Build Coastguard Worker    """Generates a string that can be used for the `Libs:` entry of a pkgconfig file"""
61*8975f5c5SAndroid Build Coastguard Worker    link_libraries = ""
62*8975f5c5SAndroid Build Coastguard Worker    for lib in libs:
63*8975f5c5SAndroid Build Coastguard Worker        # Absolute paths to file names only -> libEGL.dylib
64*8975f5c5SAndroid Build Coastguard Worker        basename = os.path.basename(lib)
65*8975f5c5SAndroid Build Coastguard Worker        # lib name only -> libEGL
66*8975f5c5SAndroid Build Coastguard Worker        libname: str = os.path.splitext(basename)[0]
67*8975f5c5SAndroid Build Coastguard Worker        # name only -> EGL
68*8975f5c5SAndroid Build Coastguard Worker        name = libname.strip('lib')
69*8975f5c5SAndroid Build Coastguard Worker        link_libraries += '-l{}'.format(name)
70*8975f5c5SAndroid Build Coastguard Worker    return link_libraries
71*8975f5c5SAndroid Build Coastguard Worker
72*8975f5c5SAndroid Build Coastguard Worker
73*8975f5c5SAndroid Build Coastguard Workerdef gen_pkgconfig(name: str, version: str, prefix: os.path.abspath, libs: list):
74*8975f5c5SAndroid Build Coastguard Worker    """Generates a pkgconfig file for the current target"""
75*8975f5c5SAndroid Build Coastguard Worker    # Remove lib from name -> EGL
76*8975f5c5SAndroid Build Coastguard Worker    no_lib_name = name.strip('lib')
77*8975f5c5SAndroid Build Coastguard Worker    description = "ANGLE's {}".format(no_lib_name)
78*8975f5c5SAndroid Build Coastguard Worker    name_lowercase = no_lib_name.lower()
79*8975f5c5SAndroid Build Coastguard Worker    link_libraries = gen_link_libraries(libs)
80*8975f5c5SAndroid Build Coastguard Worker    pc_content = PC_TEMPLATE.format(
81*8975f5c5SAndroid Build Coastguard Worker        name=name_lowercase,
82*8975f5c5SAndroid Build Coastguard Worker        prefix=prefix,
83*8975f5c5SAndroid Build Coastguard Worker        description=description,
84*8975f5c5SAndroid Build Coastguard Worker        version=version,
85*8975f5c5SAndroid Build Coastguard Worker        link_libraries=link_libraries)
86*8975f5c5SAndroid Build Coastguard Worker
87*8975f5c5SAndroid Build Coastguard Worker    lib_pkgconfig_path = os.path.join(prefix, 'lib/pkgconfig')
88*8975f5c5SAndroid Build Coastguard Worker    if not os.path.exists(lib_pkgconfig_path):
89*8975f5c5SAndroid Build Coastguard Worker        os.makedirs(lib_pkgconfig_path)
90*8975f5c5SAndroid Build Coastguard Worker
91*8975f5c5SAndroid Build Coastguard Worker    pc_path = os.path.join(lib_pkgconfig_path, '{}.pc'.format(name_lowercase))
92*8975f5c5SAndroid Build Coastguard Worker    print("Generating {}".format(pc_path))
93*8975f5c5SAndroid Build Coastguard Worker    with open(pc_path, 'w+') as pc_file:
94*8975f5c5SAndroid Build Coastguard Worker        pc_file.write(pc_content)
95*8975f5c5SAndroid Build Coastguard Worker
96*8975f5c5SAndroid Build Coastguard Worker
97*8975f5c5SAndroid Build Coastguard Workerdef install(name, version, prefix: os.path.abspath, libs: list, includes: list):
98*8975f5c5SAndroid Build Coastguard Worker    """Installs under `prefix`
99*8975f5c5SAndroid Build Coastguard Worker    - the libraries in the `libs` list
100*8975f5c5SAndroid Build Coastguard Worker    - the include directories in the `includes` list
101*8975f5c5SAndroid Build Coastguard Worker    - the pkgconfig file for current target if name is set"""
102*8975f5c5SAndroid Build Coastguard Worker    install2(libs, os.path.join(prefix, "lib"))
103*8975f5c5SAndroid Build Coastguard Worker
104*8975f5c5SAndroid Build Coastguard Worker    for include in includes:
105*8975f5c5SAndroid Build Coastguard Worker        assert (os.path.isdir(include))
106*8975f5c5SAndroid Build Coastguard Worker        incs = [inc.path for inc in os.scandir(include)]
107*8975f5c5SAndroid Build Coastguard Worker        install2(incs, os.path.join(prefix, "include"))
108*8975f5c5SAndroid Build Coastguard Worker
109*8975f5c5SAndroid Build Coastguard Worker    if name:
110*8975f5c5SAndroid Build Coastguard Worker        gen_pkgconfig(name, version, prefix, libs)
111*8975f5c5SAndroid Build Coastguard Worker
112*8975f5c5SAndroid Build Coastguard Worker
113*8975f5c5SAndroid Build Coastguard Workerdef main():
114*8975f5c5SAndroid Build Coastguard Worker    parser = argparse.ArgumentParser(description='Install script for ANGLE targets')
115*8975f5c5SAndroid Build Coastguard Worker    parser.add_argument(
116*8975f5c5SAndroid Build Coastguard Worker        '--name',
117*8975f5c5SAndroid Build Coastguard Worker        help='Name of the target (e.g., EGL or GLESv2). Set it to generate a pkgconfig file',
118*8975f5c5SAndroid Build Coastguard Worker    )
119*8975f5c5SAndroid Build Coastguard Worker    parser.add_argument(
120*8975f5c5SAndroid Build Coastguard Worker        '--version', help='SemVer of the target (e.g., 0.1.0 or 2.1)', default='0.0.0')
121*8975f5c5SAndroid Build Coastguard Worker    parser.add_argument(
122*8975f5c5SAndroid Build Coastguard Worker        '--prefix',
123*8975f5c5SAndroid Build Coastguard Worker        help='Install prefix to use (e.g., out/install or /usr/local/)',
124*8975f5c5SAndroid Build Coastguard Worker        default='',
125*8975f5c5SAndroid Build Coastguard Worker        type=os.path.abspath)
126*8975f5c5SAndroid Build Coastguard Worker    parser.add_argument(
127*8975f5c5SAndroid Build Coastguard Worker        '--libs',
128*8975f5c5SAndroid Build Coastguard Worker        help='List of libraries to install (e.g., libEGL.dylib or libGLESv2.so)',
129*8975f5c5SAndroid Build Coastguard Worker        default=[],
130*8975f5c5SAndroid Build Coastguard Worker        nargs='+',
131*8975f5c5SAndroid Build Coastguard Worker        type=os.path.abspath)
132*8975f5c5SAndroid Build Coastguard Worker    parser.add_argument(
133*8975f5c5SAndroid Build Coastguard Worker        '-I',
134*8975f5c5SAndroid Build Coastguard Worker        '--includes',
135*8975f5c5SAndroid Build Coastguard Worker        help='List of include directories to install (e.g., include or ../include)',
136*8975f5c5SAndroid Build Coastguard Worker        default=[],
137*8975f5c5SAndroid Build Coastguard Worker        nargs='+',
138*8975f5c5SAndroid Build Coastguard Worker        type=os.path.abspath)
139*8975f5c5SAndroid Build Coastguard Worker
140*8975f5c5SAndroid Build Coastguard Worker    args = parser.parse_args()
141*8975f5c5SAndroid Build Coastguard Worker    install(args.name, args.version, args.prefix, args.libs, args.includes)
142*8975f5c5SAndroid Build Coastguard Worker
143*8975f5c5SAndroid Build Coastguard Worker
144*8975f5c5SAndroid Build Coastguard Workerif __name__ == '__main__':
145*8975f5c5SAndroid Build Coastguard Worker    sys.exit(main())
146