Warning, /graphics/krita/3rdparty/ext_qt/0116-Make-Qt-relocatable.patch is written in an unsupported language. File is not indexed.

0001 From 716dcf21b9c025be6038b06736eec90038ec3a11 Mon Sep 17 00:00:00 2001
0002 From: Alexandru Croitor <alexandru.croitor@qt.io>
0003 Date: Thu, 9 Nov 2017 18:00:46 +0100
0004 Subject: [PATCH 35/47] Make Qt relocatable
0005 
0006 [ChangeLog][QtCore] Qt installations on the host system can now be
0007 relocated, i.e. moved to other directories.
0008 
0009 Add a new feature 'relocatable' that's by default enabled for
0010 non-static builds
0011   - on platforms where libdl is available,
0012   - on macOS when configured with -framework,
0013   - on Windows.
0014 
0015 If the feature is enabled, the directory where plugins, translations
0016 and other assets are loaded from is determined by the location of
0017 libQt5Core.so and the lib dir (bin dir on Windows) relative to the
0018 prefix.
0019 
0020 For static builds, the feature 'relocatable' is off by default. It can
0021 be turned on manually by passing -feature-relocatable to configure. In
0022 that case, QLibraryInfo::location(QLibraryInfo::TranslationsPaths) and
0023 friends will return paths rooted in the user application's directory.
0024 
0025 The installed and relocated qmake determines properties like
0026 QT_INSTALL_PREFIX and QT_HOST_PREFIX from the location of the qmake
0027 executable and the host bin dir relative to the host prefix. This is
0028 now always done, independent of the 'relocatable' feature.
0029 
0030 Note that qmake is currently only relocatable within an environment
0031 that has the same layout as the original build machine due to absolute
0032 paths to the original prefix in .prl, .pc and .la files.
0033 This will be addressed in a separate patch.
0034 
0035 Task-number: QTBUG-15234
0036 Change-Id: I7319e2856d8fe17f277082d71216442f52580633
0037 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
0038 ---
0039  configure.json                      |  27 ++++
0040  configure.pri                       |  21 +++
0041  qmake/option.cpp                    |   5 +
0042  src/corelib/configure.json          |  20 ---
0043  src/corelib/global/qlibraryinfo.cpp | 208 +++++++++++++++++++++++-----
0044  5 files changed, 228 insertions(+), 53 deletions(-)
0045 
0046 diff --git a/configure.json b/configure.json
0047 index 7279259484..0b06f3549a 100644
0048 --- a/configure.json
0049 +++ b/configure.json
0050 @@ -203,6 +203,21 @@
0051                  { "type": "pkgConfig", "args": "libudev" },
0052                  "-ludev"
0053              ]
0054 +        },
0055 +        "libdl": {
0056 +            "label": "dlopen()",
0057 +            "test": {
0058 +                "main": [
0059 +                    "dlclose(dlopen(0, 0));",
0060 +                    "dlsym(RTLD_DEFAULT, 0);",
0061 +                    "dlerror();"
0062 +                ]
0063 +            },
0064 +            "headers": "dlfcn.h",
0065 +            "sources": [
0066 +                "",
0067 +                "-ldl"
0068 +            ]
0069          }
0070      },
0071  
0072 @@ -1247,6 +1262,17 @@
0073              "autoDetect": false,
0074              "condition": "!features.shared",
0075              "output": [ "publicConfig", "publicQtConfig" ]
0076 +        },
0077 +        "dlopen": {
0078 +            "label": "dlopen()",
0079 +            "condition": "config.unix && libs.libdl",
0080 +            "output": [ "privateFeature" ]
0081 +        },
0082 +        "relocatable": {
0083 +            "label": "Relocatable",
0084 +            "autoDetect": "features.shared",
0085 +            "condition": "features.dlopen || config.win32 || !features.shared",
0086 +            "output": [ "privateFeature" ]
0087          }
0088      },
0089  
0090 @@ -1363,6 +1389,7 @@ Configure with '-qreal float' to create a build that is binary-compatible with 5
0091                      "args": "enable_gdb_index",
0092                      "condition": "config.gcc && !config.clang && (features.debug || features.force_debug_info || features.debug_and_release)"
0093                  },
0094 +                "relocatable",
0095                  "precompile_header",
0096                  "ltcg",
0097                  {
0098 diff --git a/configure.pri b/configure.pri
0099 index 33c90a8c2f..57c750b104 100644
0100 --- a/configure.pri
0101 +++ b/configure.pri
0102 @@ -757,6 +757,11 @@ defineTest(qtConfOutput_preparePaths) {
0103          have_hostprefix = true
0104      }
0105  
0106 +    equals(config.input.prefix, $$config.input.extprefix): \
0107 +        qmake_crossbuild = false
0108 +    else: \
0109 +        qmake_crossbuild = true
0110 +
0111      PREFIX_COMPLAINTS =
0112      PREFIX_REMINDER = false
0113      win32: \
0114 @@ -796,6 +801,18 @@ defineTest(qtConfOutput_preparePaths) {
0115          processQtPath(host, hostdatadir, $$config.rel_input.archdatadir)
0116      }
0117  
0118 +    win32:$$qtConfEvaluate("features.shared") {
0119 +        # Windows DLLs are in the bin dir.
0120 +        libloc_absolute_path = $$absolute_path($$config.rel_input.bindir, $$config.input.prefix)
0121 +    } else {
0122 +        libloc_absolute_path = $$absolute_path($$config.rel_input.libdir, $$config.input.prefix)
0123 +    }
0124 +    config.input.liblocation_to_prefix = $$relative_path($$config.input.prefix, $$libloc_absolute_path)
0125 +
0126 +    hostbindir_absolute_path = $$absolute_path($$config.rel_input.hostbindir, $$config.input.hostprefix)
0127 +    config.input.hostbindir_to_hostprefix = $$relative_path($$config.input.hostprefix, $$hostbindir_absolute_path)
0128 +    config.input.hostbindir_to_extprefix = $$relative_path($$config.input.extprefix, $$hostbindir_absolute_path)
0129 +
0130      !isEmpty(PREFIX_COMPLAINTS) {
0131          PREFIX_COMPLAINTS = "$$join(PREFIX_COMPLAINTS, "$$escape_expand(\\n)Note: ")"
0132          $$PREFIX_REMINDER: \
0133 @@ -858,9 +875,13 @@ defineTest(qtConfOutput_preparePaths) {
0134          ";" \
0135          "" \
0136          "$${LITERAL_HASH}define QT_CONFIGURE_SETTINGS_PATH \"$$config.rel_input.sysconfdir\"" \
0137 +        "$${LITERAL_HASH}define QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH \"$$config.input.liblocation_to_prefix\"" \
0138 +        "$${LITERAL_HASH}define QT_CONFIGURE_HOSTBINDIR_TO_EXTPREFIX_PATH \"$$config.input.hostbindir_to_extprefix\"" \
0139 +        "$${LITERAL_HASH}define QT_CONFIGURE_HOSTBINDIR_TO_HOSTPREFIX_PATH \"$$config.input.hostbindir_to_hostprefix\"" \
0140          "" \
0141          "$${LITERAL_HASH}ifdef QT_BUILD_QMAKE" \
0142          "$${LITERAL_HASH} define QT_CONFIGURE_SYSROOTIFY_PREFIX $$qmake_sysrootify" \
0143 +        "$${LITERAL_HASH} define QT_CONFIGURE_CROSSBUILD $$qmake_crossbuild" \
0144          "$${LITERAL_HASH}endif" \
0145          "" \
0146          "$${LITERAL_HASH}define QT_CONFIGURE_PREFIX_PATH qt_configure_prefix_path_str + 12" \
0147 diff --git a/qmake/option.cpp b/qmake/option.cpp
0148 index 626a2cec0d..e13fa47281 100644
0149 --- a/qmake/option.cpp
0150 +++ b/qmake/option.cpp
0151 @@ -661,4 +661,9 @@ QString qmake_libraryInfoFile()
0152      return QString();
0153  }
0154  
0155 +QString qmake_abslocation()
0156 +{
0157 +    return Option::globals->qmake_abslocation;
0158 +}
0159 +
0160  QT_END_NAMESPACE
0161 diff --git a/src/corelib/configure.json b/src/corelib/configure.json
0162 index 4de6cc19f3..5d657a13b5 100644
0163 --- a/src/corelib/configure.json
0164 +++ b/src/corelib/configure.json
0165 @@ -157,21 +157,6 @@
0166                  "-latomic"
0167              ]
0168          },
0169 -        "libdl": {
0170 -            "label": "dlopen()",
0171 -            "test": {
0172 -                "main": [
0173 -                    "dlclose(dlopen(0, 0));",
0174 -                    "dlsym(RTLD_DEFAULT, 0);",
0175 -                    "dlerror();"
0176 -                ]
0177 -            },
0178 -            "headers": "dlfcn.h",
0179 -            "sources": [
0180 -                "",
0181 -                "-ldl"
0182 -            ]
0183 -        },
0184          "librt": {
0185              "label": "clock_gettime()",
0186              "test": {
0187 @@ -552,11 +537,6 @@
0188              "condition": "features.clock-gettime && tests.clock-monotonic",
0189              "output": [ "feature" ]
0190          },
0191 -        "dlopen": {
0192 -            "label": "dlopen()",
0193 -            "condition": "config.unix && libs.libdl",
0194 -            "output": [ "privateFeature" ]
0195 -        },
0196          "doubleconversion": {
0197              "label": "DoubleConversion",
0198              "output": [ "privateFeature", "feature" ]
0199 diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
0200 index f2ada4ab30..9da9039f1a 100644
0201 --- a/src/corelib/global/qlibraryinfo.cpp
0202 +++ b/src/corelib/global/qlibraryinfo.cpp
0203 @@ -55,15 +55,24 @@ QT_END_NAMESPACE
0204  # include "qcoreapplication.h"
0205  #endif
0206  
0207 +#ifndef QT_BUILD_QMAKE_BOOTSTRAP
0208 +#  include "private/qglobal_p.h"
0209 +#  include "qconfig.cpp"
0210 +#endif
0211 +
0212  #ifdef Q_OS_DARWIN
0213  #  include "private/qcore_mac_p.h"
0214 -#endif
0215 +#endif // Q_OS_DARWIN
0216  
0217 -#ifndef QT_BUILD_QMAKE_BOOTSTRAP
0218 -# include "qconfig.cpp"
0219 +#include "archdetect.cpp"
0220 +
0221 +#if !defined(QT_BUILD_QMAKE) && QT_CONFIG(relocatable) && QT_CONFIG(dlopen) && !QT_CONFIG(framework)
0222 +#  include <dlfcn.h>
0223  #endif
0224  
0225 -#include "archdetect.cpp"
0226 +#if !defined(QT_BUILD_QMAKE) && QT_CONFIG(relocatable) && defined(Q_OS_WIN)
0227 +#  include <qt_windows.h>
0228 +#endif
0229  
0230  QT_BEGIN_NAMESPACE
0231  
0232 @@ -453,6 +462,160 @@ void QLibraryInfo::sysrootify(QString *path)
0233  }
0234  #endif // QT_BUILD_QMAKE
0235  
0236 +#ifndef QT_BUILD_QMAKE
0237 +static QString prefixFromAppDirHelper()
0238 +{
0239 +    QString appDir;
0240 +
0241 +    if (QCoreApplication::instance()) {
0242 +#ifdef Q_OS_DARWIN
0243 +        CFBundleRef bundleRef = CFBundleGetMainBundle();
0244 +        if (bundleRef) {
0245 +            QCFType<CFURLRef> urlRef = CFBundleCopyBundleURL(bundleRef);
0246 +            if (urlRef) {
0247 +                QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle);
0248 +#ifdef Q_OS_MACOS
0249 +                QString bundleContentsDir = QString(path) + QLatin1String("/Contents/");
0250 +                if (QDir(bundleContentsDir).exists())
0251 +                    return QDir::cleanPath(bundleContentsDir);
0252 +#else
0253 +                return QDir::cleanPath(QString(path)); // iOS
0254 +#endif // Q_OS_MACOS
0255 +            }
0256 +        }
0257 +#endif // Q_OS_DARWIN
0258 +        // We make the prefix path absolute to the executable's directory.
0259 +        appDir = QCoreApplication::applicationDirPath();
0260 +    } else {
0261 +        appDir = QDir::currentPath();
0262 +    }
0263 +
0264 +    return appDir;
0265 +}
0266 +#endif
0267 +
0268 +#if !defined(QT_BUILD_QMAKE) && QT_CONFIG(relocatable)
0269 +static QString prefixFromQtCoreLibraryHelper(const QString &qtCoreLibraryPath)
0270 +{
0271 +    const QString qtCoreLibrary = QDir::fromNativeSeparators(qtCoreLibraryPath);
0272 +    const QString libDir = QFileInfo(qtCoreLibrary).absolutePath();
0273 +    const QString prefixDir = libDir + QLatin1Char('/')
0274 +            + QLatin1String(QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH);
0275 +    return QDir::cleanPath(prefixDir);
0276 +}
0277 +
0278 +#if defined(Q_OS_WIN)
0279 +#if defined(Q_OS_WINRT)
0280 +EXTERN_C IMAGE_DOS_HEADER __ImageBase;
0281 +static HMODULE getWindowsModuleHandle()
0282 +{
0283 +    return reinterpret_cast<HMODULE>(&__ImageBase);
0284 +}
0285 +#else  // Q_OS_WINRT
0286 +static HMODULE getWindowsModuleHandle()
0287 +{
0288 +    HMODULE hModule = NULL;
0289 +    GetModuleHandleEx(
0290 +        GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
0291 +        (LPCTSTR)&QLibraryInfo::isDebugBuild, &hModule);
0292 +    return hModule;
0293 +}
0294 +#endif // !Q_OS_WINRT
0295 +#endif // Q_OS_WIN
0296 +
0297 +static QString getRelocatablePrefix()
0298 +{
0299 +    QString prefixPath;
0300 +
0301 +    // For static builds, the prefix will be the app directory.
0302 +    // For regular builds, the prefix will be relative to the location of the QtCore shared library.
0303 +#if defined(QT_STATIC)
0304 +    prefixPath = prefixFromAppDirHelper();
0305 +#elif defined(Q_OS_DARWIN) && QT_CONFIG(framework)
0306 +    CFBundleRef qtCoreBundle = CFBundleGetBundleWithIdentifier(
0307 +            CFSTR("org.qt-project.QtCore"));
0308 +    Q_ASSERT(qtCoreBundle);
0309 +
0310 +    QCFType<CFURLRef> qtCorePath = CFBundleCopyBundleURL(qtCoreBundle);
0311 +    Q_ASSERT(qtCorePath);
0312 +
0313 +    QCFType<CFURLRef> qtCorePathAbsolute = CFURLCopyAbsoluteURL(qtCorePath);
0314 +    Q_ASSERT(qtCorePathAbsolute);
0315 +
0316 +    QCFType<CFURLRef> libDirCFPath = CFURLCreateCopyDeletingLastPathComponent(NULL, qtCorePathAbsolute);
0317 +
0318 +    const QCFString libDirCFString = CFURLCopyFileSystemPath(libDirCFPath, kCFURLPOSIXPathStyle);
0319 +
0320 +    const QString prefixDir = QString(libDirCFString) + QLatin1Char('/')
0321 +        + QLatin1String(QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH);
0322 +
0323 +    prefixPath = QDir::cleanPath(prefixDir);
0324 +#elif QT_CONFIG(dlopen)
0325 +    Dl_info info;
0326 +    int result = dladdr(reinterpret_cast<void *>(&QLibraryInfo::isDebugBuild), &info);
0327 +    if (result > 0 && info.dli_fname)
0328 +        prefixPath = prefixFromQtCoreLibraryHelper(QString::fromLatin1(info.dli_fname));
0329 +#elif defined(Q_OS_WIN)
0330 +    HMODULE hModule = getWindowsModuleHandle();
0331 +    const int kBufferSize = 4096;
0332 +    wchar_t buffer[kBufferSize];
0333 +    const int pathSize = GetModuleFileName(hModule, buffer, kBufferSize);
0334 +    if (pathSize > 0)
0335 +        prefixPath = prefixFromQtCoreLibraryHelper(QString::fromWCharArray(buffer, pathSize));
0336 +#else
0337 +#error "The chosen platform / config does not support querying for a dynamic prefix."
0338 +#endif
0339 +
0340 +    Q_ASSERT_X(!prefixPath.isEmpty(), "getRelocatablePrefix",
0341 +                                      "Failed to find the Qt prefix path.");
0342 +    return prefixPath;
0343 +}
0344 +#endif
0345 +
0346 +#if defined(QT_BUILD_QMAKE) && !defined(QT_BUILD_QMAKE_BOOTSTRAP)
0347 +QString qmake_abslocation();
0348 +
0349 +static QString getPrefixFromHostBinDir(const char *hostBinDirToPrefixPath)
0350 +{
0351 +    const QFileInfo qmfi = QFileInfo(qmake_abslocation()).canonicalFilePath();
0352 +    return QDir::cleanPath(qmfi.absolutePath() + QLatin1Char('/')
0353 +                           + QLatin1String(hostBinDirToPrefixPath));
0354 +}
0355 +
0356 +static QString getExtPrefixFromHostBinDir()
0357 +{
0358 +    return getPrefixFromHostBinDir(QT_CONFIGURE_HOSTBINDIR_TO_EXTPREFIX_PATH);
0359 +}
0360 +
0361 +static QString getHostPrefixFromHostBinDir()
0362 +{
0363 +    return getPrefixFromHostBinDir(QT_CONFIGURE_HOSTBINDIR_TO_HOSTPREFIX_PATH);
0364 +}
0365 +#endif
0366 +
0367 +#ifndef QT_BUILD_QMAKE_BOOTSTRAP
0368 +static const char *getPrefix(
0369 +#ifdef QT_BUILD_QMAKE
0370 +        QLibraryInfo::PathGroup group
0371 +#endif
0372 +        )
0373 +{
0374 +#if defined(QT_BUILD_QMAKE)
0375 +#  if QT_CONFIGURE_CROSSBUILD
0376 +    if (group == QLibraryInfo::DevicePaths)
0377 +        return QT_CONFIGURE_PREFIX_PATH;
0378 +#  endif
0379 +    static QByteArray extPrefixPath = getExtPrefixFromHostBinDir().toLatin1();
0380 +    return extPrefixPath.constData();
0381 +#elif QT_CONFIG(relocatable)
0382 +    static QByteArray prefixPath = getRelocatablePrefix().toLatin1();
0383 +    return prefixPath.constData();
0384 +#else
0385 +    return QT_CONFIGURE_PREFIX_PATH;
0386 +#endif
0387 +}
0388 +#endif // QT_BUILD_QMAKE_BOOTSTRAP
0389 +
0390  /*!
0391    Returns the location specified by \a loc.
0392  */
0393 @@ -564,12 +727,11 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
0394      if (!fromConf) {
0395          const char * volatile path = 0;
0396          if (loc == PrefixPath) {
0397 -            path =
0398 -# ifdef QT_BUILD_QMAKE
0399 -                (group != DevicePaths) ?
0400 -                    QT_CONFIGURE_EXT_PREFIX_PATH :
0401 -# endif
0402 -                    QT_CONFIGURE_PREFIX_PATH;
0403 +            path = getPrefix(
0404 +#ifdef QT_BUILD_QMAKE
0405 +                        group
0406 +#endif
0407 +                   );
0408          } else if (unsigned(loc) <= sizeof(qt_configure_str_offsets)/sizeof(qt_configure_str_offsets[0])) {
0409              path = qt_configure_strs + qt_configure_str_offsets[loc - 1];
0410  #ifndef Q_OS_WIN // On Windows we use the registry
0411 @@ -578,7 +740,8 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
0412  #endif
0413  # ifdef QT_BUILD_QMAKE
0414          } else if (loc == HostPrefixPath) {
0415 -            path = QT_CONFIGURE_HOST_PREFIX_PATH;
0416 +            static const QByteArray hostPrefixPath = getHostPrefixFromHostBinDir().toLatin1();
0417 +            path = hostPrefixPath.constData();
0418  # endif
0419          }
0420  
0421 @@ -612,28 +775,7 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
0422          }
0423  #else
0424          if (loc == PrefixPath) {
0425 -            if (QCoreApplication::instance()) {
0426 -#ifdef Q_OS_DARWIN
0427 -                CFBundleRef bundleRef = CFBundleGetMainBundle();
0428 -                if (bundleRef) {
0429 -                    QCFType<CFURLRef> urlRef = CFBundleCopyBundleURL(bundleRef);
0430 -                    if (urlRef) {
0431 -                        QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle);
0432 -#ifdef Q_OS_OSX
0433 -                        QString bundleContentsDir = QString(path) + QLatin1String("/Contents/");
0434 -                        if (QDir(bundleContentsDir).exists())
0435 -                            return QDir::cleanPath(bundleContentsDir + ret);
0436 -#else
0437 -                        return QDir::cleanPath(QString(path) + QLatin1Char('/') + ret); // iOS
0438 -#endif // Q_OS_OSX
0439 -                    }
0440 -                }
0441 -#endif // Q_OS_DARWIN
0442 -                // We make the prefix path absolute to the executable's directory.
0443 -                baseDir = QCoreApplication::applicationDirPath();
0444 -            } else {
0445 -                baseDir = QDir::currentPath();
0446 -            }
0447 +            baseDir = prefixFromAppDirHelper();
0448          } else {
0449              // we make any other path absolute to the prefix directory
0450              baseDir = location(PrefixPath);
0451 -- 
0452 2.20.1.windows.1
0453