fix linkage with freetype/icu twice on linux #1877

Merged
vng merged 3 commits from vng-fixodr into master 2022-01-20 06:32:13 +00:00
16 changed files with 69 additions and 40 deletions

View file

@ -6,3 +6,4 @@ target_include_directories(freetype
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include/freetype2>
)
add_library(Freetype::Freetype ALIAS freetype)

View file

@ -1,6 +1,6 @@
project(icu)
set(SRC
add_library(icuuc
uconfig_local.h
icu/icu4c/source/common/appendable.cpp
icu/icu4c/source/common/bmpset.cpp
@ -170,6 +170,21 @@ set(SRC
icu/icu4c/source/common/uvectr32.cpp
icu/icu4c/source/common/uvectr64.h
icu/icu4c/source/common/wintz.h
)
target_include_directories(icuuc
PUBLIC
./
icu/icu4c/source/common
)
target_compile_definitions(icuuc PUBLIC UCONFIG_USE_LOCAL)
set_target_properties(icuuc PROPERTIES UNITY_BUILD OFF)
biodranik commented 2022-01-19 16:59:33 +00:00 (Migrated from github.com)
Review

Лучше если эта команда будет перед add_library выше, создающей alias. Из документации cmake не ясно, как оно работает, но сказано, что alias таргеты immutable. Возможно, последующие изменения оригинального таргета не подхватятся. Поэтому сначала лучше настраивать либу, и в самом конце сделать alias.

Лучше если эта команда будет перед add_library выше, создающей alias. Из документации cmake не ясно, как оно работает, но сказано, что alias таргеты immutable. Возможно, последующие изменения оригинального таргета не подхватятся. Поэтому сначала лучше настраивать либу, и в самом конце сделать alias.
add_library(ICU::uc ALIAS icuuc)
add_library(icui18n
icu/icu4c/source/i18n/anytrans.cpp
icu/icu4c/source/i18n/anytrans.h
icu/icu4c/source/i18n/astro.h
@ -375,18 +390,18 @@ set(SRC
icu/icu4c/source/stubdata/stubdata.cpp
)
add_library(${PROJECT_NAME} ${SRC})
target_compile_definitions(icui18n PUBLIC UCONFIG_USE_LOCAL)
target_compile_definitions(${PROJECT_NAME}
PUBLIC
UCONFIG_USE_LOCAL
)
target_include_directories(${PROJECT_NAME}
target_include_directories(icui18n
PUBLIC
./
icu/icu4c/source/common
icu/icu4c/source/i18n
PRIVATE
icu/icu4c/source/common
)
set_target_properties(${PROJECT_NAME} PROPERTIES UNITY_BUILD OFF)
target_link_libraries(icui18n PRIVATE icuuc)
set_target_properties(icui18n PROPERTIES UNITY_BUILD OFF)
add_library(ICU::i18n ALIAS icui18n)

View file

@ -310,9 +310,14 @@ set(EXPAT_SHARED_LIBS OFF)
add_subdirectory(3party/expat/expat)
add_subdirectory(3party/agg)
add_subdirectory(3party/bsdiff-courgette)
add_subdirectory(3party/freetype)
add_subdirectory(3party/gflags)
add_subdirectory(3party/icu)
if (LINUX_DETECTED)
find_package(ICU COMPONENTS uc i18n data REQUIRED)
find_package(Freetype REQUIRED)
else()
biodranik commented 2022-01-18 10:48:49 +00:00 (Migrated from github.com)
Review

Наш код явно загружает data/icudt70l.dat, хотя динамически прилинкованные пакеты на линуксе подгружают эти данные из shared библиотеки. Видимо, нужно вставить ifdef для линукса, чтобы 1) не включать этот файл в бандл и 2) не загружать его явно в коде, и проверить, что это работает.

indexer/transliteration_loader.cpp
16:  char const kICUDataFile[] = "icudt70l.dat";
qt/CMakeLists.txt
132:  icudt70l.dat
Наш код явно загружает data/icudt70l.dat, хотя динамически прилинкованные пакеты на линуксе подгружают эти данные из shared библиотеки. Видимо, нужно вставить ifdef для линукса, чтобы 1) не включать этот файл в бандл и 2) не загружать его явно в коде, и проверить, что это работает. ``` indexer/transliteration_loader.cpp 16: char const kICUDataFile[] = "icudt70l.dat"; ``` ``` qt/CMakeLists.txt 132: icudt70l.dat ```
vng commented 2022-01-18 11:59:06 +00:00 (Migrated from github.com)
Review

Я думаю это тут не мешает, ну или решать проблемы по мере поступления. Его формат скорее всего унифицирован и старые пакеты вполне могут читать эти свежие правила. ИМХО код и этот dat могут обновляться независимо.

