|
| 1 | +import argparse |
| 2 | +import hashlib |
| 3 | +import multiprocessing |
| 4 | +import os |
| 5 | +import sys |
| 6 | +from dataclasses import dataclass |
| 7 | +from typing import Any, Callable, Dict, List, Optional, Tuple |
| 8 | + |
| 9 | +PROJECT_DIR = os.path.abspath(os.path.dirname(__file__)) |
| 10 | +BASE_DIR = os.path.join(PROJECT_DIR, "..") |
| 11 | +BUILDBASE_DIR = os.path.join(BASE_DIR, "..") |
| 12 | +sys.path.insert(0, BUILDBASE_DIR) |
| 13 | + |
| 14 | + |
| 15 | +from buildbase import ( # noqa: E402 |
| 16 | + add_path, |
| 17 | + add_sora_arguments, |
| 18 | + add_webrtc_build_arguments, |
| 19 | + build_sora, |
| 20 | + build_webrtc, |
| 21 | + cd, |
| 22 | + cmake_path, |
| 23 | + cmd, |
| 24 | + cmdcap, |
| 25 | + get_sora_info, |
| 26 | + get_webrtc_info, |
| 27 | + install_cli11, |
| 28 | + install_cmake, |
| 29 | + install_llvm, |
| 30 | + install_rootfs, |
| 31 | + install_sora_and_deps, |
| 32 | + install_webrtc, |
| 33 | + mkdir_p, |
| 34 | + read_version_file, |
| 35 | +) |
| 36 | + |
| 37 | + |
| 38 | +@dataclass(frozen=True) |
| 39 | +class PlatformConfig: |
| 40 | + platform: str |
| 41 | + install_cmake_platform: str |
| 42 | + install_cmake_ext: str |
| 43 | + cmake_bin_components: Tuple[str, ...] |
| 44 | + cmake_toolchain_args: Callable[["BuildContext", Any], List[str]] |
| 45 | + requires_llvm: bool = True |
| 46 | + rootfs_conf: Optional[str] = None |
| 47 | + supports_relwithdebinfo: bool = False |
| 48 | + |
| 49 | + |
| 50 | +@dataclass |
| 51 | +class BuildContext: |
| 52 | + args: argparse.Namespace |
| 53 | + platform: str |
| 54 | + source_dir: str |
| 55 | + build_dir: str |
| 56 | + install_dir: str |
| 57 | + debug: bool |
| 58 | + |
| 59 | + |
| 60 | +def macos_cmake_toolchain_args(_: BuildContext, webrtc_info: Any) -> List[str]: |
| 61 | + sysroot = cmdcap(["xcrun", "--sdk", "macosx", "--show-sdk-path"]) |
| 62 | + return [ |
| 63 | + "-DCMAKE_SYSTEM_PROCESSOR=arm64", |
| 64 | + "-DCMAKE_OSX_ARCHITECTURES=arm64", |
| 65 | + "-DCMAKE_C_COMPILER_TARGET=aarch64-apple-darwin", |
| 66 | + "-DCMAKE_CXX_COMPILER_TARGET=aarch64-apple-darwin", |
| 67 | + f"-DCMAKE_SYSROOT={sysroot}", |
| 68 | + f"-DCMAKE_C_COMPILER={os.path.join(webrtc_info.clang_dir, 'bin', 'clang')}", |
| 69 | + f"-DCMAKE_CXX_COMPILER={os.path.join(webrtc_info.clang_dir, 'bin', 'clang++')}", |
| 70 | + f"-DLIBCXX_INCLUDE_DIR={cmake_path(os.path.join(webrtc_info.libcxx_dir, 'include'))}", |
| 71 | + ] |
| 72 | + |
| 73 | + |
| 74 | +def linux_x86_cmake_toolchain_args(_: BuildContext, webrtc_info: Any) -> List[str]: |
| 75 | + return [ |
| 76 | + f"-DCMAKE_C_COMPILER={os.path.join(webrtc_info.clang_dir, 'bin', 'clang')}", |
| 77 | + f"-DCMAKE_CXX_COMPILER={os.path.join(webrtc_info.clang_dir, 'bin', 'clang++')}", |
| 78 | + f"-DLIBCXX_INCLUDE_DIR={cmake_path(os.path.join(webrtc_info.libcxx_dir, 'include'))}", |
| 79 | + ] |
| 80 | + |
| 81 | + |
| 82 | +def linux_rootfs_cmake_toolchain_args(ctx: BuildContext, webrtc_info: Any) -> List[str]: |
| 83 | + sysroot = os.path.join(ctx.install_dir, "rootfs") |
| 84 | + return [ |
| 85 | + f"-DCMAKE_C_COMPILER={os.path.join(webrtc_info.clang_dir, 'bin', 'clang')}", |
| 86 | + f"-DCMAKE_CXX_COMPILER={os.path.join(webrtc_info.clang_dir, 'bin', 'clang++')}", |
| 87 | + f"-DLIBCXX_INCLUDE_DIR={cmake_path(os.path.join(webrtc_info.libcxx_dir, 'include'))}", |
| 88 | + "-DCMAKE_SYSTEM_NAME=Linux", |
| 89 | + "-DCMAKE_SYSTEM_PROCESSOR=aarch64", |
| 90 | + f"-DCMAKE_SYSROOT={sysroot}", |
| 91 | + "-DCMAKE_C_COMPILER_TARGET=aarch64-linux-gnu", |
| 92 | + "-DCMAKE_CXX_COMPILER_TARGET=aarch64-linux-gnu", |
| 93 | + f"-DCMAKE_FIND_ROOT_PATH={sysroot}", |
| 94 | + "-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER", |
| 95 | + "-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=BOTH", |
| 96 | + "-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=BOTH", |
| 97 | + "-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH", |
| 98 | + ] |
| 99 | + |
| 100 | + |
| 101 | +def windows_cmake_toolchain_args(_: BuildContext, __: Any) -> List[str]: |
| 102 | + return [] |
| 103 | + |
| 104 | + |
| 105 | +PLATFORMS: Dict[str, PlatformConfig] = { |
| 106 | + "macos_arm64": PlatformConfig( |
| 107 | + platform="macos_arm64", |
| 108 | + install_cmake_platform="macos-universal", |
| 109 | + install_cmake_ext="tar.gz", |
| 110 | + cmake_bin_components=("cmake", "CMake.app", "Contents", "bin"), |
| 111 | + cmake_toolchain_args=macos_cmake_toolchain_args, |
| 112 | + ), |
| 113 | + "ubuntu-22.04_x86_64": PlatformConfig( |
| 114 | + platform="ubuntu-22.04_x86_64", |
| 115 | + install_cmake_platform="linux-x86_64", |
| 116 | + install_cmake_ext="tar.gz", |
| 117 | + cmake_bin_components=("cmake", "bin"), |
| 118 | + cmake_toolchain_args=linux_x86_cmake_toolchain_args, |
| 119 | + ), |
| 120 | + "ubuntu-24.04_x86_64": PlatformConfig( |
| 121 | + platform="ubuntu-24.04_x86_64", |
| 122 | + install_cmake_platform="linux-x86_64", |
| 123 | + install_cmake_ext="tar.gz", |
| 124 | + cmake_bin_components=("cmake", "bin"), |
| 125 | + cmake_toolchain_args=linux_x86_cmake_toolchain_args, |
| 126 | + ), |
| 127 | + "ubuntu-22.04_armv8": PlatformConfig( |
| 128 | + platform="ubuntu-22.04_armv8", |
| 129 | + install_cmake_platform="linux-x86_64", |
| 130 | + install_cmake_ext="tar.gz", |
| 131 | + cmake_bin_components=("cmake", "bin"), |
| 132 | + cmake_toolchain_args=linux_rootfs_cmake_toolchain_args, |
| 133 | + rootfs_conf="ubuntu-22.04_armv8.conf", |
| 134 | + ), |
| 135 | + "ubuntu-24.04_armv8": PlatformConfig( |
| 136 | + platform="ubuntu-24.04_armv8", |
| 137 | + install_cmake_platform="linux-x86_64", |
| 138 | + install_cmake_ext="tar.gz", |
| 139 | + cmake_bin_components=("cmake", "bin"), |
| 140 | + cmake_toolchain_args=linux_rootfs_cmake_toolchain_args, |
| 141 | + rootfs_conf="ubuntu-24.04_armv8.conf", |
| 142 | + ), |
| 143 | + "windows_x86_64": PlatformConfig( |
| 144 | + platform="windows_x86_64", |
| 145 | + install_cmake_platform="windows-x86_64", |
| 146 | + install_cmake_ext="zip", |
| 147 | + cmake_bin_components=("cmake", "bin"), |
| 148 | + cmake_toolchain_args=windows_cmake_toolchain_args, |
| 149 | + requires_llvm=False, |
| 150 | + supports_relwithdebinfo=True, |
| 151 | + ), |
| 152 | +} |
| 153 | + |
| 154 | + |
| 155 | +def install_deps(config: PlatformConfig, ctx: BuildContext) -> Any: |
| 156 | + with cd(BASE_DIR): |
| 157 | + deps = read_version_file("DEPS") |
| 158 | + |
| 159 | + if config.rootfs_conf is not None: |
| 160 | + conf = os.path.join(BASE_DIR, "multistrap", config.rootfs_conf) |
| 161 | + with open(conf, "rb") as fp: |
| 162 | + version_md5 = hashlib.md5(fp.read()).hexdigest() |
| 163 | + install_rootfs( |
| 164 | + version=version_md5, |
| 165 | + version_file=os.path.join(ctx.install_dir, "rootfs.version"), |
| 166 | + install_dir=ctx.install_dir, |
| 167 | + conf=conf, |
| 168 | + ) |
| 169 | + |
| 170 | + if ctx.args.local_webrtc_build_dir is None: |
| 171 | + install_webrtc( |
| 172 | + version=deps["WEBRTC_BUILD_VERSION"], |
| 173 | + version_file=os.path.join(ctx.install_dir, "webrtc.version"), |
| 174 | + source_dir=ctx.source_dir, |
| 175 | + install_dir=ctx.install_dir, |
| 176 | + platform=config.platform, |
| 177 | + ) |
| 178 | + else: |
| 179 | + build_webrtc( |
| 180 | + platform=config.platform, |
| 181 | + local_webrtc_build_dir=ctx.args.local_webrtc_build_dir, |
| 182 | + local_webrtc_build_args=ctx.args.local_webrtc_build_args, |
| 183 | + debug=ctx.debug, |
| 184 | + ) |
| 185 | + |
| 186 | + webrtc_info = get_webrtc_info( |
| 187 | + config.platform, ctx.args.local_webrtc_build_dir, ctx.install_dir, ctx.debug |
| 188 | + ) |
| 189 | + |
| 190 | + if config.requires_llvm and ctx.args.local_webrtc_build_dir is None: |
| 191 | + webrtc_version = read_version_file(webrtc_info.version_file) |
| 192 | + install_llvm( |
| 193 | + version=".".join( |
| 194 | + [ |
| 195 | + webrtc_version["WEBRTC_SRC_TOOLS_URL"], |
| 196 | + webrtc_version["WEBRTC_SRC_TOOLS_COMMIT"], |
| 197 | + webrtc_version["WEBRTC_SRC_THIRD_PARTY_LIBCXX_SRC_URL"], |
| 198 | + webrtc_version["WEBRTC_SRC_THIRD_PARTY_LIBCXX_SRC_COMMIT"], |
| 199 | + webrtc_version["WEBRTC_SRC_BUILDTOOLS_URL"], |
| 200 | + webrtc_version["WEBRTC_SRC_BUILDTOOLS_COMMIT"], |
| 201 | + ] |
| 202 | + ), |
| 203 | + version_file=os.path.join(ctx.install_dir, "llvm.version"), |
| 204 | + install_dir=ctx.install_dir, |
| 205 | + tools_url=webrtc_version["WEBRTC_SRC_TOOLS_URL"], |
| 206 | + tools_commit=webrtc_version["WEBRTC_SRC_TOOLS_COMMIT"], |
| 207 | + libcxx_url=webrtc_version["WEBRTC_SRC_THIRD_PARTY_LIBCXX_SRC_URL"], |
| 208 | + libcxx_commit=webrtc_version["WEBRTC_SRC_THIRD_PARTY_LIBCXX_SRC_COMMIT"], |
| 209 | + buildtools_url=webrtc_version["WEBRTC_SRC_BUILDTOOLS_URL"], |
| 210 | + buildtools_commit=webrtc_version["WEBRTC_SRC_BUILDTOOLS_COMMIT"], |
| 211 | + ) |
| 212 | + |
| 213 | + if ctx.args.local_sora_cpp_sdk_dir is None: |
| 214 | + install_sora_and_deps( |
| 215 | + deps["SORA_CPP_SDK_VERSION"], |
| 216 | + deps["BOOST_VERSION"], |
| 217 | + config.platform, |
| 218 | + ctx.source_dir, |
| 219 | + ctx.install_dir, |
| 220 | + ) |
| 221 | + else: |
| 222 | + build_sora( |
| 223 | + config.platform, |
| 224 | + ctx.args.local_sora_cpp_sdk_dir, |
| 225 | + ctx.args.local_sora_cpp_sdk_args, |
| 226 | + ctx.debug, |
| 227 | + ctx.args.local_webrtc_build_dir, |
| 228 | + ) |
| 229 | + |
| 230 | + install_cmake( |
| 231 | + version=deps["CMAKE_VERSION"], |
| 232 | + version_file=os.path.join(ctx.install_dir, "cmake.version"), |
| 233 | + source_dir=ctx.source_dir, |
| 234 | + install_dir=ctx.install_dir, |
| 235 | + platform=config.install_cmake_platform, |
| 236 | + ext=config.install_cmake_ext, |
| 237 | + ) |
| 238 | + add_path(os.path.join(ctx.install_dir, *config.cmake_bin_components)) |
| 239 | + |
| 240 | + install_cli11( |
| 241 | + version=deps["CLI11_VERSION"], |
| 242 | + version_file=os.path.join(ctx.install_dir, "cli11.version"), |
| 243 | + install_dir=ctx.install_dir, |
| 244 | + ) |
| 245 | + |
| 246 | + return webrtc_info |
| 247 | + |
| 248 | + |
| 249 | +def configure_and_build(config: PlatformConfig, ctx: BuildContext, configuration: str, webrtc_info: Any): |
| 250 | + sample_build_dir = os.path.join(ctx.build_dir, "messaging_recvonly_sample") |
| 251 | + mkdir_p(sample_build_dir) |
| 252 | + with cd(sample_build_dir): |
| 253 | + sora_info = get_sora_info( |
| 254 | + config.platform, ctx.args.local_sora_cpp_sdk_dir, ctx.install_dir, ctx.debug |
| 255 | + ) |
| 256 | + cmake_args = [ |
| 257 | + f"-DCMAKE_BUILD_TYPE={configuration}", |
| 258 | + "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON", |
| 259 | + f"-DBOOST_ROOT={cmake_path(sora_info.boost_install_dir)}", |
| 260 | + f"-DWEBRTC_INCLUDE_DIR={cmake_path(webrtc_info.webrtc_include_dir)}", |
| 261 | + f"-DWEBRTC_LIBRARY_DIR={cmake_path(webrtc_info.webrtc_library_dir)}", |
| 262 | + f"-DSORA_DIR={cmake_path(sora_info.sora_install_dir)}", |
| 263 | + f"-DCLI11_DIR={cmake_path(os.path.join(ctx.install_dir, 'cli11'))}", |
| 264 | + ] |
| 265 | + cmake_args.extend(config.cmake_toolchain_args(ctx, webrtc_info)) |
| 266 | + |
| 267 | + cmd(["cmake", PROJECT_DIR] + cmake_args) |
| 268 | + cmd( |
| 269 | + [ |
| 270 | + "cmake", |
| 271 | + "--build", |
| 272 | + ".", |
| 273 | + f"-j{multiprocessing.cpu_count()}", |
| 274 | + "--config", |
| 275 | + configuration, |
| 276 | + ] |
| 277 | + ) |
| 278 | + |
| 279 | + |
| 280 | +def build_command(args: argparse.Namespace) -> None: |
| 281 | + config = PLATFORMS[args.platform] |
| 282 | + if args.relwithdebinfo and not config.supports_relwithdebinfo: |
| 283 | + raise SystemExit("--relwithdebinfo は windows_x86_64 でのみ指定できます。") |
| 284 | + |
| 285 | + configuration_dir = "debug" if args.debug else "release" |
| 286 | + ctx = BuildContext( |
| 287 | + args=args, |
| 288 | + platform=config.platform, |
| 289 | + source_dir=os.path.join(BASE_DIR, "_source", config.platform, configuration_dir), |
| 290 | + build_dir=os.path.join(BASE_DIR, "_build", config.platform, configuration_dir), |
| 291 | + install_dir=os.path.join(BASE_DIR, "_install", config.platform, configuration_dir) |
| 292 | + if args.install_dir is None |
| 293 | + else args.install_dir, |
| 294 | + debug=args.debug, |
| 295 | + ) |
| 296 | + |
| 297 | + mkdir_p(ctx.source_dir) |
| 298 | + mkdir_p(ctx.build_dir) |
| 299 | + mkdir_p(ctx.install_dir) |
| 300 | + |
| 301 | + webrtc_info = install_deps(config, ctx) |
| 302 | + |
| 303 | + if config.supports_relwithdebinfo and args.relwithdebinfo: |
| 304 | + configuration = "RelWithDebInfo" |
| 305 | + elif args.debug: |
| 306 | + configuration = "Debug" |
| 307 | + else: |
| 308 | + configuration = "Release" |
| 309 | + |
| 310 | + configure_and_build(config, ctx, configuration, webrtc_info) |
| 311 | + |
| 312 | + |
| 313 | +def main() -> None: |
| 314 | + parser = argparse.ArgumentParser() |
| 315 | + subparsers = parser.add_subparsers(dest="command", required=True) |
| 316 | + |
| 317 | + build_parser = subparsers.add_parser("build") |
| 318 | + build_parser.add_argument("platform", choices=sorted(PLATFORMS.keys())) |
| 319 | + build_parser.add_argument("--debug", action="store_true") |
| 320 | + build_parser.add_argument("--relwithdebinfo", action="store_true") |
| 321 | + build_parser.add_argument("--install-dir") |
| 322 | + add_webrtc_build_arguments(build_parser) |
| 323 | + add_sora_arguments(build_parser) |
| 324 | + build_parser.set_defaults(func=build_command) |
| 325 | + |
| 326 | + args = parser.parse_args() |
| 327 | + args.func(args) |
| 328 | + |
| 329 | + |
| 330 | +if __name__ == "__main__": |
| 331 | + main() |
0 commit comments