如何在 Solaris 10 上构建 Qt 5.2? [英] How to build Qt 5.2 on Solaris 10?

查看:58
本文介绍了如何在 Solaris 10 上构建 Qt 5.2?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Qt 页面没有列出为 Solaris 预编译的 Qt 5 软件包.四处搜索,它似乎也没有包含在流行的软件包存储库 OpenCSW 中.一些谷歌搜索表明在 Solaris 下构建 Qt 5 涉及在 Solaris 10 下的一些工作.

The Qt page does not list pre-compiled Qt 5 packages for Solaris. Searching around, it does not seem to be included in the popular package repository OpenCSW, either. Some google hits suggest that building Qt 5 under Solaris involves some work under Solaris 10.

因此我的问题是:如何在 Solaris 10 下构建 Qt 5.2?

Thus my question: How to build Qt 5.2 under Solaris 10?

推荐答案

基本上是:

cd qt-everywhere-opensource-src-5.2.0
./configure -prefix $MY_PREFIX -opensource -confirm-license -nomake tests \
    -R /opt/csw/lib/64 -R /opt/csw/X11/lib/64 -qt-xcb -platform solaris-g++-64 \
    -verbose
gmake -j16
gmake -j16 install

加上一些调整,因为 Qt 5 似乎没有用于Solaris 还很多.

plus some adjustments because Qt 5 does not seem to be used on Solaris much, yet.

wget http://download.qt-project.org/official_releases/qt/5.2/5.2.0/single/qt-everywhere-opensource-src-5.2.0.tar.gz
md5sum qt-everywhere-opensource-src-5.2.0.tar.gz
228b6384dfd7272de00fd8b2c144fecd  qt-everywhere-opensource-src-5.2.0.tar.gz

如果系统不支持md5sum,您可以使用openssl md5 filename 代替.

If the system does not habe md5sum you can use openssl md5 filename instead.

我推荐使用 OpenCSW 因为我们需要一些依赖来构建 Qt.最重要的是:

I recommend to use OpenCSW because we need some dependencies to build Qt. The most important ones are:

CSWlibxcbdevel
CSWlibicu-dev    # soft-dependency
CSWgcc4g++
CSWgmake

我建议使用 GCC 来编译 Qt.我不知道使用 Solaris Studio 的 C++ 编译器有什么好处.相反,这个编译器的 C++/STL 支持水平可能不足以满足很多用例.

I suggest to use GCC to compile Qt. I am not aware of any advantages using the C++ compiler from Solaris Studio. On the contrary, the level of C++/STL support of this compiler may be not sufficient for a lot of use cases.

确保您的环境干净.这意味着 /opt/csw/bin 首先出现并且没有设置 LD_LIBRAYR_PATH* 变量.

Make sure that you environment is clean. That means that /opt/csw/bin comes first and no LD_LIBRAYR_PATH* variables are set.