Я думаю это тут не мешает, ну или решать проблемы по мере поступления. Его формат _скорее всего_ унифицирован и старые пакеты вполне могут читать эти свежие правила. ИМХО код и этот dat могут обновляться независимо.
biodranik commented 2022-01-18 12:11:07 +00:00 (Migrated from github.com)
Review

Я не видел в описании, что старый код может работать с новыми данными. Да и как он будет работать, если данные уже загружаются в динамической либе? Тут будет ub.
Более того, на системах с разными кодировками и byte order будут печальные сюрпризы.
https://unicode-org.github.io/icu/userguide/icu_data/#sharing-icu-data-between-platforms

Я не видел в описании, что старый код может работать с новыми данными. Да и как он будет работать, если данные уже загружаются в динамической либе? Тут будет ub. Более того, на системах с разными кодировками и byte order будут печальные сюрпризы. https://unicode-org.github.io/icu/userguide/icu_data/#sharing-icu-data-between-platforms
vng commented 2022-01-18 12:26:59 +00:00 (Migrated from github.com)
Review

Мы же сейчас шарим этот несчастный файл. Мы можем оставить это на потом, когда будет реальная проблема, иначе тут changeset многократно усложнится.

Мы же сейчас шарим этот несчастный файл. Мы можем оставить это на потом, когда будет реальная проблема, иначе тут changeset многократно усложнится.
biodranik commented 2022-01-18 15:51:21 +00:00 (Migrated from github.com)
Review

А ты запускал и проверял транслитерацию?

А ты запускал и проверял транслитерацию?
biodranik commented 2022-01-18 15:52:09 +00:00 (Migrated from github.com)
Review

Это очевидный косяк и ub, зачем потом тратить время на разгребание ошибок от энтузиастов собирать и ранить код на линуксах? И они своё время будут тратить.

Это очевидный косяк и ub, зачем потом тратить время на разгребание ошибок от энтузиастов собирать и ранить код на линуксах? И они своё время будут тратить.
vng commented 2022-01-18 15:59:08 +00:00 (Migrated from github.com)
Review
  • Правка касается только Linux, все остальное остается как и было. Транслитерация у меня на Маке работает
  • Откуда ты взял UB? В нашем коде инициализации явно вызывается u_setDataDirectory на папку с dat файлом. Без этого вызова ICU сам ничего (скорее всего?) грузить не будет. Можно попросить чела проверить как она работает на линуксе, я думаю там все ок.
- Правка касается только Linux, все остальное остается как и было. Транслитерация у меня на Маке работает - Откуда ты взял UB? В нашем коде инициализации явно вызывается u_setDataDirectory на папку с dat файлом. Без этого вызова ICU сам ничего (скорее всего?) грузить не будет. Можно попросить чела проверить как она работает на линуксе, я думаю там все ок.
biodranik commented 2022-01-18 16:27:38 +00:00 (Migrated from github.com)
Review

Расскажи, как проверить, давай глянем сначала. UB будет из-за попытки загрузить новые ресурсы старой версией. Чем старее версия, как я понимаю, тем больше шансов UB. А на многих линуксах эта либа старая, в Ubuntu20 например версия 66.

Расскажи, как проверить, давай глянем сначала. UB будет из-за попытки загрузить новые ресурсы старой версией. Чем старее версия, как я понимаю, тем больше шансов UB. А на многих линуксах эта либа старая, в Ubuntu20 например версия 66.
vng commented 2022-01-18 16:34:47 +00:00 (Migrated from github.com)
Review

На CI успешно выполнились Transliteration_CompareSamples

На CI успешно выполнились Transliteration_CompareSamples
vng commented 2022-01-18 16:50:18 +00:00 (Migrated from github.com)
Review

Ну и вообще этот транслитератор начинает вызываться сразу при инициализации поиска на старте (мутит японские категории) и отрисовке. Так что если прога запускается - значит все ок.

Ну и вообще этот транслитератор начинает вызываться сразу при инициализации поиска на старте (мутит японские категории) и отрисовке. Так что если прога запускается - значит все ок.
biodranik commented 2022-01-19 09:22:54 +00:00 (Migrated from github.com)
Review

Будем ждать, пока случится не ок?

Будем ждать, пока случится не ок?
vng commented 2022-01-19 13:39:13 +00:00 (Migrated from github.com)
Review

Я не вижу зазорным тут решать проблемы по мере появления, сейчас линукс вообще не работает. Больше у меня аргументов нет, я примеры работы показал :) Наверное, можно изгольнуться и:

  • искать при сборке папку icu (что-то типа ICU_DIR)
  • искать там нужный dat файл
  • бандлить его в qt/CMakeList

