mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-09-19 06:10:03 +00:00
qt6.qtwebengine: fix build on Darwin (#515997)
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
From 3f9ac6721aaeb9e9dd6347164219dc99bfde2a29 Mon Sep 17 00:00:00 2001
|
||||
From: Louis Opter <louis@opter.org>
|
||||
Date: Sat, 2 May 2026 22:22:03 +0000
|
||||
Subject: [PATCH 1/2] CMake: rename QWELibClang_{BIN,BASE}_PATH to
|
||||
QWELibClang_LLVM_{BIN,BASE}_PATH
|
||||
|
||||
These cache vars hold the LLVM installation prefix's bin dir and root
|
||||
directory -- where llvm-config and libclang.{so,dylib,dll} live -- but
|
||||
the unqualified names suggest "the path to the clang binary." Renaming
|
||||
makes the LLVM-prefix purpose explicit and frees the unqualified
|
||||
namespace for a separate compiler-invocation-prefix distinction
|
||||
introduced in a follow-up commit.
|
||||
|
||||
No functional change.
|
||||
---
|
||||
cmake/FindQWELibClang.cmake | 24 ++++++++++++------------
|
||||
cmake/QtToolchainHelpers.cmake | 4 ++--
|
||||
2 files changed, 14 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/cmake/FindQWELibClang.cmake b/cmake/FindQWELibClang.cmake
|
||||
index 3f6f484..ef7d570 100644
|
||||
--- a/cmake/FindQWELibClang.cmake
|
||||
+++ b/cmake/FindQWELibClang.cmake
|
||||
@@ -10,7 +10,7 @@ else()
|
||||
endif()
|
||||
|
||||
function(try_clang_executable Clang_EXECUTABLE)
|
||||
- if(NOT DEFINED QWELibClang_BIN_PATH)
|
||||
+ if(NOT DEFINED QWELibClang_LLVM_BIN_PATH)
|
||||
# Extract the base dir from the clang executable
|
||||
if(MSVC)
|
||||
set(CLANG_PRINT_PATH_COMMAND /clang:-print-prog-name=clang)
|
||||
@@ -28,13 +28,13 @@ function(try_clang_executable Clang_EXECUTABLE)
|
||||
file(TO_CMAKE_PATH "${clang_output}" clang_output) # $base_path/bin/clang
|
||||
get_filename_component(clang_output "${clang_output}" DIRECTORY) # $base_path/bin
|
||||
|
||||
- set(QWELibClang_BIN_PATH "${clang_output}" CACHE INTERNAL "internal")
|
||||
+ set(QWELibClang_LLVM_BIN_PATH "${clang_output}" CACHE INTERNAL "internal")
|
||||
endif()
|
||||
|
||||
# Try to find the llvm-config executable, and extract the library location from it
|
||||
find_program(QWELibClang_LLVM_CONFIG_EXECUTABLE
|
||||
NAMES llvm-config
|
||||
- PATHS ${QWELibClang_BIN_PATH}
|
||||
+ PATHS ${QWELibClang_LLVM_BIN_PATH}
|
||||
NO_DEFAULT_PATH)
|
||||
|
||||
if (QWELibClang_LLVM_CONFIG_EXECUTABLE)
|
||||
@@ -45,17 +45,17 @@ function(try_clang_executable Clang_EXECUTABLE)
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
file(TO_CMAKE_PATH "${llvm_config_output}" llvm_config_output)
|
||||
- get_filename_component(QWELibClang_BAS_PATH "${llvm_config_output}" DIRECTORY)
|
||||
+ get_filename_component(QWELibClang_LLVM_BAS_PATH "${llvm_config_output}" DIRECTORY)
|
||||
else()
|
||||
# No llvm-config. Get the base path from the binary directory
|
||||
# This is the expected path for Windows and macOS
|
||||
- get_filename_component(QWELibClang_BAS_PATH "${QWELibClang_BIN_PATH}" DIRECTORY)
|
||||
+ get_filename_component(QWELibClang_LLVM_BAS_PATH "${QWELibClang_LLVM_BIN_PATH}" DIRECTORY)
|
||||
endif()
|
||||
- set(QWELibClang_BASE_PATH ${QWELibClang_BAS_PATH} CACHE INTERNAL "internal")
|
||||
+ set(QWELibClang_LLVM_BASE_PATH ${QWELibClang_LLVM_BAS_PATH} CACHE INTERNAL "internal")
|
||||
|
||||
find_file(Libclang_LIBRARY
|
||||
NAMES libclang.dll libclang.dylib libclang.so
|
||||
- PATHS ${llvm_config_output} ${QWELibClang_BIN_PATH} ${QWELibClang_BASE_PATH}/lib ${QWELibClang_BASE_PATH}/lib64
|
||||
+ PATHS ${llvm_config_output} ${QWELibClang_LLVM_BIN_PATH} ${QWELibClang_LLVM_BASE_PATH}/lib ${QWELibClang_LLVM_BASE_PATH}/lib64
|
||||
NO_DEFAULT_PATH)
|
||||
|
||||
get_filename_component(Libclang_LIBRARY_DIR "${Libclang_LIBRARY}" DIRECTORY)
|
||||
@@ -110,9 +110,9 @@ if(Clang_EXECUTABLE)
|
||||
endif()
|
||||
|
||||
# As a backup find the clang version used by pyside on CI
|
||||
-if(NOT (QWELibClang_LIBRARY_DIR AND QWELibClang_BASE_PATH AND QWELibClang_BIN_PATH) AND DEFINED ENV{LLVM_DYNAMIC_LIBS_100})
|
||||
+if(NOT (QWELibClang_LIBRARY_DIR AND QWELibClang_LLVM_BASE_PATH AND QWELibClang_LLVM_BIN_PATH) AND DEFINED ENV{LLVM_DYNAMIC_LIBS_100})
|
||||
unset(Clang_EXECUTABLE)
|
||||
- unset(QWELibClang_BIN_PATH CACHE)
|
||||
+ unset(QWELibClang_LLVM_BIN_PATH CACHE)
|
||||
find_program(Clang_EXECUTABLE NAMES clang PATHS $ENV{LLVM_DYNAMIC_LIBS_100}/bin)
|
||||
if(Clang_EXECUTABLE)
|
||||
try_clang_executable(${Clang_EXECUTABLE})
|
||||
@@ -122,12 +122,12 @@ endif()
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_package_handle_standard_args(QWELibClang
|
||||
- REQUIRED_VARS QWELibClang_LIBRARY_DIR QWELibClang_BASE_PATH QWELibClang_BIN_PATH
|
||||
+ REQUIRED_VARS QWELibClang_LIBRARY_DIR QWELibClang_LLVM_BASE_PATH QWELibClang_LLVM_BIN_PATH
|
||||
VERSION_VAR QWELibClang_VERSION
|
||||
)
|
||||
|
||||
-mark_as_advanced(QWELibClang_BIN_PATH)
|
||||
-mark_as_advanced(QWELibClang_BASE_PATH)
|
||||
+mark_as_advanced(QWELibClang_LLVM_BIN_PATH)
|
||||
+mark_as_advanced(QWELibClang_LLVM_BASE_PATH)
|
||||
mark_as_advanced(QWELibClang_LIBRARY_DIR)
|
||||
mark_as_advanced(QWELibClang_RUNTIME_PATH)
|
||||
mark_as_advanced(QWELibClang_RESOURCE_PATH)
|
||||
diff --git a/cmake/QtToolchainHelpers.cmake b/cmake/QtToolchainHelpers.cmake
|
||||
index b0cd2dd..885fd53 100644
|
||||
--- a/cmake/QtToolchainHelpers.cmake
|
||||
+++ b/cmake/QtToolchainHelpers.cmake
|
||||
@@ -404,7 +404,7 @@ macro(append_compiler_linker_sdk_setup)
|
||||
)
|
||||
endif()
|
||||
list(APPEND gnArgArg
|
||||
- clang_base_path="${QWELibClang_BASE_PATH}"
|
||||
+ clang_base_path="${QWELibClang_LLVM_BASE_PATH}"
|
||||
clang_version="${clang_runtime_path_version}"
|
||||
clang_use_chrome_plugins=false
|
||||
fatal_linker_warnings=false
|
||||
@@ -455,7 +455,7 @@ macro(append_compiler_linker_sdk_setup)
|
||||
endif()
|
||||
else()
|
||||
if(QT_FEATURE_use_lld_linker OR QT_FEATURE_webengine_rust_build)
|
||||
- list(APPEND gnArgArg clang_base_path="${QWELibClang_BASE_PATH}")
|
||||
+ list(APPEND gnArgArg clang_base_path="${QWELibClang_LLVM_BASE_PATH}")
|
||||
if (QT_FEATURE_webengine_rust_build)
|
||||
get_clang_runtime_path_version(clang_runtime_path_version)
|
||||
list(APPEND gnArgArg clang_version="${clang_runtime_path_version}")
|
||||
|
||||
From 76d33954567d9d96a738a4f1e8baea69d66286b2 Mon Sep 17 00:00:00 2001
|
||||
From: Louis Opter <louis@opter.org>
|
||||
Date: Sat, 2 May 2026 22:22:55 +0000
|
||||
Subject: [PATCH 2/2] CMake: source clang_base_path from CMake-detected
|
||||
compiler dir
|
||||
|
||||
The clang_base_path argument fed to Chromium's build system is used to
|
||||
invoke ${clang_base_path}/bin/clang++ when compiling chromium sources.
|
||||
Since 695dd68f8 ("Optionally build using rust"), it has been derived
|
||||
from QWELibClang_LLVM_BIN_PATH, which in turn is computed by running
|
||||
"clang -print-prog-name=clang" and taking dirname twice. That
|
||||
indirection produces wrong results on wrapped toolchains (ccache,
|
||||
distcc, sccache, nixpkgs cc-wrapper) where the wrapper script and the
|
||||
underlying clang live in different directories: the wrapper forwards
|
||||
the flag, the bare clang reports its own absolute path, and
|
||||
clang_base_path ends up at the bare LLVM prefix. The downstream
|
||||
chromium compilation then invokes the unwrapped clang, bypassing
|
||||
wrapper-injected flags such as -isystem for the libc++ headers, and
|
||||
fails on "'atomic' file not found".
|
||||
|
||||
The print-prog-name indirection has a legitimate other purpose in this
|
||||
file: locating llvm-config and libclang.{so,dylib,dll}. These live in
|
||||
the bare LLVM prefix, not the wrapper directory, because wrappers are
|
||||
deliberately scoped to compile-driver flag injection: they ship the
|
||||
cc/c++/cpp shims plus bintools symlinks, nothing else -- no lib/ and
|
||||
no LLVM dev tools alongside. So we cannot simply revert the
|
||||
indirection; QWELibClang_LLVM_BIN_PATH and QWELibClang_LLVM_BASE_PATH
|
||||
remain unchanged for the libclang/llvm-config lookups they feed.
|
||||
|
||||
Instead, introduce QWELibClang_COMPILER_BIN_PATH and
|
||||
QWELibClang_COMPILER_BASE_PATH, derived directly from Clang_EXECUTABLE
|
||||
via dirname, and route clang_base_path in QtToolchainHelpers.cmake
|
||||
through them. On a non-wrapped toolchain the two paths are identical,
|
||||
so this change is a no-op there.
|
||||
|
||||
Reproduced on x86_64-darwin with nixpkgs (Qt 6.10.2 worked because the
|
||||
pre-695dd68f8 inline "dirname dirname ${CMAKE_OBJCXX_COMPILER}" ended
|
||||
up at the wrapper directory; Qt 6.11.0 fails). After this change,
|
||||
chromium compilation invokes the wrapper, NIX_CFLAGS_COMPILE flows
|
||||
through, and qtwebengine builds successfully.
|
||||
---
|
||||
cmake/FindQWELibClang.cmake | 12 ++++++++++++
|
||||
cmake/QtToolchainHelpers.cmake | 4 ++--
|
||||
2 files changed, 14 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/cmake/FindQWELibClang.cmake b/cmake/FindQWELibClang.cmake
|
||||
index ef7d570..62c87be 100644
|
||||
--- a/cmake/FindQWELibClang.cmake
|
||||
+++ b/cmake/FindQWELibClang.cmake
|
||||
@@ -31,6 +31,15 @@ function(try_clang_executable Clang_EXECUTABLE)
|
||||
set(QWELibClang_LLVM_BIN_PATH "${clang_output}" CACHE INTERNAL "internal")
|
||||
endif()
|
||||
|
||||
+ if(NOT DEFINED QWELibClang_COMPILER_BIN_PATH)
|
||||
+ # Directory of the compiler that CMake invokes; on a wrapped toolchain
|
||||
+ # this differs from QWELibClang_LLVM_BIN_PATH.
|
||||
+ get_filename_component(compiler_bin_path "${Clang_EXECUTABLE}" DIRECTORY) # $compiler_base_path/bin
|
||||
+ get_filename_component(compiler_base_path "${compiler_bin_path}" DIRECTORY) # $compiler_base_path
|
||||
+ set(QWELibClang_COMPILER_BIN_PATH "${compiler_bin_path}" CACHE INTERNAL "internal")
|
||||
+ set(QWELibClang_COMPILER_BASE_PATH "${compiler_base_path}" CACHE INTERNAL "internal")
|
||||
+ endif()
|
||||
+
|
||||
# Try to find the llvm-config executable, and extract the library location from it
|
||||
find_program(QWELibClang_LLVM_CONFIG_EXECUTABLE
|
||||
NAMES llvm-config
|
||||
@@ -113,6 +122,7 @@ endif()
|
||||
if(NOT (QWELibClang_LIBRARY_DIR AND QWELibClang_LLVM_BASE_PATH AND QWELibClang_LLVM_BIN_PATH) AND DEFINED ENV{LLVM_DYNAMIC_LIBS_100})
|
||||
unset(Clang_EXECUTABLE)
|
||||
unset(QWELibClang_LLVM_BIN_PATH CACHE)
|
||||
+ unset(QWELibClang_COMPILER_BIN_PATH CACHE)
|
||||
find_program(Clang_EXECUTABLE NAMES clang PATHS $ENV{LLVM_DYNAMIC_LIBS_100}/bin)
|
||||
if(Clang_EXECUTABLE)
|
||||
try_clang_executable(${Clang_EXECUTABLE})
|
||||
@@ -128,6 +138,8 @@ find_package_handle_standard_args(QWELibClang
|
||||
|
||||
mark_as_advanced(QWELibClang_LLVM_BIN_PATH)
|
||||
mark_as_advanced(QWELibClang_LLVM_BASE_PATH)
|
||||
+mark_as_advanced(QWELibClang_COMPILER_BIN_PATH)
|
||||
+mark_as_advanced(QWELibClang_COMPILER_BASE_PATH)
|
||||
mark_as_advanced(QWELibClang_LIBRARY_DIR)
|
||||
mark_as_advanced(QWELibClang_RUNTIME_PATH)
|
||||
mark_as_advanced(QWELibClang_RESOURCE_PATH)
|
||||
diff --git a/cmake/QtToolchainHelpers.cmake b/cmake/QtToolchainHelpers.cmake
|
||||
index 885fd53..3c86a03 100644
|
||||
--- a/cmake/QtToolchainHelpers.cmake
|
||||
+++ b/cmake/QtToolchainHelpers.cmake
|
||||
@@ -404,7 +404,7 @@ macro(append_compiler_linker_sdk_setup)
|
||||
)
|
||||
endif()
|
||||
list(APPEND gnArgArg
|
||||
- clang_base_path="${QWELibClang_LLVM_BASE_PATH}"
|
||||
+ clang_base_path="${QWELibClang_COMPILER_BASE_PATH}"
|
||||
clang_version="${clang_runtime_path_version}"
|
||||
clang_use_chrome_plugins=false
|
||||
fatal_linker_warnings=false
|
||||
@@ -455,7 +455,7 @@ macro(append_compiler_linker_sdk_setup)
|
||||
endif()
|
||||
else()
|
||||
if(QT_FEATURE_use_lld_linker OR QT_FEATURE_webengine_rust_build)
|
||||
- list(APPEND gnArgArg clang_base_path="${QWELibClang_LLVM_BASE_PATH}")
|
||||
+ list(APPEND gnArgArg clang_base_path="${QWELibClang_COMPILER_BASE_PATH}")
|
||||
if (QT_FEATURE_webengine_rust_build)
|
||||
get_clang_runtime_path_version(clang_runtime_path_version)
|
||||
list(APPEND gnArgArg clang_version="${clang_runtime_path_version}")
|
||||
@@ -117,6 +117,12 @@ qtModule {
|
||||
|
||||
# Reproducibility QTBUG-136068
|
||||
./gn-object-sorted.patch
|
||||
]
|
||||
# Remove once merged with upstream
|
||||
++ lib.optionals stdenv.hostPlatform.isDarwin [
|
||||
./clang-base-path-from-cmake-compiler.patch
|
||||
|
||||
./lflags-remove-strip-darwin-isysroot.patch
|
||||
];
|
||||
|
||||
postPatch = ''
|
||||
@@ -158,8 +164,6 @@ qtModule {
|
||||
+ lib.optionalString stdenv.hostPlatform.isDarwin ''
|
||||
substituteInPlace cmake/QtToolchainHelpers.cmake \
|
||||
--replace-fail "/usr/bin/xcrun" "${xcbuild}/bin/xcrun"
|
||||
substituteInPlace cmake/QtToolchainHelpers.cmake \
|
||||
--replace-fail 'clang_base_path="''${QWELibClang_BASE_PATH}"' 'clang_base_path="${stdenv.cc}"'
|
||||
|
||||
# xcbuild's xcrun doesn't implement the real (proprietary) Metal shader
|
||||
# compiler, so this check always fails. The one build step that actually
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
Subject: Build: strip relative -isysroot from chromium-emitted lflags
|
||||
|
||||
In src/{core,pdf}/configure/BUILD.root.gn.in, lflags_remove is fed to
|
||||
the rsp writer in our gn fork
|
||||
(src/3rdparty/gn/src/gn/rsp_target_writer.cc, LFLAGS case) where it
|
||||
runs std::regex_replace over the accumulated ldflags before writing
|
||||
the rsp file. The intent, per the inline comment, is to drop sysroot
|
||||
flags whose path was emitted as relative.
|
||||
|
||||
Such relative paths are produced by chromium's mac/linux toolchain
|
||||
configs via rebase_path(sysroot, root_build_dir). For qtwebengine, the
|
||||
chromium root_build_dir is build/src/core/Release/$arch, so the
|
||||
rebased path is correct when read from there -- but the rsp file is
|
||||
consumed by the *cmake*-driven ninja link, which runs from build/. The
|
||||
two cwds differ by four levels, so the rebased path resolves to a
|
||||
non-existent location, triggering -Wmissing-sysroot and a subsequent
|
||||
"framework not found CoreFoundation" failure (linker falls back to a
|
||||
bogus sysroot, can't find /System/Library/Frameworks under it).
|
||||
|
||||
The existing pattern only matched the Linux --sysroot=PATH single-
|
||||
token form, so the Apple two-token form '-isysroot PATH' slipped
|
||||
through untouched. Extend the alternation to cover both, and tighten
|
||||
the path match to \.\./\S+ (the prior \.\./.*\S*? was effectively
|
||||
\.\./.* and worked only because --sysroot= was the last token in
|
||||
the Linux ldflags string -- on macOS -isysroot is followed by more
|
||||
flags like -mmacos-version-min, so we need a match that stops at the
|
||||
next whitespace).
|
||||
|
||||
Also add lflags_remove to the convert_dict target, which declares
|
||||
rsp_types but had no filter; on macOS it hits the same relative
|
||||
-isysroot issue as QtWebEngineCore (the linker fails on -lbsm because
|
||||
the bogus sysroot wins last and ld can't resolve system libs under
|
||||
it). QtWebEngineCore and QtPdf had the filter; convert_dict appears
|
||||
to have been overlooked.
|
||||
|
||||
The good absolute -isysroot is already injected on the clang++ command
|
||||
line by cmake earlier, so stripping the bad one is sufficient
|
||||
(-isysroot is last-wins, and now only the good one remains).
|
||||
|
||||
Reproduced on aarch64-darwin with nixpkgs's apple-sdk-15.5, on
|
||||
Qt 6.11.0. After this change qtwebengine builds successfully.
|
||||
|
||||
diff --git a/src/core/configure/BUILD.root.gn.in b/src/core/configure/BUILD.root.gn.in
|
||||
index cf9a3fe..3b01162 100644
|
||||
--- a/src/core/configure/BUILD.root.gn.in
|
||||
+++ b/src/core/configure/BUILD.root.gn.in
|
||||
@@ -107,7 +107,7 @@ if (ozone_platform_x11) {
|
||||
|
||||
shared_library("QtWebEngineCore") {
|
||||
rsp_types = [ "objects", "archives", "libs", "ldir", "lflags" ]
|
||||
- lflags_remove = "(--sysroot=)(\\.\\./.*\\S*?)" # ignore sysroot with realative path
|
||||
+ lflags_remove = "(--sysroot=|-isysroot )\\.\\./\\S+" # ignore sysroot with relative path
|
||||
configs += [
|
||||
":cpp20_config",
|
||||
":QtWebEngineCore_config",
|
||||
@@ -846,6 +846,7 @@ if (enable_extensions) {
|
||||
if (enable_spellcheck) {
|
||||
shared_library("convert_dict") {
|
||||
rsp_types = [ "objects", "archives", "libs", "ldir", "lflags" ]
|
||||
+ lflags_remove = "(--sysroot=|-isysroot )\\.\\./\\S+" # ignore sysroot with relative path
|
||||
configs += [ "//build/config/compiler:wexit_time_destructors" ]
|
||||
deps = [
|
||||
"//chrome/tools/convert_dict:lib",
|
||||
diff --git a/src/pdf/configure/BUILD.root.gn.in b/src/pdf/configure/BUILD.root.gn.in
|
||||
index 72d4558..c63cfda 100644
|
||||
--- a/src/pdf/configure/BUILD.root.gn.in
|
||||
+++ b/src/pdf/configure/BUILD.root.gn.in
|
||||
@@ -51,7 +51,7 @@ config("cpp20_config") {
|
||||
static_library("QtPdf") {
|
||||
complete_static_lib = true
|
||||
rsp_types = [ "objects", "archives", "libs", "ldir", "lflags" ]
|
||||
- lflags_remove = "(--sysroot=)(\\.\\./.*\\S*?)" # ignore sysroot with realative path
|
||||
+ lflags_remove = "(--sysroot=|-isysroot )\\.\\./\\S+" # ignore sysroot with relative path
|
||||
configs += [
|
||||
":cpp20_config",
|
||||
":QtPdf_config"
|
||||
Reference in New Issue
Block a user