为了简化事情,从 PATH 中删除一些目录可能是个好主意.例如,在 Solaris Studio 安装中没有 ccCC 命令被意外拾取(例如,在编译捆绑的 3rd 方组件期间.

To simplify things it is probably a good idea that some directories are removed from PATH. For example such that no cc, CC commands from a Solaris Studio installation are accidentally picked up (e.g. during the compile of a bundled 3rd party component.

/usr/sfw 下的软件太陈旧了.OpenCSW 中的 /opt/csw 是更好的替代品.那么X-Open版本对于一些使用过的系统功能来说是不够的.

The software under /usr/sfw is just too outdated. /opt/csw from OpenCSW is a better replacement. Then the X-Open version is not sufficient for some used system functions.

--- a/qtbase/mkspecs/solaris-g++-64/qmake.conf
+++ b/qtbase/mkspecs/solaris-g++-64/qmake.conf
@@ -35,7 +35,7 @@ QMAKE_LEX               = flex
 QMAKE_LEXFLAGS          =
 QMAKE_YACC              = yacc
 QMAKE_YACCFLAGS         = -d
-QMAKE_CFLAGS            = -m64 -D_XOPEN_SOURCE=500 -D__EXTENSIONS__
+QMAKE_CFLAGS            = -m64 -D_XOPEN_SOURCE=600 -D__EXTENSIONS__
 QMAKE_CFLAGS_DEPS       = -M
 QMAKE_CFLAGS_WARN_ON    = -Wall -W
 QMAKE_CFLAGS_WARN_OFF   = -w
@@ -58,8 +58,8 @@ QMAKE_CXXFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_STATIC_LIB
 QMAKE_CXXFLAGS_YACC     = $$QMAKE_CFLAGS_YACC
 QMAKE_CXXFLAGS_THREAD   = $$QMAKE_CFLAGS_THREAD

-QMAKE_INCDIR            = /usr/sfw/include
-QMAKE_LIBDIR            = /usr/sfw/lib/64
+QMAKE_INCDIR            = /opt/csw/include /opt/csw/X11/include
+QMAKE_LIBDIR            = /opt/csw/lib/64 /opt/csw/X11/lib/64
 QMAKE_INCDIR_X11        = /usr/openwin/include
 QMAKE_LIBDIR_X11        = /usr/openwin/lib/64
 QMAKE_INCDIR_OPENGL     = /usr/openwin/include

修复外壳

Solaris 带有一个 /bin/sh,它违反了 POSIX 的扩展,例如Qt 的配置脚本甚至是 qmake-generated 中的 shell 代码代码失败.

Fix the shell

Solaris comes with a /bin/sh that violates POSIX to an extend such that Qt's configure scripts and even shell-code in qmake-generated code fails.

POSIX 没有指定 /bin/sh 必须符合它只是指定系统必须在某处"有一个符合标准的 shell.在 Solaris 上,例如在 /usr/xpg4/bin/sh 下.获得符合 shell 的可移植方式是在 getconf CS_PATH ...

POSIX does not specify that /bin/sh has to be conforming it just specifies that the system must have a conforming shell available 'somewhere'. On Solaris it is e.g. under /usr/xpg4/bin/sh. The portable way to get a conforming shell is to search for it in the directories returned by getconf CS_PATH ...

无论如何,我对 Solaris 的选择是只使用 /usr/bin/bash:

Anyways, my choice for Solaris is to just use /usr/bin/bash:

无论如何,我对 Solaris 的选择是只使用 /usr/bin/bash:

Anyways, my choice for Solaris is to just use /usr/bin/bash:

--- a/configure
+++ b/configure
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/usr/bin/bash
 #############################################################################
 ##
 ## Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
--- a/qtbase/configure
+++ b/qtbase/configure
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/bash
 #############################################################################
 ##
 ## Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
@@ -6892,7 +6892,7 @@ fi'`
     echo "$CONFIG_STATUS" | grep '\-confirm\-license' >/dev/null 2>&1 || CONFIG_STATUS="$CONFIG_STATUS -confirm-license"

     [ -f "$outpath/config.status" ] && rm -f "$outpath/config.status"
-    echo "#!/bin/sh" > "$outpath/config.status"
+    echo "#!/usr/bin/bash" > "$outpath/config.status"
     [ -n "$PKG_CONFIG_SYSROOT_DIR" ] && \
         echo "export PKG_CONFIG_SYSROOT_DIR=$PKG_CONFIG_SYSROOT_DIR" >> "$outpath/config.status"
     [ -n "$PKG_CONFIG_LIBDIR" ] && \
--- a/qtbase/qmake/generators/makefile.cpp
+++ b/qtbase/qmake/generators/makefile.cpp
@@ -2306,6 +2306,10 @@ MakefileGenerator::writeHeader(QTextStream &t)
     if (ofile.lastIndexOf(Option::dir_sep) != -1)
         ofile.remove(0, ofile.lastIndexOf(Option::dir_sep) +1);
     t << "MAKEFILE      = " << ofile << endl << endl;
+
+    t << "# custom mod because Solaris /bin/sh is such a standard-violating choice\n"
+      << "#   - gs, 2013-12-23" << endl;
+    t << "SHELL         = /usr/bin/bash" << endl << endl;
 }

 QList<MakefileGenerator::SubTarget*>

修复 ICU 测试

Solaris 10 带有一个过时的 libicu - 它缺少 Qt 5 需要的功能.因此,我们简单地扩展icu-test.如果我们安装了最近的 libicu,那么要么没有 ICU 支持,要么是适当的支持.通过 OpenCSW.

Fix the ICU test

Solaris 10 comes with an outdated libicu - which is missing features Qt 5 needs. Thus, we simply extend the icu-test. Then either no ICU-support is build or proper one in case we install a recent libicu e.g. via OpenCSW.

--- a/qtbase/config.tests/unix/icu/icu.cpp
+++ b/qtbase/config.tests/unix/icu/icu.cpp
@@ -43,6 +43,16 @@
 #include <unicode/ucol.h>
 #include <unicode/ustring.h>

+// for testing if ucal_clone is there (i.e. if we have libicu >= 4.0)
+#include <unicode/ucal.h>
+
+static UCalendar *ucp(UCalendar *i)
+{
+    UErrorCode status = U_ZERO_ERROR;
+    UCalendar *r = ucal_clone(i, &status);
+    return r;
+}
+
 int main(int, char **)
 {
     UErrorCode status = U_ZERO_ERROR;
@@ -50,5 +60,10 @@ int main(int, char **)
     if (U_FAILURE(status))
         return 0;
     ucol_close(collator);
+
+    UCalendar *cal = ucal_open(0, -1, "C", UCAL_GREGORIAN, &status);
+    UCalendar *x = ucp(cal);
+    ucal_close(x);
+
     return 0;
 }

修复捆绑的 pcre

也许可以通过 OpenCSW 安装一个 libpcre.

Fix bundled pcre

Perhaps alternatively one can install a libpcre via OpenCSW.

--- a/qtbase/src/3rdparty/pcre/pcre_compile.c
+++ b/qtbase/src/3rdparty/pcre/pcre_compile.c
@@ -66,6 +66,8 @@ COMPILE_PCREx macro will already be appropriately set. */
 #endif


+#include <stdint.h>
+
 /* Macro for setting individual bits in class bitmaps. */

 #define SETBIT(a,b) a[(b)/8] |= (1 << ((b)&7))

修复sha3

至少在 Solaris 10/Sparc 上,代码使用了 fromBytesToWordfromWordtoBytes 函数,因此:

--- a/qtbase/src/3rdparty/sha3/KeccakF-1600-opt64.c
+++ b/qtbase/src/3rdparty/sha3/KeccakF-1600-opt64.c
@@ -324,7 +324,7 @@ static void KeccakPermutation(unsigned char *state)
     KeccakPermutationOnWords((UINT64*)state);
 }

