I’m building an application that both relies on qt6 and ICU4C on Linux/non-macOS Unix.
My application must be kept up to date with the latest icu releases, regardless of what ends up bundled with Qt.
When building with vcpkg on Ubuntu 24.04, things seem to “work” more or less, when using system Qt. However many users on rolling release or custom (e.g. Gentoo) distros report issues related to icu version mismatches.
I’m currently trying to build a flatpak of my app, based on the KDE 6.9 SDK and manually building icu4c version 76.1 as a source module.
I ran across two problems with this approach:
First, the call find_package(ICU 76 REQUIRED COMPONENTS data i18n uc)
would always find the locally installed version: Found ICU: /app/include (found suitable version "76.1", minimum required is "76") found components: data i18n uc
. However, inspecting the cmake cache, while the header file "unicode/utypes.h"
was indeed found in /app/include/unicode. But all of the components’ libraries were actually found from /usr/lib/x86_64-linux-gnu/libicu-*
. So that was extremely unintuitive and took a long time to notice. Thankfully passing -DICU_ROOT=/app fixes that one.
The second is that while my apps’ libraries found and link to icu 76 properly, when loading my executable that also links with Qt6, the order of icu libraries that gets loaded is all jumbled. Like so:
[📦 org.ladybird.Ladybird ~]$ ldd /app/lib/liblagom-unicode.so | grep icu
libicui18n.so.76 => /app/lib/libicui18n.so.76 (0x00007fc29aa00000)
libicuuc.so.76 => /app/lib/libicuuc.so.76 (0x00007fc29a600000)
libicudata.so.76 => /app/lib/libicudata.so.76 (0x00007fc298000000)
[📦 org.ladybird.Ladybird ~]$ ldd /app/libexec/WebContent | grep icu
libicui18n.so.75 => /usr/lib/x86_64-linux-gnu/libicui18n.so.75 (0x00007ccec4c00000)
libicuuc.so.75 => /usr/lib/x86_64-linux-gnu/libicuuc.so.75 (0x00007ccec4800000)
libicui18n.so.76 => /app/libexec/../lib/libicui18n.so.76 (0x00007ccec2200000)
libicuuc.so.76 => /app/libexec/../lib/libicuuc.so.76 (0x00007ccec1e00000)
libicudata.so.75 => /usr/lib/x86_64-linux-gnu/libicudata.so.75 (0x00007ccec0000000)
libicudata.so.76 => /app/libexec/../lib/libicudata.so.76 (0x00007ccebba00000)
Hopefully that’s enough context for the problem I’m trying to solve…
My next chosen solution is to look at the option of using an entirely different soname for the icu4c libraries I’ve built myself, and properly enforcing the version suffix feature of the icu build system.
Packaging ICU4C | ICU Documentation. Is there any support in the builtin find module for these optional library suffixes? Or am I going to have to copy https://gitlab.kitware.com/cmake/cmake/-/blob/6903385999256288d71b7d68d7a1570151a752c4/Modules/FindICU.cmake into my project and tweak it to support my custom module names? Is this a good idea/approach to support “I want up-to-date icu4c in my app while linking against a third party dep that uses icu4c?”