ICU library mismatch in multiple Qt versions
-
Reported here by me today: https://bugreports.qt.io/browse/QTBUG-139649
I couldn't find anything about this on the forum, maybe someone can point me to an existing topic?
-
Our Linux builds are supposed to support multiple platforms at the same time.
If you want a Qt build using a higher version than 73, you have to build it from source. -
It is a warning, not an error, unless you fail to ship the matching libraries with your application (then you have a different error). The Qt versions installed by the online installers come with a matching set of ICU libraries.
Is it actually causing any harm?
-
Our Linux builds are supposed to support multiple platforms at the same time.
If you want a Qt build using a higher version than 73, you have to build it from source.@Axel-Spoerl Thanks for your feedback!
I took your advice given in the bug report about installing multiple versions of ICU in parallel (much easier than building Qt from source). It was quite tricky getting it to work because of the "renaming" feature that ICU uses. Requires some special
"if...else"
logic in theqmake
project file, but it looks OK now.I had installed the
qt5-dev
libraries from the Ubuntu 24.04.3 repositories which are at Qt version 5.15.13. Also, I installed the ICUdev
packages from the Ubuntu repos which are compatible with their Qt 5 libraries. I have Qt 6 libraries installed under a folder/home/Qt/...
which Qt Creator made, and these are not in the$PATH
. So the trick was to find out which versions of ICU are needed by each QtCore.so
library.Qt 6.5.3 up to and including Qt 6.6 use ICU 56, and versions 6.7 and above use ICU 73. So I built ICU from source, being sure to download the appropriate ICU release packages, and installed those to appropriate subfolders under my
/opt/
directory:/opt/local/icu56/... /opt/local/icu73/...
In addition to that, the
INCLUDEPATH
variable needs to be set in theqmake
project file so that the headers in/opt/...
are found BEFORE the headers inusr/include/unicode
. This is what that part of my.pro
qmake project file looks like now:if(equals(QT_MAJOR_VERSION,6)) { if(lessThan(QT_MINOR_VERSION,7)) { ICU_VERSION_SUFFIX = 56 } else { ICU_VERSION_SUFFIX = 73 } ICU_INCLUDES="/opt/local/icu$${ICU_VERSION_SUFFIX}/include" ICU_LIBS_DIR="/opt/local/icu$${ICU_VERSION_SUFFIX}/lib" ##################################################### # This "#define ICU_VER=..." macro enables the header # "icu_includes.hpp" to find the correct ICU headers: ##################################################### ICU_VERSION = ICU_VER=$${ICU_VERSION_SUFFIX} DEFINES += "$${ICU_VERSION}" } else { # Qt 5 will use the system ICU libraries, which are ICU version 74.2: ICU_INCLUDES="/usr/include" ICU_LIBS_DIR="/usr/lib/x86_64-linux-gnu" } LIBS += -L\""$${ICU_LIBS_DIR}"\" -licudata -licui18n -licuio -licutest -licutu -licuuc INCLUDEPATH += \ $${ICU_INCLUDES} \ include \ # etc.
Then I have one header icu_includes.hpp which looks like this:
#ifndef ICU_INCLUDES_HPP #define ICU_INCLUDES_HPP #ifndef ICU_VER /* ICU_VER is not defined for Qt 5, only for different flavors of Qt 6: */ #include <unicode/utypes.h> #include <unicode/uclean.h> #include <unicode/ucsdet.h> #elif ICU_VER==73 #include "/opt/local/icu73/include/unicode/utypes.h" #include "/opt/local/icu73/include/unicode/uclean.h" #include "/opt/local/icu73/include/unicode/ucsdet.h" #elif ICU_VER==56 #include "/opt/local/icu56/include/unicode/utypes.h" #include "/opt/local/icu56/include/unicode/uclean.h" #include "/opt/local/icu56/include/unicode/ucsdet.h" #endif #endif // ICU_INCLUDES_HPP
All other code which calls ICU functions directly (only one
.cpp
file, actually) includes this header. Since project include paths take preference over system paths, the "renaming" of functions likeu_init()
still works correctly. That means thatu_init()
, for example, resolves tou_init_56()
, oru_init_73()
, or evenu_init_74()
depending on the Qt version.Now it has occurred to me that I could auto-generate the header using a file
icu_includes.hpp.in
and using variable substitutions from the project file (my next "TO DO"...)So, one interesting fact is that my project, when built with Qt 5, uses a higher ICU library version than when built with Qt 6! (but only because that is what the Ubuntu 24.04 system installs).
I'm sure this scenario can be improved upon, so your suggestions are most welcome! :)
-