-#if 0 // Unused in the Qt configuration
+#if 1 // Unused in the Qt configuration
 static void fromBytesToWord(UINT64 *word, const UINT8 *bytes)
 {
     unsigned int i;
@@ -445,7 +445,7 @@ static void KeccakAbsorb(unsigned char *state, const unsigned char *data, unsign
 #endif
 }

-#if 0 // Unused in the Qt configuration
+#if 1 // Unused in the Qt configuration
 static void fromWordToBytes(UINT8 *bytes, const UINT64 word)
 {
     unsigned int i;

包含/类型/使用修复

uname() 函数通过 Solaris 上的 CPP 构造激活并在该标头中声明:

Include/type/usage fixes

The uname() function is activated via a CPP construct on Solaris and is declared in that header:

--- a/qtbase/src/corelib/io/qfileselector.cpp
+++ b/qtbase/src/corelib/io/qfileselector.cpp
@@ -51,6 +51,8 @@
 #include <QtCore/QLocale>
 #include <QtCore/QDebug>

+#include <sys/utsname.h>
+
 QT_BEGIN_NAMESPACE

 //Environment variable to allow tooling full control of file selectors

在 Solaris 下,该代码路径中未使用父代码,并且代码使用 -Werror ...

Under Solaris parent is unused in that code-path and the code gets compiled with -Werror ...

--- a/qtbase/src/corelib/io/qfilesystemwatcher.cpp
+++ b/qtbase/src/corelib/io/qfilesystemwatcher.cpp
@@ -77,6 +77,7 @@ QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine(QObject
 #elif defined(Q_OS_FREEBSD) || defined(Q_OS_MAC)
     return QKqueueFileSystemWatcherEngine::create(parent);
 #else
+    (void)parent;
     return 0;
 #endif
 }

在 Solaris 下 uid_t 有一个意外"标志 (-> Werror).将其转换为 ssize_t 应该是一个可移植且安全的选择:

Under Solaris uid_t has an 'unexpected' sign (-> Werror). Casting it to ssize_t should be a portable and safe choice:

--- a/qtbase/src/corelib/io/qstandardpaths_unix.cpp
+++ b/qtbase/src/corelib/io/qstandardpaths_unix.cpp
@@ -132,7 +132,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
         }
         // "The directory MUST be owned by the user"
         QFileInfo fileInfo(xdgRuntimeDir);
-        if (fileInfo.ownerId() != myUid) {
+        if (fileInfo.ownerId() != ssize_t(myUid)) {
             qWarning("QStandardPaths: wrong ownership on runtime directory %s, %d instead of %d", qPrintable(xdgRuntimeDir),
                      fileInfo.ownerId(), myUid);
             return QString();

线程代码的类似问题(Werror 由于指针转换中的符号不​​匹配).强制转换为 size_t 应该是一个可移植的安全选择:

Similar issue with threading code (Werror because of sign-mismatch in pointer cast). Casting to size_t should be a portable safe choice:

--- a/qtbase/src/corelib/thread/qthread_unix.cpp
+++ b/qtbase/src/corelib/thread/qthread_unix.cpp
@@ -231,7 +231,7 @@ QThreadData *QThreadData::current()
         }
         data->deref();
         data->isAdopted = true;
-        data->threadId = (Qt::HANDLE)pthread_self();
+        data->threadId = (Qt::HANDLE)((size_t)pthread_self());
         if (!QCoreApplicationPrivate::theMainThread)
             QCoreApplicationPrivate::theMainThread = data->thread;
     }
@@ -314,7 +314,7 @@ void *QThreadPrivate::start(void *arg)
             thr->d_func()->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag));
         }