Если честно, у меня на это нет фуреку уже. Если ты видишь как это красиво сделать и протестить - давай.

Я не вижу зазорным тут решать проблемы по мере появления, сейчас линукс вообще не работает. Больше у меня аргументов нет, я примеры работы показал :) Наверное, можно изгольнуться и: - искать при сборке папку icu (что-то типа ICU_DIR) - искать там нужный dat файл - бандлить его в qt/CMakeList Если честно, у меня на это нет фуреку уже. Если ты видишь как это красиво сделать и протестить - давай.
biodranik commented 2022-01-19 14:09:24 +00:00 (Migrated from github.com)
Review

Судя по тому, что я видел, надо по ifdef OMIM_OS_LINUX просто не пытаться загружать ничего из нашего dat файла (и написать коммент, почему, что icu data is loaded automatically from the shared library on Linux.

If the ICU data directory string is empty, then ICU will not attempt to load data from the file system. It is then only possible to load data from the linked-in shared library or via udata_setCommonData() and udata_setAppData(). This is inflexible but provides the highest performance.

Судя по тому, что я видел, надо по ifdef OMIM_OS_LINUX просто не пытаться загружать ничего из нашего dat файла (и написать коммент, почему, что icu data is loaded automatically from the shared library on Linux. > If the ICU data directory string is empty, then ICU will not attempt to load data from the file system. It is then only possible to load data from the linked-in shared library or via udata_setCommonData() and udata_setAppData(). This is inflexible but provides the highest performance.
biodranik commented 2022-01-19 14:09:57 +00:00 (Migrated from github.com)
Review

И под Linux не добавлять .dat в ресурсы и не шиппить, конечно же. Сэкономим место.

И под Linux не добавлять .dat в ресурсы и не шиппить, конечно же. Сэкономим место.
vng commented 2022-01-19 15:10:46 +00:00 (Migrated from github.com)
Review

Я сейчас попробую, но думаю транслитерация просто не будет работать.

Я сейчас попробую, но думаю транслитерация просто не будет работать.
vng commented 2022-01-19 16:02:13 +00:00 (Migrated from github.com)
Review

Хм, все работает, по крайней мере тесты :)

Хм, все работает, по крайней мере тесты :)
biodranik commented 2022-01-19 17:12:26 +00:00 (Migrated from github.com)
Review

Гуд.

Гуд.
add_subdirectory(3party/freetype)
add_subdirectory(3party/icu)
endif()
add_subdirectory(3party/jansson)
add_subdirectory(3party/liboauthcpp)
add_subdirectory(3party/minizip)

View file

