builder.braak.pro/buildbot/config/worker/blender/__init__.py
Bart van der Braak edb56e96dc
Some checks failed
/ checks (pull_request) Failing after 14s
Implement authentication via Gitea
2024-11-20 23:59:35 +01:00

199 lines
7.3 KiB
Python

#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-or-later
# SPDX-FileCopyrightText: 2011-2024 Blender Authors
# <pep8 compliant>
import argparse
import os
import pathlib
import re
import subprocess
import worker.utils
class CodeBuilder(worker.utils.Builder):
def __init__(self, args: argparse.Namespace):
super().__init__(args, "blender", "blender")
self.needs_full_clean = args.needs_full_clean
self.needs_gpu_binaries = args.needs_gpu_binaries
self.needs_gpu_tests = args.needs_gpu_tests
self.needs_ninja = True
self.python_module = args.python_module
self.build_configuration = args.build_configuration
track_path: pathlib.Path = self.track_path
if self.platform in {"darwin", "windows"}:
if len(args.architecture):
self.architecture = args.architecture
if self.platform == "darwin":
self.build_dir = (
track_path / f"build_{self.architecture}_{self.build_configuration}"
)
else:
self.build_dir = track_path / f"build_{self.build_configuration}"
self.blender_dir = track_path / "blender.git"
self.install_dir = track_path / f"install_{self.build_configuration}"
self.package_dir = track_path / "build_package"
self.build_doc_path = track_path / "build_doc_api"
def clean(self):
worker.utils.remove_dir(self.install_dir)
worker.utils.remove_dir(self.package_dir)
worker.utils.remove_dir(self.build_doc_path)
# Call command with in compiler environment.
def call(
self, cmd: worker.utils.CmdSequence, env: worker.utils.Cmdenvironment = None
) -> int:
cmd_prefix: worker.utils.CmdList = []
if self.platform == "darwin":
# On macOS, override Xcode version if requested.
pipeline_config = self.pipeline_config()
xcode = pipeline_config.get("xcode", None)
xcode_version = xcode.get("version", None) if xcode else None
if xcode_version:
developer_dir = (
f"/Applications/Xcode-{xcode_version}.app/Contents/Developer"
)
else:
developer_dir = "/Applications/Xcode.app/Contents/Developer"
if (
self.service_env_id == "LOCAL"
and not pathlib.Path(developer_dir).exists()
):
worker.utils.warning(
f"Skip using non-existent {developer_dir} in LOCAL service environment"
)
else:
cmd_prefix = ["xcrun"]
env = dict(env) if env else os.environ.copy()
env["DEVELOPER_DIR"] = developer_dir
elif worker.utils.is_tool("scl"):
pipeline_config = self.pipeline_config()
gcc_version = pipeline_config["gcc"]["version"]
gcc_major_version = gcc_version.split(".")[0]
# On Rocky
if os.path.exists("/etc/rocky-release"):
# Stub to override configured GCC version, remove when blender build config is fixed
gcc_major_version = "11"
cmd_prefix = ["scl", "enable", f"gcc-toolset-{gcc_major_version}", "--"]
return worker.utils.call(cmd_prefix + list(cmd), env=env)
def pipeline_config(self) -> dict:
config_file_path = (
self.code_path / "build_files" / "config" / "pipeline_config.json"
)
if not config_file_path.exists():
config_file_path = config_file_path.with_suffix(".yaml")
if not config_file_path.exists():
raise Exception(f"Config file [{config_file_path}] not found, aborting")
with open(config_file_path, "r") as read_file:
if config_file_path.suffix == ".json":
import json
pipeline_config = json.load(read_file)
else:
import yaml
pipeline_config = yaml.load(read_file, Loader=yaml.SafeLoader)
return pipeline_config["buildbot"]
def blender_command_path(self) -> pathlib.Path:
if self.platform == "darwin":
return self.install_dir / "Blender.app" / "Contents" / "macOS" / "Blender"
elif self.platform == "windows":
return self.install_dir / "blender.exe"
else:
return self.install_dir / "blender"
def setup_build_environment(self) -> None:
if self.platform != "windows":
return
# CMake goes first to avoid using chocolaty cpack command.
worker.utils.info("Setting CMake path")
os.environ["PATH"] = (
"C:\\Program Files\\CMake\\bin" + os.pathsep + os.environ["PATH"]
)
worker.utils.info("Setting VC Tools env variables")
windows_build_version = "10.0.19041.0"
os.environ["PATH"] = (
f"C:\\Program Files (x86)\\Windows Kits\\10\\bin\\{windows_build_version}\\x64"
+ os.pathsep
+ os.environ["PATH"]
)
os.environ["PATH"] = (
"C:\\Program Files (x86)\\WiX Toolset v3.11\\bin"
+ os.pathsep
+ os.environ["PATH"]
)
if self.architecture == "arm64":
vs_build_tool_path = pathlib.Path(
"C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Auxiliary\\Build\\vcvarsarm64.bat"
)
vs_tool_install_dir_suffix = "\\bin\\Hostarm64\\arm64"
else:
vs_build_tool_path = pathlib.Path(
"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars64.bat"
)
vs_tool_install_dir_suffix = "\\bin\\Hostx64\\x64"
vcvars_output = subprocess.check_output(
[vs_build_tool_path, "&&", "set"], shell=True
)
vcvars_text = vcvars_output.decode("utf-8", "ignore")
for line in vcvars_text.splitlines():
match = re.match(r"(.*?)=(.*)", line)
if match:
key = match.group(1)
value = match.group(2)
if key not in os.environ:
if key not in ["PROMPT", "Path"]:
worker.utils.info(f"Adding key {key}={value}")
os.environ[key] = value
os.environ["PATH"] = (
os.environ["VCToolsInstallDir"]
+ vs_tool_install_dir_suffix
+ os.pathsep
+ os.environ["PATH"]
)
def create_argument_parser(steps: worker.utils.BuilderSteps) -> argparse.ArgumentParser:
parser = worker.utils.create_argument_parser(steps=steps)
parser.add_argument("--needs-full-clean", action="store_true", required=False)
parser.add_argument("--needs-gpu-binaries", action="store_true", required=False)
parser.add_argument("--needs-gpu-tests", action="store_true", required=False)
parser.add_argument("--python-module", action="store_true", required=False)
parser.add_argument(
"--build-configuration",
default="release",
type=str,
choices=["release", "asserts", "sanitizer", "debug"],
required=False,
)
parser.add_argument(
"--architecture",
default="",
type=str,
choices=["arm64", "x86_64", "amd64"],
required=False,
)
return parser