-        data->threadId = (Qt::HANDLE)pthread_self();
+        data->threadId = (Qt::HANDLE)((size_t)pthread_self());
         set_thread_data(data);

         data->ref();
@@ -393,7 +393,7 @@ void QThreadPrivate::finish(void *arg)
 Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW
 {
     // requires a C cast here otherwise we run into trouble on AIX
-    return (Qt::HANDLE)pthread_self();
+    return (Qt::HANDLE)((size_t)pthread_self());
 }

 #if defined(QT_LINUXBASE) && !defined(_SC_NPROCESSORS_ONLN)

结构 in_addr 在 Solaris 上有一个结构作为第一个属性,因此在使用 {0} 初始化时会向 GCC 发出警告 - 因此,在 Qt 期间产生错误-编译:

The struct in_addr has a struct as first attribute on Solaris, thus gives a warning with GCC when initializing with {0} - thus, yields an error during Qt-compile:

--- a/qtbase/src/network/socket/qnativesocketengine_unix.cpp
+++ b/qtbase/src/network/socket/qnativesocketengine_unix.cpp
@@ -63,6 +63,7 @@
 #endif

 #include <netinet/tcp.h>
+#include <string.h>

 QT_BEGIN_NAMESPACE

@@ -737,7 +738,8 @@ QNetworkInterface QNativeSocketEnginePrivate::nativeMulticastInterface() const
         return QNetworkInterface::interfaceFromIndex(v);
     }