@ -97,7 +97,8 @@ target_link_libraries(${PROJECT_NAME}
expat
jansson
succinct
icu # For transliteration.
ICU::uc
ICU::i18n # For transliteration.
oauthcpp # For base64_encode and base64_decode
minizip
${LIBZ}

View file

@ -13,6 +13,8 @@
#include <unicode/utrans.h>
#include <unicode/utypes.h>
#include "std/target_os.hpp"
#include <cstring>
#include <mutex>
@ -58,8 +60,12 @@ void Transliteration::Init(std::string const & icuDataDir)
return;
biodranik commented 2022-01-19 17:02:15 +00:00 (Migrated from github.com)
Review
  // an ICU data file. On Linux, data file is loaded automatically from the shared library.
```suggestion // an ICU data file. On Linux, data file is loaded automatically from the shared library. ```
// This function should be called before the first ICU operation that will require the loading of
// an ICU data file.
// an ICU data file. On Linux, data file is loaded automatically from the shared library.
#ifndef OMIM_OS_LINUX
u_setDataDirectory(icuDataDir.c_str());
#else
UNUSED_VALUE(icuDataDir);
#endif
for (auto const & lang : StringUtf8Multilang::GetSupportedLanguages())
{
@ -118,10 +124,7 @@ bool Transliteration::Transliterate(std::string const & transID, icu::UnicodeStr
it->second->m_transliterator->transliterate(ustr);
if (ustr.isEmpty())
return false;
return true;
return !ustr.isEmpty();
}
bool Transliteration::TransliterateForce(std::string const & str, std::string const & transliteratorId,

View file

@ -7,10 +7,12 @@
#include <mutex>
#include <string>
namespace icu
{
// From ICU library, either 3party/icu or from the system's package.
#include <unicode/uversion.h>
biodranik commented 2022-01-18 10:58:39 +00:00 (Migrated from github.com)
Review

// From ICU library, either 3party/icu or from the system's package.
#include <unicode/uversion.h>
```suggestion // From ICU library, either 3party/icu or from the system's package. #include <unicode/uversion.h> ```
U_NAMESPACE_BEGIN
class UnicodeString;
} // namespace icu
U_NAMESPACE_END
class Transliteration
{

View file

@ -169,11 +169,11 @@ target_link_libraries(${PROJECT_NAME}
geometry
coding
base
freetype
Freetype::Freetype
vulkan_wrapper
stb_image
sdf_image
icu
ICU::i18n
expat
$<$<BOOL:${PLATFORM_MAC}>:-framework\ OpenGL>
$<$<BOOL:${PLATFORM_LINUX}>:OpenGL::GL>

View file

@ -54,7 +54,6 @@
#include "platform/platform.hpp"
#include "coding/endianness.hpp"
#include "coding/transliteration.hpp"
#include "base/file_name_utils.hpp"
#include "base/timer.hpp"

View file

@ -29,7 +29,7 @@ omim_link_libraries(
opening_hours
freetype
expat
icu
ICU::i18n
jansson
protobuf
bsdiff

View file

@ -5,8 +5,6 @@
#include "coding/transliteration.hpp"
#include "coding/transliteration.hpp"
#include "base/assert.hpp"
#include "base/dfa_helpers.hpp"
#include "base/macros.hpp"

View file

@ -12,23 +12,24 @@
void InitTransliterationInstanceWithDefaultDirs()
{
Platform const & pl = GetPlatform();
#if defined(OMIM_OS_ANDROID)
char const kICUDataFile[] = "icudt70l.dat";
if (!GetPlatform().IsFileExistsByFullPath(GetPlatform().WritableDir() + kICUDataFile))
if (!pl.IsFileExistsByFullPath(pl.WritableDir() + kICUDataFile))
{
try
{
ZipFileReader::UnzipFile(GetPlatform().ResourcesDir(), std::string("assets/") + kICUDataFile,
GetPlatform().WritableDir() + kICUDataFile);
ZipFileReader::UnzipFile(pl.ResourcesDir(), std::string("assets/") + kICUDataFile,
pl.WritableDir() + kICUDataFile);
}
catch (RootException const & e)
{
LOG(LWARNING,
("Can't get transliteration data file \"", kICUDataFile, "\", reason:", e.Msg()));
LOG(LWARNING, ("Can't get transliteration data file \"", kICUDataFile, "\", reason:", e.Msg()));
}
}
Transliteration::Instance().Init(GetPlatform().WritableDir());
Transliteration::Instance().Init(pl.WritableDir());
#else
Transliteration::Instance().Init(GetPlatform().ResourcesDir());
Transliteration::Instance().Init(pl.ResourcesDir());
#endif
}

View file

@ -19,7 +19,7 @@ omim_link_libraries(
coding
geometry
base
icu
ICU::i18n
jansson
oauthcpp
protobuf

View file

@ -412,7 +412,7 @@ Framework::Framework(FrameworkParams const & params)
m_featuresFetcher.GetDataSource().AddObserver(editor);
LOG(LINFO, ("Editor initialized"));
LOG(LDEBUG, ("Editor initialized"));
m_trafficManager.SetCurrentDataVersion(m_storage.GetCurrentDataVersion());
m_trafficManager.SetSimplifiedColorScheme(LoadTrafficSimplifiedColors());

View file

@ -129,7 +129,6 @@ copy_resources(
unicode_blocks.txt
World.mwm
WorldCoasts.mwm
icudt70l.dat
00_NotoNaskhArabic-Regular.ttf
00_NotoSansThai-Regular.ttf
@ -142,11 +141,16 @@ copy_resources(
07_roboto_medium.ttf
)
if (NOT PLATFORM_LINUX)
# On Linux, ICU data is loaded from the shared library.
copy_resources(icudt70l.dat)
endif()
if (PLATFORM_MAC)
execute_process(
COMMAND cp -r ${OMIM_ROOT}/tools/shaders_compiler/macos ${RESOURCES_FOLDER}/shaders_compiler
)
elseif(PLATFORM_LINUX)
elseif (PLATFORM_LINUX)
execute_process(
biodranik commented 2022-01-19 17:11:14 +00:00 (Migrated from github.com)
Review
  # On Linux, ICU data is loaded from the shared library.
  copy_resources(icudt70l.dat)
```suggestion # On Linux, ICU data is loaded from the shared library. copy_resources(icudt70l.dat) ```
COMMAND cp -r ${OMIM_ROOT}/tools/shaders_compiler/linux ${RESOURCES_FOLDER}/shaders_compiler
)

View file

@ -24,7 +24,7 @@ omim_link_libraries(
coding
base
bsdiff
icu
ICU::i18n
jansson
oauthcpp
opening_hours

View file

@ -42,7 +42,7 @@ omim_link_libraries(
pugixml
opening_hours
succinct
icu
ICU::i18n
${Boost_LIBRARIES}
${LIBZ}
)