3ds/Wii: Update ICU to latest version
3DS was annoying because of the type mismatch (I think this can be upstreamed but it requires a Jira account, will do this later...)
Wii just builds without any patching o_O
Player test is missing but compiling is a good start xD
Yep, was also impressed it worked for wiiu, same compiler etc.
~~The icudata library gets 33 mb, resulting in an executable dol of 38 mb. Nope.~~ Whoops, missing recent icu data package...
Took a while, but with this patch, ICU works for me. Somehow the std::mutex stuff does not seem to work. The custom ICU installer is not needed, the datafile patch is.
patch section:
# Fix icu build
# Do not write objects, but source files
perl -pi -e 's|#ifndef U_DISABLE_OBJ_CODE|#if 0 // U_DISABLE_OBJ_CODE|' icu/source/tools/toolutil/pkg_genc.h
cp -rup icu icu-native
# Emit correct bigendian icudata header
patch -Np0 < icu-pkg_genc.patch
# Patch mutex support in
patch -Np0 < icu-wii-mutex.patch
Fix-Wii-ICU-custom-mutex-implementation.patch.txt
The patch
From a70c2f598450dc25ddd41ee591cd43069d623337 Mon Sep 17 00:00:00 2001
From: Carsten Teibes <[email protected]>
Date: Sat, 2 Dec 2023 05:03:56 +0100
Subject: [PATCH] Fix Wii ICU (custom mutex implementation)
---
shared/common.sh | 21 +-----
wii/2_build_toolchain.sh | 4 +-
wii/icu-pkg_genc.patch | 15 ++--
wii/icu-wii-mutex.patch | 158 +++++++++++++++++++++++++++++++++++++++
4 files changed, 168 insertions(+), 30 deletions(-)
create mode 100644 wii/icu-wii-mutex.patch
diff --git a/shared/common.sh b/shared/common.sh
index 40e4ea7..8d32019 100644
--- a/shared/common.sh
+++ b/shared/common.sh
@@ -191,25 +191,6 @@ function install_lib_icu_native {
)
}
-# Only needed for a mixed endian compile, on other platforms use
-# install_lib_icu_native
-function install_lib_icu_native_without_assembly {
- msg "**** Building ICU (native without ASM) ****"
-
- (cd icu-native/source
- unset CC
- unset CXX
- unset CFLAGS
- unset CPPFLAGS
- unset CXXFLAGS
- unset LDFLAGS
-
- chmod u+x configure
- CPPFLAGS="-DBUILD_DATA_WITHOUT_ASSEMBLY -DU_DISABLE_OBJ_CODE" ./configure --enable-static --enable-shared=no $ICU_ARGS
- make
- )
-}
-
function install_lib_icu_cross {
msg "**** Building ICU (cross) ****"
@@ -331,6 +312,6 @@ function cleanup {
libsamplerate-*/ wildmidi-*/ opus-*/ opusfile-*/ icu/ icu-native/ \
SDL2-*/ SDL2_image-*/ fmt-*/ FluidLite-*/ fluidsynth-*/ json-*/ inih-*/ \
lhasa-*/ liblcf/
- rm -f *.zip *.bz2 *.gz *.xz *.tgz icudt* *.pl .patches-applied config.cache
+ rm -f *.zip *.bz2 *.gz *.xz *.tgz icudt* .patches-applied config.cache
rm -rf sbin/ share/
}
diff --git a/wii/2_build_toolchain.sh b/wii/2_build_toolchain.sh
index ab61ded..ba3d6b9 100755
--- a/wii/2_build_toolchain.sh
+++ b/wii/2_build_toolchain.sh
@@ -78,12 +78,12 @@ function set_build_flags {
fi
export CFLAGS="-g0 -O2 -mcpu=750 -meabi -mhard-float -ffunction-sections -fdata-sections"
export CXXFLAGS="$CFLAGS"
- export CPPFLAGS="-I$PLATFORM_PREFIX/include -DGEKKO"
+ export CPPFLAGS="-I$PLATFORM_PREFIX/include -DGEKKO -I$DEVKITPRO/libogc/include"
export LDFLAGS="-L$PLATFORM_PREFIX/lib"
export CMAKE_SYSTEM_NAME="Generic"
}
-install_lib_icu_native_without_assembly
+install_lib_icu_native
set_build_flags
diff --git a/wii/icu-pkg_genc.patch b/wii/icu-pkg_genc.patch
index f36ffff..1f6fcbe 100644
--- a/wii/icu-pkg_genc.patch
+++ b/wii/icu-pkg_genc.patch
@@ -1,7 +1,6 @@
-diff -Naur icu-orig/source/tools/toolutil/pkg_gencmn.c icu-native/source/tools/toolutil/pkg_gencmn.c
---- icu-orig/source/tools/toolutil/pkg_gencmn.c 2017-02-04 00:17:49.890595524 +0100
-+++ icu-native/source/tools/toolutil/pkg_gencmn.c 2017-02-04 00:20:52.285692721 +0100
-@@ -371,7 +371,7 @@
+--- icu.orig/source/tools/toolutil/pkg_gencmn.cpp 2023-10-27 23:53:02.000000000 +0200
++++ icu/source/tools/toolutil/pkg_gencmn.cpp 2023-11-28 20:30:02.740591664 +0100
+@@ -373,7 +373,7 @@
"} U_EXPORT2 %s_dat = {\n"
" 32, 0xda, 0x27, {\n"
" %lu, 0,\n"
@@ -10,13 +9,13 @@ diff -Naur icu-orig/source/tools/toolutil/pkg_gencmn.c icu-native/source/tools/t
" {0x54, 0x6f, 0x43, 0x50},\n"
" {1, 0, 0, 0},\n"
" {0, 0, 0, 0}\n"
-@@ -381,9 +381,6 @@
- (unsigned long)fileCount,
+@@ -383,9 +383,6 @@
+ static_cast<unsigned long>(fileCount),
entrypointName,
- (unsigned long)sizeof(UDataInfo),
+ static_cast<unsigned long>(sizeof(UDataInfo)),
- U_IS_BIG_ENDIAN,
- U_CHARSET_FAMILY,
- U_SIZEOF_UCHAR,
- (unsigned long)fileCount
+ static_cast<unsigned long>(fileCount)
);
T_FileStream_writeLine(out, buffer);
diff --git a/wii/icu-wii-mutex.patch b/wii/icu-wii-mutex.patch
new file mode 100644
index 0000000..2730e5a
--- /dev/null
+++ b/wii/icu-wii-mutex.patch
@@ -0,0 +1,158 @@
+diff --color -Naur icu.orig icu
+--- icu.orig/source/common/umutex.cpp 2023-10-27 23:53:02.000000000 +0200
++++ icu/source/common/umutex.cpp 2023-12-02 04:50:47.142748510 +0100
+@@ -44,20 +44,26 @@
+ *************************************************************************************************/
+
+ namespace {
++mutex_t initMutex;
++#if 0
+ std::mutex *initMutex;
+ std::condition_variable *initCondition;
++#endif
+
+ // The ICU global mutex.
+ // Used when ICU implementation code passes nullptr for the mutex pointer.
+ UMutex globalMutex;
+
++#if 0
+ std::once_flag initFlag;
+ std::once_flag *pInitFlag = &initFlag;
++#endif
+
+ } // Anonymous namespace
+
+ U_CDECL_BEGIN
+ static UBool U_CALLCONV umtx_cleanup() {
++#if 0
+ initMutex->~mutex();
+ initCondition->~condition_variable();
+ UMutex::cleanup();
+@@ -66,17 +72,23 @@
+ // Do not use this trick anywhere else in ICU; use umtx_initOnce, not std::call_once().
+ pInitFlag->~once_flag();
+ pInitFlag = new(&initFlag) std::once_flag();
++#endif
++ LWP_MutexDestroy(initMutex);
+ return true;
+ }
+
+ static void U_CALLCONV umtx_init() {
++#if 0
+ initMutex = STATIC_NEW(std::mutex);
+ initCondition = STATIC_NEW(std::condition_variable);
+ ucln_common_registerCleanup(UCLN_COMMON_MUTEX, umtx_cleanup);
++#endif
++ LWP_MutexInit(&initMutex, 0);
+ }
+ U_CDECL_END
+
+
++#if 0
+ std::mutex *UMutex::getMutex() {
+ std::mutex *retPtr = fMutex.load(std::memory_order_acquire);
+ if (retPtr == nullptr) {
+@@ -106,6 +118,7 @@
+ }
+ gListHead = nullptr;
+ }
++#endif
+
+
+ U_CAPI void U_EXPORT2
+@@ -143,8 +156,11 @@
+ //
+ U_COMMON_API UBool U_EXPORT2
+ umtx_initImplPreInit(UInitOnce &uio) {
++ LWP_MutexLock(initMutex);
++#if 0
+ std::call_once(*pInitFlag, umtx_init);
+ std::unique_lock<std::mutex> lock(*initMutex);
++#endif
+ if (umtx_loadAcquire(uio.fState) == 0) {
+ umtx_storeRelease(uio.fState, 1);
+ return true; // Caller will next call the init function.
+@@ -152,7 +168,7 @@
+ while (umtx_loadAcquire(uio.fState) == 1) {
+ // Another thread is currently running the initialization.
+ // Wait until it completes.
+- initCondition->wait(lock);
++// initCondition->wait(lock);
+ }
+ U_ASSERT(uio.fState == 2);
+ return false;
+@@ -168,11 +184,15 @@
+
+ U_COMMON_API void U_EXPORT2
+ umtx_initImplPostInit(UInitOnce &uio) {
++#if 0
+ {
+ std::unique_lock<std::mutex> lock(*initMutex);
+ umtx_storeRelease(uio.fState, 2);
+ }
+ initCondition->notify_all();
++#endif
++ umtx_storeRelease(uio.fState, 2);
++ LWP_MutexUnlock(initMutex);
+ }
+
+ U_NAMESPACE_END
+diff --color -Naur icu.orig icu
+--- icu.orig/source/common/umutex.h 2023-10-27 23:53:02.000000000 +0200
++++ icu/source/common/umutex.h 2023-12-02 04:53:38.320939984 +0100
+@@ -25,6 +25,8 @@
+ #include <mutex>
+ #include <type_traits>
+
++#include <gccore.h>
++
+ #include "unicode/utypes.h"
+ #include "unicode/uclean.h"
+ #include "unicode/uobject.h"
+@@ -218,8 +220,10 @@
+
+ class U_COMMON_API UMutex {
+ public:
+- UMUTEX_CONSTEXPR UMutex() {}
+- ~UMutex() = default;
++ //UMUTEX_CONSTEXPR UMutex() {}
++ //~UMutex() = default;
++ UMutex() { LWP_MutexInit(&mutex, 0); }
++ ~UMutex() { LWP_MutexDestroy(mutex); }
+
+ UMutex(const UMutex &other) = delete;
+ UMutex &operator =(const UMutex &other) = delete;
+@@ -227,12 +231,24 @@
+
+ // requirements for C++ BasicLockable, allows UMutex to work with std::lock_guard
+ void lock() {
++#if 0
+ std::mutex *m = fMutex.load(std::memory_order_acquire);
+ if (m == nullptr) { m = getMutex(); }
+ m->lock();
++#endif
++ LWP_MutexLock(mutex);
++ }
++ void unlock() {
++#if 0
++ fMutex.load(std::memory_order_relaxed)->unlock();
++#endif
++ LWP_MutexUnlock(mutex);
+ }
+- void unlock() { fMutex.load(std::memory_order_relaxed)->unlock(); }
+
++private:
++ mutex_t mutex;
++
++#if 0
+ static void cleanup();
+
+ private:
+@@ -250,6 +266,7 @@
+ * be nullptr.
+ */
+ std::mutex *getMutex();
++#endif
+ };
+
+
--
2.42.0
So another case of a non standard conforming C++ feature implementation. Great :/
Thanks for figuring this out.
I built the new Wii toolchain with the patch applied (and moving # Emit correct bigendian icudata header at the correct location): Can confirm that it works fine. Could be directly combined with #177 to avoid conflicts.
Okay, let's merge this for now, the next can of worms is opened when I upgrade 3DS toolchain again (which is currently pinned).