-    struct in_addr v = { 0 };
+    struct in_addr v;
+    memset(&v, 0, sizeof(struct in_addr));
     QT_SOCKOPTLEN_T sizeofv = sizeof(v);
     if (::getsockopt(socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, &v, &sizeofv) == -1)
         return QNetworkInterface();

X11/Xutil.h 的头注释将 X11/Xutil.h 列为依赖项,事实上,如果没有这些,Solaris 下会缺少一些声明.>

The header comment of X11/Xutil.h lists X11/Xutil.h as dependency, and indeed, without that include some declarations are missing under Solaris.

--- a/qtbase/src/plugins/platforms/xcb/qxcbmime.cpp
+++ b/qtbase/src/plugins/platforms/xcb/qxcbmime.cpp
@@ -46,6 +46,7 @@
 #include <QtCore/QBuffer>
 #include <qdebug.h>

+#include <X11/Xlib.h>
 #include <X11/Xutil.h>

 #undef XCB_ATOM_STRING

X11/extensions/XIproto.h 在 Solaris 下不是 C++ 安全的.这意味着它包含结构成员名称 class.幸运的是,该代码中似乎没有使用标头.

The X11/extensions/XIproto.h is not C++-safe under Solaris. That means it contains struct members names class. Fortunately, the header does not seem to be used in that code.

--- a/qtbase/src/plugins/platforms/xcb/qxcbxsettings.cpp
+++ b/qtbase/src/plugins/platforms/xcb/qxcbxsettings.cpp
@@ -43,7 +43,7 @@

 #include <QtCore/QByteArray>

-#include <X11/extensions/XIproto.h>
+//#include <X11/extensions/XIproto.h>

 QT_BEGIN_NAMESPACE
 /* Implementation of http://standards.freedesktop.org/xsettings-spec/xsettings-0.5.html */

pow() 函数有一些 C++ 标准中指定的重载,这会在 Solaris 下引入歧义.像这样修复类型应该是可移植和安全的:

The pow() function has some overloads as specified in the C++ standard which introduce ambiguities under Solaris. Fixing the types like this should be portable and safe:

