Description of problem: Qmake returns the wrong value for QT_INSTALL_PREFIX and all other prefixes that are built from that value. This make is impossible to compile qt based applications after (re)running qmake. Version-Release number of selected component (if applicable): Qt 5.14.2 in rawhide How reproducible: Always Steps to Reproduce: 1.qmake-qt5 -query QT_INSTALL_PREFIX Actual results: /.. Expected results: /usr Additional info:
Extracted from a recent build.log here's the ./configure line that gets passed: + ./configure -verbose -confirm-license -opensource -prefix /usr -archdatadir /usr/lib64/qt5 -bindir /usr/lib64/qt5/bin -libdir /usr/lib64 -libexecdir /usr/lib64/qt5/libexec -datadir /usr/share/qt5 -docdir /usr/share/doc/qt5 -examplesdir /usr/lib64/qt5/examples -headerdir /usr/include/qt5 -importdir /usr/lib64/qt5/imports -plugindir /usr/lib64/qt5/plugins -sysconfdir /etc/xdg -translationdir /usr/share/qt5/translations -platform linux-g++ -release -shared -accessibility -dbus-linked -fontconfig -glib -gtk -icu -journald -optimized-qmake -openssl-linked -nomake tests -no-pch -no-rpath -no-separate-debug-info -no-strip -system-libjpeg -system-libpng -system-harfbuzz -system-pcre -system-sqlite -system-zlib -no-use-gold-linker -no-directfb 'QMAKE_CFLAGS_RELEASE= -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection ' 'QMAKE_CXXFLAGS_RELEASE= -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection ' 'QMAKE_LFLAGS_RELEASE= -Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld' clearly here says "-prefix /usr", so something else is misinterpreting the prefix value... somewhere.
*** Bug 1823397 has been marked as a duplicate of this bug. ***
Culprit is https://github.com/qt/qtbase/commit/4ac872639ed0dd3ae6627e05bdda821f7d128500 resp the new logic to compute the prefix (see static QString getPrefix()). The current Fedora build contains #define QT_CONFIGURE_HOSTBINDIR_TO_EXTPREFIX_PATH "../../../" which is where all starts going wrong. Digging further...
Soo.... configure.pri: 829: hostbindir_absolute_path = $$absolute_path($$config.rel_input.hostbindir, $$config.input.hostprefix) 830: config.input.hostbindir_to_hostprefix = $$relative_path($$config.input.hostprefix, $$hostbindir_absolute_path) 831: config.input.hostbindir_to_extprefix = $$relative_path($$config.input.extprefix, $$hostbindir_absolute_path) 832: message("XXXX: $$config.input.extprefix") 832: message("YYYY: $$hostbindir_absolute_path") 832: message("ZZZ: $$config.input.hostbindir_to_extprefix") $ ./configure [flags as per qt5-qtbase.spec] [...] Project MESSAGE: XXXX: /usr Project MESSAGE: YYYY: /usr/lib64/qt5/bin Project MESSAGE: ZZZ: ../../../ [...] Logic according to which getPrefix ends up computing the prefix: #include <QDir> #include <QFileInfo> #include <QTextStream> int main() { QString qmake_abslocation = "/usr/bin/qmake-qt5"; QByteArray hostBinDirToPrefixPath = "../../../"; // QByteArray hostBinDirToPrefixPath = "../"; // would work const QFileInfo qmfi = QFileInfo(qmake_abslocation).canonicalFilePath(); QString prefix = QDir::cleanPath(qmfi.absolutePath() + QLatin1Char('/') + QLatin1String(hostBinDirToPrefixPath)); QTextStream(stdout) << prefix << endl; // Prints /.. return 0; } In short, the upstream logic probably would expect hostbindir_absolute_path to be /usr/bin
Probably easiest would be to just pass -no-relocatable to ./configure ...
Thanks! Will try that, excellent work.
We'll see if this works, https://src.fedoraproject.org/rpms/qt5-qtbase/c/c5ba3dc43eb5065c28f7578f9c91cbccbfd09b24?branch=master https://koji.fedoraproject.org/koji/taskinfo?taskID=43344809
Looks like it's -no-feature-relocatable - but it's still not sufficient >.< I wonder though if, with relocation disabled, it's safe to then just do diff -rupN qtbase-everywhere-src-5.14.2/src/corelib/global/qlibraryinfo.cpp qtbase-everywhere-src-5.14.2-new/src/corelib/global/qlibraryinfo.cpp --- qtbase-everywhere-src-5.14.2/src/corelib/global/qlibraryinfo.cpp 2020-03-27 10:49:31.000000000 +0100 +++ qtbase-everywhere-src-5.14.2-new/src/corelib/global/qlibraryinfo.cpp 2020-04-13 19:16:50.367142264 +0200 @@ -672,7 +672,7 @@ static QString getPrefix( if (group == QLibraryInfo::DevicePaths) return QString::fromLocal8Bit(QT_CONFIGURE_PREFIX_PATH); # endif - return getExtPrefixFromHostBinDir(); + return QString::fromLocal8Bit(QT_CONFIGURE_PREFIX_PATH); #elif QT_CONFIG(relocatable) return getRelocatablePrefix(); #else
You're saing same problem still exists even with -no-feature-relocatable ? if so, then definitely time to bug upstream
Yes, -no-feature-relocatable alone is not sufficient, also the patch is needed. I think the main problem is that they are making false assumptions about being able to deduce prefix from the host bindir. If that assumption were correct, also getExtPrefixFromHostBinDir would work.
Actually on second thoughts, this is probably a downstream issue: the spec contains # hardlink files to {_bindir}, add -qt5 postfix to not conflict mkdir %{buildroot}%{_bindir} pushd %{buildroot}%{_qt5_bindir} for i in * ; do case "${i}" in moc|qdbuscpp2xml|qdbusxml2cpp|qmake|rcc|syncqt|uic) ln -v ${i} %{buildroot}%{_bindir}/${i}-qt5 ln -sv ${i} ${i}-qt5 ;; *) ln -v ${i} %{buildroot}%{_bindir}/${i} ;; esac done popd which makes qmake end up in %{_bindir} as qmake-qt5, whereas qt expects it to be in hostbindir_absolute_path aka /usr/lib64/qt5/. So possibly symlinking instead of hardlinking the binaries to %{_bindir} is sufficient.
Symlinks cannot be used here: multilib conficts (we're relying on rpm binary coloring)
I'd argue still upstream issue, even when built with -no-feature-relocation, it's still trying to use relocation heuristics to guess prefix. IMHO, it should only do that when that feature is enabled
Upsteamable solution would be something like #ifndef QT_BUILD_QMAKE_BOOTSTRAP static QString getPrefix( #ifdef QT_BUILD_QMAKE QLibraryInfo::PathGroup group #endif ) { #if defined(QT_BUILD_QMAKE) # if QT_CONFIGURE_CROSSBUILD if (group == QLibraryInfo::DevicePaths) return QString::fromLocal8Bit(QT_CONFIGURE_PREFIX_PATH); # elif QT_CONFIG(relocatable) // <<================= THIS return getExtPrefixFromHostBinDir(); # else return QString::fromLocal8Bit(QT_CONFIGURE_PREFIX_PATH); # endif // <<================= END THIS #elif QT_CONFIG(relocatable) return getRelocatablePrefix(); #else return QString::fromLocal8Bit(QT_CONFIGURE_PREFIX_PATH); #endif } #endif // QT_BUILD_QMAKE_BOOTSTRAP
Thanks, I'll try that patch.
https://src.fedoraproject.org/rpms/qt5-qtbase/c/6f111ade5948bf47030c876c3c7cd1f55ed14088?branch=master https://koji.fedoraproject.org/koji/taskinfo?taskID=43351493
Not sure what the point of QT_CONFIG(feature) is if it fails with a division by zero error if feature is not available, but I'm going for [1] for the mingw package. [1] https://src.fedoraproject.org/rpms/mingw-qt5-qtbase/blob/master/f/qt5-qtbase-no-relocatable.patch
Looking closer, it appears to me that the patch is only relevant for cross-compile/mingw ? It's inside the # if QT_CONFIGURE_CROSSBUILD conditional, which shouldn't be reached for the regular build, no?
No. In the code before the patch, the #endif for #if QT_CONFIGURE_CROSSBUILD is before the offending line. The patch (both the one from comment #16 and the MinGW one from comment #17) looks like it should work, does it work?
You definitely also need to patch the native version. The one from comment #16 fails with error: division by zero in #if #define QT_CONFIG(feature) (1/QT_FEATURE_##feature == 1) which makes me confused about what the point of QT_CONFIG is. The one from comment #17 works but is not generic.
The comment in qglobal.h should clear up your confusion: /* The QT_CONFIG macro implements a safe compile time check for features of Qt. Features can be in three states: 0 or undefined: This will lead to a compile error when testing for it -1: The feature is not available 1: The feature is available */ So the issue is that QT_FEATURE_relocatable is 0 or undefined, when it should be -1.
One possible source of the bug could be that the installed headers from an older version of Qt without the relocatable feature are being picked up instead of the headers from the version being built.
Actually it looks like it's sufficient to just #include "qconfig_p.h" in qlibraryinfo.cpp, as the QT_FEATURE_relocatable define isn't otherwise included in the compilation unit. (Which though would mean that the other QT_CONFIG(relocatable) are actually also broken)
qt5-qtbase-5.14.2-3.fc33+ fixes this.