Compare commits

...
2 Commits
Author SHA1 Message Date
Clifford Yapp 3c4a035e0f Get mmesh math fix 2026-08-31 19:23:28 +00:00
Clifford Yapp 5a9782e40a Experiment with Xmin for headless testing 2026-08-26 21:05:57 +00:00
10 changed files with 445 additions and 23 deletions
+5 -5
View File
@@ -200,8 +200,8 @@ include(ExternalProject)
# source patching or staging is needed.
# * Use a local URL when patching a submodule, so ExternalProject stages a
# build-tree copy before PATCH_COMMAND and other source modifications run.
# * A deliberate exception is a very large source tree such as Qt6, where the
# copy cost is significant and in-place patching/building is preferred.
# * A large source tree such as Qt6 is built in place when unmodified, but is
# staged when caller-supplied patches must be applied.
# Do not replace URL with SOURCE_DIR merely to avoid the local URL spelling;
# that can cause patches or generated-file changes to modify the checkout.
@@ -442,14 +442,14 @@ add_project(astyle GROUPS "BRLCAD")
add_project(lemon GROUPS "BRLCAD")
add_project(re2c GROUPS "BRLCAD")
add_project(perplex GROUPS "BRLCAD")
add_project(strclear GROUPS "BRLCAD")
add_project(strclear)
add_project(xmltools GROUPS "BRLCAD_EXTRA") # Used for Docbook building
# RPATH editing - LIEF has the core capabilities, and plief exposes them via
# a command line utility with patchelf compatible options, so we can drop
# either patchelf or plief into our upstream workflows.
add_project(lief GROUPS "BRLCAD")
add_project(plief GROUPS "BRLCAD")
add_project(lief)
add_project(plief)
# Keeping this set up for easy turn-on until we're confident plief+LIEF has
# all of our use cases covered - plief is preferred, but we've already hit
+38
View File
@@ -61,6 +61,44 @@ When `bext` is driven from a BRL-CAD build, `BRLCAD_COMPONENTS` can further
narrow some BRL-CAD-related packages to only those needed by the requested
component set.
## Additional bundled Tk patches
Unix builds may pass a semicolon-separated list of absolute patch paths in
`TK_EXTRA_PATCHES`. The patches are applied after bext's built-in Tk patches.
Additional arguments for Tk's Unix `configure` script may likewise be supplied
as a semicolon-separated `TK_CONFIGURE_ARGS` list. For example:
```sh
cmake -DTK_EXTRA_PATCHES=/absolute/path/tk.patch \
-DTK_CONFIGURE_ARGS=--with-example=/absolute/prefix ...
```
## Xmin-backed bundled Qt
An installed Xmin SDK can provide the complete X11/XCB/OpenGL surface for
bext's bundled Qt without linking Qt to host X libraries. Set
`QT_XMIN_ROOT` to the exact SDK prefix and provide the patch matching bext's
Qt version in `QT_EXTRA_PATCHES`:
```sh
cmake -S /path/to/bext -B /path/to/bext-build \
-DENABLE_QT=ON \
-DQT_XMIN_ROOT=/absolute/path/to/xmin-sdk \
-DQT_EXTRA_PATCHES=/absolute/path/to/Xmin/patches/qt/qt-6.11.1-xmin.patch
```
The Xmin SDK must have been installed with `XMIN_BUILD_QT_CLIENT=ON` and
`XMIN_BUILD_CLIENT_GL=ON`. This mode forces Qt's qxcb desktop-OpenGL profile,
uses bundled font and image dependencies, disables conventional X11, XCB,
xkbcommon, EGL, and OpenGL package discovery, and rejects Qt artifacts that
resolve any corresponding host libraries. Normal Qt autodetection is
unchanged when `QT_XMIN_ROOT` is empty.
Qt's installed package metadata retains an explicit dependency on Xmin.
Downstream projects must therefore keep the same SDK discoverable with
`Xmin_DIR` or `CMAKE_PREFIX_PATH`; configuration fails instead of falling back
to host X libraries when that SDK is absent.
# Official profiles
The supported configure entry points are:
+149 -6
View File
@@ -1,6 +1,16 @@
# Decide if we're using Qt6
cad_enable(QT "libqtcad")
set(QT_EXTRA_PATCHES "" CACHE STRING "Additional patches to apply to bundled Qt6")
set(QT_XMIN_ROOT "" CACHE PATH "Installed Xmin SDK used by bundled Qt6")
if (QT_XMIN_ROOT)
if (DISABLE_QT)
message(FATAL_ERROR "QT_XMIN_ROOT cannot be used when Qt is disabled")
endif ()
set(ENABLE_QT "ON" CACHE BOOL "Enable Qt6 build" FORCE)
endif ()
if (NOT ENABLE_QT AND NOT DISABLE_QT)
# Optional probe: a missing Qt6 just turns on the local build below, so pass
@@ -23,6 +33,77 @@ if (ENABLE_QT)
git_submodule_init(qt qtbase/configure)
set(QT_XMIN_ENABLED OFF)
set(QT_XMIN_DIR "")
set(QT_XMIN_RUNTIME_DIRS "")
set(QT_XMIN_CLIENT_DIR "")
set(QT_XMIN_GL_DIR "")
if (QT_XMIN_ROOT)
if (NOT UNIX OR APPLE)
message(FATAL_ERROR "The Xmin Qt profile currently requires Linux or BSD")
endif ()
if (NOT QT_EXTRA_PATCHES)
message(FATAL_ERROR
"QT_XMIN_ROOT requires the matching Xmin Qt patch in QT_EXTRA_PATCHES")
endif ()
if (NOT IS_DIRECTORY "${QT_XMIN_ROOT}")
message(FATAL_ERROR "QT_XMIN_ROOT is not an installed SDK: ${QT_XMIN_ROOT}")
endif ()
file(REAL_PATH "${QT_XMIN_ROOT}" qt_xmin_root_real)
set(QT_XMIN_ROOT "${qt_xmin_root_real}" CACHE PATH
"Installed Xmin SDK used by bundled Qt6" FORCE)
unset(Xmin_DIR CACHE)
find_package(Xmin 0.1 CONFIG REQUIRED
PATHS "${QT_XMIN_ROOT}"
NO_DEFAULT_PATH
)
if (NOT TARGET Xmin::QtX11 OR NOT TARGET Xmin::GL OR
NOT TARGET Xmin::ClientX11)
message(FATAL_ERROR
"QT_XMIN_ROOT must provide Xmin::QtX11, Xmin::GL, and Xmin::ClientX11")
endif ()
file(REAL_PATH "${Xmin_DIR}" qt_xmin_dir_real)
cmake_path(IS_PREFIX qt_xmin_root_real "${qt_xmin_dir_real}"
NORMALIZE qt_xmin_dir_in_root)
if (NOT qt_xmin_dir_in_root)
message(FATAL_ERROR
"Xmin was resolved outside QT_XMIN_ROOT: ${qt_xmin_dir_real}")
endif ()
set(QT_XMIN_DIR "${qt_xmin_dir_real}")
function(qt_xmin_imported_location target output_var)
get_target_property(imported_configs "${target}" IMPORTED_CONFIGURATIONS)
set(imported_location "")
foreach(imported_config IN LISTS imported_configs)
string(TOUPPER "${imported_config}" imported_config_upper)
get_target_property(candidate "${target}"
"IMPORTED_LOCATION_${imported_config_upper}")
if (candidate AND EXISTS "${candidate}")
set(imported_location "${candidate}")
break()
endif ()
endforeach()
if (NOT imported_location)
get_target_property(imported_location "${target}" IMPORTED_LOCATION)
endif ()
if (NOT imported_location OR NOT EXISTS "${imported_location}")
message(FATAL_ERROR "Unable to locate imported Xmin target ${target}")
endif ()
set(${output_var} "${imported_location}" PARENT_SCOPE)
endfunction()
qt_xmin_imported_location(Xmin::ClientX11 qt_xmin_client_library)
qt_xmin_imported_location(Xmin::GL qt_xmin_gl_library)
get_filename_component(QT_XMIN_CLIENT_DIR "${qt_xmin_client_library}" DIRECTORY)
get_filename_component(QT_XMIN_GL_DIR "${qt_xmin_gl_library}" DIRECTORY)
set(QT_XMIN_RUNTIME_DIRS "${QT_XMIN_GL_DIR};${QT_XMIN_CLIENT_DIR}")
list(REMOVE_DUPLICATES QT_XMIN_RUNTIME_DIRS)
set(QT_XMIN_ENABLED ON)
endif ()
RegisterDeps(Qt6)
if (isMultiConfig)
@@ -31,11 +112,54 @@ if (ENABLE_QT)
set(CBT ${CMAKE_BUILD_TYPE})
endif (isMultiConfig)
set(QT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/qt/qtbase")
set(QT_UPSTREAM_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/qt/qtbase")
set(QT_SOURCE_DIR "${QT_UPSTREAM_SOURCE_DIR}")
set(QT_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/qt6-build")
set(QT_PATCH_COMMAND)
set(qt_patch_hash_input "")
foreach(QT_EXTRA_PATCH IN LISTS QT_EXTRA_PATCHES)
if (NOT IS_ABSOLUTE "${QT_EXTRA_PATCH}")
message(FATAL_ERROR "QT_EXTRA_PATCHES entries must be absolute paths: ${QT_EXTRA_PATCH}")
endif ()
if (NOT EXISTS "${QT_EXTRA_PATCH}")
message(FATAL_ERROR "Additional Qt patch does not exist: ${QT_EXTRA_PATCH}")
endif ()
file(SHA256 "${QT_EXTRA_PATCH}" qt_patch_hash)
string(APPEND qt_patch_hash_input "${QT_EXTRA_PATCH}:${qt_patch_hash}\n")
if (NOT QT_PATCH_COMMAND)
set(QT_PATCH_COMMAND
PATCH_COMMAND ${PATCH_EXECUTABLE} -E -p1 ${PATCH_OPTIONS} -i ${QT_EXTRA_PATCH}
)
else ()
list(APPEND QT_PATCH_COMMAND
COMMAND ${PATCH_EXECUTABLE} -E -p1 ${PATCH_OPTIONS} -i ${QT_EXTRA_PATCH}
)
endif ()
endforeach()
string(SHA256 QT_PATCH_SIGNATURE "${qt_patch_hash_input}")
# Make ExternalProject's configure rule sensitive to both the selected
# profile and this wrapper script. The script's own signature then clears
# Qt's generated build tree before reconfiguring.
file(SHA256 "${CMAKE_CURRENT_SOURCE_DIR}/qt_config.cmake.in"
qt_config_template_hash)
string(SHA256 QT_CONFIG_SIGNATURE
"${QT_PATCH_SIGNATURE}|${QT_XMIN_ENABLED}|${QT_XMIN_ROOT}|${QT_XMIN_DIR}|${qt_config_template_hash}|${CMAKE_BUILD_TYPE}")
set(QT_SOURCE_ARGUMENTS SOURCE_DIR "${QT_SOURCE_DIR}")
if (QT_EXTRA_PATCHES)
string(SUBSTRING "${QT_PATCH_SIGNATURE}" 0 12 qt_patch_short_hash)
set(QT_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/qt6-source-${qt_patch_short_hash}")
set(QT_SOURCE_ARGUMENTS
URL "${QT_UPSTREAM_SOURCE_DIR}"
SOURCE_DIR "${QT_SOURCE_DIR}"
)
endif ()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/qt_config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/qt_config.cmake @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/qt_build.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/qt_build.cmake @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/qt_install.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/qt_install.cmake @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/qt_xmin_audit.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/qt_xmin_audit.cmake @ONLY)
set(QAH "OFF")
if (QT_ALLOW_HEADLESS)
@@ -43,11 +167,11 @@ if (ENABLE_QT)
endif (QT_ALLOW_HEADLESS)
ExternalProject_Add(Qt6_BLD
SOURCE_DIR "${QT_SOURCE_DIR}"
${QT_SOURCE_ARGUMENTS}
BINARY_DIR "${QT_BUILD_DIR}"
BUILD_ALWAYS ${EXT_BUILD_ALWAYS} ${LOG_OPTS}
#PATCH_COMMAND ${PATCH_EXECUTABLE};-E;-p1;${PATCH_OPTIONS};-i;${CMAKE_CURRENT_SOURCE_DIR}/qt.patch
CONFIGURE_COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=${CBT} -DQT_ALLOW_HEADLESS=${QAH} -DBEXT_QT_TARGET_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -P ${CMAKE_CURRENT_BINARY_DIR}/qt_config.cmake
${QT_PATCH_COMMAND}
CONFIGURE_COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=${CBT} -DQT_ALLOW_HEADLESS=${QAH} -DBEXT_QT_TARGET_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DQT_CONFIG_SIGNATURE=${QT_CONFIG_SIGNATURE} -P ${CMAKE_CURRENT_BINARY_DIR}/qt_config.cmake
BUILD_COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=${CBT} -P ${CMAKE_CURRENT_BINARY_DIR}/qt_build.cmake
INSTALL_COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/qt_install.cmake
LOG_CONFIGURE ${EXT_BUILD_QUIET}
@@ -59,6 +183,13 @@ if (ENABLE_QT)
TargetInstallDeps(Qt6 Qt6_DEPENDS)
set(QT_INSTALL_RPATH_DIRS "${CMAKE_BUNDLE_INSTALL_PREFIX}/${LIB_DIR}")
if (QT_XMIN_ENABLED)
list(APPEND QT_INSTALL_RPATH_DIRS ${QT_XMIN_RUNTIME_DIRS})
endif ()
list(REMOVE_DUPLICATES QT_INSTALL_RPATH_DIRS)
string(JOIN ":" QT_INSTALL_RPATH ${QT_INSTALL_RPATH_DIRS})
ExternalProject_Add(Qt6Svg_BLD
URL "${CMAKE_CURRENT_SOURCE_DIR}/qt/qtsvg"
BUILD_ALWAYS ${EXT_BUILD_ALWAYS} ${LOG_OPTS}
@@ -71,11 +202,12 @@ if (ENABLE_QT)
-DZLIB_ROOT=$<$<BOOL:${ZLIB_TARGET}>:${CMAKE_BUNDLE_INSTALL_PREFIX}>
-DQt6_DIR=${CMAKE_BUNDLE_INSTALL_PREFIX}/${LIB_DIR}/cmake/Qt6
-DQt6_ROOT=${CMAKE_BUNDLE_INSTALL_PREFIX}
$<$<BOOL:${QT_XMIN_ENABLED}>:-DXmin_DIR=${QT_XMIN_DIR}>
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_INSTALL_PREFIX=${CMAKE_BUNDLE_INSTALL_PREFIX}
-DCMAKE_INSTALL_LIBDIR:PATH=${LIB_DIR}
-DCMAKE_INSTALL_RPATH=${CMAKE_BUNDLE_INSTALL_PREFIX}/${LIB_DIR}
-DCMAKE_INSTALL_RPATH=${QT_INSTALL_RPATH}
LOG_CONFIGURE ${EXT_BUILD_QUIET}
LOG_BUILD ${EXT_BUILD_QUIET}
LOG_INSTALL ${EXT_BUILD_QUIET}
@@ -83,6 +215,18 @@ if (ENABLE_QT)
STEP_TARGETS install
)
if (QT_XMIN_ENABLED)
ExternalProject_Add_Step(Qt6Svg_BLD xmin_audit
COMMAND ${CMAKE_COMMAND}
-DQT_AUDIT_ROOT=${CMAKE_BUNDLE_INSTALL_PREFIX}
-DQT_AUDIT_INCLUDE_SVG=ON
-P ${CMAKE_CURRENT_BINARY_DIR}/qt_xmin_audit.cmake
DEPENDEES install
ALWAYS 1
COMMENT "Auditing installed QtSvg Xmin dependencies"
)
endif ()
ExternalProject_Add_StepDependencies(Qt6Svg_BLD configure Qt6_BLD-install)
# Copy the license info into position in CMAKE_BUNDLE_INSTALL_PREFIX
@@ -105,4 +249,3 @@ mark_as_advanced(Qt6_VERSION)
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+14 -1
View File
@@ -3,7 +3,9 @@
# putting that directory first makes tools such as qtwaylandscanner fail with
# missing Qt symbol versions while a newer Qt is being built.
if (NOT WIN32)
set(ENV{LD_LIBRARY_PATH} "@QT_BUILD_DIR@/@LIB_DIR@:@CMAKE_BUNDLE_INSTALL_PREFIX@/@LIB_DIR@")
set(qt_runtime_dirs "@QT_XMIN_RUNTIME_DIRS@" "@QT_BUILD_DIR@/@LIB_DIR@" "@CMAKE_BUNDLE_INSTALL_PREFIX@/@LIB_DIR@")
string(JOIN ":" qt_runtime_path ${qt_runtime_dirs})
set(ENV{LD_LIBRARY_PATH} "${qt_runtime_path}")
endif (NOT WIN32)
if ("${CMAKE_BUILD_TYPE}" STREQUAL "" OR "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
@@ -20,6 +22,17 @@ if (QT_RET)
message(FATAL_ERROR "Qt build failed: ${MSG}\n")
endif (QT_RET)
if ("@QT_XMIN_ENABLED@" STREQUAL "ON")
execute_process(
COMMAND "@CMAKE_COMMAND@" -DQT_AUDIT_ROOT=@QT_BUILD_DIR@
-P "@CMAKE_CURRENT_BINARY_DIR@/qt_xmin_audit.cmake"
RESULT_VARIABLE QT_AUDIT_RET
)
if (QT_AUDIT_RET)
message(FATAL_ERROR "Qt Xmin dependency audit failed")
endif ()
endif ()
message("Qt build succeeded: ${MSG}\n")
# Local Variables:
+112 -6
View File
@@ -1,6 +1,11 @@
set(CONFIG_FILE configure)
set(ENV_VARS)
set(CONFIG_EXTRA_OPTS)
set(QT_CMAKE_OPTS)
set(QT_XMIN_ENABLED "@QT_XMIN_ENABLED@")
set(QT_XMIN_ROOT "@QT_XMIN_ROOT@")
set(QT_XMIN_DIR "@QT_XMIN_DIR@")
set(QT_XMIN_RUNTIME_DIRS "@QT_XMIN_RUNTIME_DIRS@")
# Windows uses a different file
if (WIN32)
@@ -9,7 +14,9 @@ endif (WIN32)
# If we're not on Windows, set some environment variables
if (NOT WIN32)
set(ENV{LD_LIBRARY_PATH} "@CMAKE_BUNDLE_INSTALL_PREFIX@/@LIB_DIR@")
set(qt_runtime_dirs ${QT_XMIN_RUNTIME_DIRS} "@CMAKE_BUNDLE_INSTALL_PREFIX@/@LIB_DIR@")
string(JOIN ":" qt_runtime_path ${qt_runtime_dirs})
set(ENV{LD_LIBRARY_PATH} "${qt_runtime_path}")
set(ENV{CPPFLAGS} "-I@CMAKE_BUNDLE_INSTALL_PREFIX@/@INCLUDE_DIR@")
set(ENV{LDFLAGS} "-L@CMAKE_BUNDLE_INSTALL_PREFIX@/@LIB_DIR@")
endif (NOT WIN32)
@@ -19,6 +26,53 @@ endif (NOT WIN32)
# https://doc.qt.io/qt-6/configure-options.html
set(CONFIG_EXTRA_OPTS ${CONFIG_EXTRA_OPTS} -qt-zlib -qt-libpng)
if (QT_XMIN_ENABLED)
list(APPEND CONFIG_EXTRA_OPTS
-qpa xcb
-default-qpa xcb
-xcb
-xmin-x11
-xcb-xlib
-feature-xlib
-no-sm
-no-egl
-no-eglfs
-no-vulkan
-no-feature-gbm
-no-feature-kms
-no-feature-wayland
-no-feature-wayland-client
-no-feature-wayland-server
-no-fontconfig
-qt-freetype
-qt-harfbuzz
-qt-libjpeg
-no-dbus
-no-glib
-nomake
examples
-nomake
tests
-opengl
desktop
)
string(JOIN ":" qt_xmin_install_rpath ${QT_XMIN_RUNTIME_DIRS})
list(APPEND QT_CMAKE_OPTS
"-DXmin_DIR=${QT_XMIN_DIR}"
"-DCMAKE_INSTALL_RPATH=${qt_xmin_install_rpath}"
"-DCMAKE_DISABLE_FIND_PACKAGE_EGL=ON"
"-DCMAKE_DISABLE_FIND_PACKAGE_GLESv2=ON"
"-DCMAKE_DISABLE_FIND_PACKAGE_OpenGL=ON"
"-DCMAKE_DISABLE_FIND_PACKAGE_WrapOpenGL=ON"
"-DCMAKE_DISABLE_FIND_PACKAGE_X11=ON"
"-DCMAKE_DISABLE_FIND_PACKAGE_X11_XCB=ON"
"-DCMAKE_DISABLE_FIND_PACKAGE_XCB=ON"
"-DCMAKE_DISABLE_FIND_PACKAGE_XKB=ON"
"-DCMAKE_DISABLE_FIND_PACKAGE_XKB_COMMON_X11=ON"
"-DCMAKE_DISABLE_FIND_PACKAGE_XRender=ON"
)
endif ()
# QFileSystemWatcher selects kqueue in its C++ platform dispatch on FreeBSD.
# If the optional inotify compatibility headers are installed, however, Qt's
# feature probe enables inotify and its CMake source list omits the kqueue
@@ -43,9 +97,11 @@ endif ("${CMAKE_BUILD_TYPE}" STREQUAL "" OR "${CMAKE_BUILD_TYPE}" STREQUAL "Debu
# Qt caches command-line feature choices separately from CMAKE_BUILD_TYPE. If
# a build directory previously configured for the other build type is reused,
# FEATURE_debug can remain forced to a value whose condition is now false.
# Clear only Qt's generated CMake configuration state when the two disagree;
# compiled objects can still be reused whenever they remain compatible.
# Qt leaves nested try-compile caches and generated files throughout its build
# tree. They retain the previous source path and feature results, so a profile
# or staged-source change must clear the complete build tree.
set(qt_cache "@QT_BUILD_DIR@/CMakeCache.txt")
set(qt_signature_file "@QT_BUILD_DIR@/.bext-qt-config-signature")
set(qt_cache_stale OFF)
if (EXISTS "${qt_cache}" AND DEFINED QT_EXPECTED_BUILD_TYPE)
file(STRINGS "${qt_cache}" qt_cached_build_type_line REGEX "^CMAKE_BUILD_TYPE:[^=]*=")
@@ -65,14 +121,36 @@ if (EXISTS "${qt_cache}" AND DEFINED QT_EXPECTED_BUILD_TYPE)
endif ()
endif ()
set(qt_signature_material
"@QT_CONFIG_SIGNATURE@|${CONFIG_EXTRA_OPTS}|${QT_CMAKE_OPTS}|${QT_CONFIG_OPTS}")
string(SHA256 qt_expected_signature "${qt_signature_material}")
if (EXISTS "${qt_signature_file}")
file(READ "${qt_signature_file}" qt_cached_signature)
string(STRIP "${qt_cached_signature}" qt_cached_signature)
if (NOT qt_cached_signature STREQUAL qt_expected_signature)
set(qt_cache_stale ON)
endif ()
elseif (EXISTS "${qt_cache}")
set(qt_cache_stale ON)
endif ()
if (qt_cache_stale)
message(STATUS
"Resetting stale Qt configuration for CMAKE_BUILD_TYPE=${QT_EXPECTED_BUILD_TYPE}")
file(REMOVE "${qt_cache}")
file(REMOVE_RECURSE "@QT_BUILD_DIR@/CMakeFiles")
file(REMOVE_RECURSE "@QT_BUILD_DIR@")
file(MAKE_DIRECTORY "@QT_BUILD_DIR@")
endif ()
execute_process(COMMAND @QT_SOURCE_DIR@/${CONFIG_FILE} ${CONFIG_EXTRA_OPTS} ${QT_CONFIG_OPTS} --prefix=@CMAKE_BUNDLE_INSTALL_PREFIX@ RESULT_VARIABLE QT_RET WORKING_DIRECTORY @QT_BUILD_DIR@ OUTPUT_VARIABLE MSG ERROR_VARIABLE MSG)
set(qt_configure_args
${CONFIG_EXTRA_OPTS}
${QT_CONFIG_OPTS}
--prefix=@CMAKE_BUNDLE_INSTALL_PREFIX@
)
if (QT_CMAKE_OPTS)
list(APPEND qt_configure_args -- ${QT_CMAKE_OPTS})
endif ()
execute_process(COMMAND @QT_SOURCE_DIR@/${CONFIG_FILE} ${qt_configure_args} RESULT_VARIABLE QT_RET WORKING_DIRECTORY @QT_BUILD_DIR@ OUTPUT_VARIABLE MSG ERROR_VARIABLE MSG)
if (QT_RET)
message(FATAL_ERROR "Qt configure failed: ${MSG}\n")
@@ -106,6 +184,32 @@ qt_cache_check("FEATURE_xcb" feature_xcb)
qt_cache_check("FEATURE_wayland_client" feature_wayland_client)
qt_cache_check("FEATURE_direct2d" feature_direct2d)
qt_cache_check("QT_QPA_DEFAULT_PLATFORM" qpa_platform)
qt_cache_check("FEATURE_xmin_x11" feature_xmin_x11)
qt_cache_check("FEATURE_xmin_opengl" feature_xmin_opengl)
qt_cache_check("FEATURE_opengl" feature_opengl)
qt_cache_check("FEATURE_xcb_glx" feature_xcb_glx)
qt_cache_check("FEATURE_xcb_glx_plugin" feature_xcb_glx_plugin)
if (QT_XMIN_ENABLED)
foreach(required_feature IN ITEMS
feature_gui feature_xcb feature_xmin_x11 feature_xmin_opengl
feature_opengl feature_xcb_glx feature_xcb_glx_plugin)
if (NOT "${${required_feature}}" STREQUAL "ON")
message(FATAL_ERROR
"Xmin Qt configuration did not enable ${required_feature}: ${${required_feature}}")
endif ()
endforeach()
if (NOT qpa_platform STREQUAL "xcb")
message(FATAL_ERROR "Xmin Qt configuration did not select qxcb: ${qpa_platform}")
endif ()
qt_cache_check("Xmin_DIR" configured_xmin_dir)
file(REAL_PATH "${configured_xmin_dir}" configured_xmin_dir_real)
if (NOT configured_xmin_dir_real STREQUAL QT_XMIN_DIR)
message(FATAL_ERROR
"Qt resolved Xmin from ${configured_xmin_dir_real}, expected ${QT_XMIN_DIR}")
endif ()
endif ()
# does a window-capable backend exists for this host OS?
set(qt_has_window_gui OFF)
@@ -137,6 +241,8 @@ else()
message(STATUS "Qt platform backend check: OK (window-capable backend present).")
endif()
file(WRITE "${qt_signature_file}" "${qt_expected_signature}\n")
message("Qt configure succeeded: ${MSG}\n")
# Local Variables:
+11 -1
View File
@@ -4,6 +4,17 @@ if (QT_RET)
message(FATAL_ERROR "Qt install failed: ${MSG}\n")
endif (QT_RET)
if ("@QT_XMIN_ENABLED@" STREQUAL "ON")
execute_process(
COMMAND "@CMAKE_COMMAND@" -DQT_AUDIT_ROOT=@CMAKE_BUNDLE_INSTALL_PREFIX@
-P "@CMAKE_CURRENT_BINARY_DIR@/qt_xmin_audit.cmake"
RESULT_VARIABLE QT_AUDIT_RET
)
if (QT_AUDIT_RET)
message(FATAL_ERROR "Installed Qt Xmin dependency audit failed")
endif ()
endif ()
message("Qt install succeeded: ${MSG}\n")
# Local Variables:
@@ -12,4 +23,3 @@ message("Qt install succeeded: ${MSG}\n")
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+93
View File
@@ -0,0 +1,93 @@
cmake_minimum_required(VERSION 3.26)
if (NOT DEFINED QT_AUDIT_ROOT OR NOT QT_AUDIT_ROOT)
message(FATAL_ERROR "QT_AUDIT_ROOT is required")
endif ()
find_program(QT_LDD_EXECUTABLE ldd REQUIRED)
set(qt_xmin_audit_files
"${QT_AUDIT_ROOT}/@LIB_DIR@/libQt6Gui@CMAKE_SHARED_LIBRARY_SUFFIX@"
"${QT_AUDIT_ROOT}/@LIB_DIR@/libQt6XcbQpa@CMAKE_SHARED_LIBRARY_SUFFIX@"
"${QT_AUDIT_ROOT}/@LIB_DIR@/libQt6OpenGLWidgets@CMAKE_SHARED_LIBRARY_SUFFIX@"
"${QT_AUDIT_ROOT}/plugins/platforms/libqxcb@CMAKE_SHARED_LIBRARY_SUFFIX@"
"${QT_AUDIT_ROOT}/plugins/xcbglintegrations/libqxcb-glx-integration@CMAKE_SHARED_LIBRARY_SUFFIX@"
)
if (QT_AUDIT_INCLUDE_SVG)
list(APPEND qt_xmin_audit_files
"${QT_AUDIT_ROOT}/@LIB_DIR@/libQt6Svg@CMAKE_SHARED_LIBRARY_SUFFIX@"
"${QT_AUDIT_ROOT}/@LIB_DIR@/libQt6SvgWidgets@CMAKE_SHARED_LIBRARY_SUFFIX@"
)
endif ()
set(qt_forbidden_x_libraries
libX11
libX11-xcb
libXau
libXdmcp
libXext
libICE
libSM
libxcb
libxkbcommon
libxkbcommon-x11
libXi
libXrender
libGLX
libOpenGL
libEGL
)
foreach(qt_audit_file IN LISTS qt_xmin_audit_files)
if (NOT EXISTS "${qt_audit_file}")
message(FATAL_ERROR "Qt Xmin audit artifact is missing: ${qt_audit_file}")
endif ()
execute_process(
COMMAND "${QT_LDD_EXECUTABLE}" "${qt_audit_file}"
RESULT_VARIABLE qt_ldd_result
OUTPUT_VARIABLE qt_ldd_output
ERROR_VARIABLE qt_ldd_error
)
if (qt_ldd_result)
message(FATAL_ERROR "ldd failed for ${qt_audit_file}: ${qt_ldd_error}")
endif ()
if (qt_ldd_output MATCHES "not found")
message(FATAL_ERROR "Unresolved Qt dependency for ${qt_audit_file}:\n${qt_ldd_output}")
endif ()
foreach(qt_forbidden_library IN LISTS qt_forbidden_x_libraries)
if (qt_ldd_output MATCHES "(^|[\\n\\t ])${qt_forbidden_library}\\.so")
message(FATAL_ERROR
"Qt Xmin artifact resolved forbidden host library ${qt_forbidden_library}:\n${qt_ldd_output}")
endif ()
endforeach()
set(qt_found_xmin_client FALSE)
set(qt_found_xmin_gl FALSE)
string(REPLACE "\n" ";" qt_dependency_lines "${qt_ldd_output}")
foreach(qt_dependency_line IN LISTS qt_dependency_lines)
if (qt_dependency_line MATCHES "libXminClient\\.so")
string(FIND "${qt_dependency_line}" "@QT_XMIN_CLIENT_DIR@/" qt_xmin_client_pos)
if (qt_xmin_client_pos EQUAL -1)
message(FATAL_ERROR
"Qt resolved libXminClient outside QT_XMIN_ROOT: ${qt_dependency_line}")
endif ()
set(qt_found_xmin_client TRUE)
endif ()
if (qt_dependency_line MATCHES "libGL\\.so")
string(FIND "${qt_dependency_line}" "@QT_XMIN_GL_DIR@/" qt_xmin_gl_pos)
if (qt_xmin_gl_pos EQUAL -1)
message(FATAL_ERROR
"Qt resolved libGL outside QT_XMIN_ROOT: ${qt_dependency_line}")
endif ()
set(qt_found_xmin_gl TRUE)
endif ()
endforeach()
if (NOT qt_found_xmin_client OR NOT qt_found_xmin_gl)
message(FATAL_ERROR
"Qt artifact is not backed by both Xmin client libraries: ${qt_audit_file}\n${qt_ldd_output}")
endif ()
endforeach()
message(STATUS "Qt Xmin dependency audit passed for ${QT_AUDIT_ROOT}")
+20 -2
View File
@@ -1,6 +1,9 @@
# By the time we get here, we have run FindTCL and should know
# if we have TK.
set(TK_EXTRA_PATCHES "" CACHE STRING "Additional patches to apply to bundled Tk on Unix")
set(TK_CONFIGURE_ARGS "" CACHE STRING "Additional arguments for bundled Tk's Unix configure script")
if (USE_BRLCAD)
# Decide if we're using Tk
@@ -62,6 +65,22 @@ if (TK_DO_BUILD)
if (NOT MSVC)
set(TK_PATCH_COMMAND
${PATCH_EXECUTABLE} -E -p1 ${PATCH_OPTIONS} -i ${CMAKE_CURRENT_SOURCE_DIR}/tk.patch
COMMAND ${PATCH_EXECUTABLE} -E -p1 ${PATCH_OPTIONS} -i ${CMAKE_CURRENT_SOURCE_DIR}/tk_disable_docs.patch
)
foreach(TK_EXTRA_PATCH IN LISTS TK_EXTRA_PATCHES)
if (NOT IS_ABSOLUTE "${TK_EXTRA_PATCH}")
message(FATAL_ERROR "TK_EXTRA_PATCHES entries must be absolute paths: ${TK_EXTRA_PATCH}")
endif ()
if (NOT EXISTS "${TK_EXTRA_PATCH}")
message(FATAL_ERROR "Additional Tk patch does not exist: ${TK_EXTRA_PATCH}")
endif ()
list(APPEND TK_PATCH_COMMAND
COMMAND ${PATCH_EXECUTABLE} -E -p1 ${PATCH_OPTIONS} -i ${TK_EXTRA_PATCH}
)
endforeach()
# Check for spaces in the source and build directories - those won't work
# reliably with the Tk autotools based build.
if ("${CMAKE_CURRENT_SOURCE_DIR}" MATCHES ".* .*")
@@ -74,8 +93,7 @@ if (TK_DO_BUILD)
ExternalProject_Add(TK_BLD
URL "${CMAKE_CURRENT_SOURCE_DIR}/tk"
BUILD_ALWAYS ${EXT_BUILD_ALWAYS} ${LOG_OPTS}
PATCH_COMMAND ${PATCH_EXECUTABLE};-E;-p1;${PATCH_OPTIONS};-i;${CMAKE_CURRENT_SOURCE_DIR}/tk.patch
COMMAND ${PATCH_EXECUTABLE};-E;-p1;${PATCH_OPTIONS};-i;${CMAKE_CURRENT_SOURCE_DIR}/tk_disable_docs.patch
PATCH_COMMAND ${TK_PATCH_COMMAND}
CONFIGURE_COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/tk_configure.cmake
# NOTE: Forcing -j on all sub-make calls to work around cmake+make
+2 -1
View File
@@ -23,9 +23,10 @@ if (NOT WIN32)
set(ENV{TK_SHLIB_LD_EXTRAS} "-L@CMAKE_BUNDLE_INSTALL_PREFIX@/@LIB_DIR@")
set(WITH_TCL_FLAG "--with-tcl=@WITH_TCL_DIR@")
set(TK_EXTRA_CONFIGURE_ARGS "@TK_CONFIGURE_ARGS@")
execute_process(
COMMAND @TK_SRC_DIR@/unix/configure --prefix=@CMAKE_BUNDLE_INSTALL_PREFIX@ ${WITH_TCL_FLAG}
COMMAND @TK_SRC_DIR@/unix/configure --prefix=@CMAKE_BUNDLE_INSTALL_PREFIX@ ${WITH_TCL_FLAG} ${TK_EXTRA_CONFIGURE_ARGS}
RESULT_VARIABLE TK_RET
WORKING_DIRECTORY "@TK_BIN_DIR@"
OUTPUT_VARIABLE MSG