11cmake_minimum_required (VERSION 3.21 )
22
3- # Read CEF major version from the Windows header (used on all platforms at
4- # configure time; the per-platform header values are identical for this field).
5- file (STRINGS "src/version/cef_version_win.h" _ver_line
3+ # Read the CEF major version from the version header for the platform being
4+ # built, so each platform uses its own CEF version (the values may differ
5+ # across platforms). This runs before project() sets WIN32/APPLE/UNIX, and
6+ # builds are always native (no cross-compiling), so select by host platform.
7+ if (CMAKE_HOST_WIN32 )
8+ set (_cef_version_header "src/version/cef_version_win.h" )
9+ elseif (CMAKE_HOST_APPLE )
10+ set (_cef_version_header "src/version/cef_version_macarm64.h" )
11+ else ()
12+ set (_cef_version_header "src/version/cef_version_linux.h" )
13+ endif ()
14+ file (STRINGS "${_cef_version_header} " _ver_line
615 REGEX "^#define CHROME_VERSION_MAJOR " )
716string (REGEX REPLACE "^#define CHROME_VERSION_MAJOR ([0-9]+).*" "\\ 1" _chrome_major "${_ver_line} " )
17+ # Full CEF version string, e.g. "147.0.10+gd58e84d+chromium-147.0.7727.118".
18+ # Used to select the matching prebuilt CEF directory under build/ so a leftover
19+ # directory from a different CEF version is never picked up by accident.
20+ file (STRINGS "${_cef_version_header} " _cef_version_line
21+ REGEX "^#define CEF_VERSION " )
22+ string (REGEX REPLACE "^#define CEF_VERSION \" ([^\" ]+)\" .*" "\\ 1" _cef_version "${_cef_version_line} " )
23+ message (STATUS "CEF version header: ${_cef_version_header} -> ${_cef_version} (major ${_chrome_major} )" )
824
925project (cefpython3 VERSION "${_chrome_major} .0" LANGUAGES CXX )
1026
@@ -46,16 +62,23 @@ if(NOT CEF_ROOT)
4662 set (_cef_glob_pat "${CMAKE_SOURCE_DIR } /build/cef*_linux64" )
4763 endif ()
4864 file (GLOB _cef_candidates LIST_DIRECTORIES true "${_cef_glob_pat} " )
49- # Prefer the versioned directory over cef_<os> fallback
65+ # Select the directory matching the exact CEF version from the header, so a
66+ # leftover prebuilt dir for a different CEF version in build/ is never picked
67+ # up by accident. string(FIND) is a literal substring search (the version
68+ # contains regex-special chars like '+' and '.', so MATCHES is unsafe here).
5069 foreach (_d IN LISTS _cef_candidates)
5170 if (IS_DIRECTORY "${_d} " )
52- set (CEF_ROOT "${_d} " )
53- break ()
71+ string (FIND "${_d} " "${_cef_version} " _ver_match)
72+ if (NOT _ver_match EQUAL -1)
73+ set (CEF_ROOT "${_d} " )
74+ break ()
75+ endif ()
5476 endif ()
5577 endforeach ()
5678 if (NOT CEF_ROOT)
5779 message (FATAL_ERROR
58- "CEF_ROOT not set and cannot be auto-detected. "
80+ "CEF_ROOT not set and no prebuilt CEF ${_cef_version} found under "
81+ "build/ (matching ${_cef_glob_pat} ). "
5982 "Download and prepare CEF first (python tools/download_cef.py && "
6083 "python tools/automate.py --prebuilt-cef), or pass -DCEF_ROOT=<path>." )
6184 endif ()
@@ -122,34 +145,90 @@ add_custom_command(
122145 VERBATIM
123146)
124147
125- # ---- Fix Cython API header --------------------------------------------------
126- # Generates:
127- # cefpython_pyXX_fixed.h – original .h with #pragma warning(disable:4190)
128- # cefpython_api_fixed.h – stable single-name wrapper for cefpython_public_api.h
129- set (CEFPYTHON_H_FIXED "${PYX_STAGE_DIR} /${MODULE_NAME} _fixed.h" )
130- set (CEF_API_FIXED_H "${PYX_STAGE_DIR} /cefpython_api_fixed.h" )
131-
132- add_custom_command (
133- OUTPUT "${CEFPYTHON_H_FIXED} " "${CEF_API_FIXED_H} "
134- COMMAND "${Python_EXECUTABLE} "
135- "${CMAKE_SOURCE_DIR } /tools/cmake_fix_header.py"
136- "${CEFPYTHON_H} "
137- "${CEFPYTHON_H_FIXED} "
138- "${CEF_API_FIXED_H} "
139- "${MODULE_NAME} "
140- DEPENDS "${CEFPYTHON_H} " "${CMAKE_SOURCE_DIR } /tools/cmake_fix_header.py"
141- COMMENT "Generating ${MODULE_NAME} _fixed.h + cefpython_api_fixed.h"
142- VERBATIM
143- )
144- add_custom_target (cefpython_headers
145- DEPENDS "${CEFPYTHON_H_FIXED} " "${CEF_API_FIXED_H} " )
148+ # ---- Cython API header ------------------------------------------------------
149+ # C++ sources include the Cython-generated public API header directly via the
150+ # CEFPYTHON_API_H_FILE define (= "${MODULE_NAME}.h"); it sits in PYX_STAGE_DIR
151+ # which is on each target's include path. No post-processing is needed: the
152+ # C4190 warning is suppressed by the /wd4190 compile flag (and the renderer
153+ # subprocess, which lacks that flag, doesn't include the header at all).
154+ # cefpython_headers gates C++ compilation on the header being generated.
155+ add_custom_target (cefpython_headers DEPENDS "${CEFPYTHON_H} " )
146156
147157# ---- Static C++ libraries ---------------------------------------------------
148158# All three libs share these settings so pass them via cache variables that
149159# the subdirectory CMakeLists files can read.
150160set (CEFPYTHON_PYX_STAGE_DIR "${PYX_STAGE_DIR} " CACHE INTERNAL "" )
151161set (CEFPYTHON_CEF_ROOT "${CEF_ROOT} " CACHE INTERNAL "" )
152162set (CEFPYTHON_SRC_DIR "${SRC_DIR} " CACHE INTERNAL "" )
163+ set (CEFPYTHON_CEF_VERSION "${_cef_version} " CACHE INTERNAL "" )
164+
165+ # Windows API target level. Match upstream CEF, which builds for Windows 10
166+ # (see cef_variables.cmake: WINVER/_WIN32_WINNT=0x0A00, NTDDI_WIN10_FE).
167+ # Chromium 147 only runs on Windows 10+, so targeting an older Windows here
168+ # would just hide newer Win32 APIs without buying real backward compatibility.
169+ # Defined once and consumed by both cefpython_common_flags (browser-process
170+ # targets) and the subprocess executable so the value can't drift between files.
171+ set (CEFPYTHON_WIN_TARGET_DEFS
172+ WINVER=0x0A00 _WIN32_WINNT=0x0A00 NTDDI_VERSION=NTDDI_WIN10_FE
173+ CACHE INTERNAL "Windows API target level (matches upstream CEF: Windows 10)" )
174+
175+ # Shared compile settings for the browser-process C++ targets (the Python
176+ # extension module, client_handler, cpp_utils, cefpython_app). These flags
177+ # were previously duplicated verbatim in every CMake file - in particular the
178+ # Windows definition block with the NTDDI_VERSION/WINVER/_WIN32_WINNT triple.
179+ # Define them once here as an INTERFACE library that those targets link.
180+ #
181+ # NOTE: the subprocess executable is a *renderer*-process target with different
182+ # settings (RENDERER_PROCESS, static /MT CRT, _HAS_EXCEPTIONS=0, no /EHsc) and
183+ # deliberately does NOT use this. BROWSER_PROCESS only affects
184+ # src/subprocess/cefpython_app.cpp; it is a no-op for the other sources.
185+ add_library (cefpython_common_flags INTERFACE )
186+ target_compile_definitions (cefpython_common_flags INTERFACE
187+ BROWSER_PROCESS
188+ CEFPYTHON_API_H_FILE= "${MODULE_NAME} .h"
189+ )
190+ if (WIN32 )
191+ target_compile_options (cefpython_common_flags INTERFACE /EHsc /wd4190 )
192+ target_compile_definitions (cefpython_common_flags INTERFACE
193+ WIN32 _WIN32 _WINDOWS
194+ ${CEFPYTHON_WIN_TARGET_DEFS}
195+ NDEBUG _NDEBUG _CRT_SECURE_NO_WARNINGS NOMINMAX
196+ )
197+ else ()
198+ target_compile_options (cefpython_common_flags INTERFACE -DNDEBUG -O3 )
199+ endif ()
200+
201+ # Filter a list of source files for the current platform: drop *_win.cpp,
202+ # *_linux.cpp, *_mac.cpp/.mm, x11.cpp and gtk* files that don't belong on the
203+ # OS being built. Shared by the client_handler and subprocess CMakeLists so the
204+ # rules live in one place. IN_LIST is the *name* of the input list variable;
205+ # the result is written to the variable named by OUT_VAR in the caller's scope.
206+ function (filter_sources IN_LIST OUT_VAR )
207+ set (_result "" )
208+ foreach (_f IN LISTS ${IN_LIST} )
209+ get_filename_component (_name "${_f} " NAME )
210+ set (_skip FALSE )
211+ if (_name MATCHES "_win\\ .cpp$" AND NOT WIN32 )
212+ set (_skip TRUE )
213+ endif ()
214+ if (_name MATCHES "_linux\\ .cpp$" AND NOT (CMAKE_SYSTEM_NAME STREQUAL "Linux" ))
215+ set (_skip TRUE )
216+ endif ()
217+ if (_name MATCHES "_mac\\ .(cpp|mm)$" AND NOT APPLE )
218+ set (_skip TRUE )
219+ endif ()
220+ if (_name MATCHES "^x11\\ .cpp$" AND NOT (CMAKE_SYSTEM_NAME STREQUAL "Linux" ))
221+ set (_skip TRUE )
222+ endif ()
223+ if (_name MATCHES "gtk" AND NOT (CMAKE_SYSTEM_NAME STREQUAL "Linux" ))
224+ set (_skip TRUE )
225+ endif ()
226+ if (NOT _skip)
227+ list (APPEND _result "${_f} " )
228+ endif ()
229+ endforeach ()
230+ set (${OUT_VAR} "${_result} " PARENT_SCOPE )
231+ endfunction ()
153232
154233add_subdirectory ("${SRC_DIR} /client_handler"
155234 "${CMAKE_CURRENT_BINARY_DIR } /client_handler" )
@@ -179,16 +258,13 @@ if(ENABLE_LINE_TRACING)
179258 target_compile_definitions (${MODULE_NAME} PRIVATE CYTHON_TRACE=1 )
180259endif ()
181260
261+ # Common browser-process flags come from cefpython_common_flags; only the
262+ # module-specific extras are listed per platform below.
263+ target_link_libraries (${MODULE_NAME} PRIVATE cefpython_common_flags )
264+
182265if (WIN32 )
183266 target_include_directories (${MODULE_NAME} PRIVATE "${SRC_DIR} /windows" )
184- target_compile_options (${MODULE_NAME} PRIVATE /EHsc /wd4305 /wd4190 )
185- target_compile_definitions (${MODULE_NAME} PRIVATE
186- WIN32 _WIN32 _WINDOWS
187- NTDDI_VERSION=0x06010000 WINVER=0x0601 _WIN32_WINNT=0x0601
188- NDEBUG _NDEBUG _CRT_SECURE_NO_WARNINGS NOMINMAX
189- BROWSER_PROCESS
190- CEFPYTHON_API_H_FILE= "cefpython_api_fixed.h"
191- )
267+ target_compile_options (${MODULE_NAME} PRIVATE /wd4305 )
192268 target_link_libraries (${MODULE_NAME} PRIVATE
193269 cefpython_app
194270 client_handler
@@ -200,16 +276,11 @@ if(WIN32)
200276 target_link_options (${MODULE_NAME} PRIVATE /ignore:4217 )
201277elseif (APPLE )
202278 target_compile_options (${MODULE_NAME} PRIVATE
203- -DNDEBUG -O3
204279 -Wno-return-type-c-linkage -Wno-constant-logical-operand
205280 -stdlib=libc++ -fno-strict-aliasing -fno-rtti
206281 -fno-threadsafe-statics -fobjc-call-cxx-cdtors
207282 -fvisibility=hidden -fvisibility-inlines-hidden
208283 )
209- target_compile_definitions (${MODULE_NAME} PRIVATE
210- BROWSER_PROCESS
211- CEFPYTHON_API_H_FILE= "cefpython_api_fixed.h"
212- )
213284 target_link_options (${MODULE_NAME} PRIVATE
214285 -mmacosx-version-min=11.0
215286 -Wl,-search_paths_first -Wl,-dead_strip
@@ -223,14 +294,9 @@ elseif(APPLE)
223294 )
224295else ()
225296 target_compile_options (${MODULE_NAME} PRIVATE
226- -DNDEBUG -O3
227297 -flto -fdata-sections -ffunction-sections
228298 -Wno-stringop-overflow
229299 )
230- target_compile_definitions (${MODULE_NAME} PRIVATE
231- BROWSER_PROCESS
232- CEFPYTHON_API_H_FILE= "cefpython_api_fixed.h"
233- )
234300 target_include_directories (${MODULE_NAME} PRIVATE
235301 ${GTK3_INCLUDE_DIRS}
236302 )
0 commit comments