Bug 1823118 - qmake return wrong install prefix
Summary: qmake return wrong install prefix
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Fedora
Classification: Fedora
Component: qt5-qtbase
Version: rawhide
Hardware: x86_64
OS: Linux
unspecified
high
Target Milestone: ---
Assignee: Rex Dieter
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
: 1823397 (view as bug list)
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2020-04-11 20:18 UTC by David Hampton
Modified: 2020-04-15 14:10 UTC (History)
8 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2020-04-15 14:10:50 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description David Hampton 2020-04-11 20:18:17 UTC
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:

Comment 1 Rex Dieter 2020-04-11 21:59:42 UTC
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.

Comment 2 Rex Dieter 2020-04-13 15:27:00 UTC
*** Bug 1823397 has been marked as a duplicate of this bug. ***

Comment 3 Sandro Mani 2020-04-13 16:01:37 UTC
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...

Comment 4 Sandro Mani 2020-04-13 16:22:33 UTC
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

Comment 5 Sandro Mani 2020-04-13 16:32:21 UTC
Probably easiest would be to just pass -no-relocatable to ./configure ...

Comment 6 Rex Dieter 2020-04-13 17:05:56 UTC
Thanks!  Will try that, excellent work.

Comment 8 Sandro Mani 2020-04-13 17:17:39 UTC
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

Comment 9 Rex Dieter 2020-04-13 17:35:14 UTC
You're saing same problem still exists even with -no-feature-relocatable ?  if so, then definitely time to bug upstream

Comment 10 Sandro Mani 2020-04-13 17:38:56 UTC
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.

Comment 11 Sandro Mani 2020-04-13 19:08:43 UTC
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.

Comment 12 Rex Dieter 2020-04-13 19:11:01 UTC
Symlinks cannot be used here: multilib conficts (we're relying on rpm binary coloring)

Comment 13 Rex Dieter 2020-04-13 19:12:30 UTC
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

Comment 14 Sandro Mani 2020-04-13 19:16:19 UTC
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

Comment 15 Rex Dieter 2020-04-13 20:07:41 UTC
Thanks, I'll try that patch.

Comment 17 Sandro Mani 2020-04-13 22:54:04 UTC
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

Comment 18 Rex Dieter 2020-04-14 14:07:44 UTC
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?

Comment 19 Kevin Kofler 2020-04-14 15:45:18 UTC
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?

Comment 20 Sandro Mani 2020-04-14 15:54:28 UTC
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.

Comment 21 Kevin Kofler 2020-04-14 16:20:19 UTC
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.

Comment 22 Kevin Kofler 2020-04-14 16:21:42 UTC
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.

Comment 23 Sandro Mani 2020-04-14 16:33:07 UTC
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)

Comment 24 Sandro Mani 2020-04-15 14:10:50 UTC
qt5-qtbase-5.14.2-3.fc33+ fixes this.


Note You need to log in before you can comment on or make changes to this bug.