--- a/qtdeclarative/src/qml/jsruntime/qv4globalobject.cpp
+++ b/qtdeclarative/src/qml/jsruntime/qv4globalobject.cpp
@@ -534,7 +534,7 @@ ReturnedValue GlobalFunctions::method_parseInt(CallContext *ctx)
     }

     if (overflow) {
-        double result = (double) v_overflow * pow(R, overflow_digit_count);
+        double result = (double) v_overflow * pow(double(R), int(overflow_digit_count));
         result += v;
         return Encode(sign * result);
     } else {

在 Solaris 下, alloca 需要另一个标头:

Under Solaris, alloca needs another header:

--- a/qtdeclarative/src/qml/jsruntime/qv4stringobject.cpp
+++ b/qtdeclarative/src/qml/jsruntime/qv4stringobject.cpp
@@ -73,6 +73,11 @@
 #  include <windows.h>
 #endif

+
+#if OS(SOLARIS)
+#include <alloca.h>
+#endif
+
 using namespace QV4;

 DEFINE_MANAGED_VTABLE(StringObject);

修复深层 mkdir

Qt 做了一个深"的 mkdir()(例如类似 mkdir -p 的东西,例如创建目录层次结构,例如 ~/.config/company/product.如果现有目录位于不可写的 NFS 挂载父目录中,则 Qt 5.2 算法可能会在 Solaris 上过早中止 - 因为在这种情况下 Solaris 返回 EACCESS 而不是 EEXIST.

Fix deep mkdir

Qt does a 'deep' mkdir() (e.g. something like mkdir -p for e.g. creating a directory hierarchy, e.g. ~/.config/company/product. The Qt 5.2 algorithm may abort too soon on Solaris if an existing directory is located inside a non-writable NFS mounted parent - because in that case Solaris returns EACCESS instead of EEXIST.

--- a/qtbase/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/qtbase/src/corelib/io/qfilesystemengine_unix.cpp
@@ -579,6 +579,11 @@ bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool crea
                         // on the QNet mountpoint returns successfully and reports S_IFDIR.
                         || errno == ENOENT
 #endif
+#if defined(Q_OS_SOLARIS)
+                        // On Solaris 10, mkdir returns EACCESS on a directory which exists
+                        // inside an NFS mount ...
+                        || errno == EACCES
+#endif
                     ) {
                         QT_STATBUF st;
                         if (QT_STAT(chunk.constData(), &st) == 0 && (st.st_mode & S_IFMT) == S_IFDIR)

临时文件

Solaris 也没有 mkdtemp():

--- a/qtbase/src/corelib/io/qtemporarydir.cpp
+++ b/qtbase/src/corelib/io/qtemporarydir.cpp
@@ -52,7 +52,7 @@
 #endif

 #include <stdlib.h> // mkdtemp
-#if defined(Q_OS_QNX) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID)
+#if defined(Q_OS_QNX) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID) || defined(Q_OS_SOLARIS)
 #include <private/qfilesystemengine_p.h>
 #endif

@@ -96,7 +96,7 @@ static QString defaultTemplateName()

 static char *q_mkdtemp(char *templateName)
 {
-#if defined(Q_OS_QNX ) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID)
+#if defined(Q_OS_QNX ) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID) || defined(Q_OS_SOLARIS)
     static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

     const size_t length = strlen(templateName);

线程

Solaris 没有 pthread_get_stacksize_np(_np 后缀代表不可移植).

Pthreads

Solaris does not have pthread_get_stacksize_np (the _np suffix stands for non-portable).

Solaris 有另一个获取堆栈地址/大小值的函数.我的尝试:

Solaris has another function for getting stack-address/size values. My attempt:

--- a/qtdeclarative/src/qml/jsruntime/qv4engine.cpp
+++ b/qtdeclarative/src/qml/jsruntime/qv4engine.cpp
@@ -73,6 +73,11 @@
 #include "qv4isel_moth_p.h"

 #if USE(PTHREADS)
+
+#if OS(SOLARIS)
+#include <thread.h>
+#endif
+
 #  include <pthread.h>
 #endif

@@ -103,6 +108,11 @@ quintptr getStackLimit()
     } else
         size = pthread_get_stacksize_np(thread_self);
     stackLimit -= size;
+#  elif OS(SOLARIS)
+    stack_t ss;
+    int r = thr_stksegment(&ss);
+    (void)r;
+    stackLimit = reinterpret_cast<quintptr>(ss.ss_sp);
 #  else
     void* stackBottom = 0;
     pthread_attr_t attr;


--- a/qtdeclarative/src/qml/jsruntime/qv4mm.cpp
+++ b/qtdeclarative/src/qml/jsruntime/qv4mm.cpp
@@ -67,6 +67,11 @@
 #include <sys/storage.h>   // __tls()
 #endif

+#if OS(SOLARIS)
+#include <thread.h>
+#include <pthread.h>
+#endif
+
 QT_BEGIN_NAMESPACE

 using namespace QV4;
@@ -218,6 +223,11 @@ MemoryManager::MemoryManager()
 #  if OS(DARWIN)
     void *st = pthread_get_stackaddr_np(pthread_self());
     m_d->stackTop = static_cast<quintptr *>(st);
+#  elif OS(SOLARIS)
+    stack_t ss;
+    int r = thr_stksegment(&ss);
+    (void)r;
+    m_d->stackTop = static_cast<quintptr *>(ss.ss_sp) + ss.ss_size/sizeof(quintptr);
 #  else
     void* stackBottom = 0;
     pthread_attr_t attr;

我建议仔细检查该代码,因为我的 Qt 代码没有使用该 Qt 模块,因此,我没有对其进行太多测试.

I recommend a careful review of that code because my Qt-code does not use that Qt-module, thus, I did not test it much.

Qt 5 似乎严重依赖 XKB 扩展.如果没有 XKB 支持,您似乎无法构建 Qt 5.它与 xkbcommon 捆绑在一起.

Qt 5 seems to heavily rely on the XKB extension. It seems that you can't build Qt 5 without XKB support. It comes bundled with xkbcommon.

首先,确保它找到了正确的 XKB 数据库.否则键盘输入在您的 Qt 程序中根本不起作用!

First, make sure that it finds the right XKB database. Otherwise keyboard input does not work at all in your Qt programs!

Solaris 没有默认值 /usr/share/X11/xkb.它改为:

Solaris does not have the default value /usr/share/X11/xkb. It has instead:

/usr/X11/lib/X11/xkb
/usr/openwin/lib/X11/xkb

但我没有遇到这些 - xkbcommon 根本找不到任何带有这些的组件.

But I havn't had luck with those - xkbcommon simply could not find any components with those.

我最终将 /usr/share/X11/xkb 从 cygwin 发行版复制到自定义路径并将其配置为 XKB 数据库.

I ended up with copying /usr/share/X11/xkb from a cygwin distribution to a custom path and configuring that as XKB database.

无论您选择什么 XKB,您都必须对其进行配置:

Whatever XKB you choose you have to configure it:

--- a/qtbase/src/3rdparty/xkbcommon.pri
+++ b/qtbase/src/3rdparty/xkbcommon.pri
@@ -1,7 +1,12 @@
 QMAKE_CFLAGS += -std=gnu99 -w
 INCLUDEPATH += $$PWD/xkbcommon $$PWD/xkbcommon/src $$PWD/xkbcommon/src/xkbcomp

+solaris-g++-64 {
+DEFINES += DFLT_XKB_CONFIG_ROOT='\\"/MY/XKB/CHOICE\\"'
+} else {
 DEFINES += DFLT_XKB_CONFIG_ROOT='\\"/usr/share/X11/xkb\\"'
+}

 ### RMLVO names can be overwritten with environmental variables (See libxkbcommon documentation)
 DEFINES += DEFAULT_XKB_RULES='\\"evdev\\"'

为了测试,检查错误消息参数中的 NULL 值也是有意义的:

For testing it also make sense to check for NULL values in error message parameters:

--- a/qtbase/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp.c
+++ b/qtbase/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp.c
@@ -68,8 +68,11 @@ text_v1_keymap_new_from_names(struct xkb_keymap *keymap,
         log_err(keymap->ctx,
                 "Couldn't look up rules '%s', model '%s', layout '%s', "
                 "variant '%s', options '%s'\n",
-                rmlvo->rules, rmlvo->model, rmlvo->layout, rmlvo->variant,
-                rmlvo->options);
+                rmlvo->rules, rmlvo->model,
+                rmlvo->layout ? rmlvo->layout : "(NULL)",
+                rmlvo->variant ? rmlvo->variant : "(NULL)",
+                rmlvo->options ? rmlvo->options : "(NULL)"
+                );
         return false;
     }

还有可能您的 XServer 甚至不支持 XKB 扩展.再说一遍,我不知道Qt 5 是否可以在X 下配置disabled-XKB-support.

There is also the possibility that your XServer does not even support the XKB extension. Again, I don't know if Qt 5 can be configured with disabled-XKB-support under X.

您可以像这样检查您的 X 服务器:

You can check your X-server like this:

xprop -root | grep xkb

或者调用一个随机的 xkb 程序,例如:

Or call a random xkb-program, e.g.:

xkbvleds

此类调用不应导致如下错误:

Such call should not result in an error like:

Fatal Error: Server doesn't support a compatible XKB

如果您的 XServer 没有 XKB - Qt 程序可能会出现段错误.Qt 似乎并没有真正检查 XKB 支持.当 XKB 不可用时,它似乎没有回退机制.

In case your XServer does not have XKB - Qt programs are likely to segfault. Qt does not seem to really check for XKB support. It does not seem to have a fallback mechanism when XKB is not usable.

一些示例因为模块 quick 没有被找到而失败:

Some examples fail because of module quick not being found:

--- a/qtconnectivity/examples/bluetooth/scanner/scanner.pro
+++ b/qtconnectivity/examples/bluetooth/scanner/scanner.pro
@@ -1,4 +1,4 @@
-QT = core bluetooth quick
+QT = core bluetooth # quick
 SOURCES += qmlscanner.cpp

 TARGET = qml_scanner
diff --git a/qtconnectivity/examples/nfc/poster/poster.pro b/qtconnectivity/examples/nfc/poster/poster.pro
index d108b2a..d0d0659 100644
--- a/qtconnectivity/examples/nfc/poster/poster.pro
+++ b/qtconnectivity/examples/nfc/poster/poster.pro
@@ -1,4 +1,4 @@
-QT += qml quick network nfc widgets
+QT += qml network nfc widgets # quick

 SOURCES += \
     qmlposter.cpp

它们也没有构建.

一个 gmake install 令人惊讶地触发了几个尚未编译的模块的编译.因此并行执行它是有意义的:

A gmake install surprisingly triggers the compilation of several modules not yet compiled. Thus it make sense to execute it in parallel:

$ gmake -j16 install

(假设您的系统有足够数量的内核)

(assuming that your system has a sufficient number of cores)

捆绑的 QtHelp 模块未通过主要编译/安装步骤构建/安装.

The bundled QtHelp module is not build/installed with the main compile/install steps.

要解决这个问题:

cd qttools
PATH=$MY_PREFIX/bin:$PATH qmake
gmake
gmake install

未解决的问题

  • 当使用远程 Cygwin-X 连接时,有些颜色很奇怪 - 例如标准的小部件灰色是一些浅蓝色 - 有什么想法可以从哪里开始寻找吗?
  • QtSVG 已成功构建,但显示一个小的 SVG(例如在 QLabel 内)会挂起对话框 - truss -u : 显示 libm/QtWidget 内的函数调用 - 也许系统太慢了和/或某些代码路径未在 Solaris 上优化/与通过 ssh 的 X 转发相结合
  • 启动时打印 Qt 程序:Qt 警告:找不到系统 Compose 文件的位置.考虑设置 QTCOMPOSE 环境变量. - 不知道这是关于什么功能
  • Open issues

    • when using a remote Cygwin-X connection some colors are weird - e.g. the standard widget-gray is some light-light-blue - any ideas where to start to look for that?
    • QtSVG is successfully built but displaying a small SVG (e.g. inside a QLabel) hangs the dialog - a truss -u : shows function calls inside libm/QtWidget - perhaps the system is just way too slow and/or some code-path is not optimized on Solaris/in combination with a X-forwarding over ssh
    • a Qt-Program prints on startup: Qt Warning: Could not find a location of the system's Compose files. Consider setting the QTCOMPOSE environment variable. - no idea what feature this is about
    • 通过这些调整正常"的 Qt 程序(没有 QtSvg)编译并在 Solaris 10 下运行良好.

      With those adjustments 'normal' Qt programs (without QtSvg) compile and run fine under Solaris 10.

      这篇关于如何在 Solaris 10 上构建 Qt 5.2?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