Skip to content

Commit 5357449

Browse files
linesightclaude
andcommitted
build: derive CEF API hash from cef_api_versions.h
The CEF API hash was hand-copied into src/version/cef_version_*.h as CEF_API_HASH_PLATFORM / CEF_API_HASH_UNIVERSAL, which had to be updated manually on every CEF upgrade and could drift from the real value. Read it instead from CEF's own generated cef_api_versions.h (in CEF_ROOT/include), which is the authoritative source. cmake_prepare_pyx.py gains get_cef_api_hash() to extract the platform-matched CEF_API_HASH_<version> for the build host, and CMake passes the header path (and depends on it). The hand-copied hash lines are removed from the version headers, and the upgrade guide notes the hash is now auto-derived. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 1a0aa1f commit 5357449

6 files changed

Lines changed: 66 additions & 19 deletions

File tree

‎CMakeLists.txt‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,11 @@ add_custom_command(
113113
--out "${PYX_STAGE_DIR}"
114114
--pyversion "${PYVERSION}"
115115
--cef-version-header "${_cef_ver_header}"
116+
--cef-api-versions-header "${CEF_ROOT}/include/cef_api_versions.h"
116117
DEPENDS
117118
${_pyx_src_files}
118119
"${CMAKE_SOURCE_DIR}/tools/cmake_prepare_pyx.py"
120+
"${CEF_ROOT}/include/cef_api_versions.h"
119121
COMMENT "Preparing .pyx files -> ${PYX_STAGE_DIR}"
120122
VERBATIM
121123
)

