1*da0073e9SAndroid Build Coastguard Workerfrom __future__ import annotations 2*da0073e9SAndroid Build Coastguard Worker 3*da0073e9SAndroid Build Coastguard Workerimport os 4*da0073e9SAndroid Build Coastguard Workerimport platform 5*da0073e9SAndroid Build Coastguard Workerimport struct 6*da0073e9SAndroid Build Coastguard Workerimport sys 7*da0073e9SAndroid Build Coastguard Workerfrom itertools import chain 8*da0073e9SAndroid Build Coastguard Workerfrom typing import cast, Iterable 9*da0073e9SAndroid Build Coastguard Worker 10*da0073e9SAndroid Build Coastguard Worker 11*da0073e9SAndroid Build Coastguard WorkerIS_WINDOWS = platform.system() == "Windows" 12*da0073e9SAndroid Build Coastguard WorkerIS_DARWIN = platform.system() == "Darwin" 13*da0073e9SAndroid Build Coastguard WorkerIS_LINUX = platform.system() == "Linux" 14*da0073e9SAndroid Build Coastguard Worker 15*da0073e9SAndroid Build Coastguard WorkerIS_CONDA = ( 16*da0073e9SAndroid Build Coastguard Worker "conda" in sys.version 17*da0073e9SAndroid Build Coastguard Worker or "Continuum" in sys.version 18*da0073e9SAndroid Build Coastguard Worker or any(x.startswith("CONDA") for x in os.environ) 19*da0073e9SAndroid Build Coastguard Worker) 20*da0073e9SAndroid Build Coastguard WorkerCONDA_DIR = os.path.join(os.path.dirname(sys.executable), "..") 21*da0073e9SAndroid Build Coastguard Worker 22*da0073e9SAndroid Build Coastguard WorkerIS_64BIT = struct.calcsize("P") == 8 23*da0073e9SAndroid Build Coastguard Worker 24*da0073e9SAndroid Build Coastguard WorkerBUILD_DIR = "build" 25*da0073e9SAndroid Build Coastguard Worker 26*da0073e9SAndroid Build Coastguard Worker 27*da0073e9SAndroid Build Coastguard Workerdef check_env_flag(name: str, default: str = "") -> bool: 28*da0073e9SAndroid Build Coastguard Worker return os.getenv(name, default).upper() in ["ON", "1", "YES", "TRUE", "Y"] 29*da0073e9SAndroid Build Coastguard Worker 30*da0073e9SAndroid Build Coastguard Worker 31*da0073e9SAndroid Build Coastguard Workerdef check_negative_env_flag(name: str, default: str = "") -> bool: 32*da0073e9SAndroid Build Coastguard Worker return os.getenv(name, default).upper() in ["OFF", "0", "NO", "FALSE", "N"] 33*da0073e9SAndroid Build Coastguard Worker 34*da0073e9SAndroid Build Coastguard Worker 35*da0073e9SAndroid Build Coastguard Workerdef gather_paths(env_vars: Iterable[str]) -> list[str]: 36*da0073e9SAndroid Build Coastguard Worker return list(chain(*(os.getenv(v, "").split(os.pathsep) for v in env_vars))) 37*da0073e9SAndroid Build Coastguard Worker 38*da0073e9SAndroid Build Coastguard Worker 39*da0073e9SAndroid Build Coastguard Workerdef lib_paths_from_base(base_path: str) -> list[str]: 40*da0073e9SAndroid Build Coastguard Worker return [os.path.join(base_path, s) for s in ["lib/x64", "lib", "lib64"]] 41*da0073e9SAndroid Build Coastguard Worker 42*da0073e9SAndroid Build Coastguard Worker 43*da0073e9SAndroid Build Coastguard Worker# We promised that CXXFLAGS should also be affected by CFLAGS 44*da0073e9SAndroid Build Coastguard Workerif "CFLAGS" in os.environ and "CXXFLAGS" not in os.environ: 45*da0073e9SAndroid Build Coastguard Worker os.environ["CXXFLAGS"] = os.environ["CFLAGS"] 46*da0073e9SAndroid Build Coastguard Worker 47*da0073e9SAndroid Build Coastguard Worker 48*da0073e9SAndroid Build Coastguard Workerclass BuildType: 49*da0073e9SAndroid Build Coastguard Worker """Checks build type. The build type will be given in :attr:`cmake_build_type_env`. If :attr:`cmake_build_type_env` 50*da0073e9SAndroid Build Coastguard Worker is ``None``, then the build type will be inferred from ``CMakeCache.txt``. If ``CMakeCache.txt`` does not exist, 51*da0073e9SAndroid Build Coastguard Worker os.environ['CMAKE_BUILD_TYPE'] will be used. 52*da0073e9SAndroid Build Coastguard Worker 53*da0073e9SAndroid Build Coastguard Worker Args: 54*da0073e9SAndroid Build Coastguard Worker cmake_build_type_env (str): The value of os.environ['CMAKE_BUILD_TYPE']. If None, the actual build type will be 55*da0073e9SAndroid Build Coastguard Worker inferred. 56*da0073e9SAndroid Build Coastguard Worker 57*da0073e9SAndroid Build Coastguard Worker """ 58*da0073e9SAndroid Build Coastguard Worker 59*da0073e9SAndroid Build Coastguard Worker def __init__(self, cmake_build_type_env: str | None = None) -> None: 60*da0073e9SAndroid Build Coastguard Worker if cmake_build_type_env is not None: 61*da0073e9SAndroid Build Coastguard Worker self.build_type_string = cmake_build_type_env 62*da0073e9SAndroid Build Coastguard Worker return 63*da0073e9SAndroid Build Coastguard Worker 64*da0073e9SAndroid Build Coastguard Worker cmake_cache_txt = os.path.join(BUILD_DIR, "CMakeCache.txt") 65*da0073e9SAndroid Build Coastguard Worker if os.path.isfile(cmake_cache_txt): 66*da0073e9SAndroid Build Coastguard Worker # Found CMakeCache.txt. Use the build type specified in it. 67*da0073e9SAndroid Build Coastguard Worker from .cmake_utils import get_cmake_cache_variables_from_file 68*da0073e9SAndroid Build Coastguard Worker 69*da0073e9SAndroid Build Coastguard Worker with open(cmake_cache_txt) as f: 70*da0073e9SAndroid Build Coastguard Worker cmake_cache_vars = get_cmake_cache_variables_from_file(f) 71*da0073e9SAndroid Build Coastguard Worker # Normally it is anti-pattern to determine build type from CMAKE_BUILD_TYPE because it is not used for 72*da0073e9SAndroid Build Coastguard Worker # multi-configuration build tools, such as Visual Studio and XCode. But since we always communicate with 73*da0073e9SAndroid Build Coastguard Worker # CMake using CMAKE_BUILD_TYPE from our Python scripts, this is OK here. 74*da0073e9SAndroid Build Coastguard Worker self.build_type_string = cast(str, cmake_cache_vars["CMAKE_BUILD_TYPE"]) 75*da0073e9SAndroid Build Coastguard Worker else: 76*da0073e9SAndroid Build Coastguard Worker self.build_type_string = os.environ.get("CMAKE_BUILD_TYPE", "Release") 77*da0073e9SAndroid Build Coastguard Worker 78*da0073e9SAndroid Build Coastguard Worker def is_debug(self) -> bool: 79*da0073e9SAndroid Build Coastguard Worker "Checks Debug build." 80*da0073e9SAndroid Build Coastguard Worker return self.build_type_string == "Debug" 81*da0073e9SAndroid Build Coastguard Worker 82*da0073e9SAndroid Build Coastguard Worker def is_rel_with_deb_info(self) -> bool: 83*da0073e9SAndroid Build Coastguard Worker "Checks RelWithDebInfo build." 84*da0073e9SAndroid Build Coastguard Worker return self.build_type_string == "RelWithDebInfo" 85*da0073e9SAndroid Build Coastguard Worker 86*da0073e9SAndroid Build Coastguard Worker def is_release(self) -> bool: 87*da0073e9SAndroid Build Coastguard Worker "Checks Release build." 88*da0073e9SAndroid Build Coastguard Worker return self.build_type_string == "Release" 89*da0073e9SAndroid Build Coastguard Worker 90*da0073e9SAndroid Build Coastguard Worker 91*da0073e9SAndroid Build Coastguard Worker# hotpatch environment variable 'CMAKE_BUILD_TYPE'. 'CMAKE_BUILD_TYPE' always prevails over DEBUG or REL_WITH_DEB_INFO. 92*da0073e9SAndroid Build Coastguard Workerif "CMAKE_BUILD_TYPE" not in os.environ: 93*da0073e9SAndroid Build Coastguard Worker if check_env_flag("DEBUG"): 94*da0073e9SAndroid Build Coastguard Worker os.environ["CMAKE_BUILD_TYPE"] = "Debug" 95*da0073e9SAndroid Build Coastguard Worker elif check_env_flag("REL_WITH_DEB_INFO"): 96*da0073e9SAndroid Build Coastguard Worker os.environ["CMAKE_BUILD_TYPE"] = "RelWithDebInfo" 97*da0073e9SAndroid Build Coastguard Worker else: 98*da0073e9SAndroid Build Coastguard Worker os.environ["CMAKE_BUILD_TYPE"] = "Release" 99*da0073e9SAndroid Build Coastguard Worker 100*da0073e9SAndroid Build Coastguard Workerbuild_type = BuildType() 101