buildscripts icon indicating copy to clipboard operation
buildscripts copied to clipboard

3ds/Wii: Update ICU to latest version

Open Ghabry opened this issue 2 years ago • 4 comments

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

Ghabry avatar Nov 29 '23 14:11 Ghabry

Yep, was also impressed it worked for wiiu, same compiler etc.

carstene1ns avatar Nov 30 '23 05:11 carstene1ns

~~The icudata library gets 33 mb, resulting in an executable dol of 38 mb. Nope.~~ Whoops, missing recent icu data package...

carstene1ns avatar Nov 30 '23 19:11 carstene1ns

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

carstene1ns avatar Dec 02 '23 04:12 carstene1ns

So another case of a non standard conforming C++ feature implementation. Great :/

Thanks for figuring this out.

Ghabry avatar Dec 02 '23 07:12 Ghabry

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.

Ghabry avatar Jun 05 '24 13:06 Ghabry

Okay, let's merge this for now, the next can of worms is opened when I upgrade 3DS toolchain again (which is currently pinned).

carstene1ns avatar Jun 06 '24 19:06 carstene1ns