‎docs/Contributing-code.md‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Table of contents:
1515
* [GIL](#gil)
1616
* [Authors](#authors)
1717
* [Updating CEF version](#updating-cef-version)
18+
* [Re-importing the CEF headers](#re-importing-the-cef-headers)
1819

1920

2021
## Pull requests
@@ -178,7 +179,11 @@ cefpython and are not vendored either.
178179

179180
Steps:
180181

181-
1. Bump the version/hashes in `src/version/cef_version_{win,linux,macarm64}.h`.
182+
1. Bump the version fields in `src/version/cef_version_{win,linux,macarm64}.h`
183+
(`CEF_VERSION`, `CEF_COMMIT_*`, `CHROME_VERSION_*`, `CEF_SANDBOX_COMPAT_HASH`).
184+
The CEF **API hash** is not stored here — it is read from CEF's generated
185+
`cef_api_versions.h` (in `CEF_ROOT/include`) by `tools/cmake_prepare_pyx.py`,
186+
so there is nothing to hand-edit for it.
182187

183188
2. Find the CEF source commit — it is the `g<hash>` in the `CEF_VERSION`
184189
string. For `147.0.10+gd58e84d+chromium-147.0.7727.118` the commit is

‎src/version/cef_version_linux.h‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,6 @@
5050

5151
#define CEF_SANDBOX_COMPAT_HASH ""
5252

53-
// Experimental API hash for Linux (CEF_API_VERSION 999999).
54-
// Used by the cefpython build tools; sourced from cef_api_versions.h.
55-
#define CEF_API_HASH_PLATFORM "e1f04162d75f4f36056af4e4a02a4da0457451dd"
56-
#define CEF_API_HASH_UNIVERSAL "e1f04162d75f4f36056af4e4a02a4da0457451dd"
57-
5853
#define DO_MAKE_STRING(p) #p
5954
#define MAKE_STRING(p) DO_MAKE_STRING(p)
6055

‎src/version/cef_version_macarm64.h‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,6 @@
5050

5151
#define CEF_SANDBOX_COMPAT_HASH ""
5252

53-
// Experimental API hash for macOS (CEF_API_VERSION 999999).
54-
// Used by the cefpython build tools; sourced from cef_api_versions.h
55-
// (OS_MAC platform guard) in the CEF binary distribution.
56-
#define CEF_API_HASH_PLATFORM "48dac8d7565e012841b9d3c3935776c1a7bff589"
57-
#define CEF_API_HASH_UNIVERSAL "48dac8d7565e012841b9d3c3935776c1a7bff589"
58-
5953
#define DO_MAKE_STRING(p) #p
6054
#define MAKE_STRING(p) DO_MAKE_STRING(p)
6155

‎src/version/cef_version_win.h‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,6 @@
5050

5151
#define CEF_SANDBOX_COMPAT_HASH "2c7f1000da15f67f"
5252

53-
// Experimental API hash for Windows (CEF_API_VERSION 999999).
54-
// Used by the cefpython build tools; sourced from cef_api_versions.h.
55-
#define CEF_API_HASH_PLATFORM "65db327c10558a625d0650a0e454cc24ea6f23b4"
56-
#define CEF_API_HASH_UNIVERSAL "65db327c10558a625d0650a0e454cc24ea6f23b4"
57-
5853
#define DO_MAKE_STRING(p) #p
5954
#define MAKE_STRING(p) DO_MAKE_STRING(p)
6055

‎tools/cmake_prepare_pyx.py‎

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,53 @@ def get_cefpython_version(header_file):
2727
return ret
2828

2929

30+
# The build compiles with CEF's default API version, which cef_api_hash.h sets
31+
# to CEF_API_VERSION_EXPERIMENTAL (999999) when CEF_API_VERSION is not defined.
32+
CEF_API_VERSION_EXPERIMENTAL = 999999
33+
34+
35+
def get_host_os_macro():
36+
"""Return the CEF OS_* macro for the build host (builds are always native)."""
37+
if sys.platform.startswith("win"):
38+
return "OS_WIN"
39+
if sys.platform == "darwin":
40+
return "OS_MAC"
41+
return "OS_LINUX"
42+
43+
44+
def get_cef_api_hash(api_versions_header, api_version, os_macro):
45+
"""Extract the CEF API hash for a version+platform from cef_api_versions.h.
46+
47+
That generated header defines the hash per platform, e.g.:
48+
#if defined(OS_WIN)
49+
#define CEF_API_HASH_999999 "..."
50+
#elif defined(OS_MAC)
51+
#define CEF_API_HASH_999999 "..."
52+
#elif defined(OS_LINUX)
53+
#define CEF_API_HASH_999999 "..."
54+
#endif
55+
Each hash define is immediately preceded by its platform guard, so pick the
56+
one whose guard matches the build host. This replaces hand-copying the hash
57+
into src/version/cef_version_*.h (the hash is authoritative here).
58+
"""
59+
define = "CEF_API_HASH_{}".format(api_version)
60+
with open(api_versions_header, "r") as f:
61+
lines = f.read().splitlines()
62+
guard_re = re.compile(r"\s*#(?:if|elif)\s+defined\((OS_\w+)\)")
63+
define_re = re.compile(
64+
r'\s*#define\s+' + re.escape(define) + r'\s+"([0-9a-fA-F]+)"')
65+
for i, line in enumerate(lines):
66+
m = define_re.match(line)
67+
if not m or i == 0:
68+
continue
69+
guard = guard_re.match(lines[i - 1])
70+
if guard and guard.group(1) == os_macro:
71+
return m.group(1)
72+
raise RuntimeError(
73+
"Could not find {define} for {os} in {path}".format(
74+
define=define, os=os_macro, path=api_versions_header))
75+
76+
3077
def except_all_missing(content):
3178
"""Return the line number of a cdef/cpdef returning a C type (built-in,
3279
pointer, template or reference) whose signature declares no exception
@@ -61,6 +108,9 @@ def main():
61108
parser.add_argument("--out", required=True, help="Stage output directory")
62109
parser.add_argument("--pyversion", required=True, help="e.g. 310")
63110
parser.add_argument("--cef-version-header", required=True)
111+
parser.add_argument("--cef-api-versions-header", required=True,
112+
help="Path to CEF's generated cef_api_versions.h "
113+
"(in CEF_ROOT/include); source of the API hash.")
64114
args = parser.parse_args()
65115

66116
src_dir = args.src
@@ -78,12 +128,18 @@ def main():
78128
build=ver["CHROME_VERSION_BUILD"],
79129
patch=ver["CHROME_VERSION_PATCH"],
80130
)
131+
# API hash comes from CEF's generated cef_api_versions.h, not from a value
132+
# hand-copied into cef_version_*.h. CEF_API_HASH_UNIVERSAL is deprecated and
133+
# upstream defines it as the same value as the platform hash.
134+
api_hash = get_cef_api_hash(args.cef_api_versions_header,
135+
CEF_API_VERSION_EXPERIMENTAL,
136+
get_host_os_macro())
81137
module_vars = (
82138
'__version__ = "{v}"\n'.format(v=version_str)
83139
+ '__chrome_version__ = "{v}"\n'.format(v=chrome_ver)
84140
+ '__cef_version__ = "{v}"\n'.format(v=ver["CEF_VERSION"])
85-
+ '__cef_api_hash_platform__ = "{v}"\n'.format(v=ver["CEF_API_HASH_PLATFORM"])
86-
+ '__cef_api_hash_universal__ = "{v}"\n'.format(v=ver["CEF_API_HASH_UNIVERSAL"])
141+
+ '__cef_api_hash_platform__ = "{v}"\n'.format(v=api_hash)
142+
+ '__cef_api_hash_universal__ = "{v}"\n'.format(v=api_hash)
87143
+ '__cef_commit_hash__ = "{v}"\n'.format(v=ver["CEF_COMMIT_HASH"])
88144
+ '__cef_commit_number__ = "{v}"\n'.format(v=ver["CEF_COMMIT_NUMBER"])
89145
)

0 commit comments

Comments
 (0)