mirror of
https://github.com/aphrody-labs/cef.git
synced 2026-10-13 21:07:07 +00:00
Add a shared CEF installer that downloads, verifies, and manages CEF binary distributions on Windows. The installer is embedded in application bootstrap binaries and resolves the correct CEF version from a CDN manifest based on each application's version and ABI compatibility requirements. Key components: - CDN manifest parsing and version resolution - WinHTTP-based download with SHA-1/SHA-256 integrity verification - Authenticode catalog (.cat) signature verification - Parallel XZ decompression for fast archive extraction - Per-version metadata (cef_version.json) with full version tracking - Shared installation database for multi-app version management - Version pruning to reclaim disk space from unused versions - Revocation list support (compiled-in baseline + CDN delta) - Progress UI with WM_COPYDATA-based cancellation - Bundled CEF fallback for offline/CDN-failure scenarios
108 lines
3.1 KiB
Python
108 lines
3.1 KiB
Python
#!/usr/bin/env python3
|
|
# Copyright (c) 2026 The Chromium Embedded Framework Authors. All rights
|
|
# reserved. Use of this source code is governed by a BSD-style license that
|
|
# can be found in the LICENSE file.
|
|
"""
|
|
Shared utilities for CEF installer build-time scripts.
|
|
|
|
Used by make_installer_config.py and make_revocation_resource.py.
|
|
"""
|
|
|
|
from __future__ import absolute_import
|
|
from __future__ import print_function
|
|
|
|
import json
|
|
import os
|
|
import sys
|
|
|
|
from file_util import write_file_if_changed
|
|
|
|
|
|
def load_api_versions(path):
|
|
"""Load and return the parsed cef_api_versions.json.
|
|
|
|
Returns the parsed dict, or None on error (prints to stderr).
|
|
"""
|
|
try:
|
|
with open(path, 'r', encoding='utf-8') as f:
|
|
return json.load(f)
|
|
except Exception as e:
|
|
print('Error reading %s: %s' % (path, e), file=sys.stderr)
|
|
return None
|
|
|
|
|
|
def get_api_version_last(api_versions):
|
|
"""Get the 'last' API version string from parsed api_versions dict.
|
|
|
|
Returns the string (e.g., '14601'), or None on error (prints to stderr).
|
|
"""
|
|
last = api_versions.get('last')
|
|
if not last:
|
|
print('Error: "last" field not found in api_versions', file=sys.stderr)
|
|
return None
|
|
return last
|
|
|
|
|
|
def compute_vmin(api_versions, api_version_override=None):
|
|
"""Compute vmin (major, minor) from api_versions and optional override.
|
|
|
|
API version format: XXXYY where XXX is major and YY is minor.
|
|
e.g., 14601 -> (146, 1), 14610 -> (146, 10)
|
|
|
|
Args:
|
|
api_versions: Parsed cef_api_versions.json dict.
|
|
api_version_override: Optional string override (e.g., "14500").
|
|
|
|
Returns:
|
|
Tuple (major, minor) on success, or None on error (prints to stderr).
|
|
"""
|
|
last = get_api_version_last(api_versions)
|
|
if last is None:
|
|
return None
|
|
|
|
api_version_str = api_version_override if api_version_override else last
|
|
try:
|
|
api_version_int = int(api_version_str)
|
|
major = api_version_int // 100
|
|
minor = api_version_int % 100
|
|
return (major, minor)
|
|
except ValueError:
|
|
print('Error: Invalid API version "%s"' % api_version_str, file=sys.stderr)
|
|
return None
|
|
|
|
|
|
def format_vmin(major, minor):
|
|
"""Format vmin tuple as a version string (e.g., '146.1')."""
|
|
return '%d.%d' % (major, minor)
|
|
|
|
|
|
def ensure_parent_dir(path):
|
|
"""Create parent directory of path if it doesn't exist."""
|
|
parent = os.path.dirname(path)
|
|
if parent and not os.path.exists(parent):
|
|
os.makedirs(parent)
|
|
|
|
|
|
def write_rc_file(output_rc_path, resource_name, json_basename):
|
|
"""Write an RC file that references a JSON file as RCDATA.
|
|
|
|
Args:
|
|
output_rc_path: Path to write the RC file.
|
|
resource_name: Resource name (e.g., 'CEF_INSTALLER_CONFIG').
|
|
json_basename: Basename of the JSON file (e.g., 'installer_config.json').
|
|
"""
|
|
rc_content = '%s RCDATA "%s"\n' % (resource_name, json_basename)
|
|
ensure_parent_dir(output_rc_path)
|
|
write_file_if_changed(output_rc_path, rc_content)
|
|
|
|
|
|
def write_json_output(output_json_path, content):
|
|
"""Write JSON content to a file (only if changed).
|
|
|
|
Args:
|
|
output_json_path: Path to write the JSON file.
|
|
content: JSON string to write.
|
|
"""
|
|
ensure_parent_dir(output_json_path)
|
|
write_file_if_changed(output_json_path, content)
|