File indexing completed on 2024-12-15 04:00:58
0001 #!/usr/bin/env python3 0002 0003 # SPDX-FileCopyrightText: 2021 Mattia Basaglia <dev@dragon.best> 0004 # SPDX-License-Identifier: GPL-3.0-or-later 0005 0006 import os 0007 import shlex 0008 import pathlib 0009 import argparse 0010 import subprocess 0011 0012 0013 class Variable: 0014 def __init__(self, cmake_name, *a, **kw): 0015 self.cmake_name = cmake_name 0016 self.value = kw.pop("fixed_value", None) 0017 self.argparse_args = a 0018 self.argparse_kwargs = kw 0019 self.default_callable = self.argparse_kwargs.pop("default_callable", None) 0020 0021 self.dest = self.argparse_kwargs.get("dest", None) 0022 0023 if not self.dest: 0024 if cmake_name: 0025 self.dest = cmake_name 0026 else: 0027 self.dest = self.argparse_args[0].strip("-").replace("-", "_") 0028 0029 self.argparse_kwargs["dest"] = self.dest 0030 0031 def add_to_parser(self, parser: argparse.ArgumentParser): 0032 if self.argparse_args or self.argparse_args: 0033 parser.add_argument( 0034 *self.argparse_args, 0035 **self.argparse_kwargs 0036 ) 0037 0038 def from_parser(self, variables, ns): 0039 if self.argparse_args or self.argparse_args: 0040 self.value = getattr(ns, self.dest) 0041 0042 if self.value is None and self.default_callable: 0043 self.value = self.default_callable(variables, ns) 0044 0045 def add_to_cmd(self, cmd): 0046 if self.cmake_name: 0047 cmd.append("-D%s=%s" % (self.cmake_name, str(self.value))) 0048 0049 0050 class Variables: 0051 def __init__(self, parser: argparse.ArgumentParser()): 0052 self.variables = [] 0053 self.vars = {} 0054 self.parser = parser 0055 self.args = [] 0056 parser.add_argument("cmake_args", nargs="+", help="CMake arguments") 0057 0058 def add(self, var: Variable) -> "Variables": 0059 self.variables.append(var) 0060 self.vars[var.dest] = var 0061 var.add_to_parser(self.parser) 0062 return self 0063 0064 def var(self, *a, **kw) -> "Variables": 0065 return self.add(Variable(*a, **kw)) 0066 0067 def option(self, *a, **kw) -> "Variables": 0068 return self.add(Variable(None, *a, **kw)) 0069 0070 def fixed(self, cmake_name, value) -> "Variables": 0071 return self.add(Variable(cmake_name, fixed_value=value)) 0072 0073 def parse_args(self): 0074 ns = self.parser.parse_args() 0075 for var in self.variables: 0076 var.from_parser(self, ns) 0077 0078 self.args = ns.cmake_args 0079 return ns 0080 0081 def invoke(self): 0082 cmd = ["cmake"] 0083 for var in self.variables: 0084 var.add_to_cmd(cmd) 0085 0086 print(" ".join(map(shlex.quote, cmd))) 0087 subprocess.call(cmd + self.args) 0088 0089 def __getitem__(self, key): 0090 return self.vars[key].value 0091 0092 def error(self, msg): 0093 self.parser.error(msg) 0094 0095 0096 def build_qt_path(variables: Variables, ns): 0097 if ns.qt is None: 0098 variables.error("You must specify either --qt or --qt-path") 0099 0100 path = ns.qt_home / ".".join(map(str, ns.qt)) 0101 0102 if ns.qt < (5, 13): 0103 abi = ns.ANDROID_ABI 0104 if abi == "x86": 0105 abi_qt = abi 0106 elif abi == "armeabi-v7a": 0107 abi_qt = "armv7" 0108 elif abi == "arm64-v8a": 0109 abi_qt = "armv64_v8a" 0110 path /= "android_" + abi_qt 0111 else: 0112 path /= "android" 0113 0114 return path 0115 0116 0117 def ndk_default(variables: Variables, ns): 0118 path = variables["ANDROID_SDK"] / "ndk" 0119 attempts = list(path.iterdir()) 0120 if len(attempts) == 1: 0121 path /= attempts[0] 0122 else: 0123 variables.error("Could not determine --ndk automatically") 0124 return path 0125 0126 0127 parser = argparse.ArgumentParser() 0128 variables = Variables(parser) 0129 variables.option( 0130 "--qt", 0131 type=lambda x: tuple(map(int, x.split("."))), 0132 help="Qt Version", 0133 default=None, 0134 ) 0135 variables.option( 0136 "--qt-home", 0137 default=pathlib.Path.home() / "Qt", 0138 type=pathlib.Path, 0139 help="Home path to Qt if installed with the Qt installer", 0140 ) 0141 variables.var( 0142 "CMAKE_FIND_ROOT_PATH", 0143 "--qt-path", 0144 default=None, 0145 type=pathlib.Path, 0146 help="Base path for Qt for android, by default based on --qt-home and --qt-version", 0147 default_callable=build_qt_path, 0148 ) 0149 variables.var( 0150 "CMAKE_PREFIX_PATH", 0151 default_callable=lambda variables, ns: variables.vars["CMAKE_FIND_ROOT_PATH"].value / "lib/cmake" 0152 ) 0153 variables.fixed( 0154 "ANDROID_STL", "c++_shared" 0155 ) 0156 variables.var( 0157 "ANDROID_ABI", 0158 "--abi", 0159 choices=["armeabi-v7a", "arm64-v8a", "x86", "x86_64"], 0160 required=True 0161 ) 0162 variables.var( 0163 "ANDROID_SDK", 0164 "--sdk", 0165 default=pathlib.Path.home() / "Android" / "Sdk", 0166 type=pathlib.Path, 0167 ) 0168 variables.var( 0169 "ANDROID_NDK", 0170 "--ndk", 0171 type=pathlib.Path, 0172 default_callable=ndk_default 0173 ) 0174 variables.var( 0175 "CMAKE_TOOLCHAIN_FILE", 0176 "--toolchain", 0177 default_callable=lambda variables, ns: variables.vars["ANDROID_NDK"].value / "build/cmake/android.toolchain.cmake" 0178 ) 0179 variables.var( 0180 "ANDROID_PLATFORM", 0181 "--platform", 0182 type=int, 0183 default=29, 0184 ) 0185 variables.var( 0186 "JAVA_HOME", 0187 "--java-home", 0188 default="/usr/lib/jvm/default-java", 0189 ) 0190 0191 variables.parse_args() 0192 0193 variables.invoke()