#!/usr/bin/env python3 """Build Blender's pinned OpenEXR with the existing WASM Imath installation.""" import hashlib import re import shutil import subprocess import tarfile import urllib.request from pathlib import Path ROOT = Path(__file__).resolve().parents[2] BASE = ROOT / 'build_web_openexr' IMATH = ROOT / 'build_web_ocio/install' def main(): versions = (ROOT / 'blender-5.2.0/build_files/build_environment/cmake/versions.cmake').read_text() value = lambda name: re.search(r'set\(OPENEXR_' + name + r' ([^)]+)\)', versions)[1] version, expected, algorithm = value('VERSION'), value('HASH'), value('HASH_TYPE').lower() if not (IMATH / 'lib/cmake/Imath/ImathConfig.cmake').is_file(): raise SystemExit('Reuse/build the Web OCIO Imath installation first') BASE.mkdir(exist_ok=True) archive = BASE / ('openexr-' + version + '.tar.gz') if not archive.is_file(): with urllib.request.urlopen('https://codeload.github.com/AcademySoftwareFoundation/openexr/tar.gz/refs/tags/v' + version, timeout=60) as response: data = response.read() if hashlib.new(algorithm, data).hexdigest() != expected: raise SystemExit('OpenEXR download differs from Blender pinned source hash') archive.write_bytes(data) if hashlib.new(algorithm, archive.read_bytes()).hexdigest() != expected: raise SystemExit('OpenEXR archive differs from Blender pinned source hash') source = BASE / ('openexr-' + version) if not (source / 'CMakeLists.txt').is_file(): with tarfile.open(archive) as package: package.extractall(BASE, filter='data') toolchain = ROOT / '.emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake' subprocess.run(['cmake', '-S', str(source), '-B', str(BASE / 'build'), '-G', 'Ninja', '-DCMAKE_TOOLCHAIN_FILE=' + str(toolchain), '-DCMAKE_BUILD_TYPE=Release', '-DCMAKE_INSTALL_PREFIX=' + str(BASE / 'install'), '-DCMAKE_INSTALL_LIBDIR=lib', '-DCMAKE_PREFIX_PATH=' + str(IMATH), '-DCMAKE_FIND_ROOT_PATH=' + str(IMATH), '-DImath_DIR=' + str(IMATH / 'lib/cmake/Imath'), '-DCMAKE_CXX_FLAGS=-fexceptions', '-DCMAKE_C_FLAGS=', '-DBUILD_SHARED_LIBS=OFF', '-DBUILD_TESTING=OFF', '-DOPENEXR_ENABLE_THREADING=OFF', '-DBUILD_WEBSITE=OFF', '-DOPENEXR_INSTALL_DOCS=OFF', '-DOPENEXR_BUILD_TOOLS=OFF', '-DOPENEXR_BUILD_EXAMPLES=OFF', '-DOPENEXR_FORCE_INTERNAL_DEFLATE=ON'], cwd=ROOT, check=True) subprocess.run(['cmake', '--build', str(BASE / 'build'), '--target', 'install', '--parallel', '8'], cwd=ROOT, check=True) shutil.copy2(BASE / 'build/external/OpenJPH/src/core/libopenjph.a', BASE / 'install/lib/libopenjph.a') if __name__ == '__main__': main()