From 805c489c1cf178ce5ef3fd5cdebbd6938ac9b889 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 13 May 2026 15:21:09 -0500 Subject: [PATCH] osx/qt: look for frameworks, not dylibs Qt on Mac would typically be build & distributed as frameworks, so let's look for and handle that. We're only handling external frameworks for now, and because of that, we need to add an rpath to the Qt VCL plugin so the system knows how to find the frameworks when running LO. Change-Id: If4bdafe9899faedb18ae873b01aadf38d4132eae Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207981 Tested-by: Jenkins Reviewed-by: Michael Weghorn Reviewed-by: Dan Williams --- config_host.mk.in | 1 + configure.ac | 87 ++++++++++++++++++++++---------- solenv/gbuild/Library.mk | 1 + solenv/gbuild/platform/macosx.mk | 7 +++ vcl/Library_vclplug_qt6.mk | 4 ++ 5 files changed, 74 insertions(+), 26 deletions(-) diff --git a/config_host.mk.in b/config_host.mk.in index 9e2ac1746073..31590d50ea1d 100644 --- a/config_host.mk.in +++ b/config_host.mk.in @@ -610,6 +610,7 @@ export QT5_HAVE_GOBJECT=@QT5_HAVE_GOBJECT@ export QT5_PLATFORMS_SRCDIR=@QT5_PLATFORMS_SRCDIR@ export QT6_CFLAGS=$(gb_SPACE)@QT6_CFLAGS@ export QT6_LIBS=$(gb_SPACE)@QT6_LIBS@ +export QT6_LIBDIR=@QT6_LIBDIR@ export QT6_PLATFORMS_SRCDIR=@QT6_PLATFORMS_SRCDIR@ export QXP_CFLAGS=$(gb_SPACE)@QXP_CFLAGS@ export QXP_LIBS=$(gb_SPACE)@QXP_LIBS@ diff --git a/configure.ac b/configure.ac index 215ea9e53b4f..f29b4790d8e8 100644 --- a/configure.ac +++ b/configure.ac @@ -313,6 +313,21 @@ dnl path location is gpg, so make sure we find it unset mac_gpg_path } +dnl format a header path taking into account Mac frameworks +format_header_path() +{ + local package_dir="${1}" + local parent_dir="${2}" + local header_file="${3}" + + local header_path="${1}/${2}/${3}" + if test "$_os" = "Darwin"; then + header_path="${1}/${2}.framework/Versions/A/Headers/${3}" + fi + PathFormat "${header_path}" +} + + dnl semantically test a three digits version dnl $1 - $3 = minimal version dnl $4 - $6 = current version @@ -14153,29 +14168,40 @@ then qt6_platformsdir="`$QMAKE6 -query QT_INSTALL_PLUGINS | tr -d '\r'`/platforms" QT6_PLATFORMS_SRCDIR="$qt6_platformsdir" - qt6_test_include="QtWidgets/qapplication.h" - AC_MSG_CHECKING([for Qt6 headers]) - qt6_incdir="no" - for inc_dir in $qt6_incdirs; do - PathFormat "$inc_dir" - if test -r "${formatted_path_unix}/${qt6_test_include}"; then + # Look for Qt6 headers; on Mac we use the Qt framework that we find below, not + # a separate headers directory + if test "$_os" == "Darwin"; then + for inc_dir in $qt6_incdirs; do qt6_incdir="$inc_dir" break + done + else + qt6_test_include="QtWidgets/qapplication.h" + AC_MSG_CHECKING([for Qt6 headers]) + qt6_incdir="no" + for inc_dir in $qt6_incdirs; do + PathFormat "$inc_dir" + if test -r "${formatted_path_unix}/${qt6_test_include}"; then + qt6_incdir="$inc_dir" + break + fi + done + AC_MSG_RESULT([$qt6_incdir]) + if test "x$qt6_incdir" = "xno"; then + AC_MSG_ERROR([Qt6 headers not found. Please specify the root of your Qt6 installation by exporting QT6DIR before running "configure".]) fi - done - AC_MSG_RESULT([$qt6_incdir]) - if test "x$qt6_incdir" = "xno"; then - AC_MSG_ERROR([Qt6 headers not found. Please specify the root of your Qt6 installation by exporting QT6DIR before running "configure".]) - fi - # check for scenario: qt6-qtbase-devel-*.86_64 installed but host is i686 - AC_LANG_PUSH([C++]) - save_CPPFLAGS=$CPPFLAGS - CPPFLAGS="${CPPFLAGS} -I${qt6_incdir}" - AC_CHECK_HEADER(QtCore/qconfig.h, [], - [AC_MSG_ERROR(qconfig.h header not found.)], []) - CPPFLAGS=$save_CPPFLAGS - AC_LANG_POP([C++]) + # check for scenario: qt6-qtbase-devel-*.86_64 installed but host is i686 + AC_LANG_PUSH([C++]) + save_CPPFLAGS=$CPPFLAGS + CPPFLAGS="${CPPFLAGS} -I${qt6_incdir}" + AC_CHECK_HEADER(QtCore/qconfig.h, [], + [AC_MSG_ERROR(qconfig.h header not found.)], []) + CPPFLAGS=$save_CPPFLAGS + AC_LANG_POP([C++]) + fi + + qt6_test_library="Qt6Widgets" case "$_os" in Emscripten) qt6_library_prefix="lib" @@ -14188,8 +14214,9 @@ then qt6_library_suffixes=".lib d.lib" ;; Darwin) - qt6_library_prefix="lib" - qt6_library_suffixes=".dylib" + qt6_library_prefix="" + qt6_library_suffixes=".framework" + qt6_test_library="QtWidgets" ;; *) qt6_library_prefix="lib" @@ -14197,7 +14224,6 @@ then ;; esac - qt6_test_library="Qt6Widgets" AC_MSG_CHECKING([for Qt6 libraries]) qt6_libdir="no" for lib_dir in $qt6_libdirs; do @@ -14214,6 +14240,7 @@ then if test "x$qt6_libdir" = "xno"; then AC_MSG_ERROR([Qt6 libraries not found. Please specify the root of your Qt6 installation by exporting QT6DIR before running "configure".]) fi + QT6_LIBDIR="${qt6_libdir}" if test "$_os" = "Emscripten"; then if test ! -f "$QT6_PLATFORMS_SRCDIR"/wasm_shell.html ; then @@ -14225,27 +14252,34 @@ then fi QT6_CFLAGS="-I$qt6_incdir -DQT_NO_VERSION_TAGGING" - QT6_CFLAGS=$(printf '%s' "$QT6_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g") if test "$_os" = "WINNT"; then QT6_LIBS="-LIBPATH:${qt6_libdir} Qt6Core${qt6_library_suffix} Qt6Gui${qt6_library_suffix} Qt6Widgets${qt6_library_suffix}" elif test "$_os" = "Darwin"; then - QT6_LIBS="-rpath ${qt6_libdir} -L${qt6_libdir} -lQt6Core -lQt6Gui -lQt6Widgets" + QT6_LIBS="-F ${qt6_libdir} -framework QtCore -framework QtGui -framework QtWidgets -framework QtNetwork" + QT6_CFLAGS="${QT6_CFLAGS} -F ${qt6_libdir}" else QT6_LIBS="-L$qt6_libdir -lQt6Core -lQt6Gui -lQt6Widgets" fi + QT6_CFLAGS=$(printf '%s' "$QT6_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g") if test "$_os" = "Emscripten"; then QT6_LIBS="$QT6_LIBS -lQt6BundledPcre2 -lQt6BundledZLIB -L${qt6_platformsdir} -lqwasm -sGL_ENABLE_GET_PROC_ADDRESS" else if ! test "$enable_qt6_multimedia" = "no"; then - PathFormat "${qt6_incdir}" - if ! test -r "${formatted_path_unix}/QtMultimediaWidgets/QVideoWidget"; then + qt6_mm_headerdir="${qt6_incdir}" + if test "$_os" = "Darwin"; then + qt6_mm_headerdir="${qt6_libdir}" + fi + format_header_path "${qt6_mm_headerdir}" "QtMultimediaWidgets" "QVideoWidget" + if ! test -r "${formatted_path_unix}"; then AC_MSG_ERROR([Qt 6 QMultimedia not found.]) break fi ENABLE_QT6_MULTIMEDIA=TRUE if test "$_os" = "WINNT"; then QT6_LIBS="$QT6_LIBS Qt6Multimedia${qt6_library_suffix} Qt6MultimediaWidgets${qt6_library_suffix}" + elif test "$_os" = "Darwin"; then + QT6_LIBS="$QT6_LIBS -framework QtMultimedia -framework QtMultimediaWidgets" else QT6_LIBS="$QT6_LIBS -lQt6Multimedia -lQt6MultimediaWidgets" fi @@ -14288,6 +14322,7 @@ the root of your Qt installation by exporting QT6DIR before running "configure". fi AC_SUBST(QT6_CFLAGS) AC_SUBST(QT6_LIBS) +AC_SUBST(QT6_LIBDIR) AC_SUBST(MOC6) AC_SUBST(QT6_PLATFORMS_SRCDIR) AC_SUBST(ENABLE_QT6_MULTIMEDIA) diff --git a/solenv/gbuild/Library.mk b/solenv/gbuild/Library.mk index e58dc3974466..d438c58b31ba 100644 --- a/solenv/gbuild/Library.mk +++ b/solenv/gbuild/Library.mk @@ -261,6 +261,7 @@ gb_Library_set_x86 = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3 gb_Library_add_libs = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3)) gb_Library_disable_standard_system_libs = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3)) gb_Library_use_system_darwin_frameworks = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3)) +gb_Library_darwin_add_rpath = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3)) gb_Library_use_system_win32_libs = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3)) gb_Library_set_library_path_flags = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3)) gb_Library_use_api = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3)) diff --git a/solenv/gbuild/platform/macosx.mk b/solenv/gbuild/platform/macosx.mk index a39a9a0ef716..1cef84fa4b8a 100644 --- a/solenv/gbuild/platform/macosx.mk +++ b/solenv/gbuild/platform/macosx.mk @@ -131,6 +131,9 @@ $(call gb_Helper_abbreviate_dirs,\ $(PERL) $(SRCDIR)/solenv/bin/macosx-change-install-names.pl app $(LAYER) $(1) &&) \ $(if $(filter Library Bundle CppunitTest,$(TARGETTYPE)),\ $(PERL) $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl $(LAYER) $(1) &&) \ + $(if $(filter Library Executable,$(TARGETTYPE)),\ + $(if $(ADD_RPATH),\ + $(INSTALL_NAME_TOOL) -add_rpath $(ADD_RPATH) $(1) &&)) \ $(if $(filter Library,$(TARGETTYPE)),\ otool -l $(1) | grep -A 5 LC_ID_DYLIB \ > $(WORKDIR)/LinkTarget/$(2).exports.tmp && \ @@ -175,6 +178,10 @@ $(if $(call gb_LinkTarget__is_merged,$(1)),\ $(call gb_LinkTarget_add_libs,$(call gb_Library_get_linktarget,merged),$(foreach fw,$(2),-framework $(fw)))) endef +define gb_LinkTarget_darwin_add_rpath +$(call gb_LinkTarget_get_target,$(1)) : ADD_RPATH := +$(call gb_LinkTarget_get_target,$(1)) : ADD_RPATH := $(2) +endef # Library class diff --git a/vcl/Library_vclplug_qt6.mk b/vcl/Library_vclplug_qt6.mk index db7b3c8e42c9..676b937c81bd 100644 --- a/vcl/Library_vclplug_qt6.mk +++ b/vcl/Library_vclplug_qt6.mk @@ -185,6 +185,10 @@ $(eval $(call gb_Library_add_cxxflags,vclplug_qt6,\ $(gb_OBJCXXFLAGS) \ )) +$(eval $(call gb_Library_darwin_add_rpath,vclplug_qt6,\ + "$(QT6_LIBDIR)" \ +)) + $(eval $(call gb_Library_use_libraries,vclplug_qt6,\ vclplug_osx \ ))