From 8606b3d42fcee43bb3636829b8436e7b5fae81ae Mon Sep 17 00:00:00 2001 From: Totto16 Date: Mon, 13 Oct 2025 19:54:52 +0200 Subject: [PATCH 001/112] fix: fix compilation of the flatpak image - allow gcc 14 and 15 under linux - disable sdl2_image tests for the flatpak test run --- io.github.openbrickprotocolfoundation.oopetris.yml | 1 + tools/options/meson.build | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/io.github.openbrickprotocolfoundation.oopetris.yml b/io.github.openbrickprotocolfoundation.oopetris.yml index 60a4e3d1..d19bf507 100644 --- a/io.github.openbrickprotocolfoundation.oopetris.yml +++ b/io.github.openbrickprotocolfoundation.oopetris.yml @@ -16,6 +16,7 @@ modules: - --fatal-meson-warnings - -Drun_in_ci=true # note we always want the CI checks in the case we built the flatpak - --force-fallback-for=fmt # note, the freedesktop sdk has this installed, but it is not copiable into the runtime, so we need to build it ourself, to be able to install it correctly + - -Dsdl2_image:test=false # disable failing sdl2_image tests builddir: true build-options: build-args: diff --git a/tools/options/meson.build b/tools/options/meson.build index 2071d2f8..9cfb54b7 100644 --- a/tools/options/meson.build +++ b/tools/options/meson.build @@ -51,6 +51,11 @@ if get_option('run_in_ci') 'checks': ['>=15', '<16'], } + gcc_14_or_15_compiler = { + 'id': 'gcc', + 'checks': ['>=14', '<16'], + } + msvc_compiler_current = { 'id': 'msvc', 'checks': ['>=19.43', '<20'], From 0fd8539bc10b1d030a9426d04d9c80f0c543917d Mon Sep 17 00:00:00 2001 From: Totto16 Date: Mon, 13 Oct 2025 21:25:16 +0200 Subject: [PATCH 002/112] chore: update android versions --- platforms/android/app/build.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platforms/android/app/build.gradle b/platforms/android/app/build.gradle index f6e0d140..a3933661 100644 --- a/platforms/android/app/build.gradle +++ b/platforms/android/app/build.gradle @@ -130,7 +130,7 @@ List getAndroidABIs() { /** * Determine the version * if you specify it explicitly, that will be used, otherwise meson introspect will be called - * @return String + * @returns String */ String getVersion() { String property = project.findProperty('VERSION') @@ -319,14 +319,14 @@ android { targetCompatibility JavaVersion.VERSION_21 } - compileSdkVersion 35 - ndkVersion = "29.0.14206865" + compileSdkVersion 36 + ndkVersion = "29.0.14033849" defaultConfig { if (buildAsApplication) { applicationId "com.github.oopetris" } minSdkVersion 21 - targetSdkVersion 35 + targetSdkVersion 36 versionCode 7 versionName(versionString) } From 279c78222ac03f01a80c43c9d413557459ce88f6 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Mon, 13 Oct 2025 21:31:21 +0200 Subject: [PATCH 003/112] chore: update httplib wrap to 0.26.0 --- subprojects/cpp-httplib.wrap | 16 ++++++++-------- ..._mingw.diff => cpp-httplib-0.26.0_mingw.diff} | 0 2 files changed, 8 insertions(+), 8 deletions(-) rename subprojects/packagefiles/{cpp-httplib-0.25.0_mingw.diff => cpp-httplib-0.26.0_mingw.diff} (100%) diff --git a/subprojects/cpp-httplib.wrap b/subprojects/cpp-httplib.wrap index 1bfbded9..9c75a72c 100644 --- a/subprojects/cpp-httplib.wrap +++ b/subprojects/cpp-httplib.wrap @@ -1,11 +1,11 @@ [wrap-file] -directory = cpp-httplib-0.25.0 -source_url = https://github.com/yhirose/cpp-httplib/archive/refs/tags/v0.25.0.tar.gz -source_filename = cpp-httplib-0.25.0.tar.gz -source_hash = ac7c59fa72325d4cb9f73af266312d82632ac35a5c4c8a1be620c1f946ec9cea -source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/cpp-httplib_0.25.0-1/cpp-httplib-0.25.0.tar.gz -wrapdb_version = 0.25.0-1 -diff_files = cpp-httplib-0.25.0_mingw.diff +directory = cpp-httplib-0.26.0 +source_url = https://github.com/yhirose/cpp-httplib/archive/refs/tags/v0.26.0.tar.gz +source_filename = cpp-httplib-0.26.0.tar.gz +source_hash = a66f908f50ccb119769adce44fe1eac75f81b6ffab7c4ac0211bb663ffeb2688 +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/cpp-httplib_0.26.0-1/cpp-httplib-0.26.0.tar.gz +wrapdb_version = 0.26.0-1 +diff_files = cpp-httplib-0.26.0_mingw.diff [provide] -cpp-httplib = cpp_httplib_dep +dependency_names = cpp-httplib diff --git a/subprojects/packagefiles/cpp-httplib-0.25.0_mingw.diff b/subprojects/packagefiles/cpp-httplib-0.26.0_mingw.diff similarity index 100% rename from subprojects/packagefiles/cpp-httplib-0.25.0_mingw.diff rename to subprojects/packagefiles/cpp-httplib-0.26.0_mingw.diff From 2d4f2c855d4398e6a6989372ab2173a403179204 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Mon, 13 Oct 2025 21:50:35 +0200 Subject: [PATCH 004/112] chore: update tl-expected wrap to 1.3.1-1 --- ...-1.1.0_installable.diff => expected-1.3.0_installable.diff} | 0 subprojects/tl-expected.wrap | 3 +-- 2 files changed, 1 insertion(+), 2 deletions(-) rename subprojects/packagefiles/{expected-1.1.0_installable.diff => expected-1.3.0_installable.diff} (100%) diff --git a/subprojects/packagefiles/expected-1.1.0_installable.diff b/subprojects/packagefiles/expected-1.3.0_installable.diff similarity index 100% rename from subprojects/packagefiles/expected-1.1.0_installable.diff rename to subprojects/packagefiles/expected-1.3.0_installable.diff diff --git a/subprojects/tl-expected.wrap b/subprojects/tl-expected.wrap index 0f6610fe..008135a5 100644 --- a/subprojects/tl-expected.wrap +++ b/subprojects/tl-expected.wrap @@ -8,8 +8,7 @@ patch_filename = tl-expected_1.3.1-1_patch.zip patch_url = https://wrapdb.mesonbuild.com/v2/tl-expected_1.3.1-1/get_patch patch_hash = 91cfeae04ba6ea05792e68a37781236a7045b9e2e4e0c8b7093fd8c3e43b0bad wrapdb_version = 1.3.1-1 - -diff_files = expected-1.1.0_installable.diff +diff_files = expected-1.3.0_installable.diff [provide] dependency_names = tl-expected From 88e5cf7575240d513549b0bed7adda87fbd99376 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Mon, 13 Oct 2025 21:52:22 +0200 Subject: [PATCH 005/112] chore: update discord_social_sdk wrap to 1.6.11894 --- subprojects/discord-social-sdk.wrap | 8 ++++---- ...mingw.diff => discord_social_sdk-1.6.11894_mingw.diff} | 0 subprojects/packagefiles/discord_social_sdk/meson.build | 4 +++- 3 files changed, 7 insertions(+), 5 deletions(-) rename subprojects/packagefiles/{discord_social_sdk-1.4.9649_mingw.diff => discord_social_sdk-1.6.11894_mingw.diff} (100%) diff --git a/subprojects/discord-social-sdk.wrap b/subprojects/discord-social-sdk.wrap index 0122eb3c..1adbc59f 100644 --- a/subprojects/discord-social-sdk.wrap +++ b/subprojects/discord-social-sdk.wrap @@ -1,10 +1,10 @@ [wrap-file] directory = discord_social_sdk -source_url = https://oopetris.totto.lt/static/assets/discord/DiscordSocialSdk-1.4.9649.zip -source_filename = DiscordSocialSdk-1.4.9649.zip -source_hash = 55af4030abf3286ee0a8e562c30cd839a605063eb5e987aea110bfc81bc39312 +source_url = https://oopetris.totto.lt/static/assets/discord/DiscordSocialSdk-1.6.11894.zip +source_filename = DiscordSocialSdk-1.6.11894.zip +source_hash = 61ef7474331a1a039c65a8a07c6fbef558d4301e06aa4e2f42af9983da7698d8 patch_directory = discord_social_sdk -diff_files = discord_social_sdk-1.4.9649_mingw.diff +diff_files = discord_social_sdk-1.6.11894_mingw.diff [provide] discord-social-sdk = discord_social_sdk_dep diff --git a/subprojects/packagefiles/discord_social_sdk-1.4.9649_mingw.diff b/subprojects/packagefiles/discord_social_sdk-1.6.11894_mingw.diff similarity index 100% rename from subprojects/packagefiles/discord_social_sdk-1.4.9649_mingw.diff rename to subprojects/packagefiles/discord_social_sdk-1.6.11894_mingw.diff diff --git a/subprojects/packagefiles/discord_social_sdk/meson.build b/subprojects/packagefiles/discord_social_sdk/meson.build index d16b6b89..91c9bb7a 100644 --- a/subprojects/packagefiles/discord_social_sdk/meson.build +++ b/subprojects/packagefiles/discord_social_sdk/meson.build @@ -2,7 +2,7 @@ project( 'discord-social-sdk', 'cpp', 'c', - version: '1.4.9649', + version: '1.6.11894', meson_version: '>=1.4.0', default_options: { 'cpp_std': ['c++17'], @@ -66,6 +66,8 @@ if not meson.is_cross_build() elif host_machine.system() == 'windows' if host_machine.cpu_family() == 'x86_64' lib_base_dir = get_option('default_library') == 'static' ? 'bin' : 'lib' + elif host_machine.cpu_family() == 'aarch64' + lib_base_dir = (get_option('default_library') == 'static' ? 'bin' : 'lib') / 'arm64' else error('unsupported architecture for windows: ' + host_machine.cpu_family()) endif From a118b53e0a8aaed567e18db698a515604e6b4413 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Mon, 13 Oct 2025 22:29:12 +0200 Subject: [PATCH 006/112] fix: fix libc++ installation - make better wildcard, so that only installable packages are found --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c3b7c433..4ebe971c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -144,7 +144,7 @@ jobs: wget https://apt.llvm.org/llvm.sh chmod +x llvm.sh sudo ./llvm.sh 21 - sudo apt-get install libc++-21* libc++abi*21* -y --no-install-recommends + sudo apt-get install libc++-21* libc++abi-*21* -y --no-install-recommends echo "CC=clang-21" >> "$GITHUB_ENV" echo "CXX=clang++-21" >> "$GITHUB_ENV" echo "OBJC=clang-21" >> "$GITHUB_ENV" From 25028ada74a55a76bf87a65353901f8766ba4169 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Mon, 13 Oct 2025 22:38:09 +0200 Subject: [PATCH 007/112] fix: fix fmt header only usage --- subprojects/fmt.wrap | 2 +- subprojects/packagefiles/fmt_header_only_fix.diff | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 subprojects/packagefiles/fmt_header_only_fix.diff diff --git a/subprojects/fmt.wrap b/subprojects/fmt.wrap index a973204f..88856473 100644 --- a/subprojects/fmt.wrap +++ b/subprojects/fmt.wrap @@ -8,7 +8,7 @@ patch_filename = fmt_12.0.0-1_patch.zip patch_url = https://wrapdb.mesonbuild.com/v2/fmt_12.0.0-1/get_patch patch_hash = 307f288ebf3850abf2f0c50ac1fb07de97df9538d39146d802f3c0d6cada8998 wrapdb_version = 12.0.0-1 -diff_files = fmt_emscripten.diff +diff_files = fmt_emscripten.diff, fmt_header_only_fix.diff [provide] dependency_names = fmt, fmt_header_only diff --git a/subprojects/packagefiles/fmt_header_only_fix.diff b/subprojects/packagefiles/fmt_header_only_fix.diff new file mode 100644 index 00000000..7b8f6eef --- /dev/null +++ b/subprojects/packagefiles/fmt_header_only_fix.diff @@ -0,0 +1,14 @@ +diff --git a/meson.build b/meson.build +index 9a012e8..4608302 100644 +--- a/meson.build ++++ b/meson.build +@@ -20,6 +20,9 @@ if header_only + include_directories: 'include', + compile_args: '-DFMT_HEADER_ONLY', + ) ++ if meson.version().version_compare('>=0.54.0') ++ meson.override_dependency('fmt', fmt_header_only_dep) ++ endif + else + fmt_lib = library( + 'fmt', From 91312f3146ddba172a413191d0a3fc16a0fc5965 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 14 Oct 2025 02:26:46 +0200 Subject: [PATCH 008/112] fix: correctly install meson in Nintendo ci --- .github/workflows/nintendo.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/nintendo.yml b/.github/workflows/nintendo.yml index d0eb306e..d86eed7b 100644 --- a/.github/workflows/nintendo.yml +++ b/.github/workflows/nintendo.yml @@ -30,7 +30,6 @@ jobs: - uses: actions/checkout@v7 with: fetch-depth: '0' - # NOTE: meson has no dependencies, so --break-system-packages doesn't really break anything! - name: Setup Meson run: | From 4c3b9940315f99dee65caec231de1e703350b876 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 14 Oct 2025 02:29:21 +0200 Subject: [PATCH 009/112] ci: use newest intel macos runner image, macos:15-intel --- .github/workflows/build.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4ebe971c..3b33b3cb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -166,16 +166,6 @@ jobs: version: 15 platform: x64 - - name: Unbreak Python in GHA (MacOS 13 image) - if: matrix.config.os == 'macos' && matrix.config.os-version == 13 - run: | - # TODO: remove this, after it works again - # A workaround for "The `brew link` step did not complete successfully" error. - # See e.g. https://github.com/Homebrew/homebrew-core/issues/165793#issuecomment-1991817938 - find /usr/local/bin -lname '*/Library/Frameworks/Python.framework/*' -delete - sudo rm -rf /Library/Frameworks/Python.framework/ - brew install --force python3 && brew unlink python3 && brew unlink python3 && brew link --overwrite python3 - - name: Setup Clang (MacOS) if: matrix.config.os == 'macos' run: | From 870603e0e4a31783df413473658122d7f1fc46d9 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Wed, 29 Jul 2026 23:21:07 +0200 Subject: [PATCH 010/112] feat: add more cpp arguments --- src/executables/meson.build | 1 + tools/options/meson.build | 61 +++++++++++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/src/executables/meson.build b/src/executables/meson.build index 8b67264a..24fba64b 100644 --- a/src/executables/meson.build +++ b/src/executables/meson.build @@ -12,6 +12,7 @@ if build_application 'oopetris', main_files, dependencies: [liboopetris_graphics_dep, graphic_application_deps], + cpp_args: common_compiler_args, override_options: { 'warning_level': '3', 'werror': true, diff --git a/tools/options/meson.build b/tools/options/meson.build index 9cfb54b7..d98ed06a 100644 --- a/tools/options/meson.build +++ b/tools/options/meson.build @@ -1,15 +1,70 @@ oopetris_author = 'Coder2k' oopetris_name = 'OOPetris' +cpp = meson.get_compiler('cpp') + +common_compiler_args = cpp.get_supported_arguments( + '-Wassign-enum', + '-Wenum-conversion', + '-Wenum-switch', + '-fstrict-enums', + '-Wenum-identifier', + '-Wenum-compare', + '-Wenum-enum-conversion', + '-Wenum-float-conversion', + '-Wenum-too-large', + '-Wenum-compare-switch', + '-Wenum-compare-conditional', + '-fno-strict-aliasing', + '-Wpointer-arith', + '-Wmissing-declarations', + '-Wformat=2', + '-Wstrict-prototypes', + '-Wmissing-prototypes', + '-Wnested-externs', + '-Wold-style-definition', + '-Wundef', + '-Wunused', + '-Wcast-align', + '-Wmissing-format-attribute', + '-Wmissing-include-dirs', + '-Wlogical-op', + '-Wignored-qualifiers', + '-Werror=redundant-decls', + '-Werror=implicit', + '-Werror=nonnull', + '-Werror=init-self', + '-Werror=main', + '-Werror=missing-braces', + '-Werror=sequence-point', + '-Werror=return-type', + '-Werror=trigraphs', + '-Werror=array-bounds', + '-Werror=write-strings', + '-Werror=address', + '-Werror=int-to-pointer-cast', + '-Werror=pointer-to-int-cast', + '-Werror=empty-body', + '-Werror=write-strings', + '-Werror=strict-aliasing', + '-Wno-sign-compare', + '-Wno-cast-function-type', + '-Wno-unused-parameter', + '-Wno-missing-field-initializers', + '-Wno-type-limits', + '-Wshadow', + '-Wfloat-conversion', +) + core_lib = { 'inc_dirs': [], - 'compile_args': ['-DOOPETRIS_VERSION=' + meson.project_version()], + 'compile_args': ['-DOOPETRIS_VERSION=' + meson.project_version()] + common_compiler_args, 'deps': [], } recordings_lib = { 'inc_dirs': [], - 'compile_args': [], + 'compile_args': [] + common_compiler_args, 'deps': [], } @@ -19,7 +74,7 @@ graphics_lib = { '-DOOPETRIS_VERSION=' + meson.project_version(), '-DOOPETRIS_NAME=' + oopetris_name, '-DOOPETRIS_AUTHOR=' + oopetris_author, - ], + ] + common_compiler_args, 'deps': [], } From b6b375f72616394072b60a93e4a29161f8704887 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Thu, 30 Jul 2026 12:31:44 +0200 Subject: [PATCH 011/112] feat: update java wrapper --- wrapper/java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrapper/java b/wrapper/java index 209d69fe..a747e4c3 160000 --- a/wrapper/java +++ b/wrapper/java @@ -1 +1 @@ -Subproject commit 209d69fee297430461f39d633c7c1160df823816 +Subproject commit a747e4c33e6a67b346ece586299b377a751a0103 From ca07274d0ea75b512070df7b3bcb4ecaff2bf0ea Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 31 Jul 2026 13:44:30 +0200 Subject: [PATCH 012/112] feat: fix merge with #222 did rebase of main on 8602033397f28dbdf3cbaedb82fd881569cdde64 and that conflicts with some changes here --- platforms/android/app/build.gradle | 4 ++-- tools/options/meson.build | 5 ----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/platforms/android/app/build.gradle b/platforms/android/app/build.gradle index a3933661..3df25ac1 100644 --- a/platforms/android/app/build.gradle +++ b/platforms/android/app/build.gradle @@ -319,14 +319,14 @@ android { targetCompatibility JavaVersion.VERSION_21 } - compileSdkVersion 36 + compileSdkVersion 35 ndkVersion = "29.0.14033849" defaultConfig { if (buildAsApplication) { applicationId "com.github.oopetris" } minSdkVersion 21 - targetSdkVersion 36 + targetSdkVersion 35 versionCode 7 versionName(versionString) } diff --git a/tools/options/meson.build b/tools/options/meson.build index d98ed06a..827fbad8 100644 --- a/tools/options/meson.build +++ b/tools/options/meson.build @@ -106,11 +106,6 @@ if get_option('run_in_ci') 'checks': ['>=15', '<16'], } - gcc_14_or_15_compiler = { - 'id': 'gcc', - 'checks': ['>=14', '<16'], - } - msvc_compiler_current = { 'id': 'msvc', 'checks': ['>=19.43', '<20'], From d39edba97aa383d89d32cfacb0c455b97209351e Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 31 Jul 2026 14:01:42 +0200 Subject: [PATCH 013/112] feat: update cpp-httplib to the newest version (0.510) --- subprojects/cpp-httplib.wrap | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/subprojects/cpp-httplib.wrap b/subprojects/cpp-httplib.wrap index 9c75a72c..8a2a56cd 100644 --- a/subprojects/cpp-httplib.wrap +++ b/subprojects/cpp-httplib.wrap @@ -1,11 +1,10 @@ [wrap-file] -directory = cpp-httplib-0.26.0 -source_url = https://github.com/yhirose/cpp-httplib/archive/refs/tags/v0.26.0.tar.gz -source_filename = cpp-httplib-0.26.0.tar.gz -source_hash = a66f908f50ccb119769adce44fe1eac75f81b6ffab7c4ac0211bb663ffeb2688 -source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/cpp-httplib_0.26.0-1/cpp-httplib-0.26.0.tar.gz -wrapdb_version = 0.26.0-1 -diff_files = cpp-httplib-0.26.0_mingw.diff +directory = cpp-httplib-0.51.0 +source_url = https://github.com/yhirose/cpp-httplib/archive/refs/tags/v0.51.0.tar.gz +source_filename = cpp-httplib-0.51.0.tar.gz +source_hash = d740ced75352f44e9d66d08806dc231b5621bb3592b5a5d5b2bd890a9a9d86cc +source_fallback_url = https://wrapdb.mesonbuild.com/v2/cpp-httplib_0.51.0-1/get_source/cpp-httplib-0.51.0.tar.gz +wrapdb_version = 0.51.0-1 [provide] dependency_names = cpp-httplib From bb3d68065ea56beb088deb88160e0f62b02825d1 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 31 Jul 2026 14:16:41 +0200 Subject: [PATCH 014/112] fix: fix more merge / rebase errors --- .github/workflows/nintendo.yml | 1 + io.github.openbrickprotocolfoundation.oopetris.yml | 1 - subprojects/fmt.wrap | 2 +- ...llable.diff => expected-1.3.1_installable.diff} | 0 subprojects/packagefiles/fmt_header_only_fix.diff | 14 -------------- subprojects/tl-expected.wrap | 2 +- 6 files changed, 3 insertions(+), 17 deletions(-) rename subprojects/packagefiles/{expected-1.3.0_installable.diff => expected-1.3.1_installable.diff} (100%) delete mode 100644 subprojects/packagefiles/fmt_header_only_fix.diff diff --git a/.github/workflows/nintendo.yml b/.github/workflows/nintendo.yml index d86eed7b..d0eb306e 100644 --- a/.github/workflows/nintendo.yml +++ b/.github/workflows/nintendo.yml @@ -30,6 +30,7 @@ jobs: - uses: actions/checkout@v7 with: fetch-depth: '0' + # NOTE: meson has no dependencies, so --break-system-packages doesn't really break anything! - name: Setup Meson run: | diff --git a/io.github.openbrickprotocolfoundation.oopetris.yml b/io.github.openbrickprotocolfoundation.oopetris.yml index d19bf507..640316ad 100644 --- a/io.github.openbrickprotocolfoundation.oopetris.yml +++ b/io.github.openbrickprotocolfoundation.oopetris.yml @@ -12,7 +12,6 @@ modules: - -Dbuild_installer=true - --libdir=lib - -Dtests=true - - -Dsdl2_image:test=false - --fatal-meson-warnings - -Drun_in_ci=true # note we always want the CI checks in the case we built the flatpak - --force-fallback-for=fmt # note, the freedesktop sdk has this installed, but it is not copiable into the runtime, so we need to build it ourself, to be able to install it correctly diff --git a/subprojects/fmt.wrap b/subprojects/fmt.wrap index 88856473..a973204f 100644 --- a/subprojects/fmt.wrap +++ b/subprojects/fmt.wrap @@ -8,7 +8,7 @@ patch_filename = fmt_12.0.0-1_patch.zip patch_url = https://wrapdb.mesonbuild.com/v2/fmt_12.0.0-1/get_patch patch_hash = 307f288ebf3850abf2f0c50ac1fb07de97df9538d39146d802f3c0d6cada8998 wrapdb_version = 12.0.0-1 -diff_files = fmt_emscripten.diff, fmt_header_only_fix.diff +diff_files = fmt_emscripten.diff [provide] dependency_names = fmt, fmt_header_only diff --git a/subprojects/packagefiles/expected-1.3.0_installable.diff b/subprojects/packagefiles/expected-1.3.1_installable.diff similarity index 100% rename from subprojects/packagefiles/expected-1.3.0_installable.diff rename to subprojects/packagefiles/expected-1.3.1_installable.diff diff --git a/subprojects/packagefiles/fmt_header_only_fix.diff b/subprojects/packagefiles/fmt_header_only_fix.diff deleted file mode 100644 index 7b8f6eef..00000000 --- a/subprojects/packagefiles/fmt_header_only_fix.diff +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/meson.build b/meson.build -index 9a012e8..4608302 100644 ---- a/meson.build -+++ b/meson.build -@@ -20,6 +20,9 @@ if header_only - include_directories: 'include', - compile_args: '-DFMT_HEADER_ONLY', - ) -+ if meson.version().version_compare('>=0.54.0') -+ meson.override_dependency('fmt', fmt_header_only_dep) -+ endif - else - fmt_lib = library( - 'fmt', diff --git a/subprojects/tl-expected.wrap b/subprojects/tl-expected.wrap index 008135a5..0122fcda 100644 --- a/subprojects/tl-expected.wrap +++ b/subprojects/tl-expected.wrap @@ -8,7 +8,7 @@ patch_filename = tl-expected_1.3.1-1_patch.zip patch_url = https://wrapdb.mesonbuild.com/v2/tl-expected_1.3.1-1/get_patch patch_hash = 91cfeae04ba6ea05792e68a37781236a7045b9e2e4e0c8b7093fd8c3e43b0bad wrapdb_version = 1.3.1-1 -diff_files = expected-1.3.0_installable.diff +diff_files = expected-1.3.1_installable.diff [provide] dependency_names = tl-expected From 94c0138469442898e06aa38264214314a1a086b3 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 31 Jul 2026 14:55:57 +0200 Subject: [PATCH 015/112] fix: fix spdlog std format detection with libc++ --- ...pdlog_1.17.0_std_format_detection_fix.diff | 22 ++++++++++++ subprojects/spdlog.wrap | 2 +- tools/dependencies/meson.build | 34 ++++++++++++++++++- tools/options/meson.build | 2 ++ 4 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 subprojects/packagefiles/spdlog_1.17.0_std_format_detection_fix.diff diff --git a/subprojects/packagefiles/spdlog_1.17.0_std_format_detection_fix.diff b/subprojects/packagefiles/spdlog_1.17.0_std_format_detection_fix.diff new file mode 100644 index 00000000..f86d0901 --- /dev/null +++ b/subprojects/packagefiles/spdlog_1.17.0_std_format_detection_fix.diff @@ -0,0 +1,22 @@ +diff --git a/meson.build b/meson.build +index c842472..92099e0 100644 +--- a/meson.build ++++ b/meson.build +@@ -3,7 +3,7 @@ project( + 'cpp', + version: '1.17.0', + license: 'MIT', +- meson_version: '>=0.56.0', ++ meson_version: '>=0.59.0', + ) + + inc = include_directories('include') +@@ -14,7 +14,7 @@ spdlog_dependencies = [thread_dep] + spdlog_compile_args = [] + override_cpp = meson.version().version_compare('>=1.3.0') ? 'cpp_std=gnu++17,c++17' : 'cpp_std=gnu++17' + +-if meson.get_compiler('cpp').has_header_symbol( ++if get_option('std_format').allowed() and meson.get_compiler('cpp').has_header_symbol( + 'format', + '__cpp_lib_format', + required: get_option('std_format'), diff --git a/subprojects/spdlog.wrap b/subprojects/spdlog.wrap index 815f8f18..9b7b4bcf 100644 --- a/subprojects/spdlog.wrap +++ b/subprojects/spdlog.wrap @@ -9,7 +9,7 @@ patch_url = https://wrapdb.mesonbuild.com/v2/spdlog_1.17.0-1/get_patch patch_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/spdlog_1.17.0-1/spdlog_1.17.0-1_patch.zip patch_hash = 295bcca990facdca84256b60aaa86ba2e2320895cad30bee997d7a463a30b40c wrapdb_version = 1.17.0-1 -diff_files = spdlog_1.17.0_fmt_12.0.0_compatibility.diff, spdlog_1.17.0_no_tls_option.diff, spdlog_1.17.0_nintendo_time_fix.diff +diff_files = spdlog_1.17.0_fmt_12.0.0_compatibility.diff, spdlog_1.17.0_no_tls_option.diff, spdlog_1.17.0_nintendo_time_fix.diff, spdlog_1.17.0_std_format_detection_fix.diff [provide] diff --git a/tools/dependencies/meson.build b/tools/dependencies/meson.build index e05e6e11..23d29554 100644 --- a/tools/dependencies/meson.build +++ b/tools/dependencies/meson.build @@ -378,16 +378,44 @@ if build_application spdlog_no_tls = false + if (meson.is_cross_build() and host_machine.system() == '3ds') spdlog_no_tls = true endif + spdlog_std_format = 'auto' + + if not cpp.has_header_symbol( + 'format', + '__cpp_lib_format', + args: core_lib.get('compile_args'), + ) or not cpp.compiles( + ''' + #include + int main(void) { + /* If it's not defined as a macro, try to use as a symbol */ + #ifndef __cpp_lib_format + __cpp_lib_format; + #else + #if __cpp_lib_format < 202207L + #error "fmt not supported" + #endif + #endif + return 0; + } + ''', + args: core_lib.get('compile_args'), + ) + spdlog_std_format = 'disabled' + endif + spdlog_dep = dependency( 'spdlog', required: true, default_options: { 'tests': 'disabled', 'no_tls': spdlog_no_tls, + 'std_format': spdlog_std_format, }, ) graphics_lib += { @@ -399,8 +427,12 @@ if build_application required: false, allow_fallback: true, default_options: { - 'openssl': 'enabled', + 'tls': 'enabled', + 'tls_backend': 'openssl', 'zlib': 'enabled', + 'brotli': 'auto', + 'zstd': 'auto', + 'test': false, }, ) diff --git a/tools/options/meson.build b/tools/options/meson.build index 827fbad8..24e7676c 100644 --- a/tools/options/meson.build +++ b/tools/options/meson.build @@ -321,6 +321,8 @@ elif cpp.get_id() == 'clang' endif + message('Building C++ with libc++') + else # TODO: once clang with libstdc++ (gcc c++ stdlib) supports std::expected, remove this special behaviour allow_tl_expected_fallback = true From d7c8f7e868b677ade8f8aa51a33929d8ed9bf22b Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 31 Jul 2026 14:56:15 +0200 Subject: [PATCH 016/112] feat: update discord_social_sdk --- subprojects/discord-social-sdk.wrap | 8 ++++---- ...ingw.diff => discord_social_sdk-1.10.18247_mingw.diff} | 0 subprojects/packagefiles/discord_social_sdk/meson.build | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) rename subprojects/packagefiles/{discord_social_sdk-1.6.11894_mingw.diff => discord_social_sdk-1.10.18247_mingw.diff} (100%) diff --git a/subprojects/discord-social-sdk.wrap b/subprojects/discord-social-sdk.wrap index 1adbc59f..b14fd15c 100644 --- a/subprojects/discord-social-sdk.wrap +++ b/subprojects/discord-social-sdk.wrap @@ -1,10 +1,10 @@ [wrap-file] directory = discord_social_sdk -source_url = https://oopetris.totto.lt/static/assets/discord/DiscordSocialSdk-1.6.11894.zip -source_filename = DiscordSocialSdk-1.6.11894.zip -source_hash = 61ef7474331a1a039c65a8a07c6fbef558d4301e06aa4e2f42af9983da7698d8 +source_url = https://oopetris.totto.lt/static/assets/discord/DiscordSocialSdk-1.10.18247.zip +source_filename = DiscordSocialSdk-1.10.18247.zip +source_hash = 505bfba1a8ae3277ff2f8a04f586d39f8f22ab31467a702a540901ab1253e857 patch_directory = discord_social_sdk -diff_files = discord_social_sdk-1.6.11894_mingw.diff +diff_files = discord_social_sdk-1.10.18247_mingw.diff [provide] discord-social-sdk = discord_social_sdk_dep diff --git a/subprojects/packagefiles/discord_social_sdk-1.6.11894_mingw.diff b/subprojects/packagefiles/discord_social_sdk-1.10.18247_mingw.diff similarity index 100% rename from subprojects/packagefiles/discord_social_sdk-1.6.11894_mingw.diff rename to subprojects/packagefiles/discord_social_sdk-1.10.18247_mingw.diff diff --git a/subprojects/packagefiles/discord_social_sdk/meson.build b/subprojects/packagefiles/discord_social_sdk/meson.build index 91c9bb7a..1f3883ca 100644 --- a/subprojects/packagefiles/discord_social_sdk/meson.build +++ b/subprojects/packagefiles/discord_social_sdk/meson.build @@ -2,7 +2,7 @@ project( 'discord-social-sdk', 'cpp', 'c', - version: '1.6.11894', + version: '1.10.18247', meson_version: '>=1.4.0', default_options: { 'cpp_std': ['c++17'], From 6c6cf007aecedc9f271b4288a22cb8c59c67bc78 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 31 Jul 2026 14:57:00 +0200 Subject: [PATCH 017/112] fix: fix small compilation error --- src/lobby/httplib_client.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lobby/httplib_client.hpp b/src/lobby/httplib_client.hpp index 73a78554..e2fa9ba3 100644 --- a/src/lobby/httplib_client.hpp +++ b/src/lobby/httplib_client.hpp @@ -6,6 +6,7 @@ #pragma GCC diagnostic ignored "-Wold-style-cast" #pragma GCC diagnostic ignored "-Warray-bounds" #pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Wundef" #elif defined(_MSC_VER) #pragma warning(disable : 4100) #endif From 04aac2b8cdb7483c2f58e9b60b840e4a582f936c Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 31 Jul 2026 15:03:01 +0200 Subject: [PATCH 018/112] fix: fix cpp compiler arguments detection --- tools/options/meson.build | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/tools/options/meson.build b/tools/options/meson.build index 24e7676c..777f5054 100644 --- a/tools/options/meson.build +++ b/tools/options/meson.build @@ -3,7 +3,7 @@ oopetris_name = 'OOPetris' cpp = meson.get_compiler('cpp') -common_compiler_args = cpp.get_supported_arguments( +internal_cpp_compiler_args = cpp.get_supported_arguments( '-Wassign-enum', '-Wenum-conversion', '-Wenum-switch', @@ -56,15 +56,27 @@ common_compiler_args = cpp.get_supported_arguments( '-Wfloat-conversion', ) +common_cpp_compiler_args = [] + +foreach internal_cpp_compiler_arg : internal_cpp_compiler_args + + # cpp.get_supported_arguments reports true, but it is not really smart and the actual compiler doesn't accept this :( + ##TODO: maybe file a meson bug? + if internal_cpp_compiler_arg not in ['-Werror=implicit', '-Werror=pointer-to-int-cast'] + common_cpp_compiler_args += internal_cpp_compiler_arg + endif + +endforeach + core_lib = { 'inc_dirs': [], - 'compile_args': ['-DOOPETRIS_VERSION=' + meson.project_version()] + common_compiler_args, + 'compile_args': ['-DOOPETRIS_VERSION=' + meson.project_version()] + common_cpp_compiler_args, 'deps': [], } recordings_lib = { 'inc_dirs': [], - 'compile_args': [] + common_compiler_args, + 'compile_args': [] + common_cpp_compiler_args, 'deps': [], } @@ -74,7 +86,7 @@ graphics_lib = { '-DOOPETRIS_VERSION=' + meson.project_version(), '-DOOPETRIS_NAME=' + oopetris_name, '-DOOPETRIS_AUTHOR=' + oopetris_author, - ] + common_compiler_args, + ] + common_cpp_compiler_args, 'deps': [], } From 74765a798af76b43ab39abad3684dc9a0d59f895 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 31 Jul 2026 15:15:09 +0200 Subject: [PATCH 019/112] fix: fix some compiler errors with the new strict flags - especially gcc reports many error with the new strict compiler flags --- src/executables/game/application.cpp | 12 +++++------ src/libs/core/helper/color.hpp | 4 ++-- src/libs/core/helper/date.cpp | 11 ++++++++++ .../utility/additional_information.hpp | 8 ++++---- src/libs/recordings/utility/recording.cpp | 9 ++++++--- src/libs/recordings/utility/recording.hpp | 2 +- .../utility/tetrion_core_information.hpp | 20 +++++++++---------- src/scenes/scene.hpp | 6 +++--- 8 files changed, 43 insertions(+), 29 deletions(-) diff --git a/src/executables/game/application.cpp b/src/executables/game/application.cpp index 0a6ceb83..e11c5be6 100644 --- a/src/executables/game/application.cpp +++ b/src/executables/game/application.cpp @@ -376,23 +376,23 @@ void Application::update() { std::visit( helper::Overloaded{ - [this, index](const scenes::Scene::Pop&) { + [this, index](const scenes::Scene::Pop&) -> void { m_scene_stack.erase( m_scene_stack.begin() + static_cast(index) ); }, - [this](const scenes::Scene::Push& push) { + [this](const scenes::Scene::Push& push) -> void { spdlog::info("pushing back scene {}", magic_enum::enum_name(push.target_scene)); m_scene_stack.push_back( scenes::create_scene(*this, push.target_scene, push.layout) ); }, - [this](scenes::Scene::RawPush& raw_push) { - spdlog::info("pushing back scene {}", raw_push.name); - m_scene_stack.push_back(std::move(raw_push.scene)); + [this](scenes::Scene::RawPush& raw_push) -> void { + spdlog::info("pushing back scene {}", raw_push.m_name); + m_scene_stack.push_back(std::move(raw_push.m_scene)); }, - [this](const scenes::Scene::Switch& scene_switch) { + [this](const scenes::Scene::Switch& scene_switch) -> void { spdlog::info( "switching to scene {}", magic_enum::enum_name(scene_switch.m_target_scene) ); diff --git a/src/libs/core/helper/color.hpp b/src/libs/core/helper/color.hpp index b47601a6..580c4b4d 100644 --- a/src/libs/core/helper/color.hpp +++ b/src/libs/core/helper/color.hpp @@ -223,9 +223,9 @@ struct Color { const FloatType offset = value - chroma; - const auto finish_value = [offset](FloatType value) -> u8 { + const auto finish_value = [offset](FloatType f_value) -> u8 { const auto result = - std::clamp(value + offset, static_cast(0.0), static_cast(1.0)) + std::clamp(f_value + offset, static_cast(0.0), static_cast(1.0)) * static_cast(0xFF); return static_cast(round_constexpr(result)); diff --git a/src/libs/core/helper/date.cpp b/src/libs/core/helper/date.cpp index 1af602ac..301e3bf5 100644 --- a/src/libs/core/helper/date.cpp +++ b/src/libs/core/helper/date.cpp @@ -87,7 +87,18 @@ date::ISO8601Date::format_tm_struct(std::tm time_struct, const char* format_stri static constexpr auto buffer_size = usize{ 100 }; std::array buffer{}; +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +#endif + const auto result = std::strftime(buffer.data(), buffer.size(), format_string, &time_struct); + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + + if (result == 0) { return helper::unexpected{ "error calling std::strftime" }; } diff --git a/src/libs/recordings/utility/additional_information.hpp b/src/libs/recordings/utility/additional_information.hpp index 57fbd06d..16feca03 100644 --- a/src/libs/recordings/utility/additional_information.hpp +++ b/src/libs/recordings/utility/additional_information.hpp @@ -97,14 +97,14 @@ namespace recorder { return false; } - const auto& other = this->as>(); + const auto& nested_other = this->as>(); - if (other.size() != value.size()) { + if (nested_other.size() != value.size()) { return false; } - for (decltype(other.size()) i = 0; i < other.size(); ++i) { - if (other.at(i) != value.at(i)) { + for (decltype(nested_other.size()) i = 0; i < nested_other.size(); ++i) { + if (nested_other.at(i) != value.at(i)) { return false; } } diff --git a/src/libs/recordings/utility/recording.cpp b/src/libs/recordings/utility/recording.cpp index 7c621ac0..9fd11033 100644 --- a/src/libs/recordings/utility/recording.cpp +++ b/src/libs/recordings/utility/recording.cpp @@ -4,9 +4,12 @@ #include -recorder::TetrionHeader::TetrionHeader(Random::Seed seed, u32 starting_level) - : seed{ seed }, - starting_level{ starting_level } { } +recorder::TetrionHeader::TetrionHeader( + Random::Seed seed_a, //NOLINT(bugprone-easily-swappable-parameters) + u32 starting_level_a +) + : seed{ seed_a }, + starting_level{ starting_level_a } { } [[nodiscard]] const std::vector& recorder::Recording::tetrion_headers() const { diff --git a/src/libs/recordings/utility/recording.hpp b/src/libs/recordings/utility/recording.hpp index 2faff8f7..14b32b2e 100644 --- a/src/libs/recordings/utility/recording.hpp +++ b/src/libs/recordings/utility/recording.hpp @@ -37,7 +37,7 @@ namespace recorder { Random::Seed seed; u32 starting_level; - OOPETRIS_RECORDINGS_EXPORTED TetrionHeader(Random::Seed seed, u32 starting_level); + OOPETRIS_RECORDINGS_EXPORTED TetrionHeader(Random::Seed seed_a, u32 starting_level_a); }; struct Recording { diff --git a/src/libs/recordings/utility/tetrion_core_information.hpp b/src/libs/recordings/utility/tetrion_core_information.hpp index 8f7df5a6..44b7662e 100644 --- a/src/libs/recordings/utility/tetrion_core_information.hpp +++ b/src/libs/recordings/utility/tetrion_core_information.hpp @@ -11,15 +11,15 @@ struct TetrionCoreInformation { MinoStack mino_stack; TetrionCoreInformation( - u8 tetrion_index, // NOLINT(bugprone-easily-swappable-parameters) - u32 level, - u64 score, - u32 lines_cleared, - MinoStack mino_stack + u8 tetrion_index_a, // NOLINT(bugprone-easily-swappable-parameters) + u32 level_a, + u64 score_a, + u32 lines_cleared_a, + MinoStack mino_stack_a ) - : tetrion_index{ tetrion_index }, - level{ level }, - score{ score }, - lines_cleared{ lines_cleared }, - mino_stack{ std::move(mino_stack) } { }; + : tetrion_index{ tetrion_index_a }, + level{ level_a }, + score{ score_a }, + lines_cleared{ lines_cleared_a }, + mino_stack{ std::move(mino_stack_a) } { }; }; diff --git a/src/scenes/scene.hpp b/src/scenes/scene.hpp index 407782c4..fab12b17 100644 --- a/src/scenes/scene.hpp +++ b/src/scenes/scene.hpp @@ -49,9 +49,9 @@ namespace scenes { std::string name; std::unique_ptr scene; - RawPush(std::string name, std::unique_ptr&& scene) - : name{ std::move(name) }, - scene{ std::move(scene) } { } + RawPush(std::string name_a, std::unique_ptr&& scene_a) + : name{ std::move(name_a) }, + scene{ std::move(scene_a) } { } }; struct Pop { }; From 13c2cf3f848a77ef6834a38c572c564066bb938a Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 31 Jul 2026 15:24:35 +0200 Subject: [PATCH 020/112] fix: fix more compiler errors with the new strict flags - especially gcc reports many error with the new strict compiler flags --- src/executables/game/application.cpp | 4 +- .../utility/command_line_arguments.hpp | 12 ++--- src/game/command_line_arguments.cpp | 16 +++--- src/game/command_line_arguments.hpp | 8 +-- src/graphics/rect.hpp | 6 +-- src/input/input_creator.hpp | 20 ++++---- src/input/touch_input.hpp | 43 +++++++++------- src/lobby/credentials/secret.hpp | 14 +++++- src/lobby/httplib_client.hpp | 1 + src/scenes/scene.hpp | 12 ++--- src/scenes/settings_menu/settings_menu.cpp | 4 +- src/ui/layouts/scroll_layout.cpp | 50 ++++++++++--------- src/ui/layouts/scroll_layout.hpp | 12 ++--- tools/options/meson.build | 4 ++ 14 files changed, 116 insertions(+), 90 deletions(-) diff --git a/src/executables/game/application.cpp b/src/executables/game/application.cpp index e11c5be6..7fc5c09c 100644 --- a/src/executables/game/application.cpp +++ b/src/executables/game/application.cpp @@ -389,8 +389,8 @@ void Application::update() { ); }, [this](scenes::Scene::RawPush& raw_push) -> void { - spdlog::info("pushing back scene {}", raw_push.m_name); - m_scene_stack.push_back(std::move(raw_push.m_scene)); + spdlog::info("pushing back scene {}", raw_push.name); + m_scene_stack.push_back(std::move(raw_push.scene)); }, [this](const scenes::Scene::Switch& scene_switch) -> void { spdlog::info( diff --git a/src/executables/utility/command_line_arguments.hpp b/src/executables/utility/command_line_arguments.hpp index 22be1a88..58871af4 100644 --- a/src/executables/utility/command_line_arguments.hpp +++ b/src/executables/utility/command_line_arguments.hpp @@ -25,14 +25,14 @@ struct CommandLineArguments final { template - CommandLineArguments(std::filesystem::path&& recording_path, T&& value) - : recording_path{ std::move(recording_path) }, - value{ std::forward(value) } { } + CommandLineArguments(std::filesystem::path&& recording_path_a, T&& value_a) + : recording_path{ std::move(recording_path_a) }, + value{ std::forward(value_a) } { } template - CommandLineArguments(std::filesystem::path&& recording_path, const T& value) - : recording_path{ std::move(recording_path) }, - value{ value } { } + CommandLineArguments(std::filesystem::path&& recording_path_a, const T& value_a) + : recording_path{ std::move(recording_path_a) }, + value{ value_a } { } [[nodiscard]] static helper::expected from_args(int argc, char** argv) noexcept { diff --git a/src/game/command_line_arguments.cpp b/src/game/command_line_arguments.cpp index 48f068aa..fa8c2820 100644 --- a/src/game/command_line_arguments.cpp +++ b/src/game/command_line_arguments.cpp @@ -5,12 +5,12 @@ CommandLineArguments::CommandLineArguments( - std::optional recording_path, - std::optional target_fps, - Level starting_level, - bool silent + std::optional recording_path_a, + std::optional target_fps_a, + Level starting_level_a, + bool silent_a ) - : recording_path{ std::move(recording_path) }, - target_fps{ target_fps }, - starting_level{ starting_level }, - silent{ silent } { } + : recording_path{ std::move(recording_path_a) }, + target_fps{ target_fps_a }, + starting_level{ starting_level_a }, + silent{ silent_a } { } diff --git a/src/game/command_line_arguments.hpp b/src/game/command_line_arguments.hpp index 2abf4402..14ade19d 100644 --- a/src/game/command_line_arguments.hpp +++ b/src/game/command_line_arguments.hpp @@ -23,9 +23,9 @@ struct CommandLineArguments final { bool silent; OOPETRIS_GRAPHICS_EXPORTED CommandLineArguments( - std::optional recording_path, - std::optional target_fps, - Level starting_level = default_starting_level, - bool silent = default_silent + std::optional recording_path_a, + std::optional target_fps_a, + Level starting_level_a = default_starting_level, + bool silent_a = default_silent ); }; diff --git a/src/graphics/rect.hpp b/src/graphics/rect.hpp index cf930672..43ba75e1 100644 --- a/src/graphics/rect.hpp +++ b/src/graphics/rect.hpp @@ -14,9 +14,9 @@ namespace shapes { Point bottom_right; constexpr AbstractRect() = default; - constexpr AbstractRect(Point top_left, Point bottom_right) // NOLINT(bugprone-easily-swappable-parameters) - : top_left{ top_left }, - bottom_right{ bottom_right } { } + constexpr AbstractRect(Point top_left_a, Point bottom_right_a) // NOLINT(bugprone-easily-swappable-parameters) + : top_left{ top_left_a }, + bottom_right{ bottom_right_a } { } constexpr AbstractRect(T x_pos, T y_pos, T width, T height) : top_left{ x_pos, y_pos }, bottom_right{ x_pos + width - 1, y_pos + height - 1 } { } diff --git a/src/input/input_creator.hpp b/src/input/input_creator.hpp index 1c3f44de..bd95f0b2 100644 --- a/src/input/input_creator.hpp +++ b/src/input/input_creator.hpp @@ -19,17 +19,17 @@ namespace tetrion { std::optional> recording_writer; StartingParameters( - u32 target_fps, - Random::Seed seed, - u32 starting_level, // NOLINT(bugprone-easily-swappable-parameters) - u8 tetrion_index, - std::optional> recording_writer = std::nullopt + u32 target_fps_a, // NOLINT(bugprone-easily-swappable-parameters) + Random::Seed seed_a, + u32 starting_level_a, + u8 tetrion_index_a, + std::optional> recording_writer_a = std::nullopt ) - : target_fps{ target_fps }, - seed{ seed }, - starting_level{ starting_level }, - tetrion_index{ tetrion_index }, - recording_writer{ std::move(recording_writer) } { } + : target_fps{ target_fps_a }, + seed{ seed_a }, + starting_level{ starting_level_a }, + tetrion_index{ tetrion_index_a }, + recording_writer{ std::move(recording_writer_a) } { } }; } // namespace tetrion diff --git a/src/input/touch_input.hpp b/src/input/touch_input.hpp index 26d1de72..3e99b76c 100644 --- a/src/input/touch_input.hpp +++ b/src/input/touch_input.hpp @@ -27,7 +27,8 @@ namespace input { const SDL_Event& event ) const override; - [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::string describe_navigation_event(NavigationEvent event + [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::string describe_navigation_event( + NavigationEvent event ) const override; [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::optional get_pointer_event( @@ -62,8 +63,12 @@ namespace input { Uint32 timestamp; float x; float y; - explicit PressedState(Uint32 timestamp, float x_pos, float y_pos) //NOLINT(bugprone-easily-swappable-parameters) - : timestamp{ timestamp }, + explicit PressedState( + Uint32 timestamp_a, //NOLINT(bugprone-easily-swappable-parameters) + float x_pos, + float y_pos + ) + : timestamp{ timestamp_a }, x{ x_pos }, y{ y_pos } { } }; @@ -97,7 +102,8 @@ namespace input { OOPETRIS_GRAPHICS_EXPORTED void handle_event(const SDL_Event& event) override; OOPETRIS_GRAPHICS_EXPORTED void update(SimulationStep simulation_step_index) override; - [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::optional get_menu_event(const SDL_Event& event + [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::optional get_menu_event( + const SDL_Event& event ) const override; [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::string describe_menu_event(MenuEvent event) const override; @@ -177,14 +183,13 @@ namespace nlohmann { ::json::check_for_no_additional_keys( - obj, - { - "type", - "move_x_threshold", - "move_y_threshold", - "rotation_duration_threshold", - "drop_duration_threshold", - } + obj, { + "type", + "move_x_threshold", + "move_y_threshold", + "rotation_duration_threshold", + "drop_duration_threshold", + } ); const auto move_x_threshold = json_helper::get_number(obj, "move_x_threshold"); @@ -209,12 +214,14 @@ namespace nlohmann { static void to_json(json& obj, const input::TouchSettings& settings) { - obj = nlohmann::json::object({ - { "move_x_threshold", settings.move_x_threshold }, - { "move_y_threshold", settings.move_y_threshold }, - { "rotation_duration_threshold", settings.rotation_duration_threshold }, - { "drop_duration_threshold", settings.drop_duration_threshold } - }); + obj = nlohmann::json::object( + { + { "move_x_threshold", settings.move_x_threshold }, + { "move_y_threshold", settings.move_y_threshold }, + { "rotation_duration_threshold", settings.rotation_duration_threshold }, + { "drop_duration_threshold", settings.drop_duration_threshold } + } + ); } }; } // namespace nlohmann diff --git a/src/lobby/credentials/secret.hpp b/src/lobby/credentials/secret.hpp index 5d333097..71b231b3 100644 --- a/src/lobby/credentials/secret.hpp +++ b/src/lobby/credentials/secret.hpp @@ -13,7 +13,18 @@ #if defined(__linux__) +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" +#endif + #include + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + + #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) #include @@ -52,7 +63,8 @@ namespace secret { OOPETRIS_GRAPHICS_EXPORTED SecretStorage(SecretStorage&& other) noexcept; SecretStorage& operator=(SecretStorage&& other) noexcept = delete; - [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED helper::expected load(const std::string& key + [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED helper::expected load( + const std::string& key ) const; [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::optional diff --git a/src/lobby/httplib_client.hpp b/src/lobby/httplib_client.hpp index e2fa9ba3..5bb1332c 100644 --- a/src/lobby/httplib_client.hpp +++ b/src/lobby/httplib_client.hpp @@ -7,6 +7,7 @@ #pragma GCC diagnostic ignored "-Warray-bounds" #pragma GCC diagnostic ignored "-Wunused-parameter" #pragma GCC diagnostic ignored "-Wundef" +#pragma GCC diagnostic ignored "-Wredundant-decls" #elif defined(_MSC_VER) #pragma warning(disable : 4100) #endif diff --git a/src/scenes/scene.hpp b/src/scenes/scene.hpp index fab12b17..55a2f68b 100644 --- a/src/scenes/scene.hpp +++ b/src/scenes/scene.hpp @@ -31,18 +31,18 @@ namespace scenes { std::string name; std::unique_ptr scene; - RawSwitch(std::string name, std::unique_ptr&& scene) - : name{ std::move(name) }, - scene{ std::move(scene) } { } + RawSwitch(std::string name_a, std::unique_ptr&& scene_a) + : name{ std::move(name_a) }, + scene{ std::move(scene_a) } { } }; struct Push { SceneId target_scene; ui::Layout layout; - Push(const SceneId target_scene, const ui::Layout& layout) - : target_scene{ target_scene }, - layout{ layout } { } + Push(const SceneId target_scene_a, const ui::Layout& layout_a) + : target_scene{ target_scene_a }, + layout{ layout_a } { } }; struct RawPush { diff --git a/src/scenes/settings_menu/settings_menu.cpp b/src/scenes/settings_menu/settings_menu.cpp index 01d62b27..b0982dc6 100644 --- a/src/scenes/settings_menu/settings_menu.cpp +++ b/src/scenes/settings_menu/settings_menu.cpp @@ -85,8 +85,8 @@ namespace scenes { service_provider->music_manager().add_volume_listener( listener_name, [this, scroll_layout_index, slider_index](std::optional) { - auto* scroll_layout = this->m_main_layout.get(scroll_layout_index); - scroll_layout->get(slider_index)->on_change(); + auto* volume_scroll_layout = this->m_main_layout.get(scroll_layout_index); + volume_scroll_layout->get(slider_index)->on_change(); if (auto volume = this->m_service_provider->music_manager().get_volume(); volume.has_value()) { this->m_settings.volume = static_cast(volume.value()); diff --git a/src/ui/layouts/scroll_layout.cpp b/src/ui/layouts/scroll_layout.cpp index 8e46ce69..ddeda908 100644 --- a/src/ui/layouts/scroll_layout.cpp +++ b/src/ui/layouts/scroll_layout.cpp @@ -3,7 +3,7 @@ #include "input/input.hpp" #include "scroll_layout.hpp" -ui::ItemSize::ItemSize(const u32 height, ItemSizeType type) : height{ height }, type{ type } { } +ui::ItemSize::ItemSize(const u32 height_a, ItemSizeType type_a) : height{ height_a }, type{ type_a } { } [[nodiscard]] u32 ui::ItemSize::get_height() const { @@ -14,34 +14,36 @@ ui::ItemSize::ItemSize(const u32 height, ItemSizeType type) : height{ height }, return type; } -ui::AbsolutItemSize::AbsolutItemSize(const u32 height) : ItemSize{ height, ItemSizeType::Absolut } { } +ui::AbsolutItemSize::AbsolutItemSize(const u32 height_a) : ItemSize{ height_a, ItemSizeType::Absolut } { } -ui::RelativeItemSize::RelativeItemSize(const shapes::URect& rect, const double height) - : ItemSize{ static_cast(height * rect.height()), ItemSizeType::Relative } { +ui::RelativeItemSize::RelativeItemSize(const shapes::URect& rect, const double height_d) + : ItemSize{ static_cast(height_d * rect.height()), ItemSizeType::Relative } { // no checks for upper cases, since it theoretically can also be larger than the whole screen! - assert(height >= 0.0 && "height has to be in correct percentage range!"); + assert(height_d >= 0.0 && "height has to be in correct percentage range!"); } -ui::RelativeItemSize::RelativeItemSize(const Window* window, const double height) - : RelativeItemSize{ window->screen_rect(), height } { } -ui::RelativeItemSize::RelativeItemSize(const Window& window, const double height) - : RelativeItemSize{ window.screen_rect(), height } { } -ui::RelativeItemSize::RelativeItemSize(const Layout& layout, const double height) - : RelativeItemSize{ layout.get_rect(), height } { } +ui::RelativeItemSize::RelativeItemSize(const Window* window, const double height_d) + : RelativeItemSize{ window->screen_rect(), height_d } { } +ui::RelativeItemSize::RelativeItemSize(const Window& window, const double height_d) + : RelativeItemSize{ window.screen_rect(), height_d } { } +ui::RelativeItemSize::RelativeItemSize(const Layout& layout, const double height_d) + : RelativeItemSize{ layout.get_rect(), height_d } { } ui::ScrollLayout::ScrollLayout( - ServiceProvider* service_provider, - u32 focus_id, - Margin gap, - std::pair margin, - const Layout& layout, - bool is_top_level - ) - : FocusLayout{ - layout, focus_id, FocusOptions{ .wrap_around=is_top_level, .allow_tab=is_top_level }, is_top_level}, // if on top, we support tab and wrap around, otherwise not - m_gap{ gap }, - m_texture{ std::nullopt }, - m_service_provider{ service_provider }, - m_step_size{ static_cast(layout.get_rect().height() * 0.05) } { + ServiceProvider* service_provider, + u32 focus_id, + Margin gap, + std::pair margin, + const Layout& layout, + bool is_top_level +) + : FocusLayout{ + layout, focus_id, FocusOptions{ .wrap_around = is_top_level, .allow_tab = is_top_level }, + is_top_level +}, // if on top, we support tab and wrap around, otherwise not + m_gap{ gap }, + m_texture{ std::nullopt }, + m_service_provider{ service_provider }, + m_step_size{ static_cast(layout.get_rect().height() * 0.05) } { const auto layout_rect = layout.get_rect(); const auto absolut_margin = std::pair{ static_cast(margin.first * layout_rect.width()), diff --git a/src/ui/layouts/scroll_layout.hpp b/src/ui/layouts/scroll_layout.hpp index c4f29eac..eac77ad2 100644 --- a/src/ui/layouts/scroll_layout.hpp +++ b/src/ui/layouts/scroll_layout.hpp @@ -20,7 +20,7 @@ namespace ui { ItemSizeType type; protected: - ItemSize(u32 height, ItemSizeType type); + ItemSize(u32 height_a, ItemSizeType type_a); public: [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED u32 get_height() const; @@ -29,15 +29,15 @@ namespace ui { }; struct AbsolutItemSize : public ItemSize { - OOPETRIS_GRAPHICS_EXPORTED explicit AbsolutItemSize(u32 height); + OOPETRIS_GRAPHICS_EXPORTED explicit AbsolutItemSize(u32 height_a); }; struct RelativeItemSize : public ItemSize { - OOPETRIS_GRAPHICS_EXPORTED RelativeItemSize(const shapes::URect& rect, double height); - OOPETRIS_GRAPHICS_EXPORTED RelativeItemSize(const Window* window, double height); - OOPETRIS_GRAPHICS_EXPORTED RelativeItemSize(const Window& window, double height); - OOPETRIS_GRAPHICS_EXPORTED RelativeItemSize(const Layout& layout, double height); + OOPETRIS_GRAPHICS_EXPORTED RelativeItemSize(const shapes::URect& rect, double height_d); + OOPETRIS_GRAPHICS_EXPORTED RelativeItemSize(const Window* window, double height_d); + OOPETRIS_GRAPHICS_EXPORTED RelativeItemSize(const Window& window, double height_d); + OOPETRIS_GRAPHICS_EXPORTED RelativeItemSize(const Layout& layout, double height_d); }; diff --git a/tools/options/meson.build b/tools/options/meson.build index 777f5054..e34af035 100644 --- a/tools/options/meson.build +++ b/tools/options/meson.build @@ -68,6 +68,10 @@ foreach internal_cpp_compiler_arg : internal_cpp_compiler_args endforeach +if cpp.get_id() == 'gcc' + common_cpp_compiler_args += cpp.get_supported_arguments('-Wno-missing-braces') +endif + core_lib = { 'inc_dirs': [], 'compile_args': ['-DOOPETRIS_VERSION=' + meson.project_version()] + common_cpp_compiler_args, From 1210494274b4e2f2486344fb7915a16232669702 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 31 Jul 2026 15:26:07 +0200 Subject: [PATCH 021/112] fix: fix meson formatting --- tools/dependencies/meson.build | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/dependencies/meson.build b/tools/dependencies/meson.build index 23d29554..fe1056e4 100644 --- a/tools/dependencies/meson.build +++ b/tools/dependencies/meson.build @@ -386,11 +386,11 @@ if build_application spdlog_std_format = 'auto' if not cpp.has_header_symbol( - 'format', - '__cpp_lib_format', - args: core_lib.get('compile_args'), - ) or not cpp.compiles( - ''' + 'format', + '__cpp_lib_format', + args: core_lib.get('compile_args'), + ) or not cpp.compiles( + ''' #include int main(void) { /* If it's not defined as a macro, try to use as a symbol */ @@ -404,8 +404,8 @@ if build_application return 0; } ''', - args: core_lib.get('compile_args'), - ) + args: core_lib.get('compile_args'), + ) spdlog_std_format = 'disabled' endif From bbe6f44ad35e927edf37316f61e956364bcf8223 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 31 Jul 2026 15:27:57 +0200 Subject: [PATCH 022/112] fix: fix more compile errors --- src/lobby/curl_client.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lobby/curl_client.hpp b/src/lobby/curl_client.hpp index 60505fa0..a9cf2d81 100644 --- a/src/lobby/curl_client.hpp +++ b/src/lobby/curl_client.hpp @@ -8,6 +8,7 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" +#pragma GCC diagnostic ignored "-Wundef" #endif #include From 550b140a9bb3327c37f44324b384f58ccbcc2b81 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 31 Jul 2026 15:38:53 +0200 Subject: [PATCH 023/112] fix: fix small android compilation error --- src/executables/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/executables/meson.build b/src/executables/meson.build index 24fba64b..0cb8bea9 100644 --- a/src/executables/meson.build +++ b/src/executables/meson.build @@ -12,7 +12,7 @@ if build_application 'oopetris', main_files, dependencies: [liboopetris_graphics_dep, graphic_application_deps], - cpp_args: common_compiler_args, + cpp_args: common_cpp_compiler_args, override_options: { 'warning_level': '3', 'werror': true, From 7a5900a176bfdaa9ab09e364813e1972160e23f1 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 31 Jul 2026 15:57:39 +0200 Subject: [PATCH 024/112] fix: fix more third party compilation errors --- src/helper/nfd_include.hpp | 13 +++++++++++++ src/lobby/curl_client.hpp | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/helper/nfd_include.hpp b/src/helper/nfd_include.hpp index 417b9ec3..c4d5a633 100644 --- a/src/helper/nfd_include.hpp +++ b/src/helper/nfd_include.hpp @@ -10,8 +10,21 @@ #ifdef _WIN32 #define NFD_DIFFERENT_NATIVE_FUNCTIONS #endif + + +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wundef" + +#endif + #include +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + + #include #include #include diff --git a/src/lobby/curl_client.hpp b/src/lobby/curl_client.hpp index a9cf2d81..189f6b22 100644 --- a/src/lobby/curl_client.hpp +++ b/src/lobby/curl_client.hpp @@ -4,7 +4,7 @@ #include "./client.hpp" -#if defined(__3DS__) +#if defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" @@ -14,7 +14,7 @@ #include -#if defined(__3DS__) +#if defined(__GNUC__) #pragma GCC diagnostic pop #endif From c4df1b584d3398b2b3cd7abfb2c03d2cd0979d83 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 31 Jul 2026 15:59:43 +0200 Subject: [PATCH 025/112] fix: fix small web compilation error --- src/executables/game/application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/executables/game/application.cpp b/src/executables/game/application.cpp index 7fc5c09c..109a8c18 100644 --- a/src/executables/game/application.cpp +++ b/src/executables/game/application.cpp @@ -124,7 +124,7 @@ Application::Application(std::shared_ptr&& window, CommandLineArguments& Application::~Application() = default; #if defined(__EMSCRIPTEN__) -void c_loop_entry(void* arg) { +static void c_loop_entry(void* arg) { auto application = reinterpret_cast(arg); application->emscripten_do_process(); application->loop_entry_emscripten(); From 0cd45664ce04b21a51d47ed4f08ccbc49659dc5d Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 31 Jul 2026 16:28:55 +0200 Subject: [PATCH 026/112] fix: fix test cases --- tests/core/color.cpp | 6 +++--- tests/graphics/sdl_key.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/core/color.cpp b/tests/core/color.cpp index ae4b42a1..b6d8c1d4 100644 --- a/tests/core/color.cpp +++ b/tests/core/color.cpp @@ -35,18 +35,18 @@ operator==(const HSVColor& value1, const HSVColor& value2) { //NOLINT(misc-use-i // make colors printable -void PrintTo(const Color& color, std::ostream* os) { //NOLINT(misc-use-internal-linkage) +static void PrintTo(const Color& color, std::ostream* os) { //NOLINT(misc-use-internal-linkage) *os << color.to_string(); } -void PrintTo(const HSVColor& color, std::ostream* os) { //NOLINT(misc-use-internal-linkage) +static void PrintTo(const HSVColor& color, std::ostream* os) { //NOLINT(misc-use-internal-linkage) *os << color.to_string(); } namespace color { - void PrintTo(const SerializeMode& value, std::ostream* os) { //NOLINT(misc-use-internal-linkage) + static void PrintTo(const SerializeMode& value, std::ostream* os) { //NOLINT(misc-use-internal-linkage) *os << magic_enum::enum_name(value); } diff --git a/tests/graphics/sdl_key.cpp b/tests/graphics/sdl_key.cpp index 26c610ba..e14e6e15 100644 --- a/tests/graphics/sdl_key.cpp +++ b/tests/graphics/sdl_key.cpp @@ -13,12 +13,12 @@ namespace sdl { // make keys printable - void PrintTo(const Key& key, std::ostream* os) { //NOLINT(misc-use-internal-linkage) + static void PrintTo(const Key& key, std::ostream* os) { //NOLINT(misc-use-internal-linkage) *os << key.to_string(); } - std::ostream& operator<<(std::ostream& os, const Key& value) { //NOLINT(misc-use-internal-linkage) + static std::ostream& operator<<(std::ostream& os, const Key& value) { //NOLINT(misc-use-internal-linkage) os << value.to_string(); return os; } From 3693c6ae274f0395ff61cb7a7afa2d1bfb28b570 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 31 Jul 2026 20:06:35 +0200 Subject: [PATCH 027/112] feat: install discord partner sdk vendor lib correctly --- .../packagefiles/discord_social_sdk/meson.build | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/subprojects/packagefiles/discord_social_sdk/meson.build b/subprojects/packagefiles/discord_social_sdk/meson.build index 1f3883ca..a37e38c6 100644 --- a/subprojects/packagefiles/discord_social_sdk/meson.build +++ b/subprojects/packagefiles/discord_social_sdk/meson.build @@ -87,6 +87,21 @@ if not meson.is_cross_build() required: true, ) + + if host_machine.system() == 'linux' + install_lib_dir = get_option('prefix') / get_option('libdir') + + discord_partner_sdk_file = files( + meson.project_source_root() / lib_dir / 'libdiscord_partner_sdk.so' + ) + + install_data( + discord_partner_sdk_file, + install_dir: install_lib_dir, + install_tag: 'runtime', + ) + endif + ## NOTE: this is a static library, as it doesn't export the symbols correctly, so on windows the dll would fail to link discord_social_sdk_lib = static_library( 'discord_social_sdk', From 3c5b88880d8a3cd568d6c556b8d2e42442fd2ad6 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 31 Jul 2026 21:32:44 +0200 Subject: [PATCH 028/112] feat: fix some minor web script errors --- platforms/build-web.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/platforms/build-web.sh b/platforms/build-web.sh index 8b05e367..f84bd93e 100755 --- a/platforms/build-web.sh +++ b/platforms/build-web.sh @@ -64,12 +64,12 @@ export EMSCRIPTEN_ROOT if [ ! -d "$EMSCRIPTEN_ROOT" ]; then git clone https://github.com/emscripten-core/emsdk.git "$EMSCRIPTEN_ROOT" - git -C "$EMSCRIPTEN_ROOT" checkout "$EMSCRIPTEN_RELEASE_TAG" else git -C "$EMSCRIPTEN_ROOT" fetch - git -C "$EMSCRIPTEN_ROOT" checkout "$EMSCRIPTEN_RELEASE_TAG" fi +git -C "$EMSCRIPTEN_ROOT" checkout "$EMSCRIPTEN_RELEASE_TAG" + export EMSDK_NODE_TOOL="node-$EMSDK_EXECUTE_NODE_VERSION-64bit" "$EMSCRIPTEN_ROOT/emsdk" install "$EMSCRIPTEN_RELEASE_TAG" "$EMSDK_NODE_TOOL" @@ -77,18 +77,18 @@ export EMSDK_NODE_TOOL="node-$EMSDK_EXECUTE_NODE_VERSION-64bit" EMSCRIPTEN_UPSTREAM_ROOT="$EMSCRIPTEN_ROOT/upstream/emscripten" -EMSCRIPTEN_PACTH_FILE="$EMSCRIPTEN_UPSTREAM_ROOT/.patched_manually.meta" +EMSCRIPTEN_PATCH_FILE="$EMSCRIPTEN_UPSTREAM_ROOT/.patched_manually.meta" PATCH_DIR="platforms/emscripten" -if ! [ -e "$EMSCRIPTEN_PACTH_FILE" ]; then +if ! [ -e "$EMSCRIPTEN_PATCH_FILE" ]; then ##TODO: upstream those patches # see: https://github.com/emscripten-core/emscripten/pull/18379 # and: https://github.com/emscripten-core/emscripten/pull/22946 git apply --unsafe-paths -p1 --directory="$EMSCRIPTEN_UPSTREAM_ROOT" "$PATCH_DIR/sdl2_image_port.diff" - touch "$EMSCRIPTEN_PACTH_FILE" + touch "$EMSCRIPTEN_PATCH_FILE" fi # git apply path @@ -145,7 +145,7 @@ cpu = '$CPU_ARCH' endian = '$ENDIANESS' [constants] -emscripten_root = '$(pwd)/emsdk' +emscripten_root = '$EMSCRIPTEN_ROOT' [binaries] c = '$CC' From dc3c722c7adbad683771b45d25d0c25a8abe5a90 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 31 Jul 2026 21:32:58 +0200 Subject: [PATCH 029/112] feat: add base for uefi cross compile script --- platforms/build-uefi.sh | 251 ++++++++++++++++++++++++++++++++++++++++ platforms/build.sh | 2 +- platforms/versions.sh | 4 + 3 files changed, 256 insertions(+), 1 deletion(-) create mode 100755 platforms/build-uefi.sh mode change 100644 => 100755 platforms/versions.sh diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh new file mode 100755 index 00000000..4c989556 --- /dev/null +++ b/platforms/build-uefi.sh @@ -0,0 +1,251 @@ +#!/usr/bin/env bash + +# Exit immediately if a command exits with a non-zero status. +set -e +## Treat undefined variables as an error +set -u +# fails if any part of a pipeline (|) fails +set -o pipefail + +## options: "smart, complete_rebuild" +export COMPILE_TYPE="smart" + +export BUILDTYPE="debug" + +export RUN_IN_CI="false" + +export RUNTIME_TARGET="emulator" + +if [ "$#" -eq 0 ]; then + # nothing + echo "Using compile type '$COMPILE_TYPE'" +elif [ "$#" -eq 1 ]; then + COMPILE_TYPE="$1" +elif [ "$#" -eq 2 ]; then + COMPILE_TYPE="$1" + BUILDTYPE="$2" +elif [ "$#" -eq 3 ]; then + COMPILE_TYPE="$1" + BUILDTYPE="$2" + + if [ -z "$3" ]; then + RUN_IN_CI="false" + else + RUN_IN_CI="true" + fi +elif [ "$#" -eq 4 ]; then + COMPILE_TYPE="$1" + BUILDTYPE="$2" + + if [ -z "$3" ]; then + RUN_IN_CI="false" + else + RUN_IN_CI="true" + fi + RUNTIME_TARGET="$2" +else + echo "Too many arguments given, expected 1, 2 or 3" + exit 1 +fi + +if [ "$COMPILE_TYPE" == "smart" ]; then + : # noop +elif [ "$COMPILE_TYPE" == "complete_rebuild" ]; then + : # noop +else + echo "Invalid COMPILE_TYPE, expected: 'smart' or 'complete_rebuild'" + exit 1 +fi + +if [ "$RUNTIME_TARGET" == "emulator" ]; then + : # noop +elif [ "$RUNTIME_TARGET" == "hardware" ]; then + : # noop +else + echo "Invalid RUNTIME_TARGET, expected: 'emulator' or 'hardware'" + exit 1 +fi + +if [ ! -d "toolchains" ]; then + mkdir -p toolchains +fi + +# source dependency version information + +SCRIPT_DIR="$(realpath "$(dirname -- "${BASH_SOURCE[0]}")")" + +# shellcheck source=./platforms/versions.sh +source "$SCRIPT_DIR/versions.sh" + +# shellcheck source=./platforms/helper.sh +source "$SCRIPT_DIR/helper.sh" + +EDK2_ROOT="$(pwd)/toolchains/edk2" +export EDK2_ROOT + +if [ ! -d "$EDK2_ROOT" ]; then + git clone https://github.com/tianocore/edk2 "$EDK2_ROOT" +else + git -C "$EDK2_ROOT" fetch +fi + +git -C "$EDK2_ROOT" checkout "$EDK2_RELEASE_TAG" +git -C "$EDK2_ROOT" submodule update --init + +export EDK_TOOLS_PATH="$EDK2_ROOT/BaseTools" + +pushd "$EDK2_ROOT" + +make -C BaseTools + +set +u + +# shellcheck disable=SC1091 +source "$EDK2_ROOT/edksetup.sh" + +set -u + +export EDK2_CONF_TARGET="$EDK2_ROOT/Conf/target.txt" + +EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM="EmulatorPkg/EmulatorPkg.dsc" + +if [ "$RUNTIME_TARGET" == "emulator" ]; then + EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM="EmulatorPkg/EmulatorPkg.dsc" +elif [ "$RUNTIME_TARGET" == "hardware" ]; then + EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM="MdeModulePkg/MdeModulePkg.dsc" +else + echo "Invalid RUNTIME_TARGET, expected: 'emulator' or 'hardware'" + exit 1 +fi + +declare -A EDK2_TARGET_PROPERTIES=(["ACTIVE_PLATFORM"]="$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" ["TARGET"]="$(echo "$BUILDTYPE" | tr "[:lower:]" "[:upper:]")" ["TARGET_ARCH"]="X64" ["TOOL_CHAIN_TAG"]="GCC") + +for EDK2_TARGET_PROPERTY in "${!EDK2_TARGET_PROPERTIES[@]}"; do + EDK2_TARGET_PROPERTY_VALUE="${EDK2_TARGET_PROPERTIES[$EDK2_TARGET_PROPERTY]}" + + sed -i "s|^${EDK2_TARGET_PROPERTY}[[:space:]]*=.*\$|${EDK2_TARGET_PROPERTY} = $EDK2_TARGET_PROPERTY_VALUE|" "$EDK2_CONF_TARGET" +done + +popd + +exit 1 + +## build the needed dependencies +embuilder build sdl2-mt harfbuzz-mt freetype zlib sdl2_ttf mpg123 "sdl2_mixer-mp3-mt" libpng-mt "sdl2_image:formats=png,svg:mt=1" icu-mt + +export EDK2_SYS_ROOT="$EDK2_UPSTREAM_ROOT/cache/sysroot" + +export BUILD_DIR="build/web" + +export PKG_CONFIG_PATH="$EDK2_SYS_ROOT/lib/pkgconfig" + +export CC="emcc" +export CXX="em++" +export AR="emar" +export RANLIB="emranlib" +export STRIP="emstrip" +export NM="emnm" + +export ARCH="wasm32" +export CPU_ARCH="wasm32" +export ENDIANESS="little" + +export ROMFS="platforms/romfs" + +export PACKAGE_FLAGS="'--use-port=sdl2', '--use-port=harfbuzz', '--use-port=freetype', '--use-port=zlib', '--use-port=sdl2_ttf', '--use-port=mpg123', '--use-port=sdl2_mixer', '-sSDL2_MIXER_FORMATS=[\"mp3\"]','--use-port=libpng', '--use-port=sdl2_image','-sSDL2_IMAGE_FORMATS=[\"png\",\"svg\"]', '--use-port=icu'" + +#TODO use '-sMEMORY64', '-m64', and target wasm64 +export COMMON_FLAGS="'-fexceptions', '-pthread', '-sUSE_PTHREADS=1', '-sEXCEPTION_CATCHING_ALLOWED=[..]', $PACKAGE_FLAGS" + +# TODO see if ALLOW_MEMORY_GROWTH is needed, but if we load ttf's and music it likely is and we don't have to debug OOm crashes, that aren't handled by some third party library, which is painful +export LINK_FLAGS="$COMMON_FLAGS, '-sEXPORT_ALL=1', '-sWASM=1', '-sALLOW_MEMORY_GROWTH=1', '-sASSERTIONS=1','-sERROR_ON_UNDEFINED_SYMBOLS=1', '-sFETCH=1', '-sEXIT_RUNTIME=1'" +export COMPILE_FLAGS="$COMMON_FLAGS ,'-DAUDIO_PREFER_MP3'" + +export CROSS_FILE="./platforms/crossbuild/web.ini" + +validate_parent_dir "$CROSS_FILE" + +cat <"$CROSS_FILE" +[host_machine] +system = 'uefi' +cpu_family = '$ARCH' +cpu = '$CPU_ARCH' +endian = '$ENDIANESS' + +[target_machine] +system = 'uefi' +cpu_family = '$ARCH' +cpu = '$CPU_ARCH' +endian = '$ENDIANESS' + +[constants] +edk2_root = '$EDK2_ROOT' + +[binaries] +c = '$CC' +cpp = '$CXX' +ar = '$AR' +ranlib = '$RANLIB' +strip = '$STRIP' +nm = '$NM' + +# pkg-config = ['emmake', 'pkg-config'] +# cmake = ['emmake', 'cmake'] +# sdl2-config = ['emconfigure', 'sdl2-config'] + +# exe_wrapper = '$EMSDK_NODE' + +[built-in options] +c_std = 'c11' +cpp_std = 'c++23' +c_args = [$COMPILE_FLAGS] +cpp_args = [$COMPILE_FLAGS] +c_link_args = [$LINK_FLAGS] +cpp_link_args = [$LINK_FLAGS] + +[properties] +pkg_config_libdir = '$PKG_CONFIG_PATH' +needs_exe_wrapper = true +sys_root = '$EDK2_SYS_ROOT' + +APP_ROMFS='$ROMFS/assets/' + +[cmake] + +CMAKE_FIND_ROOT_PATH_MODE_PROGRAM = 'BOTH' +CMAKE_FIND_ROOT_PATH_MODE_LIBRARY = 'ONLY' +CMAKE_FIND_ROOT_PATH_MODE_INCLUDE = 'ONLY' +CMAKE_FIND_ROOT_PATH_MODE_PACKAGE = 'ONLY' + +CMAKE_FIND_ROOT_PATH = '$EDK2_SYS_ROOT/lib/cmake' + +EOF + +if [ ! -d "$ROMFS" ]; then + + mkdir -p "$ROMFS" + + cp -r assets "$ROMFS/" + +fi + +if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "$BUILD_DIR" ]; then + + meson setup "$BUILD_DIR" \ + "--wipe" \ + --cross-file "$CROSS_FILE" \ + "-Dbuildtype=$BUILDTYPE" \ + -Ddefault_library=static \ + -Dtests=false \ + "-Drun_in_ci=$RUN_IN_CI" \ + --fatal-meson-warnings + +fi + +meson compile -C "$BUILD_DIR" + +if [ -n "${ENABLE_TESTING:-}" ]; then + + meson test -C "$BUILD_DIR" + +fi diff --git a/platforms/build.sh b/platforms/build.sh index 874576f0..bc81970a 100755 --- a/platforms/build.sh +++ b/platforms/build.sh @@ -17,7 +17,7 @@ SCRIPT_DIR="$(realpath "$(dirname -- "${BASH_SOURCE[0]}")")" PLATFORM="$1" shift -SUPPORTED_PLATFORMS=("3ds" "android" "switch" "web") +SUPPORTED_PLATFORMS=("3ds" "android" "switch" "uefi" "web") for PLTFRM in "${SUPPORTED_PLATFORMS[@]}"; do if [ "$PLATFORM" == "$PLTFRM" ]; then diff --git a/platforms/versions.sh b/platforms/versions.sh old mode 100644 new mode 100755 index 9e84e3f5..dd68cf35 --- a/platforms/versions.sh +++ b/platforms/versions.sh @@ -30,3 +30,7 @@ export NDK_VER_DESC="r29" export EMSCRIPTEN_RELEASE_TAG="6.0.5" export EMSDK_EXECUTE_NODE_VERSION="24.7.0" + +# edk2 section + +export EDK2_RELEASE_TAG="edk2-stable202605" From 60f6b1a90a2141badd7e4ad6286506e951bd4e57 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 31 Jul 2026 21:52:38 +0200 Subject: [PATCH 030/112] feat: more uefi build process --- platforms/build-uefi.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 4c989556..dc298726 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -83,6 +83,8 @@ source "$SCRIPT_DIR/helper.sh" EDK2_ROOT="$(pwd)/toolchains/edk2" export EDK2_ROOT +export WORKSPACE="$EDK2_ROOT" + if [ ! -d "$EDK2_ROOT" ]; then git clone https://github.com/tianocore/edk2 "$EDK2_ROOT" else @@ -93,6 +95,8 @@ git -C "$EDK2_ROOT" checkout "$EDK2_RELEASE_TAG" git -C "$EDK2_ROOT" submodule update --init export EDK_TOOLS_PATH="$EDK2_ROOT/BaseTools" +export PACKAGES_PATH="$EDK2_ROOT" + pushd "$EDK2_ROOT" @@ -126,6 +130,12 @@ for EDK2_TARGET_PROPERTY in "${!EDK2_TARGET_PROPERTIES[@]}"; do sed -i "s|^${EDK2_TARGET_PROPERTY}[[:space:]]*=.*\$|${EDK2_TARGET_PROPERTY} = $EDK2_TARGET_PROPERTY_VALUE|" "$EDK2_CONF_TARGET" done +export EDK2_LINUX_BIN_PATH="$EDK_TOOLS_PATH/Bin/Linux-x86_64" +export EDK2_POSIX_BIN_PATH="$EDK_TOOLS_PATH/BinWrappers/PosixLike" + + +export EDK2_BUILD_COMMAND="$EDK2_POSIX_BIN_PATH/build" + popd exit 1 From a5f6bb6458fc96582772ec987462f854a7cf9f0f Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 31 Jul 2026 23:41:09 +0200 Subject: [PATCH 031/112] feat: more uefi progress --- platforms/.gitignore | 1 + platforms/build-uefi.sh | 84 +++++++++++++++++----------- platforms/helper.sh | 2 - platforms/uefi/g++-wrapper.sh | 80 ++++++++++++++++++++++++++ platforms/uefi/gcc-wrapper.sh | 80 ++++++++++++++++++++++++++ platforms/uefi/pkg-config-wrapper.sh | 13 +++++ 6 files changed, 225 insertions(+), 35 deletions(-) create mode 100755 platforms/uefi/g++-wrapper.sh create mode 100755 platforms/uefi/gcc-wrapper.sh create mode 100755 platforms/uefi/pkg-config-wrapper.sh diff --git a/platforms/.gitignore b/platforms/.gitignore index dd2bbd75..1ba8225c 100644 --- a/platforms/.gitignore +++ b/platforms/.gitignore @@ -1,5 +1,6 @@ crossbuild.ini crossbuild/*.ini +crossbuild/uefi*.json *.elf *.nacp diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index dc298726..64bd179d 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -97,7 +97,6 @@ git -C "$EDK2_ROOT" submodule update --init export EDK_TOOLS_PATH="$EDK2_ROOT/BaseTools" export PACKAGES_PATH="$EDK2_ROOT" - pushd "$EDK2_ROOT" make -C BaseTools @@ -105,7 +104,7 @@ make -C BaseTools set +u # shellcheck disable=SC1091 -source "$EDK2_ROOT/edksetup.sh" +source "$EDK2_ROOT/edksetup.sh" "--reconfig" set -u @@ -122,7 +121,12 @@ else exit 1 fi -declare -A EDK2_TARGET_PROPERTIES=(["ACTIVE_PLATFORM"]="$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" ["TARGET"]="$(echo "$BUILDTYPE" | tr "[:lower:]" "[:upper:]")" ["TARGET_ARCH"]="X64" ["TOOL_CHAIN_TAG"]="GCC") +EDK2_TARGET_PROPERTIES_BUILDTYPE="$(echo "$BUILDTYPE" | tr "[:lower:]" "[:upper:]")" + +EDK2_TARGET_PROPERTIES_ARCH="X64" +EDK2_TARGET_PROPERTIES_TOOLCHAIN="GCC" + +declare -A EDK2_TARGET_PROPERTIES=(["ACTIVE_PLATFORM"]="$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" ["TARGET"]="$EDK2_TARGET_PROPERTIES_BUILDTYPE" ["TARGET_ARCH"]="$EDK2_TARGET_PROPERTIES_ARCH" ["TOOL_CHAIN_TAG"]="$EDK2_TARGET_PROPERTIES_TOOLCHAIN") for EDK2_TARGET_PROPERTY in "${!EDK2_TARGET_PROPERTIES[@]}"; do EDK2_TARGET_PROPERTY_VALUE="${EDK2_TARGET_PROPERTIES[$EDK2_TARGET_PROPERTY]}" @@ -133,45 +137,39 @@ done export EDK2_LINUX_BIN_PATH="$EDK_TOOLS_PATH/Bin/Linux-x86_64" export EDK2_POSIX_BIN_PATH="$EDK_TOOLS_PATH/BinWrappers/PosixLike" - export EDK2_BUILD_COMMAND="$EDK2_POSIX_BIN_PATH/build" -popd - -exit 1 +if ! [ -e "$WORKSPACE/OopetrisPkg" ]; then + ln -s "$SCRIPT_DIR/uefi/references/OopetrisPkg" "$WORKSPACE/OopetrisPkg" +fi -## build the needed dependencies -embuilder build sdl2-mt harfbuzz-mt freetype zlib sdl2_ttf mpg123 "sdl2_mixer-mp3-mt" libpng-mt "sdl2_image:formats=png,svg:mt=1" icu-mt +popd -export EDK2_SYS_ROOT="$EDK2_UPSTREAM_ROOT/cache/sysroot" +export BUILD_DIR="build/uefi" -export BUILD_DIR="build/web" +export PKG_CONFIG_PATH="$EDK2_ROOT/lib/pkgconfig" -export PKG_CONFIG_PATH="$EDK2_SYS_ROOT/lib/pkgconfig" +export CC="$SCRIPT_DIR/uefi/gcc-wrapper.sh" +export CXX="$SCRIPT_DIR/uefi/g++-wrapper.sh" +export AR="" +export RANLIB="" +export STRIP="" +export NM="" -export CC="emcc" -export CXX="em++" -export AR="emar" -export RANLIB="emranlib" -export STRIP="emstrip" -export NM="emnm" +export PKG_CONFIG_EXEC="$SCRIPT_DIR/uefi/pkg-config-wrapper.sh" -export ARCH="wasm32" -export CPU_ARCH="wasm32" +export ARCH="x86_64" +export CPU_ARCH="x86_64" export ENDIANESS="little" export ROMFS="platforms/romfs" -export PACKAGE_FLAGS="'--use-port=sdl2', '--use-port=harfbuzz', '--use-port=freetype', '--use-port=zlib', '--use-port=sdl2_ttf', '--use-port=mpg123', '--use-port=sdl2_mixer', '-sSDL2_MIXER_FORMATS=[\"mp3\"]','--use-port=libpng', '--use-port=sdl2_image','-sSDL2_IMAGE_FORMATS=[\"png\",\"svg\"]', '--use-port=icu'" - -#TODO use '-sMEMORY64', '-m64', and target wasm64 -export COMMON_FLAGS="'-fexceptions', '-pthread', '-sUSE_PTHREADS=1', '-sEXCEPTION_CATCHING_ALLOWED=[..]', $PACKAGE_FLAGS" +export COMMON_FLAGS="'-fexceptions', '-pthread'" -# TODO see if ALLOW_MEMORY_GROWTH is needed, but if we load ttf's and music it likely is and we don't have to debug OOm crashes, that aren't handled by some third party library, which is painful -export LINK_FLAGS="$COMMON_FLAGS, '-sEXPORT_ALL=1', '-sWASM=1', '-sALLOW_MEMORY_GROWTH=1', '-sASSERTIONS=1','-sERROR_ON_UNDEFINED_SYMBOLS=1', '-sFETCH=1', '-sEXIT_RUNTIME=1'" +export LINK_FLAGS="$COMMON_FLAGS" export COMPILE_FLAGS="$COMMON_FLAGS ,'-DAUDIO_PREFER_MP3'" -export CROSS_FILE="./platforms/crossbuild/web.ini" +export CROSS_FILE="./platforms/crossbuild/uefi.ini" validate_parent_dir "$CROSS_FILE" @@ -199,11 +197,9 @@ ranlib = '$RANLIB' strip = '$STRIP' nm = '$NM' -# pkg-config = ['emmake', 'pkg-config'] -# cmake = ['emmake', 'cmake'] -# sdl2-config = ['emconfigure', 'sdl2-config'] -# exe_wrapper = '$EMSDK_NODE' +pkg-config = '$PKG_CONFIG_EXEC' +cmake = '' [built-in options] c_std = 'c11' @@ -216,7 +212,6 @@ cpp_link_args = [$LINK_FLAGS] [properties] pkg_config_libdir = '$PKG_CONFIG_PATH' needs_exe_wrapper = true -sys_root = '$EDK2_SYS_ROOT' APP_ROMFS='$ROMFS/assets/' @@ -227,7 +222,7 @@ CMAKE_FIND_ROOT_PATH_MODE_LIBRARY = 'ONLY' CMAKE_FIND_ROOT_PATH_MODE_INCLUDE = 'ONLY' CMAKE_FIND_ROOT_PATH_MODE_PACKAGE = 'ONLY' -CMAKE_FIND_ROOT_PATH = '$EDK2_SYS_ROOT/lib/cmake' +CMAKE_FIND_ROOT_PATH = '' EOF @@ -239,6 +234,29 @@ if [ ! -d "$ROMFS" ]; then fi +export EDK2_INFO_FILE="./platforms/crossbuild/uefi_info.json" + +validate_parent_dir "$EDK2_INFO_FILE" + +cat <"$EDK2_INFO_FILE" +{ + "build": "$EDK2_BUILD_COMMAND", + "arch": "$EDK2_TARGET_PROPERTIES_ARCH", + "workspace": "$WORKSPACE", + "platform": "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM", + "buildtype": "$EDK2_TARGET_PROPERTIES_BUILDTYPE", + "toolchain": "$EDK2_TARGET_PROPERTIES_TOOLCHAIN" +} +EOF + +# "$EDK2_BUILD_COMMAND" -a "$EDK2_TARGET_PROPERTIES_ARCH" \ +# -p "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" \ +# -m "$WORKSPACE/CustomPkg/HelloWorld.inf" \ +# -b "$EDK2_TARGET_PROPERTIES_BUILDTYPE" \ +# -t "$EDK2_TARGET_PROPERTIES_TOOLCHAIN" \ +# -w \ +# -v + if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "$BUILD_DIR" ]; then meson setup "$BUILD_DIR" \ diff --git a/platforms/helper.sh b/platforms/helper.sh index c766ce2c..26019a23 100755 --- a/platforms/helper.sh +++ b/platforms/helper.sh @@ -1,7 +1,5 @@ #!/usr/bin/env bash -## 3ds section - validate_parent_dir() { local FILE="$1" local PARENT_DIR diff --git a/platforms/uefi/g++-wrapper.sh b/platforms/uefi/g++-wrapper.sh new file mode 100755 index 00000000..b7b1fff0 --- /dev/null +++ b/platforms/uefi/g++-wrapper.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash + +# Exit immediately if a command exits with a non-zero status. +set -e +## Treat undefined variables as an error +set -u +# fails if any part of a pipeline (|) fails +set -o pipefail + +SCRIPT_DIR="$(realpath "$(dirname -- "${BASH_SOURCE[0]}")")" + +# shellcheck source=./platforms/helper.sh +source "$SCRIPT_DIR/../helper.sh" + +CXX="g++-15" + +# Capture all args +ARGS=("$@") +NEW_ARGS=() + +MODE="unknown" +OUTPUT_FILE="" +NEXT_IS_OUTPUT="false" + +for arg in "${ARGS[@]}"; do + case "$arg" in + -Wl,--version | -Wl,-v) + MODE="pass" + NEW_ARGS+=("$arg") + ;; + -c) + MODE="compile" + NEW_ARGS+=("$arg") + ;; + -o) + NEW_ARGS+=("$arg") + NEXT_IS_OUTPUT="true" + ;; + *.o) + MODE="O_FILES" + NEW_ARGS+=("$arg") + ;; + --version | -dM|-xc\+\+) + MODE="pass" + NEW_ARGS+=("$arg") + ;; + *) + if [[ "$NEXT_IS_OUTPUT" == true ]]; then + OUTPUT_FILE="$arg" + NEXT_IS_OUTPUT=false + fi + NEW_ARGS+=("$arg") + ;; + esac +done + +if [[ "$MODE" == "pass" ]]; then + exec "$CXX" "${NEW_ARGS[@]}" +elif [[ "$MODE" == "compile" ]]; then + if [ -z "$OUTPUT_FILE" ]; then + echo " ${NEW_ARGS[*]}" >&2 + echo "Missing output file" >&2 + exit 2 + fi + + validate_parent_dir "$OUTPUT_FILE" + + cat <"$OUTPUT_FILE" +{ + "invocation": $(printf '%s\n' "${ARGS[@]}" | jq -R . | jq -sc .), + "args": $(printf '%s\n' "${NEW_ARGS[@]}" | jq -R . | jq -sc .), + "type": "cpp" +} +EOF + +else + echo " ${NEW_ARGS[*]}" >&2 + echo "Not recognized intent: $MODE" >&2 + exit 2 +fi diff --git a/platforms/uefi/gcc-wrapper.sh b/platforms/uefi/gcc-wrapper.sh new file mode 100755 index 00000000..3b249e80 --- /dev/null +++ b/platforms/uefi/gcc-wrapper.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash + +# Exit immediately if a command exits with a non-zero status. +set -e +## Treat undefined variables as an error +set -u +# fails if any part of a pipeline (|) fails +set -o pipefail + +SCRIPT_DIR="$(realpath "$(dirname -- "${BASH_SOURCE[0]}")")" + +# shellcheck source=./platforms/helper.sh +source "$SCRIPT_DIR/../helper.sh" + +CC="gcc-15" + +# Capture all args +ARGS=("$@") +NEW_ARGS=() + +MODE="unknown" +OUTPUT_FILE="" +NEXT_IS_OUTPUT="false" + +for arg in "${ARGS[@]}"; do + case "$arg" in + -Wl,--version | -Wl,-v) + MODE="pass" + NEW_ARGS+=("$arg") + ;; + -c) + MODE="compile" + NEW_ARGS+=("$arg") + ;; + -o) + NEW_ARGS+=("$arg") + NEXT_IS_OUTPUT="true" + ;; + *.o) + MODE="O_FILES" + NEW_ARGS+=("$arg") + ;; + --version | -dM) + MODE="pass" + NEW_ARGS+=("$arg") + ;; + *) + if [[ "$NEXT_IS_OUTPUT" == true ]]; then + OUTPUT_FILE="$arg" + NEXT_IS_OUTPUT=false + fi + NEW_ARGS+=("$arg") + ;; + esac +done + +if [[ "$MODE" == "pass" ]]; then + exec "$CC" "${NEW_ARGS[@]}" +elif [[ "$MODE" == "compile" ]]; then + if [ -z "$OUTPUT_FILE" ]; then + echo " ${NEW_ARGS[*]}" >&2 + echo "Missing output file" >&2 + exit 2 + fi + + validate_parent_dir "$OUTPUT_FILE" + + cat <"$OUTPUT_FILE" +{ + "invocation": $(printf '%s\n' "${ARGS[@]}" | jq -R . | jq -sc .), + "args": $(printf '%s\n' "${NEW_ARGS[@]}" | jq -R . | jq -sc .), + "type": "c" +} +EOF + +else + echo " ${NEW_ARGS[*]}" >&2 + echo "Not recognized intent: $MODE" >&2 + exit 2 +fi diff --git a/platforms/uefi/pkg-config-wrapper.sh b/platforms/uefi/pkg-config-wrapper.sh new file mode 100755 index 00000000..2f940b38 --- /dev/null +++ b/platforms/uefi/pkg-config-wrapper.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -eu + +# Capture all args +ARGS=("$@") +NEW_ARGS=() + +for ARG in "${ARGS[@]}"; do + echo "$ARG" +done + +exit 2 From 1b6c041791bb67b2724fa5715ef86d138e408714 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 31 Jul 2026 23:52:42 +0200 Subject: [PATCH 032/112] feat: more progress in the uefi target --- platforms/build-uefi.sh | 5 +++-- platforms/uefi/g++-wrapper.sh | 2 +- platforms/uefi/gcc-wrapper.sh | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 64bd179d..e9566de3 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -265,8 +265,9 @@ if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "$BUILD_DIR" ]; then "-Dbuildtype=$BUILDTYPE" \ -Ddefault_library=static \ -Dtests=false \ - "-Drun_in_ci=$RUN_IN_CI" \ - --fatal-meson-warnings + --wrap-mode=nofallback \ + "-Drun_in_ci=$RUN_IN_CI" #TODO: enable \ + #--fatal-meson-warnings fi diff --git a/platforms/uefi/g++-wrapper.sh b/platforms/uefi/g++-wrapper.sh index b7b1fff0..b1440d6e 100755 --- a/platforms/uefi/g++-wrapper.sh +++ b/platforms/uefi/g++-wrapper.sh @@ -40,7 +40,7 @@ for arg in "${ARGS[@]}"; do MODE="O_FILES" NEW_ARGS+=("$arg") ;; - --version | -dM|-xc\+\+) + --version | -dM | -xc\+\+) MODE="pass" NEW_ARGS+=("$arg") ;; diff --git a/platforms/uefi/gcc-wrapper.sh b/platforms/uefi/gcc-wrapper.sh index 3b249e80..e89be472 100755 --- a/platforms/uefi/gcc-wrapper.sh +++ b/platforms/uefi/gcc-wrapper.sh @@ -40,7 +40,7 @@ for arg in "${ARGS[@]}"; do MODE="O_FILES" NEW_ARGS+=("$arg") ;; - --version | -dM) + --version | -dM | -xc) MODE="pass" NEW_ARGS+=("$arg") ;; From bdb0cd08f009a262f15144cdf821d8394bc52680 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 1 Aug 2026 00:49:35 +0200 Subject: [PATCH 033/112] feat; some uefi progress - make sdl2 findable by the pkg-config wrapper, it gets added as library by the edk2 build system later --- platforms/build-uefi.sh | 1 + platforms/uefi/pkg-config-wrapper.sh | 89 ++++++++++++++++++++++-- platforms/uefi/references/libraries.json | 6 ++ platforms/uefi/references/mappings.json | 10 +++ tools/dependencies/meson.build | 5 +- 5 files changed, 105 insertions(+), 6 deletions(-) create mode 100644 platforms/uefi/references/libraries.json create mode 100644 platforms/uefi/references/mappings.json diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index e9566de3..c62e0030 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -265,6 +265,7 @@ if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "$BUILD_DIR" ]; then "-Dbuildtype=$BUILDTYPE" \ -Ddefault_library=static \ -Dtests=false \ + --force-fallback-for="fmt,nlohmann_json,magic_enum,utf8cpp" \ --wrap-mode=nofallback \ "-Drun_in_ci=$RUN_IN_CI" #TODO: enable \ #--fatal-meson-warnings diff --git a/platforms/uefi/pkg-config-wrapper.sh b/platforms/uefi/pkg-config-wrapper.sh index 2f940b38..67bd516a 100755 --- a/platforms/uefi/pkg-config-wrapper.sh +++ b/platforms/uefi/pkg-config-wrapper.sh @@ -1,13 +1,92 @@ #!/usr/bin/env bash -set -eu +# Exit immediately if a command exits with a non-zero status. +set -e +## Treat undefined variables as an error +set -u +# fails if any part of a pipeline (|) fails +set -o pipefail + +SCRIPT_DIR="$(realpath "$(dirname -- "${BASH_SOURCE[0]}")")" + +# shellcheck source=./platforms/helper.sh +source "$SCRIPT_DIR/../helper.sh" + +LIBRARIES_FILE="$SCRIPT_DIR/references/libraries.json" + +PKG_CONFIG="pkg-config" # Capture all args ARGS=("$@") -NEW_ARGS=() -for ARG in "${ARGS[@]}"; do - echo "$ARG" +MODE="unknown" +WHAT="" +PACKAGE_NAME="" +NEXT_IS_PACKAGE_NAME="false" + +for arg in "${ARGS[@]}"; do + case "$arg" in + --version) + MODE="pass" + ;; + --modversion) + MODE="get" + WHAT="version" + NEXT_IS_PACKAGE_NAME="true" + ;; + --cflags) + MODE="get" + WHAT="cflags" + NEXT_IS_PACKAGE_NAME="true" + ;; + --libs) + MODE="get" + WHAT="libflags" + NEXT_IS_PACKAGE_NAME="true" + ;; + *) + if [[ "$NEXT_IS_PACKAGE_NAME" == true ]]; then + PACKAGE_NAME="$arg" + NEXT_IS_PACKAGE_NAME=false + fi + ;; + esac done -exit 2 +if [[ "$MODE" == "pass" ]]; then + exec "$PKG_CONFIG" "${ARGS[@]}" +elif [[ "$MODE" == "get" ]]; then + if [ -z "$PACKAGE_NAME" ]; then + echo " ${ARGS[*]}" >&2 + echo "Missing package name" >&2 + exit 2 + fi + + LIBRARY_ENTRY="$(jq -M -r -c ".[\"${PACKAGE_NAME}\"]" "$LIBRARIES_FILE")" + + if [ "$LIBRARY_ENTRY" = "null" ]; then + exit 1 + fi + + if [[ "$WHAT" == "version" ]]; then + echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"version\"]" + exit 0 + elif [[ "$WHAT" == "cflags" ]]; then + echo "--use-lib=$PACKAGE_NAME" + echo "--lib_name=$("$LIBRARY_ENTRY" | jq -M -r -c ".[\"name\"]")" + exit 0 + elif [[ "$WHAT" == "libflags" ]]; then + echo "-L,--use-lib=$PACKAGE_NAME" + echo "-L,--lib_name=$("$LIBRARY_ENTRY" | jq -M -r -c ".[\"name\"]")" + exit 0 + else + echo " ${ARGS[*]}" >&2 + echo "Not recognized intent: $MODE" >&2 + exit 3 + fi + +else + echo " ${ARGS[*]}" >&2 + echo "Not recognized intent: $MODE" >&2 + exit 2 +fi diff --git a/platforms/uefi/references/libraries.json b/platforms/uefi/references/libraries.json new file mode 100644 index 00000000..4f0c6a96 --- /dev/null +++ b/platforms/uefi/references/libraries.json @@ -0,0 +1,6 @@ +{ + "sdl2": { + "name": "LibraryPkg/SDL2Pkg.inf", + "version": "2.32.10" + } +} diff --git a/platforms/uefi/references/mappings.json b/platforms/uefi/references/mappings.json new file mode 100644 index 00000000..b1cc3a56 --- /dev/null +++ b/platforms/uefi/references/mappings.json @@ -0,0 +1,10 @@ +{ + "oopetris": { + "type": "application", + "name": "OOpetrisApplication" + }, + "oopetris_core": { + "type": "library", + "name": "OOpetrisCore" + } +} diff --git a/tools/dependencies/meson.build b/tools/dependencies/meson.build index fe1056e4..7962df37 100644 --- a/tools/dependencies/meson.build +++ b/tools/dependencies/meson.build @@ -133,6 +133,8 @@ if meson.is_cross_build() 'deps': [graphics_lib.get('deps'), native_deps], } + elif host_machine.system() == 'uefi' + warning('TODO: implement') else error('Unhandled cross built system: ' + host_machine.system()) endif @@ -143,7 +145,8 @@ fmt_use_header_only = false if ( meson.is_cross_build() and (host_machine.system() == 'switch' - or host_machine.system() == '3ds') + or host_machine.system() == '3ds' + or host_machine.system() == 'uefi') ) fmt_use_header_only = true endif From 41072c05e75040e0ca56aaa8b4bfa2ceb031f9d8 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 1 Aug 2026 00:53:25 +0200 Subject: [PATCH 034/112] fix: more uefi progress --- platforms/build-uefi.sh | 6 +++--- platforms/uefi/references/libraries.json | 8 ++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index c62e0030..db1f9f89 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -140,7 +140,7 @@ export EDK2_POSIX_BIN_PATH="$EDK_TOOLS_PATH/BinWrappers/PosixLike" export EDK2_BUILD_COMMAND="$EDK2_POSIX_BIN_PATH/build" if ! [ -e "$WORKSPACE/OopetrisPkg" ]; then - ln -s "$SCRIPT_DIR/uefi/references/OopetrisPkg" "$WORKSPACE/OopetrisPkg" + ln -s "$WORKSPACE/OopetrisPkg" "$SCRIPT_DIR/uefi/references/OopetrisPkg" fi popd @@ -265,10 +265,10 @@ if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "$BUILD_DIR" ]; then "-Dbuildtype=$BUILDTYPE" \ -Ddefault_library=static \ -Dtests=false \ - --force-fallback-for="fmt,nlohmann_json,magic_enum,utf8cpp" \ + --force-fallback-for="fmt,nlohmann_json,magic_enum,utf8cpp,sdl2_ttf,freetype2,spdlog" \ --wrap-mode=nofallback \ "-Drun_in_ci=$RUN_IN_CI" #TODO: enable \ - #--fatal-meson-warnings + #--fatal-meson-warnings fi diff --git a/platforms/uefi/references/libraries.json b/platforms/uefi/references/libraries.json index 4f0c6a96..f0478031 100644 --- a/platforms/uefi/references/libraries.json +++ b/platforms/uefi/references/libraries.json @@ -2,5 +2,13 @@ "sdl2": { "name": "LibraryPkg/SDL2Pkg.inf", "version": "2.32.10" + }, + "sdl2_image": { + "name": "LibraryPkg/SDL2ImagePkg.inf", + "version": "2.6.3" + }, + "sdl2_mixer": { + "name": "LibraryPkg/SDL2ImagePkg.inf", + "version": "2.6.2" } } From be20f7aaf9f7e080c1387ddfaa76e90566224953 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 1 Aug 2026 00:58:16 +0200 Subject: [PATCH 035/112] feat: more uefi progress --- platforms/build-uefi.sh | 2 +- src/executables/meson.build | 2 ++ src/lobby/meson.build | 2 ++ tools/dependencies/meson.build | 6 ++++++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index db1f9f89..2d7c0aef 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -265,7 +265,7 @@ if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "$BUILD_DIR" ]; then "-Dbuildtype=$BUILDTYPE" \ -Ddefault_library=static \ -Dtests=false \ - --force-fallback-for="fmt,nlohmann_json,magic_enum,utf8cpp,sdl2_ttf,freetype2,spdlog" \ + --force-fallback-for="fmt,nlohmann_json,magic_enum,utf8cpp,sdl2_ttf,freetype2,spdlog,argparse" \ --wrap-mode=nofallback \ "-Drun_in_ci=$RUN_IN_CI" #TODO: enable \ #--fatal-meson-warnings diff --git a/src/executables/meson.build b/src/executables/meson.build index 0cb8bea9..415167aa 100644 --- a/src/executables/meson.build +++ b/src/executables/meson.build @@ -133,6 +133,8 @@ if build_application ) endif + elif host_machine.system() == 'uefi' + warning('TODO: implement') else error('Unhandled cross built system: ' + host_machine.system()) endif diff --git a/src/lobby/meson.build b/src/lobby/meson.build index 5ebbad64..86427fa4 100644 --- a/src/lobby/meson.build +++ b/src/lobby/meson.build @@ -4,6 +4,8 @@ elif online_multiplayer_system == 'httplib' graphics_src_files += files('httplib_client.cpp', 'httplib_client.hpp') elif online_multiplayer_system == 'web' graphics_src_files += files('web_client.cpp', 'web_client.hpp') +elif online_multiplayer_system == 'uefi' + warning('TODO: implement') else error('Unhandled online_multiplayer_system: \'' + online_multiplayer_system + '\'') endif diff --git a/tools/dependencies/meson.build b/tools/dependencies/meson.build index 7962df37..9d076437 100644 --- a/tools/dependencies/meson.build +++ b/tools/dependencies/meson.build @@ -454,6 +454,12 @@ if build_application graphics_lib += { 'compile_args': [graphics_lib.get('compile_args'), '-D_OOPETRIS_ONLINE_SYSTEM=1'], } + elif meson.is_cross_build() and host_machine.system() == 'uefi' + online_multiplayer_system = 'uefi' + + graphics_lib += { + 'compile_args': [graphics_lib.get('compile_args'), '-D_OOPETRIS_ONLINE_SYSTEM=2'], + } else online_multiplayer_system = 'curl' From fbc84a937a984eb14a9148fd2f4ac9a7b668fa0d Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 1 Aug 2026 01:22:46 +0200 Subject: [PATCH 036/112] feat: fix the wrapper files for the uefi - make mode changes checked - unify <$TOOL> reporting - fix OUTPUT_FILE detection --- platforms/uefi/g++-wrapper.sh | 42 ++++++++++++++------------ platforms/uefi/gcc-wrapper.sh | 44 ++++++++++++++++------------ platforms/uefi/pkg-config-wrapper.sh | 30 ++++++++++++++----- 3 files changed, 72 insertions(+), 44 deletions(-) diff --git a/platforms/uefi/g++-wrapper.sh b/platforms/uefi/g++-wrapper.sh index b1440d6e..ed5d34c7 100755 --- a/platforms/uefi/g++-wrapper.sh +++ b/platforms/uefi/g++-wrapper.sh @@ -13,52 +13,58 @@ SCRIPT_DIR="$(realpath "$(dirname -- "${BASH_SOURCE[0]}")")" source "$SCRIPT_DIR/../helper.sh" CXX="g++-15" +TOOL="G++" # Capture all args ARGS=("$@") -NEW_ARGS=() MODE="unknown" + +change_mode() { + local NEW_MODE="$1" + + if [[ "$MODE" == "unknown" ]]; then + MODE="$NEW_MODE" + elif [[ "$MODE" == "$NEW_MODE" ]]; then + : + else + echo "<$TOOL> ${ARGS[*]}" >&2 + echo "Can't change mode from $MODE to $NEW_MODE" >&2 + exit 4 + fi +} + OUTPUT_FILE="" NEXT_IS_OUTPUT="false" for arg in "${ARGS[@]}"; do case "$arg" in -Wl,--version | -Wl,-v) - MODE="pass" - NEW_ARGS+=("$arg") + change_mode "pass" ;; -c) - MODE="compile" - NEW_ARGS+=("$arg") + change_mode "compile" ;; -o) - NEW_ARGS+=("$arg") NEXT_IS_OUTPUT="true" ;; - *.o) - MODE="O_FILES" - NEW_ARGS+=("$arg") - ;; --version | -dM | -xc\+\+) - MODE="pass" - NEW_ARGS+=("$arg") + change_mode "pass" ;; *) if [[ "$NEXT_IS_OUTPUT" == true ]]; then OUTPUT_FILE="$arg" NEXT_IS_OUTPUT=false fi - NEW_ARGS+=("$arg") ;; esac done if [[ "$MODE" == "pass" ]]; then - exec "$CXX" "${NEW_ARGS[@]}" + exec "$CXX" "${ARGS[@]}" elif [[ "$MODE" == "compile" ]]; then if [ -z "$OUTPUT_FILE" ]; then - echo " ${NEW_ARGS[*]}" >&2 + echo "<$TOOL> ${ARGS[*]}" >&2 echo "Missing output file" >&2 exit 2 fi @@ -67,14 +73,14 @@ elif [[ "$MODE" == "compile" ]]; then cat <"$OUTPUT_FILE" { - "invocation": $(printf '%s\n' "${ARGS[@]}" | jq -R . | jq -sc .), - "args": $(printf '%s\n' "${NEW_ARGS[@]}" | jq -R . | jq -sc .), + "cwd": "$(pwd)", + "args": $(printf '%s\n' "${ARGS[@]}" | jq -R . | jq -sc .), "type": "cpp" } EOF else - echo " ${NEW_ARGS[*]}" >&2 + echo "<$TOOL> ${ARGS[*]}" >&2 echo "Not recognized intent: $MODE" >&2 exit 2 fi diff --git a/platforms/uefi/gcc-wrapper.sh b/platforms/uefi/gcc-wrapper.sh index e89be472..fa254296 100755 --- a/platforms/uefi/gcc-wrapper.sh +++ b/platforms/uefi/gcc-wrapper.sh @@ -13,52 +13,58 @@ SCRIPT_DIR="$(realpath "$(dirname -- "${BASH_SOURCE[0]}")")" source "$SCRIPT_DIR/../helper.sh" CC="gcc-15" +TOOL="GCC" # Capture all args ARGS=("$@") -NEW_ARGS=() MODE="unknown" + +change_mode() { + local NEW_MODE="$1" + + if [[ "$MODE" == "unknown" ]]; then + MODE="$NEW_MODE" + elif [[ "$MODE" == "$NEW_MODE" ]]; then + : + else + echo "<$TOOL> ${ARGS[*]}" >&2 + echo "Can't change mode from $MODE to $NEW_MODE" >&2 + exit 4 + fi +} + OUTPUT_FILE="" NEXT_IS_OUTPUT="false" for arg in "${ARGS[@]}"; do case "$arg" in -Wl,--version | -Wl,-v) - MODE="pass" - NEW_ARGS+=("$arg") + change_mode "pass" ;; -c) - MODE="compile" - NEW_ARGS+=("$arg") + change_mode "compile" ;; -o) - NEW_ARGS+=("$arg") NEXT_IS_OUTPUT="true" ;; - *.o) - MODE="O_FILES" - NEW_ARGS+=("$arg") - ;; --version | -dM | -xc) - MODE="pass" - NEW_ARGS+=("$arg") + change_mode "pass" ;; *) if [[ "$NEXT_IS_OUTPUT" == true ]]; then OUTPUT_FILE="$arg" NEXT_IS_OUTPUT=false fi - NEW_ARGS+=("$arg") ;; esac done if [[ "$MODE" == "pass" ]]; then - exec "$CC" "${NEW_ARGS[@]}" + exec "$CC" "${ARGS[@]}" elif [[ "$MODE" == "compile" ]]; then if [ -z "$OUTPUT_FILE" ]; then - echo " ${NEW_ARGS[*]}" >&2 + echo "<$TOOL> ${ARGS[*]}" >&2 echo "Missing output file" >&2 exit 2 fi @@ -66,15 +72,15 @@ elif [[ "$MODE" == "compile" ]]; then validate_parent_dir "$OUTPUT_FILE" cat <"$OUTPUT_FILE" -{ - "invocation": $(printf '%s\n' "${ARGS[@]}" | jq -R . | jq -sc .), - "args": $(printf '%s\n' "${NEW_ARGS[@]}" | jq -R . | jq -sc .), +{ + "cwd": "$(pwd)", + "args": $(printf '%s\n' "${ARGS[@]}" | jq -R . | jq -sc .), "type": "c" } EOF else - echo " ${NEW_ARGS[*]}" >&2 + echo "<$TOOL> ${ARGS[*]}" >&2 echo "Not recognized intent: $MODE" >&2 exit 2 fi diff --git a/platforms/uefi/pkg-config-wrapper.sh b/platforms/uefi/pkg-config-wrapper.sh index 67bd516a..276ab546 100755 --- a/platforms/uefi/pkg-config-wrapper.sh +++ b/platforms/uefi/pkg-config-wrapper.sh @@ -15,11 +15,27 @@ source "$SCRIPT_DIR/../helper.sh" LIBRARIES_FILE="$SCRIPT_DIR/references/libraries.json" PKG_CONFIG="pkg-config" +TOOL="PKG-CONFIG" # Capture all args ARGS=("$@") MODE="unknown" + +change_mode() { + local NEW_MODE="$1" + + if [[ "$MODE" == "unknown" ]]; then + MODE="$NEW_MODE" + elif [[ "$MODE" == "$NEW_MODE" ]]; then + : + else + echo "<$TOOL> ${ARGS[*]}" >&2 + echo "Can't change mode from $MODE to $NEW_MODE" >&2 + exit 4 + fi +} + WHAT="" PACKAGE_NAME="" NEXT_IS_PACKAGE_NAME="false" @@ -27,20 +43,20 @@ NEXT_IS_PACKAGE_NAME="false" for arg in "${ARGS[@]}"; do case "$arg" in --version) - MODE="pass" + change_mode "pass" ;; --modversion) - MODE="get" + change_mode "get" WHAT="version" NEXT_IS_PACKAGE_NAME="true" ;; --cflags) - MODE="get" + change_mode "get" WHAT="cflags" NEXT_IS_PACKAGE_NAME="true" ;; --libs) - MODE="get" + change_mode "get" WHAT="libflags" NEXT_IS_PACKAGE_NAME="true" ;; @@ -57,7 +73,7 @@ if [[ "$MODE" == "pass" ]]; then exec "$PKG_CONFIG" "${ARGS[@]}" elif [[ "$MODE" == "get" ]]; then if [ -z "$PACKAGE_NAME" ]; then - echo " ${ARGS[*]}" >&2 + echo "<$TOOL> ${ARGS[*]}" >&2 echo "Missing package name" >&2 exit 2 fi @@ -80,13 +96,13 @@ elif [[ "$MODE" == "get" ]]; then echo "-L,--lib_name=$("$LIBRARY_ENTRY" | jq -M -r -c ".[\"name\"]")" exit 0 else - echo " ${ARGS[*]}" >&2 + echo "<$TOOL> ${ARGS[*]}" >&2 echo "Not recognized intent: $MODE" >&2 exit 3 fi else - echo " ${ARGS[*]}" >&2 + echo "<$TOOL> ${ARGS[*]}" >&2 echo "Not recognized intent: $MODE" >&2 exit 2 fi From 2d0f1f72a3fda6fb92e6085de7904c4e18508180 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 1 Aug 2026 01:33:35 +0200 Subject: [PATCH 037/112] feat: support linking in the gcc wrappers for uefi --- platforms/uefi/g++-wrapper.sh | 31 ++++++++++++++++++++++++++++++- platforms/uefi/gcc-wrapper.sh | 31 ++++++++++++++++++++++++++++++- src/executables/meson.build | 13 ++++++++++++- 3 files changed, 72 insertions(+), 3 deletions(-) diff --git a/platforms/uefi/g++-wrapper.sh b/platforms/uefi/g++-wrapper.sh index ed5d34c7..57c0814b 100755 --- a/platforms/uefi/g++-wrapper.sh +++ b/platforms/uefi/g++-wrapper.sh @@ -45,6 +45,9 @@ for arg in "${ARGS[@]}"; do -c) change_mode "compile" ;; + -Wl,*) + change_mode "link" + ;; -o) NEXT_IS_OUTPUT="true" ;; @@ -55,6 +58,13 @@ for arg in "${ARGS[@]}"; do if [[ "$NEXT_IS_OUTPUT" == true ]]; then OUTPUT_FILE="$arg" NEXT_IS_OUTPUT=false + else + case "$arg" in + *.a | *.so) + change_mode "link" + ;; + *) ;; + esac fi ;; esac @@ -75,7 +85,26 @@ elif [[ "$MODE" == "compile" ]]; then { "cwd": "$(pwd)", "args": $(printf '%s\n' "${ARGS[@]}" | jq -R . | jq -sc .), - "type": "cpp" + "language": "cpp", + "type": "compile" +} +EOF + +elif [[ "$MODE" == "link" ]]; then + if [ -z "$OUTPUT_FILE" ]; then + echo "<$TOOL> ${ARGS[*]}" >&2 + echo "Missing output file" >&2 + exit 2 + fi + + validate_parent_dir "$OUTPUT_FILE" + + cat <"$OUTPUT_FILE" +{ + "cwd": "$(pwd)", + "args": $(printf '%s\n' "${ARGS[@]}" | jq -R . | jq -sc .), + "language": "cpp", + "type": "link" } EOF diff --git a/platforms/uefi/gcc-wrapper.sh b/platforms/uefi/gcc-wrapper.sh index fa254296..8ee4a9d5 100755 --- a/platforms/uefi/gcc-wrapper.sh +++ b/platforms/uefi/gcc-wrapper.sh @@ -45,6 +45,9 @@ for arg in "${ARGS[@]}"; do -c) change_mode "compile" ;; + -Wl,*) + change_mode "link" + ;; -o) NEXT_IS_OUTPUT="true" ;; @@ -55,6 +58,13 @@ for arg in "${ARGS[@]}"; do if [[ "$NEXT_IS_OUTPUT" == true ]]; then OUTPUT_FILE="$arg" NEXT_IS_OUTPUT=false + else + case "$arg" in + *.a | *.so) + change_mode "link" + ;; + *) ;; + esac fi ;; esac @@ -75,7 +85,26 @@ elif [[ "$MODE" == "compile" ]]; then { "cwd": "$(pwd)", "args": $(printf '%s\n' "${ARGS[@]}" | jq -R . | jq -sc .), - "type": "c" + "language": "c", + "type": "compile" +} +EOF + +elif [[ "$MODE" == "link" ]]; then + if [ -z "$OUTPUT_FILE" ]; then + echo "<$TOOL> ${ARGS[*]}" >&2 + echo "Missing output file" >&2 + exit 2 + fi + + validate_parent_dir "$OUTPUT_FILE" + + cat <"$OUTPUT_FILE" +{ + "cwd": "$(pwd)", + "args": $(printf '%s\n' "${ARGS[@]}" | jq -R . | jq -sc .), + "language": "c", + "type": "link" } EOF diff --git a/src/executables/meson.build b/src/executables/meson.build index 415167aa..6914a2c0 100644 --- a/src/executables/meson.build +++ b/src/executables/meson.build @@ -134,7 +134,18 @@ if build_application endif elif host_machine.system() == 'uefi' - warning('TODO: implement') + warning('TODO: implement fully') + + oopetris_exe = executable( + 'oopetris', + main_files, + dependencies: [liboopetris_graphics_dep, graphic_application_deps], + override_options: { + 'warning_level': '3', + 'werror': true, + }, + install: true, + ) else error('Unhandled cross built system: ' + host_machine.system()) endif From 8af8d969cd169bda76622276a356ac1b267313cc Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 1 Aug 2026 01:40:29 +0200 Subject: [PATCH 038/112] feat: uefi gcc wrappers, detect dependencies --- platforms/uefi/g++-wrapper.sh | 17 +++++++++++++++-- platforms/uefi/gcc-wrapper.sh | 17 +++++++++++++++-- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/platforms/uefi/g++-wrapper.sh b/platforms/uefi/g++-wrapper.sh index 57c0814b..a4191db3 100755 --- a/platforms/uefi/g++-wrapper.sh +++ b/platforms/uefi/g++-wrapper.sh @@ -18,6 +18,7 @@ TOOL="G++" # Capture all args ARGS=("$@") +DEPENDENCIES=() MODE="unknown" change_mode() { @@ -62,6 +63,10 @@ for arg in "${ARGS[@]}"; do case "$arg" in *.a | *.so) change_mode "link" + DEPENDENCIES+=("$arg") + ;; + *.o) + DEPENDENCIES+=("$arg") ;; *) ;; esac @@ -86,7 +91,11 @@ elif [[ "$MODE" == "compile" ]]; then "cwd": "$(pwd)", "args": $(printf '%s\n' "${ARGS[@]}" | jq -R . | jq -sc .), "language": "cpp", - "type": "compile" + "type": "compile", + "dependencies": { + "output": "$OUTPUT_FILE", + "files": $(printf '%s\n' "${DEPENDENCIES[@]}" | jq -R . | jq -sc .) + } } EOF @@ -104,7 +113,11 @@ elif [[ "$MODE" == "link" ]]; then "cwd": "$(pwd)", "args": $(printf '%s\n' "${ARGS[@]}" | jq -R . | jq -sc .), "language": "cpp", - "type": "link" + "type": "link", + "dependencies": { + "output": "$OUTPUT_FILE", + "files": $(printf '%s\n' "${DEPENDENCIES[@]}" | jq -R . | jq -sc .) + } } EOF diff --git a/platforms/uefi/gcc-wrapper.sh b/platforms/uefi/gcc-wrapper.sh index 8ee4a9d5..504f925f 100755 --- a/platforms/uefi/gcc-wrapper.sh +++ b/platforms/uefi/gcc-wrapper.sh @@ -18,6 +18,7 @@ TOOL="GCC" # Capture all args ARGS=("$@") +DEPENDENCIES=() MODE="unknown" change_mode() { @@ -62,6 +63,10 @@ for arg in "${ARGS[@]}"; do case "$arg" in *.a | *.so) change_mode "link" + DEPENDENCIES+=("$arg") + ;; + *.o) + DEPENDENCIES+=("$arg") ;; *) ;; esac @@ -86,7 +91,11 @@ elif [[ "$MODE" == "compile" ]]; then "cwd": "$(pwd)", "args": $(printf '%s\n' "${ARGS[@]}" | jq -R . | jq -sc .), "language": "c", - "type": "compile" + "type": "compile", + "dependencies": { + "output": "$OUTPUT_FILE", + "files": $(printf '%s\n' "${DEPENDENCIES[@]}" | jq -R . | jq -sc .) + } } EOF @@ -104,7 +113,11 @@ elif [[ "$MODE" == "link" ]]; then "cwd": "$(pwd)", "args": $(printf '%s\n' "${ARGS[@]}" | jq -R . | jq -sc .), "language": "c", - "type": "link" + "type": "link", + "dependencies": { + "output": "$OUTPUT_FILE", + "files": $(printf '%s\n' "${DEPENDENCIES[@]}" | jq -R . | jq -sc .) + } } EOF From 3d960aabfe5abd733f5b4a00dce28e4b02f37e7a Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 1 Aug 2026 01:52:12 +0200 Subject: [PATCH 039/112] feat: ignore the same output fiel in the uefi gcc wrappers --- platforms/uefi/g++-wrapper.sh | 28 ++++++++++++++++++++++++---- platforms/uefi/gcc-wrapper.sh | 32 ++++++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/platforms/uefi/g++-wrapper.sh b/platforms/uefi/g++-wrapper.sh index a4191db3..7911e85b 100755 --- a/platforms/uefi/g++-wrapper.sh +++ b/platforms/uefi/g++-wrapper.sh @@ -19,6 +19,21 @@ TOOL="G++" ARGS=("$@") DEPENDENCIES=() + +validate_dependencies() { + + for DEPENDENCY in "${DEPENDENCIES[@]}"; do + FILE="$(realpath "$DEPENDENCY")" + + if ! (jq -e "." "$FILE" >/dev/null); then + echo "<$TOOL> ${ARGS[*]}" >&2 + echo "Dependency '$FILE' is not a valid json file" >&2 + exit 5 + fi + + done +} + MODE="unknown" change_mode() { @@ -36,7 +51,7 @@ change_mode() { } OUTPUT_FILE="" -NEXT_IS_OUTPUT="false" +NEXT_TYPE="unknown" for arg in "${ARGS[@]}"; do case "$arg" in @@ -50,15 +65,20 @@ for arg in "${ARGS[@]}"; do change_mode "link" ;; -o) - NEXT_IS_OUTPUT="true" + NEXT_TYPE="output" + ;; + -MQ) + NEXT_TYPE="ignore" ;; --version | -dM | -xc\+\+) change_mode "pass" ;; *) - if [[ "$NEXT_IS_OUTPUT" == true ]]; then + if [[ "$NEXT_TYPE" == "output" ]]; then OUTPUT_FILE="$arg" - NEXT_IS_OUTPUT=false + NEXT_TYPE="unknown" + elif [[ "$NEXT_TYPE" == "ignore" ]]; then + NEXT_TYPE="unknown" else case "$arg" in *.a | *.so) diff --git a/platforms/uefi/gcc-wrapper.sh b/platforms/uefi/gcc-wrapper.sh index 504f925f..44ac9f79 100755 --- a/platforms/uefi/gcc-wrapper.sh +++ b/platforms/uefi/gcc-wrapper.sh @@ -19,6 +19,21 @@ TOOL="GCC" ARGS=("$@") DEPENDENCIES=() + +validate_dependencies() { + + for DEPENDENCY in "${DEPENDENCIES[@]}"; do + FILE="$(realpath "$DEPENDENCY")" + + if ! (jq -e "." "$FILE" >/dev/null); then + echo "<$TOOL> ${ARGS[*]}" >&2 + echo "Dependency '$FILE' is not a valid json file" >&2 + exit 5 + fi + + done +} + MODE="unknown" change_mode() { @@ -36,7 +51,7 @@ change_mode() { } OUTPUT_FILE="" -NEXT_IS_OUTPUT="false" +NEXT_TYPE="unknown" for arg in "${ARGS[@]}"; do case "$arg" in @@ -50,15 +65,20 @@ for arg in "${ARGS[@]}"; do change_mode "link" ;; -o) - NEXT_IS_OUTPUT="true" + NEXT_TYPE="output" + ;; + -MQ) + NEXT_TYPE="ignore" ;; --version | -dM | -xc) change_mode "pass" ;; *) - if [[ "$NEXT_IS_OUTPUT" == true ]]; then + if [[ "$NEXT_TYPE" == "output" ]]; then OUTPUT_FILE="$arg" - NEXT_IS_OUTPUT=false + NEXT_TYPE="unknown" + elif [[ "$NEXT_TYPE" == "ignore" ]]; then + NEXT_TYPE="unknown" else case "$arg" in *.a | *.so) @@ -86,6 +106,8 @@ elif [[ "$MODE" == "compile" ]]; then validate_parent_dir "$OUTPUT_FILE" + validate_dependencies + cat <"$OUTPUT_FILE" { "cwd": "$(pwd)", @@ -108,6 +130,8 @@ elif [[ "$MODE" == "link" ]]; then validate_parent_dir "$OUTPUT_FILE" + validate_dependencies + cat <"$OUTPUT_FILE" { "cwd": "$(pwd)", From 0acb92dbaf62b7d245d4c62fa520044856ac3c56 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 1 Aug 2026 02:04:36 +0200 Subject: [PATCH 040/112] feat: improve uefi wrapper scripts - add ar wrapper script, so that the created libraries are correct json files - create common file for the three compiler like wrappers --- platforms/build-uefi.sh | 2 +- platforms/uefi/ar-wrapper.sh | 84 +++++++++++++++++++++++++++++++++++ platforms/uefi/base.sh | 33 ++++++++++++++ platforms/uefi/g++-wrapper.sh | 36 ++------------- platforms/uefi/gcc-wrapper.sh | 35 ++------------- 5 files changed, 125 insertions(+), 65 deletions(-) create mode 100755 platforms/uefi/ar-wrapper.sh create mode 100644 platforms/uefi/base.sh diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 2d7c0aef..073808e9 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -151,7 +151,7 @@ export PKG_CONFIG_PATH="$EDK2_ROOT/lib/pkgconfig" export CC="$SCRIPT_DIR/uefi/gcc-wrapper.sh" export CXX="$SCRIPT_DIR/uefi/g++-wrapper.sh" -export AR="" +export AR="$SCRIPT_DIR/uefi/ar-wrapper.sh" export RANLIB="" export STRIP="" export NM="" diff --git a/platforms/uefi/ar-wrapper.sh b/platforms/uefi/ar-wrapper.sh new file mode 100755 index 00000000..6e17e695 --- /dev/null +++ b/platforms/uefi/ar-wrapper.sh @@ -0,0 +1,84 @@ +#!/usr/bin/env bash + +# Exit immediately if a command exits with a non-zero status. +set -e +## Treat undefined variables as an error +set -u +# fails if any part of a pipeline (|) fails +set -o pipefail + +SCRIPT_DIR="$(realpath "$(dirname -- "${BASH_SOURCE[0]}")")" + +# shellcheck source=./platforms/helper.sh +source "$SCRIPT_DIR/../helper.sh" + +TOOL="AR" +AR="gcc-ar-15" + +# shellcheck source=./platforms/uefi/base.sh +source "$SCRIPT_DIR/base.sh" + +# Capture all args +ARGS=("$@") + +OUTPUT_FILE="" +NEXT_TYPE="unknown" + +for arg in "${ARGS[@]}"; do + case "$arg" in + --version) + change_mode "pass" + ;; + csr) + change_mode "create" + NEXT_TYPE="output" + ;; + *) + if [[ "$NEXT_TYPE" == "output" ]]; then + OUTPUT_FILE="$arg" + NEXT_TYPE="unknown" + elif [[ "$NEXT_TYPE" == "ignore" ]]; then + NEXT_TYPE="unknown" + else + case "$arg" in + *.a | *.so | *.o) + DEPENDENCIES+=("$arg") + ;; + *) ;; + esac + fi + ;; + esac +done + +if [[ "$MODE" == "pass" ]]; then + exec "$AR" "${ARGS[@]}" +elif [[ "$MODE" == "create" ]]; then + if [ -z "$OUTPUT_FILE" ]; then + echo "<$TOOL> ${ARGS[*]}" >&2 + echo "Missing output file" >&2 + exit 2 + fi + + validate_parent_dir "$OUTPUT_FILE" + + validate_dependencies + + cat <"$OUTPUT_FILE" +{ + "cwd": "$(pwd)", + "args": $(printf '%s\n' "${ARGS[@]}" | jq -R . | jq -sc .), + "language": "ar", + "type": "archive", + "dependencies": { + "output": "$OUTPUT_FILE", + "files": $(printf '%s\n' "${DEPENDENCIES[@]}" | jq -R . | jq -sc .) + } +} +EOF + +else + echo "<$TOOL> ${ARGS[*]}" >&2 + echo "Not recognized intent: $MODE" >&2 + exit 2 +fi diff --git a/platforms/uefi/base.sh b/platforms/uefi/base.sh new file mode 100644 index 00000000..83f6f90b --- /dev/null +++ b/platforms/uefi/base.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +DEPENDENCIES=() + +validate_dependencies() { + + for DEPENDENCY in "${DEPENDENCIES[@]}"; do + FILE="$(realpath "$DEPENDENCY")" + + if ! (jq -e "." "$FILE" >/dev/null); then + echo "<$TOOL> ${ARGS[*]}" >&2 + echo "Dependency '$FILE' is not a valid json file" >&2 + exit 5 + fi + + done +} + +MODE="unknown" + +change_mode() { + local NEW_MODE="$1" + + if [[ "$MODE" == "unknown" ]]; then + MODE="$NEW_MODE" + elif [[ "$MODE" == "$NEW_MODE" ]]; then + : + else + echo "<$TOOL> ${ARGS[*]}" >&2 + echo "Can't change mode from $MODE to $NEW_MODE" >&2 + exit 4 + fi +} diff --git a/platforms/uefi/g++-wrapper.sh b/platforms/uefi/g++-wrapper.sh index 7911e85b..dc4753ee 100755 --- a/platforms/uefi/g++-wrapper.sh +++ b/platforms/uefi/g++-wrapper.sh @@ -15,40 +15,12 @@ source "$SCRIPT_DIR/../helper.sh" CXX="g++-15" TOOL="G++" -# Capture all args -ARGS=("$@") - -DEPENDENCIES=() - -validate_dependencies() { +# shellcheck source=./platforms/uefi/base.sh +source "$SCRIPT_DIR/base.sh" - for DEPENDENCY in "${DEPENDENCIES[@]}"; do - FILE="$(realpath "$DEPENDENCY")" - - if ! (jq -e "." "$FILE" >/dev/null); then - echo "<$TOOL> ${ARGS[*]}" >&2 - echo "Dependency '$FILE' is not a valid json file" >&2 - exit 5 - fi - - done -} -MODE="unknown" - -change_mode() { - local NEW_MODE="$1" - - if [[ "$MODE" == "unknown" ]]; then - MODE="$NEW_MODE" - elif [[ "$MODE" == "$NEW_MODE" ]]; then - : - else - echo "<$TOOL> ${ARGS[*]}" >&2 - echo "Can't change mode from $MODE to $NEW_MODE" >&2 - exit 4 - fi -} +# Capture all args +ARGS=("$@") OUTPUT_FILE="" NEXT_TYPE="unknown" diff --git a/platforms/uefi/gcc-wrapper.sh b/platforms/uefi/gcc-wrapper.sh index 44ac9f79..e931609b 100755 --- a/platforms/uefi/gcc-wrapper.sh +++ b/platforms/uefi/gcc-wrapper.sh @@ -15,41 +15,12 @@ source "$SCRIPT_DIR/../helper.sh" CC="gcc-15" TOOL="GCC" +# shellcheck source=./platforms/uefi/base.sh +source "$SCRIPT_DIR/base.sh" + # Capture all args ARGS=("$@") -DEPENDENCIES=() - -validate_dependencies() { - - for DEPENDENCY in "${DEPENDENCIES[@]}"; do - FILE="$(realpath "$DEPENDENCY")" - - if ! (jq -e "." "$FILE" >/dev/null); then - echo "<$TOOL> ${ARGS[*]}" >&2 - echo "Dependency '$FILE' is not a valid json file" >&2 - exit 5 - fi - - done -} - -MODE="unknown" - -change_mode() { - local NEW_MODE="$1" - - if [[ "$MODE" == "unknown" ]]; then - MODE="$NEW_MODE" - elif [[ "$MODE" == "$NEW_MODE" ]]; then - : - else - echo "<$TOOL> ${ARGS[*]}" >&2 - echo "Can't change mode from $MODE to $NEW_MODE" >&2 - exit 4 - fi -} - OUTPUT_FILE="" NEXT_TYPE="unknown" From 234afc09e3f0c6e90b24349445ba850979a6ba53 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 1 Aug 2026 19:21:06 +0200 Subject: [PATCH 041/112] feat: output error messages to stderr in bash scripts --- platforms/build-3ds.sh | 5 ++--- platforms/build-android.sh | 16 ++++++---------- platforms/build-switch.sh | 5 ++--- platforms/build-web.sh | 4 ++-- platforms/build.sh | 2 +- platforms/versions.sh | 2 ++ 6 files changed, 15 insertions(+), 19 deletions(-) diff --git a/platforms/build-3ds.sh b/platforms/build-3ds.sh index 5c167886..461f6027 100755 --- a/platforms/build-3ds.sh +++ b/platforms/build-3ds.sh @@ -32,7 +32,7 @@ elif [ "$#" -eq 3 ]; then RUN_IN_CI="true" fi else - echo "Too many arguments given, expected 1, 2 or 3" + echo "Too many arguments given, expected 1, 2 or 3" >&2 exit 1 fi @@ -41,7 +41,7 @@ if [ "$COMPILE_TYPE" == "smart" ]; then elif [ "$COMPILE_TYPE" == "complete_rebuild" ]; then : # noop else - echo "Invalid COMPILE_TYPE, expected: 'smart' or 'complete_rebuild'" + echo "Invalid COMPILE_TYPE, expected: 'smart' or 'complete_rebuild'" >&2 exit 1 fi @@ -67,7 +67,6 @@ export BUILD_DIR="build/3ds" export TOOL_PREFIX="arm-none-eabi" - export BIN_DIR="$PORTLIBS_PATH_3DS/bin" export PKG_CONFIG_EXEC="$BIN_DIR/$TOOL_PREFIX-pkg-config" export CMAKE="$BIN_DIR/$TOOL_PREFIX-cmake" diff --git a/platforms/build-android.sh b/platforms/build-android.sh index 065dd9bd..c9ccda5f 100755 --- a/platforms/build-android.sh +++ b/platforms/build-android.sh @@ -41,14 +41,14 @@ fi if [ ! -e "$BASE_PATH/meta/abis.json" ]; then - echo "no abis.json file found, to determine supported abis" + echo "no abis.json file found, to determine supported abis" >&2 exit 2 fi if [ ! -e "$BASE_PATH/meta/platforms.json" ]; then - echo "no platforms.json file found, to determine supported platforms and SDKs" + echo "no platforms.json file found, to determine supported platforms and SDKs" >&2 exit 2 fi @@ -56,7 +56,7 @@ fi SDK_VERSION=$(jq '.max' -M -r -c "$BASE_PATH/meta/platforms.json") export SDK_VERSION -mapfile -t ARCH_KEYS < <(jq 'keys' -M -r -c "$BASE_PATH/meta/abis.json" | tr -d '[]"' | sed 's/,/\n/g') +mapfile -t ARCH_KEYS < <(jq 'keys[]' -M -r -c "$BASE_PATH/meta/abis.json") export ARCH_KEYS_INDEX=("${!ARCH_KEYS[@]}") @@ -82,7 +82,7 @@ elif [ "$#" -eq 1 ] || [ "$#" -eq 2 ] || [ "$#" -eq 3 ] || [ "$#" -eq 4 ]; then done if [ -z "$FOUND" ]; then - echo "Invalid arch: '${ARCH}', supported archs are:" "${ARCH_KEYS[@]}" + echo "Invalid arch: '${ARCH}', supported archs are:" "${ARCH_KEYS[@]}" >&2 exit 2 fi @@ -106,7 +106,7 @@ elif [ "$#" -eq 1 ] || [ "$#" -eq 2 ] || [ "$#" -eq 3 ] || [ "$#" -eq 4 ]; then fi else - echo "Too many arguments given, expected 1, 2, 3 or 4" + echo "Too many arguments given, expected 1, 2, 3 or 4" >&2 exit 1 fi @@ -115,11 +115,10 @@ if [ "$COMPILE_TYPE" == "smart" ]; then elif [ "$COMPILE_TYPE" == "complete_rebuild" ]; then : # noop else - echo "Invalid COMPILE_TYPE, expected: 'smart' or 'complete_rebuild'" + echo "Invalid COMPILE_TYPE, expected: 'smart' or 'complete_rebuild'" >&2 exit 1 fi - for INDEX in "${ARCH_KEYS_INDEX[@]}"; do export KEY=${ARCH_KEYS[$INDEX]} @@ -148,7 +147,6 @@ for INDEX in "${ARCH_KEYS_INDEX[@]}"; do if [ "$COMPILE_TYPE" == "complete_rebuild" ] || ! [ -e "$SYS_ROOT" ]; then - if [ -d "${SYS_ROOT:?}/" ]; then rm -rf "${SYS_ROOT:?}/" @@ -249,7 +247,6 @@ for INDEX in "${ARCH_KEYS_INDEX[@]}"; do ## build flac with cmake (meson port doesn't work for 32 bits machines atm) (we need to check for fseeko and ftello correctly in there) - pushd "$SYS_ROOT" BUILD_DIR_FLAC="build-flac" @@ -377,7 +374,6 @@ for INDEX in "${ARCH_KEYS_INDEX[@]}"; do validate_parent_dir "$CROSS_FILE" - cat <"$CROSS_FILE" [host_machine] system = 'android' diff --git a/platforms/build-switch.sh b/platforms/build-switch.sh index bf30ab0d..b7e4953d 100755 --- a/platforms/build-switch.sh +++ b/platforms/build-switch.sh @@ -32,7 +32,7 @@ elif [ "$#" -eq 3 ]; then RUN_IN_CI="true" fi else - echo "Too many arguments given, expected 1, 2 or 3" + echo "Too many arguments given, expected 1, 2 or 3" >&2 exit 1 fi @@ -41,7 +41,7 @@ if [ "$COMPILE_TYPE" == "smart" ]; then elif [ "$COMPILE_TYPE" == "complete_rebuild" ]; then : # noop else - echo "Invalid COMPILE_TYPE, expected: 'smart' or 'complete_rebuild'" + echo "Invalid COMPILE_TYPE, expected: 'smart' or 'complete_rebuild'" >&2 exit 1 fi @@ -55,7 +55,6 @@ source "$SCRIPT_DIR/versions.sh" # shellcheck source=./platforms/helper.sh source "$SCRIPT_DIR/helper.sh" - export DEVKITPRO="/opt/devkitpro" export ARCH_DEVKIT_FOLDER="$DEVKITPRO/devkitA64" export COMPILER_BIN="$ARCH_DEVKIT_FOLDER/bin" diff --git a/platforms/build-web.sh b/platforms/build-web.sh index f84bd93e..96bf1ac3 100755 --- a/platforms/build-web.sh +++ b/platforms/build-web.sh @@ -32,7 +32,7 @@ elif [ "$#" -eq 3 ]; then RUN_IN_CI="true" fi else - echo "Too many arguments given, expected 1, 2 or 3" + echo "Too many arguments given, expected 1, 2 or 3" >&2 exit 1 fi @@ -41,7 +41,7 @@ if [ "$COMPILE_TYPE" == "smart" ]; then elif [ "$COMPILE_TYPE" == "complete_rebuild" ]; then : # noop else - echo "Invalid COMPILE_TYPE, expected: 'smart' or 'complete_rebuild'" + echo "Invalid COMPILE_TYPE, expected: 'smart' or 'complete_rebuild'" >&2 exit 1 fi diff --git a/platforms/build.sh b/platforms/build.sh index bc81970a..ffe4ceb9 100755 --- a/platforms/build.sh +++ b/platforms/build.sh @@ -28,5 +28,5 @@ for PLTFRM in "${SUPPORTED_PLATFORMS[@]}"; do done -echo "Invalid PLATFORM, expected one of: ${SUPPORTED_PLATFORMS[*]}" +echo "Invalid PLATFORM, expected one of: ${SUPPORTED_PLATFORMS[*]}" >&2 exit 1 diff --git a/platforms/versions.sh b/platforms/versions.sh index dd68cf35..45d278b6 100755 --- a/platforms/versions.sh +++ b/platforms/versions.sh @@ -34,3 +34,5 @@ export EMSDK_EXECUTE_NODE_VERSION="24.7.0" # edk2 section export EDK2_RELEASE_TAG="edk2-stable202605" + +export EDK2_LIBC_COMMIT_HASH="c8313c11c2dc43647aa4c9f73baf3b323c68ecba" From f67555bffd9eddbcc047dcdcda71f54dd8684c81 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 1 Aug 2026 19:21:23 +0200 Subject: [PATCH 042/112] feat more uefi build progress --- src/executables/meson.build | 15 +++---- src/executables/platforms/uefi/meson.build | 48 ++++++++++++++++++++++ 2 files changed, 53 insertions(+), 10 deletions(-) create mode 100644 src/executables/platforms/uefi/meson.build diff --git a/src/executables/meson.build b/src/executables/meson.build index 6914a2c0..189d999c 100644 --- a/src/executables/meson.build +++ b/src/executables/meson.build @@ -134,18 +134,13 @@ if build_application endif elif host_machine.system() == 'uefi' - warning('TODO: implement fully') - oopetris_exe = executable( - 'oopetris', + _uefi_options = [ + app_name, main_files, - dependencies: [liboopetris_graphics_dep, graphic_application_deps], - override_options: { - 'warning_level': '3', - 'werror': true, - }, - install: true, - ) + [liboopetris_graphics_dep, graphic_application_deps], + ] + subdir('platforms/uefi') else error('Unhandled cross built system: ' + host_machine.system()) endif diff --git a/src/executables/platforms/uefi/meson.build b/src/executables/platforms/uefi/meson.build new file mode 100644 index 00000000..8070a659 --- /dev/null +++ b/src/executables/platforms/uefi/meson.build @@ -0,0 +1,48 @@ +## get the options object and "unpack" it + +_uefi_exe_name = _uefi_options[0] +_uefi_src_files = _uefi_options[1] +_uefi_deps = _uefi_options[2] + +## compilation + +_uefi_final_description = executable( + _uefi_exe_name, + _uefi_src_files, + dependencies: _uefi_deps, + override_options: { + 'warning_level': '3', + 'werror': true, + }, +) + + +_uefi_extract_defs_exe = find_program( + 'extract-defintions.sh', + dirs: [meson.project_source_root() / 'platforms' / 'uefi'], + required: true, +) + +_uefi_extract_defs = custom_target( + _uefi_exe_name + '.json', + command: [_uefi_extract_defs_exe, _uefi_final_description, '@OUTPUT@'], + depends: [_uefi_final_description], + output: ['OOPetrisPkg.inf'], + build_by_default: true, +) + + +_uefi_compile_final_exe = find_program( + 'compile-final.sh', + dirs: [meson.project_source_root() / 'platforms' / 'uefi'], + required: true, +) + + +oopetris_efi = custom_target( + _uefi_exe_name + '.efi', + command: [_uefi_compile_final_exe, _uefi_extract_defs, '@OUTPUT@'], + depends: [_uefi_extract_defs], + output: [_uefi_exe_name + '.efi'], + build_by_default: true, +) From 5f45bf0f5be4afdaa8f9fab3deab2d5b6678db0d Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 1 Aug 2026 19:21:48 +0200 Subject: [PATCH 043/112] feat: more uefi progress --- platforms/build-uefi.sh | 49 +++++-- platforms/uefi/compile-final.sh | 86 +++++++++++ platforms/uefi/extract-defintions.sh | 185 ++++++++++++++++++++++++ platforms/uefi/g++-wrapper.sh | 4 +- platforms/uefi/gcc-wrapper.sh | 3 + platforms/uefi/pkg-config-wrapper.sh | 4 +- platforms/uefi/references/mappings.json | 43 +++++- 7 files changed, 356 insertions(+), 18 deletions(-) create mode 100755 platforms/uefi/compile-final.sh create mode 100755 platforms/uefi/extract-defintions.sh diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 073808e9..be92a68a 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -42,9 +42,9 @@ elif [ "$#" -eq 4 ]; then else RUN_IN_CI="true" fi - RUNTIME_TARGET="$2" + RUNTIME_TARGET="$4" else - echo "Too many arguments given, expected 1, 2 or 3" + echo "Too many arguments given, expected 1, 2 or 3" >&2 exit 1 fi @@ -53,7 +53,7 @@ if [ "$COMPILE_TYPE" == "smart" ]; then elif [ "$COMPILE_TYPE" == "complete_rebuild" ]; then : # noop else - echo "Invalid COMPILE_TYPE, expected: 'smart' or 'complete_rebuild'" + echo "Invalid COMPILE_TYPE, expected: 'smart' or 'complete_rebuild'" >&2 exit 1 fi @@ -62,7 +62,7 @@ if [ "$RUNTIME_TARGET" == "emulator" ]; then elif [ "$RUNTIME_TARGET" == "hardware" ]; then : # noop else - echo "Invalid RUNTIME_TARGET, expected: 'emulator' or 'hardware'" + echo "Invalid RUNTIME_TARGET, expected: 'emulator' or 'hardware'" >&2 exit 1 fi @@ -94,6 +94,17 @@ fi git -C "$EDK2_ROOT" checkout "$EDK2_RELEASE_TAG" git -C "$EDK2_ROOT" submodule update --init +EDK2_LIBC_ROOT="$(pwd)/toolchains/edk2-libc" +export EDK2_LIBC_ROOT + +if [ ! -d "$EDK2_LIBC_ROOT" ]; then + git clone https://github.com/tianocore/edk2-libc "$EDK2_LIBC_ROOT" +else + git -C "$EDK2_LIBC_ROOT" fetch +fi + +git -C "$EDK2_LIBC_ROOT" checkout "$EDK2_LIBC_COMMIT_HASH" + export EDK_TOOLS_PATH="$EDK2_ROOT/BaseTools" export PACKAGES_PATH="$EDK2_ROOT" @@ -117,7 +128,7 @@ if [ "$RUNTIME_TARGET" == "emulator" ]; then elif [ "$RUNTIME_TARGET" == "hardware" ]; then EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM="MdeModulePkg/MdeModulePkg.dsc" else - echo "Invalid RUNTIME_TARGET, expected: 'emulator' or 'hardware'" + echo "Invalid RUNTIME_TARGET, expected: 'emulator' or 'hardware'" >&2 exit 1 fi @@ -139,14 +150,33 @@ export EDK2_POSIX_BIN_PATH="$EDK_TOOLS_PATH/BinWrappers/PosixLike" export EDK2_BUILD_COMMAND="$EDK2_POSIX_BIN_PATH/build" -if ! [ -e "$WORKSPACE/OopetrisPkg" ]; then - ln -s "$WORKSPACE/OopetrisPkg" "$SCRIPT_DIR/uefi/references/OopetrisPkg" -fi +# add links to needed packages -popd +set -x + +EDK2_LIB_PACKAGES=("StdLib" "StdLibPrivateInternalFiles") + +for EDK2_LIB_PACKAGE in "${EDK2_LIB_PACKAGES[@]}"; do + + if ! [ -e "$WORKSPACE/$EDK2_LIB_PACKAGE" ]; then + ln -s "$EDK2_LIBC_ROOT/$EDK2_LIB_PACKAGE" "$WORKSPACE/$EDK2_LIB_PACKAGE" + fi + +done export BUILD_DIR="build/uefi" +export BUILD_DIR_ABS="$(pwd)/$BUILD_DIR" + +export EDK2_GENERATED_PACKAGES="$BUILD_DIR_ABS/GeneratedPackages" + +if ! [ -e "$WORKSPACE/GeneratedPackages" ]; then + mkdir -p "$EDK2_GENERATED_PACKAGES" + ln -s "$EDK2_GENERATED_PACKAGES" "$WORKSPACE/GeneratedPackages" +fi + +popd + export PKG_CONFIG_PATH="$EDK2_ROOT/lib/pkgconfig" export CC="$SCRIPT_DIR/uefi/gcc-wrapper.sh" @@ -246,6 +276,7 @@ cat <"$EDK2_INFO_FILE" "platform": "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM", "buildtype": "$EDK2_TARGET_PROPERTIES_BUILDTYPE", "toolchain": "$EDK2_TARGET_PROPERTIES_TOOLCHAIN" + "generated_packages": "$EDK2_GENERATED_PACKAGES" } EOF diff --git a/platforms/uefi/compile-final.sh b/platforms/uefi/compile-final.sh new file mode 100755 index 00000000..cd69c471 --- /dev/null +++ b/platforms/uefi/compile-final.sh @@ -0,0 +1,86 @@ +#!/usr/bin/env bash + +# Exit immediately if a command exits with a non-zero status. +set -e +## Treat undefined variables as an error +set -u +# fails if any part of a pipeline (|) fails +set -o pipefail + +exit 45 + +SCRIPT_DIR="$(realpath "$(dirname -- "${BASH_SOURCE[0]}")")" + +# shellcheck source=./platforms/helper.sh +source "$SCRIPT_DIR/../helper.sh" + +TOOL="AR" +AR="gcc-ar-15" + +# shellcheck source=./platforms/uefi/base.sh +source "$SCRIPT_DIR/base.sh" + +# Capture all args +ARGS=("$@") + +OUTPUT_FILE="" +NEXT_TYPE="unknown" + +for arg in "${ARGS[@]}"; do + case "$arg" in + --version) + change_mode "pass" + ;; + csr) + change_mode "create" + NEXT_TYPE="output" + ;; + *) + if [[ "$NEXT_TYPE" == "output" ]]; then + OUTPUT_FILE="$arg" + NEXT_TYPE="unknown" + elif [[ "$NEXT_TYPE" == "ignore" ]]; then + NEXT_TYPE="unknown" + else + case "$arg" in + *.a | *.so | *.o) + DEPENDENCIES+=("$arg") + ;; + *) ;; + esac + fi + ;; + esac +done + +if [[ "$MODE" == "pass" ]]; then + exec "$AR" "${ARGS[@]}" +elif [[ "$MODE" == "create" ]]; then + if [ -z "$OUTPUT_FILE" ]; then + echo "<$TOOL> ${ARGS[*]}" >&2 + echo "Missing output file" >&2 + exit 2 + fi + + validate_parent_dir "$OUTPUT_FILE" + + validate_dependencies + + cat <"$OUTPUT_FILE" +{ + "cwd": "$(pwd)", + "args": $(printf '%s\n' "${ARGS[@]}" | jq -R . | jq -sc .), + "language": "ar", + "type": "archive", + "dependencies": { + "output": "$OUTPUT_FILE", + "files": $(printf '%s\n' "${DEPENDENCIES[@]}" | jq -R . | jq -sc .) + } +} +EOF + +else + echo "<$TOOL> ${ARGS[*]}" >&2 + echo "Not recognized intent: $MODE" >&2 + exit 2 +fi diff --git a/platforms/uefi/extract-defintions.sh b/platforms/uefi/extract-defintions.sh new file mode 100755 index 00000000..e6ca9cdf --- /dev/null +++ b/platforms/uefi/extract-defintions.sh @@ -0,0 +1,185 @@ +#!/usr/bin/env bash + +# Exit immediately if a command exits with a non-zero status. +set -e +## Treat undefined variables as an error +set -u +# fails if any part of a pipeline (|) fails +set -o pipefail + +SCRIPT_DIR="$(realpath "$(dirname -- "${BASH_SOURCE[0]}")")" + +# shellcheck source=./platforms/helper.sh +source "$SCRIPT_DIR/../helper.sh" + +expand_array_inf() { + local FILES=("$@") + + for FILE in "${FILES[@]}"; do + + echo " $FILE" + + done + +} + +if [ "$#" -eq 2 ]; then + SOURCE_FILE="$1" + DEST_FILE="$2" +else + echo "Too many arguments given, expected 1 or 2" >&2 + exit 1 +fi + +DEST_FILE_NAME=$(basename -- "$DEST_FILE") +DEST_FILE_EXT="${DEST_FILE_NAME##*.}" +DEST_FILE_STEM="${DEST_FILE_NAME%.*}" + +if [ "$DEST_FILE_EXT" != "inf" ]; then + echo "Error: invalid dest file extension: $DEST_FILE_EXT" >&2 + exit 2 +fi + +MAPPINGS_FILE="$SCRIPT_DIR/references/mappings.json" + +MAPPING_ENTRY="$(jq -M -r -c ".[\"file\"][\"${DEST_FILE_STEM}\"]" "$MAPPINGS_FILE")" + +if [ "$MAPPING_ENTRY" = "null" ]; then + echo "Error: invalid name '$DEST_FILE_STEM': not found in mappings file" >&2 + exit 2 +fi + +SOURCE_FILE_TYPE="$(jq -M -r -c '.["type"]' "$SOURCE_FILE")" + +if [ "$SOURCE_FILE_TYPE" == "link" ] || [ "$SOURCE_FILE_TYPE" == "archive" ]; then + : +else + echo "Error: invalid source file type: $SOURCE_FILE_TYPE" >&2 + exit 2 +fi + +mapfile -t FILE_DEPENDENCIES < <(jq '.["dependencies"]["files"][]' -M -r -c "$SOURCE_FILE") + +DEP_SOURCES=() +DEP_PACKAGES=() +DEP_BUILD_OPTIONS=() + +for FILE_DEPENDENCY in "${FILE_DEPENDENCIES[@]}"; do + + FILE_DEPENDENCY_TYPE="$(jq -M -r -c '.["type"]' "$FILE_DEPENDENCY")" + + if [ "$FILE_DEPENDENCY_TYPE" == "compile" ]; then + mapfile -t FILE_DEPENDENCY_FILES < <(jq '.["dependencies"]["files"][]' -M -r -c "$FILE_DEPENDENCY") + + for FILE_DEPENDENCY_FILE in "${FILE_DEPENDENCY_FILES[@]}"; do + DEP_SOURCES+=("$FILE_DEPENDENCY_FILE") + done + elif [ "$FILE_DEPENDENCY_TYPE" == "archive" ] || [ "$FILE_DEPENDENCY_TYPE" == "link" ]; then + + DEP_OUTPUT="$(jq -M -r -c '.["dependencies"]["output"]' "$FILE_DEPENDENCY")" + + DEP_OUTPUT_NAME=$(basename -- "$DEP_OUTPUT") + DEP_OUTPUT_STEM="${DEP_OUTPUT_NAME%.*}" + + MAPPING_ENTRY_DEP="$(jq -M -r -c ".[\"name\"][\"${DEP_OUTPUT_STEM}\"]" "$MAPPINGS_FILE")" + + if [ "$MAPPING_ENTRY_DEP" = "null" ]; then + echo "Error: invalid name '$DEP_OUTPUT_STEM': not found in mappings file" >&2 + exit 2 + fi + + MAPPING_ENTRY_DEP_NAME="$(echo "$MAPPING_ENTRY_DEP" | jq -M -r -c ".[\"version\"]")" + + PACKAGE_NAME="GeneratedPackages/$MAPPING_ENTRY_DEP_NAME.inf" + + DEP_PACKAGES+=("$PACKAGE_NAME") + else + echo "Error: invalid source file type: $FILE_DEPENDENCY_TYPE" >&2 + exit 2 + fi + +done + +validate_parent_dir "$DEST_FILE" + +MAPPING_TYPE="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"type\"]")" +MAPPING_NAME="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"name\"]")" +MAPPING_GUID="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"guid\"]")" +MAPPING_VERSION="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"version\"]")" + +if [ "$MAPPING_TYPE" == "application" ]; then + + cat <"$DEST_FILE" +[Defines] + INF_VERSION = 1.25 + BASE_NAME = $MAPPING_NAME + FILE_GUID = $MAPPING_GUID + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = $MAPPING_VERSION + ENTRY_POINT = UefiMain + +[Sources] +$(expand_array_inf "${DEP_SOURCES[@]}") + +[Packages] + MdePkg/MdePkg.dec +$(expand_array_inf "${DEP_PACKAGES[@]}") + +[LibraryClasses] + UefiApplicationEntryPoint + UefiLib + +[Guids] + +[Ppis] + +[Protocols] + +[FeaturePcd] + +[Pcd] + +[BuildOptions] +$(expand_array_inf "${DEP_BUILD_OPTIONS[@]}") +EOF + +elif [ "$MAPPING_TYPE" == "library" ]; then + + MAPPING_LIB_NAME="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"lib\"]")" + + cat <"$DEST_FILE" +[Defines] + INF_VERSION = 1.25 + BASE_NAME = $MAPPING_NAME + FILE_GUID = $MAPPING_GUID + MODULE_TYPE = BASE + VERSION_STRING = $MAPPING_VERSION + LIBRARY_CLASS = $MAPPING_LIB_NAME|UEFI_APPLICATION + +[Sources] +$(expand_array_inf "${DEP_SOURCES[@]}") + +[Packages] + MdePkg/MdePkg.dec +$(expand_array_inf "${DEP_PACKAGES[@]}") + +[LibraryClasses] + UefiLib + +[Guids] + +[Ppis] + +[Protocols] + +[FeaturePcd] + +[Pcd] + +[BuildOptions] +$(expand_array_inf "${DEP_BUILD_OPTIONS[@]}") +EOF +else + echo "Error: invalid mapping type: $MAPPING_TYPE" >&2 + exit 2 +fi diff --git a/platforms/uefi/g++-wrapper.sh b/platforms/uefi/g++-wrapper.sh index dc4753ee..c5cc9197 100755 --- a/platforms/uefi/g++-wrapper.sh +++ b/platforms/uefi/g++-wrapper.sh @@ -18,7 +18,6 @@ TOOL="G++" # shellcheck source=./platforms/uefi/base.sh source "$SCRIPT_DIR/base.sh" - # Capture all args ARGS=("$@") @@ -60,6 +59,9 @@ for arg in "${ARGS[@]}"; do *.o) DEPENDENCIES+=("$arg") ;; + *.cpp) + DEPENDENCIES+=("$arg") + ;; *) ;; esac fi diff --git a/platforms/uefi/gcc-wrapper.sh b/platforms/uefi/gcc-wrapper.sh index e931609b..293a0784 100755 --- a/platforms/uefi/gcc-wrapper.sh +++ b/platforms/uefi/gcc-wrapper.sh @@ -59,6 +59,9 @@ for arg in "${ARGS[@]}"; do *.o) DEPENDENCIES+=("$arg") ;; + *.c) + DEPENDENCIES+=("$arg") + ;; *) ;; esac fi diff --git a/platforms/uefi/pkg-config-wrapper.sh b/platforms/uefi/pkg-config-wrapper.sh index 276ab546..75cedc20 100755 --- a/platforms/uefi/pkg-config-wrapper.sh +++ b/platforms/uefi/pkg-config-wrapper.sh @@ -89,11 +89,11 @@ elif [[ "$MODE" == "get" ]]; then exit 0 elif [[ "$WHAT" == "cflags" ]]; then echo "--use-lib=$PACKAGE_NAME" - echo "--lib_name=$("$LIBRARY_ENTRY" | jq -M -r -c ".[\"name\"]")" + echo "--lib_name=$(echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"name\"]")" exit 0 elif [[ "$WHAT" == "libflags" ]]; then echo "-L,--use-lib=$PACKAGE_NAME" - echo "-L,--lib_name=$("$LIBRARY_ENTRY" | jq -M -r -c ".[\"name\"]")" + echo "-L,--lib_name=$(echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"name\"]")" exit 0 else echo "<$TOOL> ${ARGS[*]}" >&2 diff --git a/platforms/uefi/references/mappings.json b/platforms/uefi/references/mappings.json index b1cc3a56..d66bc953 100644 --- a/platforms/uefi/references/mappings.json +++ b/platforms/uefi/references/mappings.json @@ -1,10 +1,41 @@ { - "oopetris": { - "type": "application", - "name": "OOpetrisApplication" + "file": { + "OOPetrisPkg": { + "type": "application", + "name": "OOPetrisApplication", + "guid": "da6e059f-d6bd-4136-8f1b-b19c9062f3cd", + "version": "0.5.6", + "comment": "TODO: generate this file by meson, and set the version by it! (use .in template)" + }, + "OOPetrisCorePkg": { + "type": "library", + "name": "OOPetrisCoreLib", + "lib": "LibOOPetrisCore", + "guid": "022bf605-571b-4d01-aeb5-e587e0045d6a", + "version": "0.5.6" + } }, - "oopetris_core": { - "type": "library", - "name": "OOpetrisCore" + "name": { + "liboopetris_graphics": { + "name": "OOPetrisGraphicsPkg" + }, + "liboopetris_recordings": { + "name": "OOPetrisRecordingsPkg" + }, + "liboopetris_core": { + "name": "OOPetrisCorePkg" + }, + "libsdl2_ttf": { + "name": "SDL2TTFPkg" + }, + "libfreetype": { + "name": "FreetypePkg" + }, + "libz": { + "name": "ZLibPkg" + }, + "libspdlog": { + "name": "SpdlogPkg" + } } } From b7d91d176ec9ddbdf57e99935d28cb6ceb7da45a Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 1 Aug 2026 21:40:34 +0200 Subject: [PATCH 044/112] feat: more uefi progress --- platforms/build-uefi.sh | 2 +- ...t-defintions.sh => extract-definitions.sh} | 49 ++++++++++++++++--- platforms/uefi/pkg-config-wrapper.sh | 2 +- .../platforms/uefi}/libraries.json | 2 +- .../platforms/uefi/mappings.json.in | 19 +++++-- src/executables/platforms/uefi/meson.build | 20 +++++++- 6 files changed, 79 insertions(+), 15 deletions(-) rename platforms/uefi/{extract-defintions.sh => extract-definitions.sh} (78%) rename {platforms/uefi/references => src/executables/platforms/uefi}/libraries.json (84%) rename platforms/uefi/references/mappings.json => src/executables/platforms/uefi/mappings.json.in (61%) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index be92a68a..edcdf976 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -275,7 +275,7 @@ cat <"$EDK2_INFO_FILE" "workspace": "$WORKSPACE", "platform": "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM", "buildtype": "$EDK2_TARGET_PROPERTIES_BUILDTYPE", - "toolchain": "$EDK2_TARGET_PROPERTIES_TOOLCHAIN" + "toolchain": "$EDK2_TARGET_PROPERTIES_TOOLCHAIN", "generated_packages": "$EDK2_GENERATED_PACKAGES" } EOF diff --git a/platforms/uefi/extract-defintions.sh b/platforms/uefi/extract-definitions.sh similarity index 78% rename from platforms/uefi/extract-defintions.sh rename to platforms/uefi/extract-definitions.sh index e6ca9cdf..1d518cd2 100755 --- a/platforms/uefi/extract-defintions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -23,14 +23,16 @@ expand_array_inf() { } -if [ "$#" -eq 2 ]; then +if [ "$#" -eq 3 ]; then SOURCE_FILE="$1" DEST_FILE="$2" + MAPPINGS_FILE="$3" else - echo "Too many arguments given, expected 1 or 2" >&2 + echo "Too many arguments given, expected 3" >&2 exit 1 fi +DEST_FILE_DIR=$(dirname -- "$DEST_FILE") DEST_FILE_NAME=$(basename -- "$DEST_FILE") DEST_FILE_EXT="${DEST_FILE_NAME##*.}" DEST_FILE_STEM="${DEST_FILE_NAME%.*}" @@ -40,12 +42,10 @@ if [ "$DEST_FILE_EXT" != "inf" ]; then exit 2 fi -MAPPINGS_FILE="$SCRIPT_DIR/references/mappings.json" - MAPPING_ENTRY="$(jq -M -r -c ".[\"file\"][\"${DEST_FILE_STEM}\"]" "$MAPPINGS_FILE")" if [ "$MAPPING_ENTRY" = "null" ]; then - echo "Error: invalid name '$DEST_FILE_STEM': not found in mappings file" >&2 + echo "Error: invalid name '$DEST_FILE_STEM': not found in mappings 'file'" >&2 exit 2 fi @@ -60,6 +60,23 @@ fi mapfile -t FILE_DEPENDENCIES < <(jq '.["dependencies"]["files"][]' -M -r -c "$SOURCE_FILE") +UEFI_INFO_FILE="$(realpath "$SCRIPT_DIR/../crossbuild/uefi_info.json")" +UEFI_INFO_GENERATED_PACKAGES_DIR="$(jq -M -r -c '.["generated_packages"]' "$UEFI_INFO_FILE")" + +link_package() { + local PACKAGE_NAME="$1" + local SOURCE_FILE="$2" + + local FINAL_FILE="$UEFI_INFO_GENERATED_PACKAGES_DIR/$PACKAGE_NAME" + + if [ -e "$FINAL_FILE" ]; then + rm "$FINAL_FILE" + fi + + ln -s "$SOURCE_FILE" "$FINAL_FILE" + +} + DEP_SOURCES=() DEP_PACKAGES=() DEP_BUILD_OPTIONS=() @@ -78,20 +95,36 @@ for FILE_DEPENDENCY in "${FILE_DEPENDENCIES[@]}"; do DEP_OUTPUT="$(jq -M -r -c '.["dependencies"]["output"]' "$FILE_DEPENDENCY")" + if [ "$DEP_OUTPUT" = "null" ]; then + echo "Error: output '$DEP_OUTPUT'" >&2 + exit 2 + fi + DEP_OUTPUT_NAME=$(basename -- "$DEP_OUTPUT") DEP_OUTPUT_STEM="${DEP_OUTPUT_NAME%.*}" MAPPING_ENTRY_DEP="$(jq -M -r -c ".[\"name\"][\"${DEP_OUTPUT_STEM}\"]" "$MAPPINGS_FILE")" if [ "$MAPPING_ENTRY_DEP" = "null" ]; then - echo "Error: invalid name '$DEP_OUTPUT_STEM': not found in mappings file" >&2 + echo "Error: invalid name '$DEP_OUTPUT_STEM': not found in mappings 'name'" >&2 exit 2 fi - MAPPING_ENTRY_DEP_NAME="$(echo "$MAPPING_ENTRY_DEP" | jq -M -r -c ".[\"version\"]")" + MAPPING_ENTRY_DEP_NAME="$(echo "$MAPPING_ENTRY_DEP" | jq -M -r -c ".[\"name\"]")" + + if [ "$MAPPING_ENTRY_DEP_NAME" = "null" ]; then + echo "Error: invalid name '$MAPPING_ENTRY_DEP_NAME': not found in dependency mapping 'name'" >&2 + exit 2 + fi PACKAGE_NAME="GeneratedPackages/$MAPPING_ENTRY_DEP_NAME.inf" + DEP_OUTPUT_FILE="$DEST_FILE_DIR/$MAPPING_ENTRY_DEP_NAME.inf" + + if ! [ -e "$DEP_OUTPUT_FILE" ]; then + "$SCRIPT_DIR/extract-definitions.sh" "$FILE_DEPENDENCY" "$DEP_OUTPUT_FILE" + fi + DEP_PACKAGES+=("$PACKAGE_NAME") else echo "Error: invalid source file type: $FILE_DEPENDENCY_TYPE" >&2 @@ -183,3 +216,5 @@ else echo "Error: invalid mapping type: $MAPPING_TYPE" >&2 exit 2 fi + +link_package "$DEST_FILE_NAME" "$DEST_FILE" diff --git a/platforms/uefi/pkg-config-wrapper.sh b/platforms/uefi/pkg-config-wrapper.sh index 75cedc20..20f366e9 100755 --- a/platforms/uefi/pkg-config-wrapper.sh +++ b/platforms/uefi/pkg-config-wrapper.sh @@ -12,7 +12,7 @@ SCRIPT_DIR="$(realpath "$(dirname -- "${BASH_SOURCE[0]}")")" # shellcheck source=./platforms/helper.sh source "$SCRIPT_DIR/../helper.sh" -LIBRARIES_FILE="$SCRIPT_DIR/references/libraries.json" +LIBRARIES_FILE="$(realpath "$SCRIPT_DIR/../../src/executables/platforms/uefi/libraries.json")" PKG_CONFIG="pkg-config" TOOL="PKG-CONFIG" diff --git a/platforms/uefi/references/libraries.json b/src/executables/platforms/uefi/libraries.json similarity index 84% rename from platforms/uefi/references/libraries.json rename to src/executables/platforms/uefi/libraries.json index f0478031..fd36bf8c 100644 --- a/platforms/uefi/references/libraries.json +++ b/src/executables/platforms/uefi/libraries.json @@ -8,7 +8,7 @@ "version": "2.6.3" }, "sdl2_mixer": { - "name": "LibraryPkg/SDL2ImagePkg.inf", + "name": "LibraryPkg/SDL2MixerPkg.inf", "version": "2.6.2" } } diff --git a/platforms/uefi/references/mappings.json b/src/executables/platforms/uefi/mappings.json.in similarity index 61% rename from platforms/uefi/references/mappings.json rename to src/executables/platforms/uefi/mappings.json.in index d66bc953..4785eff5 100644 --- a/platforms/uefi/references/mappings.json +++ b/src/executables/platforms/uefi/mappings.json.in @@ -4,15 +4,28 @@ "type": "application", "name": "OOPetrisApplication", "guid": "da6e059f-d6bd-4136-8f1b-b19c9062f3cd", - "version": "0.5.6", - "comment": "TODO: generate this file by meson, and set the version by it! (use .in template)" + "version": "@OOPETRIS_VERSION@", }, "OOPetrisCorePkg": { "type": "library", "name": "OOPetrisCoreLib", "lib": "LibOOPetrisCore", "guid": "022bf605-571b-4d01-aeb5-e587e0045d6a", - "version": "0.5.6" + "version": "@OOPETRIS_VERSION@" + }, + "OOPetrisGraphicsPkg": { + "type": "library", + "name": "OOPetrisGraphicsLib", + "lib": "LibOOPetrisGraphics", + "guid": "0bfc59b5-090c-4cd0-a0b7-498dcbed1e6e", + "version": "@OOPETRIS_VERSION@" + }, + "SDL2TTFPkg": { + "type": "library", + "name": "SDL2TTFLib", + "lib": "LibSDL2TTF", + "guid": "2252bce8-bee1-4ab8-9896-2ab58576e9db", + "version": "@SDL2_TTF_VERSION@" } }, "name": { diff --git a/src/executables/platforms/uefi/meson.build b/src/executables/platforms/uefi/meson.build index 8070a659..79c2b5fd 100644 --- a/src/executables/platforms/uefi/meson.build +++ b/src/executables/platforms/uefi/meson.build @@ -16,16 +16,32 @@ _uefi_final_description = executable( }, ) +_uefi_mappings_conf = configuration_data( + { + 'OOPETRIS_VERSION': meson.project_version(), + } +) + +_uefi_mappings_file = configure_file( + input: 'mappings.json.in', + output: 'mappings.json', + configuration: _uefi_mappings_conf, +) _uefi_extract_defs_exe = find_program( - 'extract-defintions.sh', + 'extract-definitions.sh', dirs: [meson.project_source_root() / 'platforms' / 'uefi'], required: true, ) _uefi_extract_defs = custom_target( _uefi_exe_name + '.json', - command: [_uefi_extract_defs_exe, _uefi_final_description, '@OUTPUT@'], + command: [ + _uefi_extract_defs_exe, + _uefi_final_description, + '@OUTPUT@', + _uefi_mappings_file, + ], depends: [_uefi_final_description], output: ['OOPetrisPkg.inf'], build_by_default: true, From eb57526417bc9a1d9ba42741f5bb966642c8dde7 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 1 Aug 2026 21:52:38 +0200 Subject: [PATCH 045/112] feat: fix wrapper script for uefi --- platforms/uefi/ar-wrapper.sh | 4 +- platforms/uefi/base.sh | 10 +++ platforms/uefi/compile-final.sh | 76 ------------------- platforms/uefi/g++-wrapper.sh | 14 ++-- platforms/uefi/gcc-wrapper.sh | 14 ++-- .../platforms/uefi/mappings.json.in | 2 +- 6 files changed, 31 insertions(+), 89 deletions(-) diff --git a/platforms/uefi/ar-wrapper.sh b/platforms/uefi/ar-wrapper.sh index 6e17e695..00435f6b 100755 --- a/platforms/uefi/ar-wrapper.sh +++ b/platforms/uefi/ar-wrapper.sh @@ -67,12 +67,12 @@ elif [[ "$MODE" == "create" ]]; then cat <"$OUTPUT_FILE" { "cwd": "$(pwd)", - "args": $(printf '%s\n' "${ARGS[@]}" | jq -R . | jq -sc .), + "args": $(to_json_array "${ARGS[@]}"), "language": "ar", "type": "archive", "dependencies": { "output": "$OUTPUT_FILE", - "files": $(printf '%s\n' "${DEPENDENCIES[@]}" | jq -R . | jq -sc .) + "files": $(to_json_array "${DEPENDENCIES[@]}") } } EOF diff --git a/platforms/uefi/base.sh b/platforms/uefi/base.sh index 83f6f90b..80bb9f03 100644 --- a/platforms/uefi/base.sh +++ b/platforms/uefi/base.sh @@ -31,3 +31,13 @@ change_mode() { exit 4 fi } + +to_json_array() { + local ARRAY=("$@") + + if [ "${#ARRAY[@]}" -eq 0 ]; then + echo "[]" + else + printf '%s\n' "${ARRAY[@]}" | jq -R . | jq -sc . + fi +} diff --git a/platforms/uefi/compile-final.sh b/platforms/uefi/compile-final.sh index cd69c471..cb97f75b 100755 --- a/platforms/uefi/compile-final.sh +++ b/platforms/uefi/compile-final.sh @@ -8,79 +8,3 @@ set -u set -o pipefail exit 45 - -SCRIPT_DIR="$(realpath "$(dirname -- "${BASH_SOURCE[0]}")")" - -# shellcheck source=./platforms/helper.sh -source "$SCRIPT_DIR/../helper.sh" - -TOOL="AR" -AR="gcc-ar-15" - -# shellcheck source=./platforms/uefi/base.sh -source "$SCRIPT_DIR/base.sh" - -# Capture all args -ARGS=("$@") - -OUTPUT_FILE="" -NEXT_TYPE="unknown" - -for arg in "${ARGS[@]}"; do - case "$arg" in - --version) - change_mode "pass" - ;; - csr) - change_mode "create" - NEXT_TYPE="output" - ;; - *) - if [[ "$NEXT_TYPE" == "output" ]]; then - OUTPUT_FILE="$arg" - NEXT_TYPE="unknown" - elif [[ "$NEXT_TYPE" == "ignore" ]]; then - NEXT_TYPE="unknown" - else - case "$arg" in - *.a | *.so | *.o) - DEPENDENCIES+=("$arg") - ;; - *) ;; - esac - fi - ;; - esac -done - -if [[ "$MODE" == "pass" ]]; then - exec "$AR" "${ARGS[@]}" -elif [[ "$MODE" == "create" ]]; then - if [ -z "$OUTPUT_FILE" ]; then - echo "<$TOOL> ${ARGS[*]}" >&2 - echo "Missing output file" >&2 - exit 2 - fi - - validate_parent_dir "$OUTPUT_FILE" - - validate_dependencies - - cat <"$OUTPUT_FILE" -{ - "cwd": "$(pwd)", - "args": $(printf '%s\n' "${ARGS[@]}" | jq -R . | jq -sc .), - "language": "ar", - "type": "archive", - "dependencies": { - "output": "$OUTPUT_FILE", - "files": $(printf '%s\n' "${DEPENDENCIES[@]}" | jq -R . | jq -sc .) - } -} -EOF - -else - echo "<$TOOL> ${ARGS[*]}" >&2 - echo "Not recognized intent: $MODE" >&2 - exit 2 -fi diff --git a/platforms/uefi/g++-wrapper.sh b/platforms/uefi/g++-wrapper.sh index c5cc9197..b4677de2 100755 --- a/platforms/uefi/g++-wrapper.sh +++ b/platforms/uefi/g++-wrapper.sh @@ -18,6 +18,8 @@ TOOL="G++" # shellcheck source=./platforms/uefi/base.sh source "$SCRIPT_DIR/base.sh" +COMPILED=() + # Capture all args ARGS=("$@") @@ -60,7 +62,7 @@ for arg in "${ARGS[@]}"; do DEPENDENCIES+=("$arg") ;; *.cpp) - DEPENDENCIES+=("$arg") + COMPILED+=("$arg") ;; *) ;; esac @@ -83,12 +85,14 @@ elif [[ "$MODE" == "compile" ]]; then cat <"$OUTPUT_FILE" { "cwd": "$(pwd)", - "args": $(printf '%s\n' "${ARGS[@]}" | jq -R . | jq -sc .), + "args": $(to_json_array "${ARGS[@]}"), "language": "cpp", "type": "compile", "dependencies": { "output": "$OUTPUT_FILE", - "files": $(printf '%s\n' "${DEPENDENCIES[@]}" | jq -R . | jq -sc .) + "files": $(to_json_array "${DEPENDENCIES[@]}" "${COMPILED[@]}"), + "dependencies": $(to_json_array "${DEPENDENCIES[@]}"), + "compiled": $(to_json_array "${COMPILED[@]}") } } EOF @@ -105,12 +109,12 @@ elif [[ "$MODE" == "link" ]]; then cat <"$OUTPUT_FILE" { "cwd": "$(pwd)", - "args": $(printf '%s\n' "${ARGS[@]}" | jq -R . | jq -sc .), + "args": $(to_json_array "${ARGS[@]}"), "language": "cpp", "type": "link", "dependencies": { "output": "$OUTPUT_FILE", - "files": $(printf '%s\n' "${DEPENDENCIES[@]}" | jq -R . | jq -sc .) + "files": $(to_json_array "${DEPENDENCIES[@]}") } } EOF diff --git a/platforms/uefi/gcc-wrapper.sh b/platforms/uefi/gcc-wrapper.sh index 293a0784..93df9f09 100755 --- a/platforms/uefi/gcc-wrapper.sh +++ b/platforms/uefi/gcc-wrapper.sh @@ -18,6 +18,8 @@ TOOL="GCC" # shellcheck source=./platforms/uefi/base.sh source "$SCRIPT_DIR/base.sh" +COMPILED=() + # Capture all args ARGS=("$@") @@ -60,7 +62,7 @@ for arg in "${ARGS[@]}"; do DEPENDENCIES+=("$arg") ;; *.c) - DEPENDENCIES+=("$arg") + COMPILED+=("$arg") ;; *) ;; esac @@ -85,12 +87,14 @@ elif [[ "$MODE" == "compile" ]]; then cat <"$OUTPUT_FILE" { "cwd": "$(pwd)", - "args": $(printf '%s\n' "${ARGS[@]}" | jq -R . | jq -sc .), + "args": $(to_json_array "${ARGS[@]}"), "language": "c", "type": "compile", "dependencies": { "output": "$OUTPUT_FILE", - "files": $(printf '%s\n' "${DEPENDENCIES[@]}" | jq -R . | jq -sc .) + "files": $(to_json_array "${DEPENDENCIES[@]}" "${COMPILED[@]}"), + "dependencies": $(to_json_array "${DEPENDENCIES[@]}"), + "compiled": $(to_json_array "${COMPILED[@]}") } } EOF @@ -109,12 +113,12 @@ elif [[ "$MODE" == "link" ]]; then cat <"$OUTPUT_FILE" { "cwd": "$(pwd)", - "args": $(printf '%s\n' "${ARGS[@]}" | jq -R . | jq -sc .), + "args": $(to_json_array "${ARGS[@]}"), "language": "c", "type": "link", "dependencies": { "output": "$OUTPUT_FILE", - "files": $(printf '%s\n' "${DEPENDENCIES[@]}" | jq -R . | jq -sc .) + "files": $(to_json_array "${DEPENDENCIES[@]}") } } EOF diff --git a/src/executables/platforms/uefi/mappings.json.in b/src/executables/platforms/uefi/mappings.json.in index 4785eff5..5607a92a 100644 --- a/src/executables/platforms/uefi/mappings.json.in +++ b/src/executables/platforms/uefi/mappings.json.in @@ -4,7 +4,7 @@ "type": "application", "name": "OOPetrisApplication", "guid": "da6e059f-d6bd-4136-8f1b-b19c9062f3cd", - "version": "@OOPETRIS_VERSION@", + "version": "@OOPETRIS_VERSION@" }, "OOPetrisCorePkg": { "type": "library", From 7ef6ad9887cee10a8a5407f84157b1a9ac0b5e8a Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 1 Aug 2026 21:56:36 +0200 Subject: [PATCH 046/112] fix: more uefi wrapper script fixes --- platforms/uefi/ar-wrapper.sh | 10 +++++----- platforms/uefi/extract-definitions.sh | 6 +++++- platforms/uefi/g++-wrapper.sh | 14 +++++++------- platforms/uefi/gcc-wrapper.sh | 14 +++++++------- platforms/uefi/pkg-config-wrapper.sh | 8 ++++---- 5 files changed, 28 insertions(+), 24 deletions(-) diff --git a/platforms/uefi/ar-wrapper.sh b/platforms/uefi/ar-wrapper.sh index 00435f6b..cf4bac1c 100755 --- a/platforms/uefi/ar-wrapper.sh +++ b/platforms/uefi/ar-wrapper.sh @@ -24,8 +24,8 @@ ARGS=("$@") OUTPUT_FILE="" NEXT_TYPE="unknown" -for arg in "${ARGS[@]}"; do - case "$arg" in +for ARG in "${ARGS[@]}"; do + case "$ARG" in --version) change_mode "pass" ;; @@ -35,14 +35,14 @@ for arg in "${ARGS[@]}"; do ;; *) if [[ "$NEXT_TYPE" == "output" ]]; then - OUTPUT_FILE="$arg" + OUTPUT_FILE="$ARG" NEXT_TYPE="unknown" elif [[ "$NEXT_TYPE" == "ignore" ]]; then NEXT_TYPE="unknown" else - case "$arg" in + case "$ARG" in *.a | *.so | *.o) - DEPENDENCIES+=("$arg") + DEPENDENCIES+=("$ARG") ;; *) ;; esac diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 1d518cd2..82a31ebb 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -73,8 +73,12 @@ link_package() { rm "$FINAL_FILE" fi + set -x + ln -s "$SOURCE_FILE" "$FINAL_FILE" + set +x + } DEP_SOURCES=() @@ -122,7 +126,7 @@ for FILE_DEPENDENCY in "${FILE_DEPENDENCIES[@]}"; do DEP_OUTPUT_FILE="$DEST_FILE_DIR/$MAPPING_ENTRY_DEP_NAME.inf" if ! [ -e "$DEP_OUTPUT_FILE" ]; then - "$SCRIPT_DIR/extract-definitions.sh" "$FILE_DEPENDENCY" "$DEP_OUTPUT_FILE" + "$SCRIPT_DIR/extract-definitions.sh" "$FILE_DEPENDENCY" "$DEP_OUTPUT_FILE" "$MAPPINGS_FILE" fi DEP_PACKAGES+=("$PACKAGE_NAME") diff --git a/platforms/uefi/g++-wrapper.sh b/platforms/uefi/g++-wrapper.sh index b4677de2..2674da61 100755 --- a/platforms/uefi/g++-wrapper.sh +++ b/platforms/uefi/g++-wrapper.sh @@ -26,8 +26,8 @@ ARGS=("$@") OUTPUT_FILE="" NEXT_TYPE="unknown" -for arg in "${ARGS[@]}"; do - case "$arg" in +for ARG in "${ARGS[@]}"; do + case "$ARG" in -Wl,--version | -Wl,-v) change_mode "pass" ;; @@ -48,21 +48,21 @@ for arg in "${ARGS[@]}"; do ;; *) if [[ "$NEXT_TYPE" == "output" ]]; then - OUTPUT_FILE="$arg" + OUTPUT_FILE="$ARG" NEXT_TYPE="unknown" elif [[ "$NEXT_TYPE" == "ignore" ]]; then NEXT_TYPE="unknown" else - case "$arg" in + case "$ARG" in *.a | *.so) change_mode "link" - DEPENDENCIES+=("$arg") + DEPENDENCIES+=("$ARG") ;; *.o) - DEPENDENCIES+=("$arg") + DEPENDENCIES+=("$ARG") ;; *.cpp) - COMPILED+=("$arg") + COMPILED+=("$ARG") ;; *) ;; esac diff --git a/platforms/uefi/gcc-wrapper.sh b/platforms/uefi/gcc-wrapper.sh index 93df9f09..c8f3f547 100755 --- a/platforms/uefi/gcc-wrapper.sh +++ b/platforms/uefi/gcc-wrapper.sh @@ -26,8 +26,8 @@ ARGS=("$@") OUTPUT_FILE="" NEXT_TYPE="unknown" -for arg in "${ARGS[@]}"; do - case "$arg" in +for ARG in "${ARGS[@]}"; do + case "$ARG" in -Wl,--version | -Wl,-v) change_mode "pass" ;; @@ -48,21 +48,21 @@ for arg in "${ARGS[@]}"; do ;; *) if [[ "$NEXT_TYPE" == "output" ]]; then - OUTPUT_FILE="$arg" + OUTPUT_FILE="$ARG" NEXT_TYPE="unknown" elif [[ "$NEXT_TYPE" == "ignore" ]]; then NEXT_TYPE="unknown" else - case "$arg" in + case "$ARG" in *.a | *.so) change_mode "link" - DEPENDENCIES+=("$arg") + DEPENDENCIES+=("$ARG") ;; *.o) - DEPENDENCIES+=("$arg") + DEPENDENCIES+=("$ARG") ;; *.c) - COMPILED+=("$arg") + COMPILED+=("$ARG") ;; *) ;; esac diff --git a/platforms/uefi/pkg-config-wrapper.sh b/platforms/uefi/pkg-config-wrapper.sh index 20f366e9..fdf590ad 100755 --- a/platforms/uefi/pkg-config-wrapper.sh +++ b/platforms/uefi/pkg-config-wrapper.sh @@ -17,7 +17,7 @@ LIBRARIES_FILE="$(realpath "$SCRIPT_DIR/../../src/executables/platforms/uefi/lib PKG_CONFIG="pkg-config" TOOL="PKG-CONFIG" -# Capture all args +# Capture all ARGs ARGS=("$@") MODE="unknown" @@ -40,8 +40,8 @@ WHAT="" PACKAGE_NAME="" NEXT_IS_PACKAGE_NAME="false" -for arg in "${ARGS[@]}"; do - case "$arg" in +for ARG in "${ARGS[@]}"; do + case "$ARG" in --version) change_mode "pass" ;; @@ -62,7 +62,7 @@ for arg in "${ARGS[@]}"; do ;; *) if [[ "$NEXT_IS_PACKAGE_NAME" == true ]]; then - PACKAGE_NAME="$arg" + PACKAGE_NAME="$ARG" NEXT_IS_PACKAGE_NAME=false fi ;; From dadb87edaee0984b6d5deac602452b017bf82428 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 1 Aug 2026 22:10:24 +0200 Subject: [PATCH 047/112] fix: fix more uefi wrapper script stuff --- platforms/build-uefi.sh | 3 ++- platforms/uefi/ar-wrapper.sh | 4 ++-- platforms/uefi/base.sh | 19 +++++++++++++++++++ platforms/uefi/extract-definitions.sh | 2 +- platforms/uefi/g++-wrapper.sh | 8 ++++---- platforms/uefi/gcc-wrapper.sh | 8 ++++---- 6 files changed, 32 insertions(+), 12 deletions(-) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index edcdf976..0deff07a 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -273,7 +273,8 @@ cat <"$EDK2_INFO_FILE" "build": "$EDK2_BUILD_COMMAND", "arch": "$EDK2_TARGET_PROPERTIES_ARCH", "workspace": "$WORKSPACE", - "platform": "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM", + "platform": "$WORKSPACE/$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM", + "platform_name": "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM", "buildtype": "$EDK2_TARGET_PROPERTIES_BUILDTYPE", "toolchain": "$EDK2_TARGET_PROPERTIES_TOOLCHAIN", "generated_packages": "$EDK2_GENERATED_PACKAGES" diff --git a/platforms/uefi/ar-wrapper.sh b/platforms/uefi/ar-wrapper.sh index cf4bac1c..4cb9730a 100755 --- a/platforms/uefi/ar-wrapper.sh +++ b/platforms/uefi/ar-wrapper.sh @@ -35,14 +35,14 @@ for ARG in "${ARGS[@]}"; do ;; *) if [[ "$NEXT_TYPE" == "output" ]]; then - OUTPUT_FILE="$ARG" + OUTPUT_FILE="$(normalize_file "$ARG")" NEXT_TYPE="unknown" elif [[ "$NEXT_TYPE" == "ignore" ]]; then NEXT_TYPE="unknown" else case "$ARG" in *.a | *.so | *.o) - DEPENDENCIES+=("$ARG") + DEPENDENCIES+=("$(resolve_file "$ARG")") ;; *) ;; esac diff --git a/platforms/uefi/base.sh b/platforms/uefi/base.sh index 80bb9f03..ac47d08d 100644 --- a/platforms/uefi/base.sh +++ b/platforms/uefi/base.sh @@ -41,3 +41,22 @@ to_json_array() { printf '%s\n' "${ARRAY[@]}" | jq -R . | jq -sc . fi } + +resolve_file() { + local FILE="$1" + + if ! [ -e "$FILE" ]; then + echo "<$TOOL> ${ARGS[*]}" >&2 + echo "Can't resolve file '$FILE': not found" >&2 + exit 6 + fi + + realpath "$FILE" + +} + +normalize_file() { + local FILE="$1" + + realpath "$FILE" +} diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 82a31ebb..f739db01 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -25,7 +25,7 @@ expand_array_inf() { if [ "$#" -eq 3 ]; then SOURCE_FILE="$1" - DEST_FILE="$2" + DEST_FILE="$(realpath "$2")" MAPPINGS_FILE="$3" else echo "Too many arguments given, expected 3" >&2 diff --git a/platforms/uefi/g++-wrapper.sh b/platforms/uefi/g++-wrapper.sh index 2674da61..e7f22f9a 100755 --- a/platforms/uefi/g++-wrapper.sh +++ b/platforms/uefi/g++-wrapper.sh @@ -48,7 +48,7 @@ for ARG in "${ARGS[@]}"; do ;; *) if [[ "$NEXT_TYPE" == "output" ]]; then - OUTPUT_FILE="$ARG" + OUTPUT_FILE="$(normalize_file "$ARG")" NEXT_TYPE="unknown" elif [[ "$NEXT_TYPE" == "ignore" ]]; then NEXT_TYPE="unknown" @@ -56,13 +56,13 @@ for ARG in "${ARGS[@]}"; do case "$ARG" in *.a | *.so) change_mode "link" - DEPENDENCIES+=("$ARG") + DEPENDENCIES+=("$(resolve_file "$ARG")") ;; *.o) - DEPENDENCIES+=("$ARG") + DEPENDENCIES+=("$(resolve_file "$ARG")") ;; *.cpp) - COMPILED+=("$ARG") + COMPILED+=("$(resolve_file "$ARG")") ;; *) ;; esac diff --git a/platforms/uefi/gcc-wrapper.sh b/platforms/uefi/gcc-wrapper.sh index c8f3f547..9657c0dd 100755 --- a/platforms/uefi/gcc-wrapper.sh +++ b/platforms/uefi/gcc-wrapper.sh @@ -48,7 +48,7 @@ for ARG in "${ARGS[@]}"; do ;; *) if [[ "$NEXT_TYPE" == "output" ]]; then - OUTPUT_FILE="$ARG" + OUTPUT_FILE="$(normalize_file "$ARG")" NEXT_TYPE="unknown" elif [[ "$NEXT_TYPE" == "ignore" ]]; then NEXT_TYPE="unknown" @@ -56,13 +56,13 @@ for ARG in "${ARGS[@]}"; do case "$ARG" in *.a | *.so) change_mode "link" - DEPENDENCIES+=("$ARG") + DEPENDENCIES+=("$(resolve_file "$ARG")") ;; *.o) - DEPENDENCIES+=("$ARG") + DEPENDENCIES+=("$(resolve_file "$ARG")") ;; *.c) - COMPILED+=("$ARG") + COMPILED+=("$(resolve_file "$ARG")") ;; *) ;; esac From 54825b016d4dcc5f39aef16a1249d310dc5f87cf Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 1 Aug 2026 22:33:19 +0200 Subject: [PATCH 048/112] fix: get the version of the uefi packages in another way --- platforms/uefi/extract-definitions.sh | 30 +++++++++++++------ .../uefi/{mappings.json.in => mappings.json} | 9 +++--- src/executables/platforms/uefi/meson.build | 13 -------- 3 files changed, 25 insertions(+), 27 deletions(-) rename src/executables/platforms/uefi/{mappings.json.in => mappings.json} (84%) diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index f739db01..68c70da1 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -23,15 +23,31 @@ expand_array_inf() { } -if [ "$#" -eq 3 ]; then +set -x + +get_mapped_version() { + local INPUT="$1" + + MESON_INFO_FILE="$(pwd)/meson-info/intro-projectinfo.json" + + if [ "$INPUT" == "oopetris" ]; then + jq -M -r -c ".[\"version\"]" "$MESON_INFO_FILE" + else + jq -M -r -c ".[\"subprojects\"][] | select(.[\"name\"] == \"$INPUT\") | .[\"version\"] " "$MESON_INFO_FILE" + fi + +} + +if [ "$#" -eq 2 ]; then SOURCE_FILE="$1" DEST_FILE="$(realpath "$2")" - MAPPINGS_FILE="$3" else - echo "Too many arguments given, expected 3" >&2 + echo "Too many arguments given, expected 2" >&2 exit 1 fi +MAPPINGS_FILE="$(realpath "$SCRIPT_DIR/../../src/executables/platforms/uefi/mappings.json")" + DEST_FILE_DIR=$(dirname -- "$DEST_FILE") DEST_FILE_NAME=$(basename -- "$DEST_FILE") DEST_FILE_EXT="${DEST_FILE_NAME##*.}" @@ -73,12 +89,8 @@ link_package() { rm "$FINAL_FILE" fi - set -x - ln -s "$SOURCE_FILE" "$FINAL_FILE" - set +x - } DEP_SOURCES=() @@ -126,7 +138,7 @@ for FILE_DEPENDENCY in "${FILE_DEPENDENCIES[@]}"; do DEP_OUTPUT_FILE="$DEST_FILE_DIR/$MAPPING_ENTRY_DEP_NAME.inf" if ! [ -e "$DEP_OUTPUT_FILE" ]; then - "$SCRIPT_DIR/extract-definitions.sh" "$FILE_DEPENDENCY" "$DEP_OUTPUT_FILE" "$MAPPINGS_FILE" + "$SCRIPT_DIR/extract-definitions.sh" "$FILE_DEPENDENCY" "$DEP_OUTPUT_FILE" fi DEP_PACKAGES+=("$PACKAGE_NAME") @@ -142,7 +154,7 @@ validate_parent_dir "$DEST_FILE" MAPPING_TYPE="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"type\"]")" MAPPING_NAME="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"name\"]")" MAPPING_GUID="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"guid\"]")" -MAPPING_VERSION="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"version\"]")" +MAPPING_VERSION="$(get_mapped_version "$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"version\"]")")" if [ "$MAPPING_TYPE" == "application" ]; then diff --git a/src/executables/platforms/uefi/mappings.json.in b/src/executables/platforms/uefi/mappings.json similarity index 84% rename from src/executables/platforms/uefi/mappings.json.in rename to src/executables/platforms/uefi/mappings.json index 5607a92a..3ee80877 100644 --- a/src/executables/platforms/uefi/mappings.json.in +++ b/src/executables/platforms/uefi/mappings.json @@ -4,28 +4,27 @@ "type": "application", "name": "OOPetrisApplication", "guid": "da6e059f-d6bd-4136-8f1b-b19c9062f3cd", - "version": "@OOPETRIS_VERSION@" + "version": "oopetris" }, "OOPetrisCorePkg": { "type": "library", "name": "OOPetrisCoreLib", "lib": "LibOOPetrisCore", "guid": "022bf605-571b-4d01-aeb5-e587e0045d6a", - "version": "@OOPETRIS_VERSION@" + "version": "oopetris" }, "OOPetrisGraphicsPkg": { "type": "library", "name": "OOPetrisGraphicsLib", "lib": "LibOOPetrisGraphics", "guid": "0bfc59b5-090c-4cd0-a0b7-498dcbed1e6e", - "version": "@OOPETRIS_VERSION@" + "version": "oopetris" }, "SDL2TTFPkg": { "type": "library", "name": "SDL2TTFLib", "lib": "LibSDL2TTF", - "guid": "2252bce8-bee1-4ab8-9896-2ab58576e9db", - "version": "@SDL2_TTF_VERSION@" + "guid": "2252bce8-bee1-4ab8-9896-2ab58576e9db" } }, "name": { diff --git a/src/executables/platforms/uefi/meson.build b/src/executables/platforms/uefi/meson.build index 79c2b5fd..76fc68a8 100644 --- a/src/executables/platforms/uefi/meson.build +++ b/src/executables/platforms/uefi/meson.build @@ -16,18 +16,6 @@ _uefi_final_description = executable( }, ) -_uefi_mappings_conf = configuration_data( - { - 'OOPETRIS_VERSION': meson.project_version(), - } -) - -_uefi_mappings_file = configure_file( - input: 'mappings.json.in', - output: 'mappings.json', - configuration: _uefi_mappings_conf, -) - _uefi_extract_defs_exe = find_program( 'extract-definitions.sh', dirs: [meson.project_source_root() / 'platforms' / 'uefi'], @@ -40,7 +28,6 @@ _uefi_extract_defs = custom_target( _uefi_extract_defs_exe, _uefi_final_description, '@OUTPUT@', - _uefi_mappings_file, ], depends: [_uefi_final_description], output: ['OOPetrisPkg.inf'], From ff964071dc0c86ffa52d4a95f1f334be12e4ac01 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 1 Aug 2026 22:40:01 +0200 Subject: [PATCH 049/112] feat: more uefi progress --- platforms/build-uefi.sh | 2 -- platforms/uefi/extract-definitions.sh | 2 -- src/executables/platforms/uefi/mappings.json | 25 ++++++++++++++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 0deff07a..83a73933 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -152,8 +152,6 @@ export EDK2_BUILD_COMMAND="$EDK2_POSIX_BIN_PATH/build" # add links to needed packages -set -x - EDK2_LIB_PACKAGES=("StdLib" "StdLibPrivateInternalFiles") for EDK2_LIB_PACKAGE in "${EDK2_LIB_PACKAGES[@]}"; do diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 68c70da1..413ae543 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -23,8 +23,6 @@ expand_array_inf() { } -set -x - get_mapped_version() { local INPUT="$1" diff --git a/src/executables/platforms/uefi/mappings.json b/src/executables/platforms/uefi/mappings.json index 3ee80877..99f99945 100644 --- a/src/executables/platforms/uefi/mappings.json +++ b/src/executables/platforms/uefi/mappings.json @@ -20,11 +20,36 @@ "guid": "0bfc59b5-090c-4cd0-a0b7-498dcbed1e6e", "version": "oopetris" }, + "OOPetrisRecordingsPkg": { + "type": "library", + "name": "OOPetrisRecordingsLib", + "lib": "LibOOPetrisRecordings", + "guid": "84b90385-bd32-41e3-ba8d-ba4a056d72f5", + "version": "oopetris" + }, "SDL2TTFPkg": { "type": "library", "name": "SDL2TTFLib", "lib": "LibSDL2TTF", "guid": "2252bce8-bee1-4ab8-9896-2ab58576e9db" + }, + "FreetypePkg": { + "type": "library", + "name": "FreetypeLib", + "lib": "LibFreetype", + "guid": "d6ea8d4f-c8e7-4a8c-988d-e316100b0742" + }, + "ZLibPkg": { + "type": "library", + "name": "ZLib", + "lib": "LibZ", + "guid": "cc61c805-2419-4b68-b806-495d11be162c" + }, + "SpdlogPkg": { + "type": "library", + "name": "SpdlogLib", + "lib": "LibSpdlog", + "guid": "dee047db-15c9-4d79-ab08-79d6244d9b0e" } }, "name": { From fb8b26c39221cd4a5bdaf7b44648ad8c73ce1497 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 1 Aug 2026 23:11:58 +0200 Subject: [PATCH 050/112] fix: add more uefi fixes --- platforms/build-uefi.sh | 7 ----- platforms/uefi/compile-final.sh | 33 ++++++++++++++++++++ platforms/uefi/extract-definitions.sh | 29 ++++++++++++++++- src/executables/platforms/uefi/mappings.json | 12 ++++--- 4 files changed, 69 insertions(+), 12 deletions(-) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 83a73933..c4557c03 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -279,13 +279,6 @@ cat <"$EDK2_INFO_FILE" } EOF -# "$EDK2_BUILD_COMMAND" -a "$EDK2_TARGET_PROPERTIES_ARCH" \ -# -p "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" \ -# -m "$WORKSPACE/CustomPkg/HelloWorld.inf" \ -# -b "$EDK2_TARGET_PROPERTIES_BUILDTYPE" \ -# -t "$EDK2_TARGET_PROPERTIES_TOOLCHAIN" \ -# -w \ -# -v if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "$BUILD_DIR" ]; then diff --git a/platforms/uefi/compile-final.sh b/platforms/uefi/compile-final.sh index cb97f75b..7713bb3d 100755 --- a/platforms/uefi/compile-final.sh +++ b/platforms/uefi/compile-final.sh @@ -7,4 +7,37 @@ set -u # fails if any part of a pipeline (|) fails set -o pipefail +SCRIPT_DIR="$(realpath "$(dirname -- "${BASH_SOURCE[0]}")")" + +# shellcheck source=./platforms/helper.sh +source "$SCRIPT_DIR/../helper.sh" + +if [ "$#" -eq 2 ]; then + BUILD_INF="$(realpath "$1")" + DEST_FILE="$(realpath "$2")" +else + echo "Too many arguments given, expected 2" >&2 + exit 1 +fi + +UEFI_INFO_FILE="$(realpath "$SCRIPT_DIR/../crossbuild/uefi_info.json")" +EDK2_BUILD_COMMAND="$(jq -M -r -c '.["build"]' "$UEFI_INFO_FILE")" +EDK2_TARGET_PROPERTIES_ARCH="$(jq -M -r -c '.["arch"]' "$UEFI_INFO_FILE")" +WORKSPACE="$(jq -M -r -c '.["workspace"]' "$UEFI_INFO_FILE")" +EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM="$(jq -M -r -c '.["platform"]' "$UEFI_INFO_FILE")" +EDK2_TARGET_PROPERTIES_BUILDTYPE="$(jq -M -r -c '.["buildtype"]' "$UEFI_INFO_FILE")" +EDK2_TARGET_PROPERTIES_TOOLCHAIN="$(jq -M -r -c '.["toolchain"]' "$UEFI_INFO_FILE")" + +"$EDK2_BUILD_COMMAND" -a "$EDK2_TARGET_PROPERTIES_ARCH" \ + -p "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" \ + -m "$BUILD_INF" \ + -b "$EDK2_TARGET_PROPERTIES_BUILDTYPE" \ + -t "$EDK2_TARGET_PROPERTIES_TOOLCHAIN" \ + -w # -v # verbose + +OUTPUT_FILE="TODO" + +# link the output .efi to the correct location + +echo "TODO" exit 45 diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 413ae543..f9c742bf 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -30,6 +30,9 @@ get_mapped_version() { if [ "$INPUT" == "oopetris" ]; then jq -M -r -c ".[\"version\"]" "$MESON_INFO_FILE" + elif [ "$INPUT" == "null" ]; then + echo "Error: invalid version argument: $INPUT" >&2 + exit 2 else jq -M -r -c ".[\"subprojects\"][] | select(.[\"name\"] == \"$INPUT\") | .[\"version\"] " "$MESON_INFO_FILE" fi @@ -76,6 +79,21 @@ mapfile -t FILE_DEPENDENCIES < <(jq '.["dependencies"]["files"][]' -M -r -c "$SO UEFI_INFO_FILE="$(realpath "$SCRIPT_DIR/../crossbuild/uefi_info.json")" UEFI_INFO_GENERATED_PACKAGES_DIR="$(jq -M -r -c '.["generated_packages"]' "$UEFI_INFO_FILE")" +EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM="$(jq -M -r -c '.["platform"]' "$UEFI_INFO_FILE")" + +add_component_to_platform() { + local PACKAGE_NAME="$1" + + local FINAL_PKG_NAME="GeneratedPackages/$PACKAGE_NAME" + + if grep -q "$FINAL_PKG_NAME" "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM"; then + : # found already, do nothing + else + echo "[Components]" >>"$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" + echo " $FINAL_PKG_NAME" >>"$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" + fi + +} link_package() { local PACKAGE_NAME="$1" @@ -89,6 +107,8 @@ link_package() { ln -s "$SOURCE_FILE" "$FINAL_FILE" + add_component_to_platform "$PACKAGE_NAME" + } DEP_SOURCES=() @@ -132,6 +152,7 @@ for FILE_DEPENDENCY in "${FILE_DEPENDENCIES[@]}"; do fi PACKAGE_NAME="GeneratedPackages/$MAPPING_ENTRY_DEP_NAME.inf" + PACKAGE_NAME_DEC="GeneratedPackages/$MAPPING_ENTRY_DEP_NAME.dec" DEP_OUTPUT_FILE="$DEST_FILE_DIR/$MAPPING_ENTRY_DEP_NAME.inf" @@ -139,7 +160,7 @@ for FILE_DEPENDENCY in "${FILE_DEPENDENCIES[@]}"; do "$SCRIPT_DIR/extract-definitions.sh" "$FILE_DEPENDENCY" "$DEP_OUTPUT_FILE" fi - DEP_PACKAGES+=("$PACKAGE_NAME") + DEP_PACKAGES+=("$PACKAGE_NAME_DEC") else echo "Error: invalid source file type: $FILE_DEPENDENCY_TYPE" >&2 exit 2 @@ -154,6 +175,12 @@ MAPPING_NAME="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"name\"]")" MAPPING_GUID="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"guid\"]")" MAPPING_VERSION="$(get_mapped_version "$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"version\"]")")" +if [ -z "$MAPPING_VERSION" ]; then + echo "Error: invalid version extracted '$MAPPING_NAME': $MAPPING_VERSION" >&2 + exit 2 + +fi + if [ "$MAPPING_TYPE" == "application" ]; then cat <"$DEST_FILE" diff --git a/src/executables/platforms/uefi/mappings.json b/src/executables/platforms/uefi/mappings.json index 99f99945..270c3fd5 100644 --- a/src/executables/platforms/uefi/mappings.json +++ b/src/executables/platforms/uefi/mappings.json @@ -31,25 +31,29 @@ "type": "library", "name": "SDL2TTFLib", "lib": "LibSDL2TTF", - "guid": "2252bce8-bee1-4ab8-9896-2ab58576e9db" + "guid": "2252bce8-bee1-4ab8-9896-2ab58576e9db", + "version": "sdl2_ttf" }, "FreetypePkg": { "type": "library", "name": "FreetypeLib", "lib": "LibFreetype", - "guid": "d6ea8d4f-c8e7-4a8c-988d-e316100b0742" + "guid": "d6ea8d4f-c8e7-4a8c-988d-e316100b0742", + "version": "freetype2" }, "ZLibPkg": { "type": "library", "name": "ZLib", "lib": "LibZ", - "guid": "cc61c805-2419-4b68-b806-495d11be162c" + "guid": "cc61c805-2419-4b68-b806-495d11be162c", + "version": "zlib" }, "SpdlogPkg": { "type": "library", "name": "SpdlogLib", "lib": "LibSpdlog", - "guid": "dee047db-15c9-4d79-ab08-79d6244d9b0e" + "guid": "dee047db-15c9-4d79-ab08-79d6244d9b0e", + "version": "spdlog" } }, "name": { From b67929d89b46314211de29507ad9544dcf8bae89 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 1 Aug 2026 23:34:37 +0200 Subject: [PATCH 051/112] fix: fix some uefi generation issues --- platforms/uefi/extract-definitions.sh | 59 ++++++++++++++++++++------- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index f9c742bf..4c945747 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -105,15 +105,27 @@ link_package() { rm "$FINAL_FILE" fi + validate_parent_dir "$FINAL_FILE" + ln -s "$SOURCE_FILE" "$FINAL_FILE" - add_component_to_platform "$PACKAGE_NAME" + local SOURCE_FILE_EXT="${SOURCE_FILE##*.}" + + if [ "$SOURCE_FILE_EXT" == "inf" ]; then + add_component_to_platform "$PACKAGE_NAME" + elif [ "$SOURCE_FILE_EXT" == "dec" ]; then + : + else + echo "Invalid package extension in link_package '$SOURCE_FILE_EXT'" >&2 + exit 2 + fi } DEP_SOURCES=() DEP_PACKAGES=() DEP_BUILD_OPTIONS=() +DEP_INCLUDES=() for FILE_DEPENDENCY in "${FILE_DEPENDENCIES[@]}"; do @@ -151,8 +163,7 @@ for FILE_DEPENDENCY in "${FILE_DEPENDENCIES[@]}"; do exit 2 fi - PACKAGE_NAME="GeneratedPackages/$MAPPING_ENTRY_DEP_NAME.inf" - PACKAGE_NAME_DEC="GeneratedPackages/$MAPPING_ENTRY_DEP_NAME.dec" + PACKAGE_NAME="GeneratedPackages/Lib/$MAPPING_ENTRY_DEP_NAME.dec" DEP_OUTPUT_FILE="$DEST_FILE_DIR/$MAPPING_ENTRY_DEP_NAME.inf" @@ -160,7 +171,7 @@ for FILE_DEPENDENCY in "${FILE_DEPENDENCIES[@]}"; do "$SCRIPT_DIR/extract-definitions.sh" "$FILE_DEPENDENCY" "$DEP_OUTPUT_FILE" fi - DEP_PACKAGES+=("$PACKAGE_NAME_DEC") + DEP_PACKAGES+=("$PACKAGE_NAME") else echo "Error: invalid source file type: $FILE_DEPENDENCY_TYPE" >&2 exit 2 @@ -168,8 +179,6 @@ for FILE_DEPENDENCY in "${FILE_DEPENDENCIES[@]}"; do done -validate_parent_dir "$DEST_FILE" - MAPPING_TYPE="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"type\"]")" MAPPING_NAME="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"name\"]")" MAPPING_GUID="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"guid\"]")" @@ -183,6 +192,8 @@ fi if [ "$MAPPING_TYPE" == "application" ]; then + validate_parent_dir "$DEST_FILE" + cat <"$DEST_FILE" [Defines] INF_VERSION = 1.25 @@ -217,11 +228,19 @@ $(expand_array_inf "${DEP_PACKAGES[@]}") $(expand_array_inf "${DEP_BUILD_OPTIONS[@]}") EOF + link_package "$DEST_FILE_NAME" "$DEST_FILE" + elif [ "$MAPPING_TYPE" == "library" ]; then MAPPING_LIB_NAME="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"lib\"]")" - cat <"$DEST_FILE" + LIB_DEST_DIR="$DEST_FILE_DIR/Lib" + + validate_parent_dir "$LIB_DEST_DIR/dummy" + + LIB_DEST_FILE_INF="$LIB_DEST_DIR/$DEST_FILE_STEM.inf" + + cat <"$LIB_DEST_FILE_INF" [Defines] INF_VERSION = 1.25 BASE_NAME = $MAPPING_NAME @@ -240,22 +259,32 @@ $(expand_array_inf "${DEP_PACKAGES[@]}") [LibraryClasses] UefiLib -[Guids] +[BuildOptions] +$(expand_array_inf "${DEP_BUILD_OPTIONS[@]}") +EOF -[Ppis] + link_package "Lib/$DEST_FILE_STEM.inf" "$LIB_DEST_FILE_INF" -[Protocols] + LIB_DEST_FILE_DEC="$LIB_DEST_DIR/$DEST_FILE_STEM.dec" -[FeaturePcd] + cat <"$LIB_DEST_FILE_DEC" +[Defines] + DEC_SPECIFICATION = 1.25 + PACKAGE_NAME = $MAPPING_NAME + PACKAGE_GUID = $MAPPING_GUID + PACKAGE_VERSION = $MAPPING_VERSION -[Pcd] +[Includes] +$(expand_array_inf "${DEP_INCLUDES[@]}") -[BuildOptions] +[LibraryClasses] + ##TODO $(expand_array_inf "${DEP_BUILD_OPTIONS[@]}") EOF + + link_package "Lib/$DEST_FILE_STEM.dec" "$LIB_DEST_FILE_DEC" + else echo "Error: invalid mapping type: $MAPPING_TYPE" >&2 exit 2 fi - -link_package "$DEST_FILE_NAME" "$DEST_FILE" From ad5f2ba299e2f5a8fa800664df78dcef7a9c715d Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 1 Aug 2026 23:42:05 +0200 Subject: [PATCH 052/112] fix: more uefi fixes --- platforms/uefi/compile-final.sh | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/platforms/uefi/compile-final.sh b/platforms/uefi/compile-final.sh index 7713bb3d..a0c69bc2 100755 --- a/platforms/uefi/compile-final.sh +++ b/platforms/uefi/compile-final.sh @@ -28,9 +28,30 @@ EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM="$(jq -M -r -c '.["platform"]' "$UEFI_INF EDK2_TARGET_PROPERTIES_BUILDTYPE="$(jq -M -r -c '.["buildtype"]' "$UEFI_INFO_FILE")" EDK2_TARGET_PROPERTIES_TOOLCHAIN="$(jq -M -r -c '.["toolchain"]' "$UEFI_INFO_FILE")" +BUILD_NAME=$(basename -- $"$BUILD_INF") + +BUILD_FILE_TARGET="GeneratedPackages/$BUILD_NAME" + +BUILD_FILE_TARGET_ABS="$WORKSPACE/$BUILD_FILE_TARGET" + +if ! [ -e "$BUILD_FILE_TARGET_ABS" ]; then + echo "Build file is not in the workspace: $BUILD_FILE_TARGET" >&2 + exit 2 +elif ! readlink "$BUILD_FILE_TARGET_ABS"; then + echo "Build file is not a symlink: $BUILD_FILE_TARGET_ABS" >&2 + exit 2 +else + BUILD_TARGET_LINK_TARGET="$(readlink "$BUILD_FILE_TARGET_ABS")" + + if [ "$BUILD_TARGET_LINK_TARGET" != "$BUILD_INF" ]; then + echo "Build file isn't linked correctly: '$BUILD_TARGET_LINK_TARGET' != '$BUILD_INF'" >&2 + exit 2 + fi +fi + "$EDK2_BUILD_COMMAND" -a "$EDK2_TARGET_PROPERTIES_ARCH" \ -p "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" \ - -m "$BUILD_INF" \ + -m "$BUILD_FILE_TARGET" \ -b "$EDK2_TARGET_PROPERTIES_BUILDTYPE" \ -t "$EDK2_TARGET_PROPERTIES_TOOLCHAIN" \ -w # -v # verbose From d8857eac25b05fb5ee803ee18db05799238f6480 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sun, 2 Aug 2026 00:28:15 +0200 Subject: [PATCH 053/112] feat: add correct flags for uefi compilation in the cross file --- platforms/build-uefi.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index c4557c03..5604bf47 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -192,7 +192,7 @@ export ENDIANESS="little" export ROMFS="platforms/romfs" -export COMMON_FLAGS="'-fexceptions', '-pthread'" +export COMMON_FLAGS="'-fexceptions', '-pthread', '-fshort-wchar', '-fno-builtin', '-fno-strict-aliasing', '-fno-common', '-fstack-protector', '-ffunction-sections', '-fdata-sections', '-m64', '-DEFIAPI=__attribute__((ms_abi))', '-maccumulate-outgoing-args', '-mno-red-zone', '-mcmodel=small', '-fno-asynchronous-unwind-tables', '-fno-omit-frame-pointer'" export LINK_FLAGS="$COMMON_FLAGS" export COMPILE_FLAGS="$COMMON_FLAGS ,'-DAUDIO_PREFER_MP3'" @@ -279,7 +279,6 @@ cat <"$EDK2_INFO_FILE" } EOF - if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "$BUILD_DIR" ]; then meson setup "$BUILD_DIR" \ From 8cae03cac0317490448672236ec0a4bb1faed9bf Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sun, 2 Aug 2026 00:36:48 +0200 Subject: [PATCH 054/112] feat: add include detection for the uefi generators and wrappers --- platforms/uefi/extract-definitions.sh | 66 ++++++++++++++++++-- src/executables/platforms/uefi/mappings.json | 24 ++++--- 2 files changed, 78 insertions(+), 12 deletions(-) diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 4c945747..80fd2822 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -26,15 +26,15 @@ expand_array_inf() { get_mapped_version() { local INPUT="$1" - MESON_INFO_FILE="$(pwd)/meson-info/intro-projectinfo.json" + MESON_PROJECT_INFO_FILE="$(pwd)/meson-info/intro-projectinfo.json" if [ "$INPUT" == "oopetris" ]; then - jq -M -r -c ".[\"version\"]" "$MESON_INFO_FILE" + jq -M -r -c ".[\"version\"]" "$MESON_PROJECT_INFO_FILE" elif [ "$INPUT" == "null" ]; then echo "Error: invalid version argument: $INPUT" >&2 exit 2 else - jq -M -r -c ".[\"subprojects\"][] | select(.[\"name\"] == \"$INPUT\") | .[\"version\"] " "$MESON_INFO_FILE" + jq -M -r -c ".[\"subprojects\"][] | select(.[\"name\"] == \"$INPUT\") | .[\"version\"]" "$MESON_PROJECT_INFO_FILE" fi } @@ -125,7 +125,6 @@ link_package() { DEP_SOURCES=() DEP_PACKAGES=() DEP_BUILD_OPTIONS=() -DEP_INCLUDES=() for FILE_DEPENDENCY in "${FILE_DEPENDENCIES[@]}"; do @@ -179,6 +178,64 @@ for FILE_DEPENDENCY in "${FILE_DEPENDENCIES[@]}"; do done +DEP_INCLUDES=() + +MESON_TARGETS_INFO_FILE="$(pwd)/meson-info/intro-targets.json" + +SOURCE_FILE_OUTPUT="$(jq -M -r -c '.["dependencies"]["output"]' "$SOURCE_FILE")" + +if [ "$SOURCE_FILE_OUTPUT" = "null" ]; then + echo "Error: output '$SOURCE_FILE_OUTPUT'" >&2 + exit 2 +fi + +SOURCE_FILE_OUTPUT_NAME=$(basename -- "$SOURCE_FILE_OUTPUT") +SOURCE_FILE_OUTPUT_STEM="${SOURCE_FILE_OUTPUT_NAME%.*}" + +SOURCE_FILE_ENTRY="$(jq -M -r -c ".[\"name\"][\"${SOURCE_FILE_OUTPUT_STEM}\"]" "$MAPPINGS_FILE")" + +if [ "$SOURCE_FILE_ENTRY" = "null" ]; then + echo "Error: invalid name '$SOURCE_FILE_OUTPUT_STEM': not found in mappings 'name'" >&2 + exit 2 +fi + +SOURCE_FILE_ENTRY_MESON_NAME="$(echo "$SOURCE_FILE_ENTRY" | jq -M -r -c ".[\"meson\"]")" + +if [ "$SOURCE_FILE_ENTRY_MESON_NAME" = "null" ]; then + echo "Error: invalid name '$SOURCE_FILE_ENTRY_MESON_NAME': not found in dependency mapping 'meson'" >&2 + exit 2 +fi + +MESON_TARGETS_INFO_LIB="$( + jq -M -r -c ".[] | select(.[\"name\"] == \"$SOURCE_FILE_ENTRY_MESON_NAME\")" "$MESON_TARGETS_INFO_FILE" +)" + +if [ "$MESON_TARGETS_INFO_LIB" = "null" ]; then + echo "Error: invalid name '$SOURCE_FILE_ENTRY_MESON_NAME': not found in meson targets file'" >&2 + exit 2 +fi + +MESON_TARGETS_INFO_LIB_TYPE="$(echo "$MESON_TARGETS_INFO_LIB" | jq -M -r -c ".[\"type\"]")" + +if [ "$MESON_TARGETS_INFO_LIB_TYPE" == "static library" ] || [ "$MESON_TARGETS_INFO_LIB_TYPE" == "executable" ]; then + : +else + echo "Error: invalid meson target type: $MESON_TARGETS_INFO_LIB_TYPE" >&2 + exit 2 +fi + +mapfile -t MESON_TARGETS_INFO_LIB_PARAMATERS < <(echo "$MESON_TARGETS_INFO_LIB" | jq '.["target_sources"][] | select( has("compiler") ) | .["parameters"][]' -M -r -c) + +for MESON_TARGETS_INFO_LIB_PARAMATER in "${MESON_TARGETS_INFO_LIB_PARAMATERS[@]}"; do + + case "$MESON_TARGETS_INFO_LIB_PARAMATER" in + -I*) + DEP_INCLUDES+=("${MESON_TARGETS_INFO_LIB_PARAMATER:2}") + ;; + *) ;; + esac +done + MAPPING_TYPE="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"type\"]")" MAPPING_NAME="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"name\"]")" MAPPING_GUID="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"guid\"]")" @@ -279,7 +336,6 @@ $(expand_array_inf "${DEP_INCLUDES[@]}") [LibraryClasses] ##TODO -$(expand_array_inf "${DEP_BUILD_OPTIONS[@]}") EOF link_package "Lib/$DEST_FILE_STEM.dec" "$LIB_DEST_FILE_DEC" diff --git a/src/executables/platforms/uefi/mappings.json b/src/executables/platforms/uefi/mappings.json index 270c3fd5..ef9bea72 100644 --- a/src/executables/platforms/uefi/mappings.json +++ b/src/executables/platforms/uefi/mappings.json @@ -58,25 +58,35 @@ }, "name": { "liboopetris_graphics": { - "name": "OOPetrisGraphicsPkg" + "name": "OOPetrisGraphicsPkg", + "meson": "oopetris_graphics" }, "liboopetris_recordings": { - "name": "OOPetrisRecordingsPkg" + "name": "OOPetrisRecordingsPkg", + "meson": "oopetris_recordings" }, "liboopetris_core": { - "name": "OOPetrisCorePkg" + "name": "OOPetrisCorePkg", + "meson": "oopetris_core" }, "libsdl2_ttf": { - "name": "SDL2TTFPkg" + "name": "SDL2TTFPkg", + "meson": "sdl2_ttf" }, "libfreetype": { - "name": "FreetypePkg" + "name": "FreetypePkg", + "meson": "freetype" }, "libz": { - "name": "ZLibPkg" + "name": "ZLibPkg", + "meson": "z" }, "libspdlog": { - "name": "SpdlogPkg" + "name": "SpdlogPkg", + "meson": "spdlog" + }, + "oopetris": { + "meson": "oopetris" } } } From 929f321845d90f56fa0154e10c83af726c869c02 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sun, 2 Aug 2026 01:13:28 +0200 Subject: [PATCH 055/112] fix: fix some uefi c++ compiler errors --- platforms/build-uefi.sh | 28 ++++++++++++++++++++++----- platforms/uefi/cxx_compiler.diff | 21 ++++++++++++++++++++ platforms/uefi/extract-definitions.sh | 12 ++++++++++++ src/libs/core/helper/utils.hpp | 7 +++++++ 4 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 platforms/uefi/cxx_compiler.diff diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 5604bf47..403b0dc6 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -108,6 +108,20 @@ git -C "$EDK2_LIBC_ROOT" checkout "$EDK2_LIBC_COMMIT_HASH" export EDK_TOOLS_PATH="$EDK2_ROOT/BaseTools" export PACKAGES_PATH="$EDK2_ROOT" +EDK2_PATCH_FILE="$EDK2_ROOT/.patched_manually.meta" + +PATCH_DIR="platforms/uefi" + +if ! [ -e "$EDK2_PATCH_FILE" ]; then + ##TODO: upstream those patches + # see: https://github.com/emscripten-core/emscripten/pull/18379 + # and: https://github.com/emscripten-core/emscripten/pull/22946 + + git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/cxx_compiler.diff" + + touch "$EDK2_PATCH_FILE" +fi + pushd "$EDK2_ROOT" make -C BaseTools @@ -177,8 +191,12 @@ popd export PKG_CONFIG_PATH="$EDK2_ROOT/lib/pkgconfig" -export CC="$SCRIPT_DIR/uefi/gcc-wrapper.sh" -export CXX="$SCRIPT_DIR/uefi/g++-wrapper.sh" +export CC_WRAPPER="$SCRIPT_DIR/uefi/gcc-wrapper.sh" +export CXX_WRAPPER="$SCRIPT_DIR/uefi/g++-wrapper.sh" + +export CC="gcc-15" +export CXX="g++-15" + export AR="$SCRIPT_DIR/uefi/ar-wrapper.sh" export RANLIB="" export STRIP="" @@ -195,7 +213,7 @@ export ROMFS="platforms/romfs" export COMMON_FLAGS="'-fexceptions', '-pthread', '-fshort-wchar', '-fno-builtin', '-fno-strict-aliasing', '-fno-common', '-fstack-protector', '-ffunction-sections', '-fdata-sections', '-m64', '-DEFIAPI=__attribute__((ms_abi))', '-maccumulate-outgoing-args', '-mno-red-zone', '-mcmodel=small', '-fno-asynchronous-unwind-tables', '-fno-omit-frame-pointer'" export LINK_FLAGS="$COMMON_FLAGS" -export COMPILE_FLAGS="$COMMON_FLAGS ,'-DAUDIO_PREFER_MP3'" +export COMPILE_FLAGS="$COMMON_FLAGS ,'-D__UEFI__', '-DAUDIO_PREFER_MP3'" export CROSS_FILE="./platforms/crossbuild/uefi.ini" @@ -218,8 +236,8 @@ endian = '$ENDIANESS' edk2_root = '$EDK2_ROOT' [binaries] -c = '$CC' -cpp = '$CXX' +c = '$CC_WRAPPER' +cpp = '$CXX_WRAPPER' ar = '$AR' ranlib = '$RANLIB' strip = '$STRIP' diff --git a/platforms/uefi/cxx_compiler.diff b/platforms/uefi/cxx_compiler.diff new file mode 100644 index 00000000..4e46f91d --- /dev/null +++ b/platforms/uefi/cxx_compiler.diff @@ -0,0 +1,21 @@ +diff --git a/BaseTools/Conf/build_rule.template b/BaseTools/Conf/build_rule.template +index 0c454ee3d5..4b9d63e912 100755 +--- a/BaseTools/Conf/build_rule.template ++++ b/BaseTools/Conf/build_rule.template +@@ -144,13 +144,13 @@ + $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj + + +- "$(CC)" /Fo${dst} $(DEPS_FLAGS) $(CC_FLAGS) $(CXX_FLAGS) $(INC) ${src} ++ "$(CXX)" /Fo${dst} $(DEPS_FLAGS) $(CXX_FLAGS) $(INC) ${src} + + +- "$(CC)" $(DEPS_FLAGS) $(CC_FLAGS) $(CXX_FLAGS) -c -o ${dst} $(INC) ${src} ++ "$(CXX)" $(DEPS_FLAGS) $(CXX_FLAGS) -c -o ${dst} $(INC) ${src} + + +- "$(CC)" $(DEPS_FLAGS) $(CC_FLAGS) $(CXX_FLAGS) -o ${dst} $(INC) ${src} ++ "$(CXX)" $(DEPS_FLAGS) $(CXX_FLAGS) -o ${dst} $(INC) ${src} + + [C-Code-File.BASE.AARCH64,C-Code-File.SEC.AARCH64,C-Code-File.PEI_CORE.AARCH64,C-Code-File.PEIM.AARCH64] + diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 80fd2822..443d5ffc 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -282,6 +282,11 @@ $(expand_array_inf "${DEP_PACKAGES[@]}") [Pcd] [BuildOptions] + *_*_*_CC_FLAGS = -D__UEFI__ + + *_*_*_CC_FLAGS = -std=c11 + *_*_*_CXX_FLAGS = -std=c++23 + $(expand_array_inf "${DEP_BUILD_OPTIONS[@]}") EOF @@ -317,6 +322,13 @@ $(expand_array_inf "${DEP_PACKAGES[@]}") UefiLib [BuildOptions] +[BuildOptions] + *_*_*_CC_FLAGS = -D__UEFI__ + + *_*_*_CC_FLAGS = -std=c11 + *_*_*_CXX_FLAGS = -std=c++23 + +$(expand_array_inf "${DEP_BUILD_OPTIONS[@]}") $(expand_array_inf "${DEP_BUILD_OPTIONS[@]}") EOF diff --git a/src/libs/core/helper/utils.hpp b/src/libs/core/helper/utils.hpp index a2289f5c..6895009e 100644 --- a/src/libs/core/helper/utils.hpp +++ b/src/libs/core/helper/utils.hpp @@ -129,6 +129,13 @@ namespace utils { #define UNUSED(x) (void(x)) // NOLINT(cppcoreguidelines-macro-usage) + +#if defined(__UEFI__) +#ifdef UNREACHABLE +#undef UNREACHABLE +#endif +#endif + #if !defined(NDEBUG) #define UNREACHABLE() /* NOLINT(cppcoreguidelines-macro-usage)*/ \ do { /* NOLINT(cppcoreguidelines-avoid-do-while)*/ \ From 70494f10af36a1d752606a1bb51d420e01574df7 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sun, 2 Aug 2026 02:22:27 +0200 Subject: [PATCH 056/112] fix: fix build dir linksin uefi wrapper --- platforms/build-uefi.sh | 12 ++++++------ platforms/helper.sh | 21 +++++++++++++++++++++ platforms/uefi/extract-definitions.sh | 2 +- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 403b0dc6..3bd0142e 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -122,6 +122,10 @@ if ! [ -e "$EDK2_PATCH_FILE" ]; then touch "$EDK2_PATCH_FILE" fi +export BUILD_DIR="build/uefi" + +export BUILD_DIR_ABS="$(pwd)/$BUILD_DIR" + pushd "$EDK2_ROOT" make -C BaseTools @@ -171,20 +175,16 @@ EDK2_LIB_PACKAGES=("StdLib" "StdLibPrivateInternalFiles") for EDK2_LIB_PACKAGE in "${EDK2_LIB_PACKAGES[@]}"; do if ! [ -e "$WORKSPACE/$EDK2_LIB_PACKAGE" ]; then - ln -s "$EDK2_LIBC_ROOT/$EDK2_LIB_PACKAGE" "$WORKSPACE/$EDK2_LIB_PACKAGE" + link_files_checked "$EDK2_LIBC_ROOT/$EDK2_LIB_PACKAGE" "$WORKSPACE/$EDK2_LIB_PACKAGE" fi done -export BUILD_DIR="build/uefi" - -export BUILD_DIR_ABS="$(pwd)/$BUILD_DIR" - export EDK2_GENERATED_PACKAGES="$BUILD_DIR_ABS/GeneratedPackages" if ! [ -e "$WORKSPACE/GeneratedPackages" ]; then mkdir -p "$EDK2_GENERATED_PACKAGES" - ln -s "$EDK2_GENERATED_PACKAGES" "$WORKSPACE/GeneratedPackages" + link_files_checked "$EDK2_GENERATED_PACKAGES" "$WORKSPACE/GeneratedPackages" fi popd diff --git a/platforms/helper.sh b/platforms/helper.sh index 26019a23..b22f462c 100755 --- a/platforms/helper.sh +++ b/platforms/helper.sh @@ -9,3 +9,24 @@ validate_parent_dir() { mkdir -p "$PARENT_DIR" fi } + +validate_abs() { + local FILE="$1" + + if [[ "${FILE:0:1}" != "/" ]]; then + echo "Not an absolute path: $FILE" >&2 + exit 7 + fi + +} + +link_files_checked() { + local SOURCE="$1" + local DEST="$2" + + validate_abs "$SOURCE" + validate_abs "$DEST" + + ln -s "$SOURCE" "$DEST" + +} diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 443d5ffc..3c4e98b1 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -107,7 +107,7 @@ link_package() { validate_parent_dir "$FINAL_FILE" - ln -s "$SOURCE_FILE" "$FINAL_FILE" + link_files_checked "$SOURCE_FILE" "$FINAL_FILE" local SOURCE_FILE_EXT="${SOURCE_FILE##*.}" From 82c465a6b90b03d959cd56e523bde4479f100b89 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Mon, 3 Aug 2026 13:51:35 +0200 Subject: [PATCH 057/112] fix: process more target options for uefi .inf generation - also add pkg-config found libraries - also add -D compile options --- platforms/uefi/extract-definitions.sh | 14 ++++++++------ platforms/uefi/pkg-config-wrapper.sh | 8 ++++---- src/executables/platforms/uefi/libraries.json | 6 +++--- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 3c4e98b1..724a078a 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -232,6 +232,14 @@ for MESON_TARGETS_INFO_LIB_PARAMATER in "${MESON_TARGETS_INFO_LIB_PARAMATERS[@]} -I*) DEP_INCLUDES+=("${MESON_TARGETS_INFO_LIB_PARAMATER:2}") ;; + -D*) + DEP_BUILD_OPTIONS+=("*_*_*_*_FLAGS = ${MESON_TARGETS_INFO_LIB_PARAMATER}") + ;; + --use-lib:pkg=*) + DEP_PACKAGE_NAME="${MESON_TARGETS_INFO_LIB_PARAMATER:14}" + DEP_PACKAGES+=("LibraryPkg/$DEP_PACKAGE_NAME/$DEP_PACKAGE_NAME.dec") + ;; + *) ;; esac done @@ -282,8 +290,6 @@ $(expand_array_inf "${DEP_PACKAGES[@]}") [Pcd] [BuildOptions] - *_*_*_CC_FLAGS = -D__UEFI__ - *_*_*_CC_FLAGS = -std=c11 *_*_*_CXX_FLAGS = -std=c++23 @@ -322,13 +328,9 @@ $(expand_array_inf "${DEP_PACKAGES[@]}") UefiLib [BuildOptions] -[BuildOptions] - *_*_*_CC_FLAGS = -D__UEFI__ - *_*_*_CC_FLAGS = -std=c11 *_*_*_CXX_FLAGS = -std=c++23 -$(expand_array_inf "${DEP_BUILD_OPTIONS[@]}") $(expand_array_inf "${DEP_BUILD_OPTIONS[@]}") EOF diff --git a/platforms/uefi/pkg-config-wrapper.sh b/platforms/uefi/pkg-config-wrapper.sh index fdf590ad..9d3481b6 100755 --- a/platforms/uefi/pkg-config-wrapper.sh +++ b/platforms/uefi/pkg-config-wrapper.sh @@ -88,12 +88,12 @@ elif [[ "$MODE" == "get" ]]; then echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"version\"]" exit 0 elif [[ "$WHAT" == "cflags" ]]; then - echo "--use-lib=$PACKAGE_NAME" - echo "--lib_name=$(echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"name\"]")" + echo "--use-lib:name=$PACKAGE_NAME" + echo "--use-lib:pkg=$(echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"pkg\"]")" exit 0 elif [[ "$WHAT" == "libflags" ]]; then - echo "-L,--use-lib=$PACKAGE_NAME" - echo "-L,--lib_name=$(echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"name\"]")" + echo "-L,--use-lib:name=$PACKAGE_NAME" + echo "-L,--use-lib:pkg=$(echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"pkg\"]")" exit 0 else echo "<$TOOL> ${ARGS[*]}" >&2 diff --git a/src/executables/platforms/uefi/libraries.json b/src/executables/platforms/uefi/libraries.json index fd36bf8c..bd3d9d7b 100644 --- a/src/executables/platforms/uefi/libraries.json +++ b/src/executables/platforms/uefi/libraries.json @@ -1,14 +1,14 @@ { "sdl2": { - "name": "LibraryPkg/SDL2Pkg.inf", + "pkg": "SDL2Pkg", "version": "2.32.10" }, "sdl2_image": { - "name": "LibraryPkg/SDL2ImagePkg.inf", + "name": "SDL2ImagePkg", "version": "2.6.3" }, "sdl2_mixer": { - "name": "LibraryPkg/SDL2MixerPkg.inf", + "pkg": "SDL2MixerPkg", "version": "2.6.2" } } From aa69009eab51d5a5262e6ae550a4ef0d2d312835 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Mon, 3 Aug 2026 23:53:18 +0200 Subject: [PATCH 058/112] feat: use shared libraries instea of static ones - this helps as the linking of those gets more arguments, so the .inf and .dec files are accurate, without inspecting the meson target info file --- platforms/build-uefi.sh | 8 +++--- platforms/uefi/ar-wrapper.sh | 26 ++++++++++++------ platforms/uefi/base.sh | 52 ++++++++++++++++++++++++++++++++++-- 3 files changed, 72 insertions(+), 14 deletions(-) mode change 100644 => 100755 platforms/uefi/base.sh diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 3bd0142e..b60ecdcd 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -182,7 +182,7 @@ done export EDK2_GENERATED_PACKAGES="$BUILD_DIR_ABS/GeneratedPackages" -if ! [ -e "$WORKSPACE/GeneratedPackages" ]; then +if [ -e "$BUILD_DIR_ABS" ] && ! [ -e "$WORKSPACE/GeneratedPackages" ]; then mkdir -p "$EDK2_GENERATED_PACKAGES" link_files_checked "$EDK2_GENERATED_PACKAGES" "$WORKSPACE/GeneratedPackages" fi @@ -210,10 +210,10 @@ export ENDIANESS="little" export ROMFS="platforms/romfs" -export COMMON_FLAGS="'-fexceptions', '-pthread', '-fshort-wchar', '-fno-builtin', '-fno-strict-aliasing', '-fno-common', '-fstack-protector', '-ffunction-sections', '-fdata-sections', '-m64', '-DEFIAPI=__attribute__((ms_abi))', '-maccumulate-outgoing-args', '-mno-red-zone', '-mcmodel=small', '-fno-asynchronous-unwind-tables', '-fno-omit-frame-pointer'" +export COMMON_FLAGS="'-fexceptions', '-pthread', '-fshort-wchar', '-fno-builtin', '-fno-strict-aliasing', '-fno-common', '-fstack-protector', '-ffunction-sections', '-fdata-sections', '-m64', '-maccumulate-outgoing-args', '-mno-red-zone', '-mcmodel=small', '-fno-asynchronous-unwind-tables', '-fno-omit-frame-pointer'" export LINK_FLAGS="$COMMON_FLAGS" -export COMPILE_FLAGS="$COMMON_FLAGS ,'-D__UEFI__', '-DAUDIO_PREFER_MP3'" +export COMPILE_FLAGS="$COMMON_FLAGS ,'-D__UEFI__', '-DEFIAPI=__attribute__((ms_abi))', '-DAUDIO_PREFER_MP3'" export CROSS_FILE="./platforms/crossbuild/uefi.ini" @@ -303,7 +303,7 @@ if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "$BUILD_DIR" ]; then "--wipe" \ --cross-file "$CROSS_FILE" \ "-Dbuildtype=$BUILDTYPE" \ - -Ddefault_library=static \ + -Ddefault_library=shared \ -Dtests=false \ --force-fallback-for="fmt,nlohmann_json,magic_enum,utf8cpp,sdl2_ttf,freetype2,spdlog,argparse" \ --wrap-mode=nofallback \ diff --git a/platforms/uefi/ar-wrapper.sh b/platforms/uefi/ar-wrapper.sh index 4cb9730a..67553780 100755 --- a/platforms/uefi/ar-wrapper.sh +++ b/platforms/uefi/ar-wrapper.sh @@ -22,7 +22,7 @@ source "$SCRIPT_DIR/base.sh" ARGS=("$@") OUTPUT_FILE="" -NEXT_TYPE="unknown" +DEPENDENCIES=() for ARG in "${ARGS[@]}"; do case "$ARG" in @@ -31,21 +31,31 @@ for ARG in "${ARGS[@]}"; do ;; csr) change_mode "create" - NEXT_TYPE="output" + change_next_type "output" ;; *) if [[ "$NEXT_TYPE" == "output" ]]; then OUTPUT_FILE="$(normalize_file "$ARG")" - NEXT_TYPE="unknown" + reset_next_type elif [[ "$NEXT_TYPE" == "ignore" ]]; then - NEXT_TYPE="unknown" - else + reset_next_type + elif [[ "$NEXT_TYPE" == "unknown" ]]; then case "$ARG" in - *.a | *.so | *.o) + *.o) DEPENDENCIES+=("$(resolve_file "$ARG")") ;; - *) ;; + *.a | *.so) + echo "Invalid file detected: '$ARG'" >&2 + exit 5 + ;; + *) + echo "Invalid argument detected: '$ARG'" >&2 + exit 6 + ;; esac + else + echo "Not recognized next type: $NEXT_TYPE" >&2 + exit 11 fi ;; esac @@ -62,7 +72,7 @@ elif [[ "$MODE" == "create" ]]; then validate_parent_dir "$OUTPUT_FILE" - validate_dependencies + validate_dependencies "${DEPENDENCIES[@]}" cat <"$OUTPUT_FILE" { diff --git a/platforms/uefi/base.sh b/platforms/uefi/base.sh old mode 100644 new mode 100755 index ac47d08d..b26da359 --- a/platforms/uefi/base.sh +++ b/platforms/uefi/base.sh @@ -1,8 +1,7 @@ #!/usr/bin/env bash -DEPENDENCIES=() - validate_dependencies() { + local DEPENDENCIES=("$@") for DEPENDENCY in "${DEPENDENCIES[@]}"; do FILE="$(realpath "$DEPENDENCY")" @@ -16,6 +15,21 @@ validate_dependencies() { done } +validate_files() { + local FILES=("$@") + + for FILE in "${FILES[@]}"; do + FILE="$(realpath "$FILE")" + + if ! [ -e "$FILE" ]; then + echo "<$TOOL> ${ARGS[*]}" >&2 + echo "File '$FILE' does not exist" >&2 + exit 5 + fi + + done +} + MODE="unknown" change_mode() { @@ -32,6 +46,35 @@ change_mode() { fi } +NEXT_TYPE="unknown" + +change_next_type() { + local NEW_TYPE="$1" + + if [[ "$NEXT_TYPE" == "unknown" ]]; then + NEXT_TYPE="$NEW_TYPE" + elif [[ "$NEXT_TYPE" == "$NEW_TYPE" ]]; then + : + else + echo "<$TOOL> ${ARGS[*]}" >&2 + echo "Can't change next type from $NEXT_TYPE to $NEW_TYPE" >&2 + exit 4 + fi +} + +reset_next_type() { + NEXT_TYPE="unknown" +} + +require_empty_array() { + local ARRAY=("$@") + + if [ "${#ARRAY[@]}" -ne 0 ]; then + echo "Array is nto empty but ${#ARRAY[@]} long" >&2 + exit 9 + fi +} + to_json_array() { local ARRAY=("$@") @@ -60,3 +103,8 @@ normalize_file() { realpath "$FILE" } + +is_soname() { + local SO_NAME="$1" + [[ "$SO_NAME" =~ (^|/)lib[^/]+\.so(\.[0-9]+)*$ ]] +} From 45eaa3168fe236da8b603c6df40cb324bc2cfdf7 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Mon, 3 Aug 2026 23:54:03 +0200 Subject: [PATCH 059/112] feat: improve the gcc and g++ wrapper script for uefi - report wrong argument and parse gcc argument semi good --- platforms/uefi/g++-wrapper.sh | 124 +++++++++++++++++++++++---- platforms/uefi/gcc-wrapper.sh | 122 +++++++++++++++++++++----- platforms/uefi/pkg-config-wrapper.sh | 8 +- 3 files changed, 210 insertions(+), 44 deletions(-) diff --git a/platforms/uefi/g++-wrapper.sh b/platforms/uefi/g++-wrapper.sh index e7f22f9a..4ca4f3bb 100755 --- a/platforms/uefi/g++-wrapper.sh +++ b/platforms/uefi/g++-wrapper.sh @@ -24,7 +24,9 @@ COMPILED=() ARGS=("$@") OUTPUT_FILE="" -NEXT_TYPE="unknown" +DEPENDENCIES_O=() +DEPENDENCIES_SRC=() +DEPENDENCIES_LINK=() for ARG in "${ARGS[@]}"; do case "$ARG" in @@ -36,36 +38,109 @@ for ARG in "${ARGS[@]}"; do ;; -Wl,*) change_mode "link" + LINK_ARG="${ARG:4}" + case "$LINK_ARG" in + --as-needed | --no-undefined | -O* | -soname,* | -rpath,*) + # ignore, valid arguments + ;; + --start-group) + change_next_type "link" + ;; + --end-group) + reset_next_type + ;; + -t:use-lib*) + # ignore here, the extraction uses that for inf and dec dependencies + ;; + *) + echo "Invalid link argument detected: '$LINK_ARG'" >&2 + exit 6 + ;; + esac ;; -o) - NEXT_TYPE="output" + change_next_type "output" ;; - -MQ) - NEXT_TYPE="ignore" + -MQ | -MF) + change_next_type "ignore" ;; - --version | -dM | -xc\+\+) + --version | -dM) + change_mode "pass" + ;; + -x) + change_mode "pass" + change_next_type "ignore" + ;; + -xc++) + # C++ specific change_mode "pass" ;; *) if [[ "$NEXT_TYPE" == "output" ]]; then OUTPUT_FILE="$(normalize_file "$ARG")" - NEXT_TYPE="unknown" + reset_next_type elif [[ "$NEXT_TYPE" == "ignore" ]]; then - NEXT_TYPE="unknown" - else + reset_next_type + elif [[ "$NEXT_TYPE" == "link" ]]; then case "$ARG" in + -l*) + DEPENDENCIES_LINK+=("SYSTEM:${ARG:2}") + ;; + *.o) + echo "Invalid file detected: '$ARG'" >&2 + exit 5 + ;; + *.cpp) + # C++ specific + echo "Invalid file detected: '$ARG'" >&2 + exit 5 + ;; *.a | *.so) - change_mode "link" - DEPENDENCIES+=("$(resolve_file "$ARG")") + DEPENDENCIES_LINK+=("$(resolve_file "$ARG")") ;; + *) + if is_soname "$ARG"; then + DEPENDENCIES_LINK+=("$(resolve_file "$ARG")") + else + echo "Invalid link group argument detected: '$ARG'" >&2 + exit 6 + fi + ;; + esac + elif [[ "$NEXT_TYPE" == "unknown" ]]; then + case "$ARG" in *.o) - DEPENDENCIES+=("$(resolve_file "$ARG")") + DEPENDENCIES_O+=("$(resolve_file "$ARG")") ;; *.cpp) - COMPILED+=("$(resolve_file "$ARG")") + # C++ specific + DEPENDENCIES_SRC+=("$(resolve_file "$ARG")") + ;; + *.a | *.so) + DEPENDENCIES_LINK+=("$(resolve_file "$ARG")") + ;; + -cpp) + # ignore this for meson usage, even if gcc only uses this for fortran, but it doesn't complain about it + ;; + -v | -E | - | -g | -MD | -pthread | -shared | -std=* | -f* | -m* | -D* | -U* | -W* | -O* | -I*) + # ignore, valid arguments + ;; + -t:use-lib*) + # ignore here, the extraction uses that for inf and dec dependencies + ;; + *) + if is_soname "$ARG"; then + DEPENDENCIES_LINK+=("$(resolve_file "$ARG")") + else + + echo "Invalid argument detected: '$ARG'" >&2 + exit 6 + fi ;; - *) ;; esac + else + echo "Not recognized next type: $NEXT_TYPE" >&2 + exit 11 fi ;; esac @@ -82,17 +157,21 @@ elif [[ "$MODE" == "compile" ]]; then validate_parent_dir "$OUTPUT_FILE" + validate_files "${DEPENDENCIES_SRC[@]}" + + require_empty_array "${DEPENDENCIES_O[@]}" + + require_empty_array "${DEPENDENCIES_LINK[@]}" + cat <"$OUTPUT_FILE" -{ +{ "cwd": "$(pwd)", "args": $(to_json_array "${ARGS[@]}"), "language": "cpp", "type": "compile", "dependencies": { "output": "$OUTPUT_FILE", - "files": $(to_json_array "${DEPENDENCIES[@]}" "${COMPILED[@]}"), - "dependencies": $(to_json_array "${DEPENDENCIES[@]}"), - "compiled": $(to_json_array "${COMPILED[@]}") + "src": $(to_json_array "${DEPENDENCIES_SRC[@]}") } } EOF @@ -106,15 +185,22 @@ elif [[ "$MODE" == "link" ]]; then validate_parent_dir "$OUTPUT_FILE" + validate_dependencies "${DEPENDENCIES_O[@]}" + + validate_dependencies "${DEPENDENCIES_LINK[@]}" + + require_empty_array "${DEPENDENCIES_SRC[@]}" + cat <"$OUTPUT_FILE" -{ +{ "cwd": "$(pwd)", "args": $(to_json_array "${ARGS[@]}"), "language": "cpp", "type": "link", "dependencies": { "output": "$OUTPUT_FILE", - "files": $(to_json_array "${DEPENDENCIES[@]}") + "o_files": $(to_json_array "${DEPENDENCIES_O[@]}"), + "link_files": $(to_json_array "${DEPENDENCIES_LINK[@]}") } } EOF diff --git a/platforms/uefi/gcc-wrapper.sh b/platforms/uefi/gcc-wrapper.sh index 9657c0dd..a2fb98dd 100755 --- a/platforms/uefi/gcc-wrapper.sh +++ b/platforms/uefi/gcc-wrapper.sh @@ -18,13 +18,13 @@ TOOL="GCC" # shellcheck source=./platforms/uefi/base.sh source "$SCRIPT_DIR/base.sh" -COMPILED=() - # Capture all args ARGS=("$@") OUTPUT_FILE="" -NEXT_TYPE="unknown" +DEPENDENCIES_O=() +DEPENDENCIES_SRC=() +DEPENDENCIES_LINK=() for ARG in "${ARGS[@]}"; do case "$ARG" in @@ -36,36 +36,109 @@ for ARG in "${ARGS[@]}"; do ;; -Wl,*) change_mode "link" + LINK_ARG="${ARG:4}" + case "$LINK_ARG" in + --as-needed | --no-undefined | -O* | -soname,* | -rpath,*) + # ignore, valid arguments + ;; + --start-group) + change_next_type "link" + ;; + --end-group) + reset_next_type + ;; + -t:use-lib*) + # ignore here, the extraction uses that for inf and dec dependencies + ;; + *) + echo "Invalid link argument detected: '$LINK_ARG'" >&2 + exit 6 + ;; + esac ;; -o) - NEXT_TYPE="output" + change_next_type "output" + ;; + -MQ | -MF) + change_next_type "ignore" ;; - -MQ) - NEXT_TYPE="ignore" + --version | -dM) + change_mode "pass" ;; - --version | -dM | -xc) + -x) + change_mode "pass" + change_next_type "ignore" + ;; + -xc) + # C specific change_mode "pass" ;; *) if [[ "$NEXT_TYPE" == "output" ]]; then OUTPUT_FILE="$(normalize_file "$ARG")" - NEXT_TYPE="unknown" + reset_next_type elif [[ "$NEXT_TYPE" == "ignore" ]]; then - NEXT_TYPE="unknown" - else + reset_next_type + elif [[ "$NEXT_TYPE" == "link" ]]; then case "$ARG" in + -l*) + DEPENDENCIES_LINK+=("SYSTEM:${ARG:2}") + ;; + *.o) + echo "Invalid file detected: '$ARG'" >&2 + exit 5 + ;; + *.c) + # C specific + echo "Invalid file detected: '$ARG'" >&2 + exit 5 + ;; *.a | *.so) - change_mode "link" - DEPENDENCIES+=("$(resolve_file "$ARG")") + DEPENDENCIES_LINK+=("$(resolve_file "$ARG")") + ;; + *) + if is_soname "$ARG"; then + DEPENDENCIES_LINK+=("$(resolve_file "$ARG")") + else + echo "Invalid link group argument detected: '$ARG'" >&2 + exit 6 + fi ;; + esac + elif [[ "$NEXT_TYPE" == "unknown" ]]; then + case "$ARG" in *.o) - DEPENDENCIES+=("$(resolve_file "$ARG")") + DEPENDENCIES_O+=("$(resolve_file "$ARG")") ;; *.c) - COMPILED+=("$(resolve_file "$ARG")") + # C specific + DEPENDENCIES_SRC+=("$(resolve_file "$ARG")") + ;; + *.a | *.so) + DEPENDENCIES_LINK+=("$(resolve_file "$ARG")") + ;; + -cpp) + # ignore this for meson usage, even if gcc only uses this for fortran, but it doesn't complain about it + ;; + -v | -E | - | -g | -MD | -pthread | -shared | -std=* | -f* | -m* | -D* | -U* | -W* | -O* | -I*) + # ignore, valid arguments + ;; + -t:use-lib*) + # ignore here, the extraction uses that for inf and dec dependencies + ;; + *) + if is_soname "$ARG"; then + DEPENDENCIES_LINK+=("$(resolve_file "$ARG")") + else + + echo "Invalid argument detected: '$ARG'" >&2 + exit 6 + fi ;; - *) ;; esac + else + echo "Not recognized next type: $NEXT_TYPE" >&2 + exit 11 fi ;; esac @@ -82,7 +155,11 @@ elif [[ "$MODE" == "compile" ]]; then validate_parent_dir "$OUTPUT_FILE" - validate_dependencies + validate_files "${DEPENDENCIES_SRC[@]}" + + require_empty_array "${DEPENDENCIES_O[@]}" + + require_empty_array "${DEPENDENCIES_LINK[@]}" cat <"$OUTPUT_FILE" { @@ -92,9 +169,7 @@ elif [[ "$MODE" == "compile" ]]; then "type": "compile", "dependencies": { "output": "$OUTPUT_FILE", - "files": $(to_json_array "${DEPENDENCIES[@]}" "${COMPILED[@]}"), - "dependencies": $(to_json_array "${DEPENDENCIES[@]}"), - "compiled": $(to_json_array "${COMPILED[@]}") + "src": $(to_json_array "${DEPENDENCIES_SRC[@]}") } } EOF @@ -108,7 +183,11 @@ elif [[ "$MODE" == "link" ]]; then validate_parent_dir "$OUTPUT_FILE" - validate_dependencies + validate_dependencies "${DEPENDENCIES_O[@]}" + + validate_dependencies "${DEPENDENCIES_LINK[@]}" + + require_empty_array "${DEPENDENCIES_SRC[@]}" cat <"$OUTPUT_FILE" { @@ -118,7 +197,8 @@ elif [[ "$MODE" == "link" ]]; then "type": "link", "dependencies": { "output": "$OUTPUT_FILE", - "files": $(to_json_array "${DEPENDENCIES[@]}") + "o_files": $(to_json_array "${DEPENDENCIES_O[@]}"), + "link_files": $(to_json_array "${DEPENDENCIES_LINK[@]}") } } EOF diff --git a/platforms/uefi/pkg-config-wrapper.sh b/platforms/uefi/pkg-config-wrapper.sh index 9d3481b6..25f336f2 100755 --- a/platforms/uefi/pkg-config-wrapper.sh +++ b/platforms/uefi/pkg-config-wrapper.sh @@ -88,12 +88,12 @@ elif [[ "$MODE" == "get" ]]; then echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"version\"]" exit 0 elif [[ "$WHAT" == "cflags" ]]; then - echo "--use-lib:name=$PACKAGE_NAME" - echo "--use-lib:pkg=$(echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"pkg\"]")" + echo "-t:use-lib:name=$PACKAGE_NAME" + echo "-t:use-lib:pkg=$(echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"pkg\"]")" exit 0 elif [[ "$WHAT" == "libflags" ]]; then - echo "-L,--use-lib:name=$PACKAGE_NAME" - echo "-L,--use-lib:pkg=$(echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"pkg\"]")" + echo "-Wl,-t:use-lib:name=$PACKAGE_NAME" + echo "-Wl,-t:use-lib:pkg=$(echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"pkg\"]")" exit 0 else echo "<$TOOL> ${ARGS[*]}" >&2 From fff9335f800e3a5224ab1ac5928f19cb1742c786 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 4 Aug 2026 00:21:42 +0200 Subject: [PATCH 060/112] fix: more uefi wrapper and general scripts improvement --- platforms/build-uefi.sh | 5 ++ platforms/uefi/extract-definitions.sh | 80 ++++++++++++++++----------- platforms/uefi/g++-wrapper.sh | 3 +- platforms/uefi/gcc-wrapper.sh | 3 +- 4 files changed, 56 insertions(+), 35 deletions(-) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index b60ecdcd..2b62516e 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -310,6 +310,11 @@ if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "$BUILD_DIR" ]; then "-Drun_in_ci=$RUN_IN_CI" #TODO: enable \ #--fatal-meson-warnings + if ! [ -e "$WORKSPACE/GeneratedPackages" ]; then + mkdir -p "$EDK2_GENERATED_PACKAGES" + link_files_checked "$EDK2_GENERATED_PACKAGES" "$WORKSPACE/GeneratedPackages" + fi + fi meson compile -C "$BUILD_DIR" diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 724a078a..b2aa4ee2 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -23,6 +23,22 @@ expand_array_inf() { } +is_soname() { + local SO_NAME="$1" + [[ "$SO_NAME" =~ (^|/)lib[^/]+\.so(\.[0-9]+)*$ ]] +} + +output_stem() { + local INPUT="$1" + + if is_soname "$INPUT"; then + echo "${INPUT%%.so*}" + else + echo "${INPUT%.*}" + fi + +} + get_mapped_version() { local INPUT="$1" @@ -75,7 +91,7 @@ else exit 2 fi -mapfile -t FILE_DEPENDENCIES < <(jq '.["dependencies"]["files"][]' -M -r -c "$SOURCE_FILE") +mapfile -t FILE_DEPENDENCIES < <(jq -e '.["dependencies"]["files"][]' -M -r -c "$SOURCE_FILE") UEFI_INFO_FILE="$(realpath "$SCRIPT_DIR/../crossbuild/uefi_info.json")" UEFI_INFO_GENERATED_PACKAGES_DIR="$(jq -M -r -c '.["generated_packages"]' "$UEFI_INFO_FILE")" @@ -131,14 +147,14 @@ for FILE_DEPENDENCY in "${FILE_DEPENDENCIES[@]}"; do FILE_DEPENDENCY_TYPE="$(jq -M -r -c '.["type"]' "$FILE_DEPENDENCY")" if [ "$FILE_DEPENDENCY_TYPE" == "compile" ]; then - mapfile -t FILE_DEPENDENCY_FILES < <(jq '.["dependencies"]["files"][]' -M -r -c "$FILE_DEPENDENCY") + mapfile -t FILE_DEPENDENCY_SRC < <(jq -e '.["dependencies"]["src"][]' -M -r -c "$FILE_DEPENDENCY") - for FILE_DEPENDENCY_FILE in "${FILE_DEPENDENCY_FILES[@]}"; do - DEP_SOURCES+=("$FILE_DEPENDENCY_FILE") + for FILE_DEPENDENCY_SRC in "${FILE_DEPENDENCY_SRC[@]}"; do + DEP_SOURCES+=("$FILE_DEPENDENCY_SRC") done elif [ "$FILE_DEPENDENCY_TYPE" == "archive" ] || [ "$FILE_DEPENDENCY_TYPE" == "link" ]; then - DEP_OUTPUT="$(jq -M -r -c '.["dependencies"]["output"]' "$FILE_DEPENDENCY")" + DEP_OUTPUT="$(jq -e -M -r -c '.["dependencies"]["output"]' "$FILE_DEPENDENCY")" if [ "$DEP_OUTPUT" = "null" ]; then echo "Error: output '$DEP_OUTPUT'" >&2 @@ -146,12 +162,12 @@ for FILE_DEPENDENCY in "${FILE_DEPENDENCIES[@]}"; do fi DEP_OUTPUT_NAME=$(basename -- "$DEP_OUTPUT") - DEP_OUTPUT_STEM="${DEP_OUTPUT_NAME%.*}" + DEP_OUTPUT_STEM="$(output_stem "$DEP_OUTPUT_NAME")" MAPPING_ENTRY_DEP="$(jq -M -r -c ".[\"name\"][\"${DEP_OUTPUT_STEM}\"]" "$MAPPINGS_FILE")" if [ "$MAPPING_ENTRY_DEP" = "null" ]; then - echo "Error: invalid name '$DEP_OUTPUT_STEM': not found in mappings 'name'" >&2 + echo "Error: invalid name '$DEP_OUTPUT_STEM': not found in mappings 'name' (dep)" >&2 exit 2 fi @@ -190,12 +206,12 @@ if [ "$SOURCE_FILE_OUTPUT" = "null" ]; then fi SOURCE_FILE_OUTPUT_NAME=$(basename -- "$SOURCE_FILE_OUTPUT") -SOURCE_FILE_OUTPUT_STEM="${SOURCE_FILE_OUTPUT_NAME%.*}" +SOURCE_FILE_OUTPUT_STEM="$(output_stem "$SOURCE_FILE_OUTPUT_NAME")" SOURCE_FILE_ENTRY="$(jq -M -r -c ".[\"name\"][\"${SOURCE_FILE_OUTPUT_STEM}\"]" "$MAPPINGS_FILE")" if [ "$SOURCE_FILE_ENTRY" = "null" ]; then - echo "Error: invalid name '$SOURCE_FILE_OUTPUT_STEM': not found in mappings 'name'" >&2 + echo "Error: invalid name '$SOURCE_FILE_OUTPUT_STEM': not found in mappings 'name' (src)" >&2 exit 2 fi @@ -217,32 +233,34 @@ fi MESON_TARGETS_INFO_LIB_TYPE="$(echo "$MESON_TARGETS_INFO_LIB" | jq -M -r -c ".[\"type\"]")" -if [ "$MESON_TARGETS_INFO_LIB_TYPE" == "static library" ] || [ "$MESON_TARGETS_INFO_LIB_TYPE" == "executable" ]; then - : -else - echo "Error: invalid meson target type: $MESON_TARGETS_INFO_LIB_TYPE" >&2 - exit 2 -fi +if [ "$MESON_TARGETS_INFO_LIB_TYPE" == "static library" ]; then -mapfile -t MESON_TARGETS_INFO_LIB_PARAMATERS < <(echo "$MESON_TARGETS_INFO_LIB" | jq '.["target_sources"][] | select( has("compiler") ) | .["parameters"][]' -M -r -c) + mapfile -t MESON_TARGETS_INFO_LIB_PARAMATERS < <(echo "$MESON_TARGETS_INFO_LIB" | jq '.["target_sources"][] | select( has("compiler") ) | .["parameters"][]' -M -r -c) -for MESON_TARGETS_INFO_LIB_PARAMATER in "${MESON_TARGETS_INFO_LIB_PARAMATERS[@]}"; do + for MESON_TARGETS_INFO_LIB_PARAMATER in "${MESON_TARGETS_INFO_LIB_PARAMATERS[@]}"; do - case "$MESON_TARGETS_INFO_LIB_PARAMATER" in - -I*) - DEP_INCLUDES+=("${MESON_TARGETS_INFO_LIB_PARAMATER:2}") - ;; - -D*) - DEP_BUILD_OPTIONS+=("*_*_*_*_FLAGS = ${MESON_TARGETS_INFO_LIB_PARAMATER}") - ;; - --use-lib:pkg=*) - DEP_PACKAGE_NAME="${MESON_TARGETS_INFO_LIB_PARAMATER:14}" - DEP_PACKAGES+=("LibraryPkg/$DEP_PACKAGE_NAME/$DEP_PACKAGE_NAME.dec") - ;; + case "$MESON_TARGETS_INFO_LIB_PARAMATER" in + -I*) + DEP_INCLUDES+=("${MESON_TARGETS_INFO_LIB_PARAMATER:2}") + ;; + -D*) + DEP_BUILD_OPTIONS+=("*_*_*_*_FLAGS = ${MESON_TARGETS_INFO_LIB_PARAMATER}") + ;; + -t:use-lib:pkg=*) + DEP_PACKAGE_NAME="${MESON_TARGETS_INFO_LIB_PARAMATER:15}" + DEP_PACKAGES+=("LibraryPkg/$DEP_PACKAGE_NAME/$DEP_PACKAGE_NAME.dec") + ;; - *) ;; - esac -done + *) ;; + esac + done +elif [ "$MESON_TARGETS_INFO_LIB_TYPE" == "executable" ] || [ "$MESON_TARGETS_INFO_LIB_TYPE" == "shared library" ]; then + echo "TODO" + exit 34 +else + echo "Error: invalid meson target type: $MESON_TARGETS_INFO_LIB_TYPE" >&2 + exit 2 +fi MAPPING_TYPE="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"type\"]")" MAPPING_NAME="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"name\"]")" diff --git a/platforms/uefi/g++-wrapper.sh b/platforms/uefi/g++-wrapper.sh index 4ca4f3bb..cb72dfc7 100755 --- a/platforms/uefi/g++-wrapper.sh +++ b/platforms/uefi/g++-wrapper.sh @@ -199,8 +199,7 @@ elif [[ "$MODE" == "link" ]]; then "type": "link", "dependencies": { "output": "$OUTPUT_FILE", - "o_files": $(to_json_array "${DEPENDENCIES_O[@]}"), - "link_files": $(to_json_array "${DEPENDENCIES_LINK[@]}") + "files": $(to_json_array "${DEPENDENCIES_O[@]}" "${DEPENDENCIES_LINK[@]}") } } EOF diff --git a/platforms/uefi/gcc-wrapper.sh b/platforms/uefi/gcc-wrapper.sh index a2fb98dd..64d6b358 100755 --- a/platforms/uefi/gcc-wrapper.sh +++ b/platforms/uefi/gcc-wrapper.sh @@ -197,8 +197,7 @@ elif [[ "$MODE" == "link" ]]; then "type": "link", "dependencies": { "output": "$OUTPUT_FILE", - "o_files": $(to_json_array "${DEPENDENCIES_O[@]}"), - "link_files": $(to_json_array "${DEPENDENCIES_LINK[@]}") + "files": $(to_json_array "${DEPENDENCIES_O[@]}" "${DEPENDENCIES_LINK[@]}") } } EOF From 5c9aa51ac9478cc4c6c8705c1a38ff794b98ec21 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 4 Aug 2026 01:20:07 +0200 Subject: [PATCH 061/112] fix some uefi fixes --- platforms/uefi/extract-definitions.sh | 44 ++++++++++--------- src/executables/platforms/uefi/libraries.json | 2 +- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index b2aa4ee2..7b756dc8 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -233,30 +233,32 @@ fi MESON_TARGETS_INFO_LIB_TYPE="$(echo "$MESON_TARGETS_INFO_LIB" | jq -M -r -c ".[\"type\"]")" -if [ "$MESON_TARGETS_INFO_LIB_TYPE" == "static library" ]; then - - mapfile -t MESON_TARGETS_INFO_LIB_PARAMATERS < <(echo "$MESON_TARGETS_INFO_LIB" | jq '.["target_sources"][] | select( has("compiler") ) | .["parameters"][]' -M -r -c) - - for MESON_TARGETS_INFO_LIB_PARAMATER in "${MESON_TARGETS_INFO_LIB_PARAMATERS[@]}"; do - - case "$MESON_TARGETS_INFO_LIB_PARAMATER" in - -I*) - DEP_INCLUDES+=("${MESON_TARGETS_INFO_LIB_PARAMATER:2}") - ;; - -D*) - DEP_BUILD_OPTIONS+=("*_*_*_*_FLAGS = ${MESON_TARGETS_INFO_LIB_PARAMATER}") - ;; - -t:use-lib:pkg=*) - DEP_PACKAGE_NAME="${MESON_TARGETS_INFO_LIB_PARAMATER:15}" - DEP_PACKAGES+=("LibraryPkg/$DEP_PACKAGE_NAME/$DEP_PACKAGE_NAME.dec") - ;; +mapfile -t MESON_TARGETS_INFO_LIB_PARAMATERS < <(echo "$MESON_TARGETS_INFO_LIB" | jq '.["target_sources"][] | select( has("compiler") ) | .["parameters"][]' -M -r -c) + +for MESON_TARGETS_INFO_LIB_PARAMATER in "${MESON_TARGETS_INFO_LIB_PARAMATERS[@]}"; do + + case "$MESON_TARGETS_INFO_LIB_PARAMATER" in + -I*) + DEP_INCLUDES+=("${MESON_TARGETS_INFO_LIB_PARAMATER:2}") + ;; + -D*) + DEP_BUILD_OPTIONS+=("*_*_*_*_FLAGS = ${MESON_TARGETS_INFO_LIB_PARAMATER}") + ;; + -t:use-lib:pkg=*) + DEP_PACKAGE_NAME="${MESON_TARGETS_INFO_LIB_PARAMATER:15}" + DEP_PACKAGES+=("LibraryPkg/$DEP_PACKAGE_NAME/$DEP_PACKAGE_NAME.dec") + ;; + + *) ;; + esac +done - *) ;; - esac - done +# TODO: what should i do here, archives alias static_libraries don't specify argument, but executables and shared libraries hae -Wl -l or similar arguments +if [ "$MESON_TARGETS_INFO_LIB_TYPE" == "static library" ]; then + echo "TODO" elif [ "$MESON_TARGETS_INFO_LIB_TYPE" == "executable" ] || [ "$MESON_TARGETS_INFO_LIB_TYPE" == "shared library" ]; then echo "TODO" - exit 34 + # exit 34 else echo "Error: invalid meson target type: $MESON_TARGETS_INFO_LIB_TYPE" >&2 exit 2 diff --git a/src/executables/platforms/uefi/libraries.json b/src/executables/platforms/uefi/libraries.json index bd3d9d7b..c3f3d5ad 100644 --- a/src/executables/platforms/uefi/libraries.json +++ b/src/executables/platforms/uefi/libraries.json @@ -4,7 +4,7 @@ "version": "2.32.10" }, "sdl2_image": { - "name": "SDL2ImagePkg", + "pkg": "SDL2ImagePkg", "version": "2.6.3" }, "sdl2_mixer": { From 4ddd4870e4001b28bf55d376eef4b9a2feee5d64 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 4 Aug 2026 01:43:45 +0200 Subject: [PATCH 062/112] fix: fix GeneratedPackages link --- platforms/build-uefi.sh | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 2b62516e..517e987e 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -124,8 +124,6 @@ fi export BUILD_DIR="build/uefi" -export BUILD_DIR_ABS="$(pwd)/$BUILD_DIR" - pushd "$EDK2_ROOT" make -C BaseTools @@ -180,13 +178,6 @@ for EDK2_LIB_PACKAGE in "${EDK2_LIB_PACKAGES[@]}"; do done -export EDK2_GENERATED_PACKAGES="$BUILD_DIR_ABS/GeneratedPackages" - -if [ -e "$BUILD_DIR_ABS" ] && ! [ -e "$WORKSPACE/GeneratedPackages" ]; then - mkdir -p "$EDK2_GENERATED_PACKAGES" - link_files_checked "$EDK2_GENERATED_PACKAGES" "$WORKSPACE/GeneratedPackages" -fi - popd export PKG_CONFIG_PATH="$EDK2_ROOT/lib/pkgconfig" @@ -284,6 +275,8 @@ export EDK2_INFO_FILE="./platforms/crossbuild/uefi_info.json" validate_parent_dir "$EDK2_INFO_FILE" +export EDK2_GENERATED_PACKAGES="$(pwd)/$BUILD_DIR/GeneratedPackages" + cat <"$EDK2_INFO_FILE" { "build": "$EDK2_BUILD_COMMAND", @@ -310,7 +303,9 @@ if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "$BUILD_DIR" ]; then "-Drun_in_ci=$RUN_IN_CI" #TODO: enable \ #--fatal-meson-warnings - if ! [ -e "$WORKSPACE/GeneratedPackages" ]; then + if ! [ -L "$WORKSPACE/GeneratedPackages" ]; then + + echo "mkdir: $EDK2_GENERATED_PACKAGES" mkdir -p "$EDK2_GENERATED_PACKAGES" link_files_checked "$EDK2_GENERATED_PACKAGES" "$WORKSPACE/GeneratedPackages" fi From e65708127b72fc2d035965a44d10df5802b12da4 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 4 Aug 2026 03:06:22 +0200 Subject: [PATCH 063/112] fix; fix some things for the uefi compilation --- ...b.openbrickprotocolfoundation.oopetris.yml | 1 - platforms/build-uefi.sh | 43 +++++++++++++++++-- platforms/uefi/g++-wrapper.sh | 5 ++- platforms/uefi/gcc-wrapper.sh | 5 ++- src/executables/platforms/3ds/meson.build | 2 +- src/executables/platforms/uefi/libraries.json | 10 +++-- tools/dependencies/meson.build | 3 ++ 7 files changed, 57 insertions(+), 12 deletions(-) diff --git a/io.github.openbrickprotocolfoundation.oopetris.yml b/io.github.openbrickprotocolfoundation.oopetris.yml index 640316ad..06f3fdec 100644 --- a/io.github.openbrickprotocolfoundation.oopetris.yml +++ b/io.github.openbrickprotocolfoundation.oopetris.yml @@ -15,7 +15,6 @@ modules: - --fatal-meson-warnings - -Drun_in_ci=true # note we always want the CI checks in the case we built the flatpak - --force-fallback-for=fmt # note, the freedesktop sdk has this installed, but it is not copiable into the runtime, so we need to build it ourself, to be able to install it correctly - - -Dsdl2_image:test=false # disable failing sdl2_image tests builddir: true build-options: build-args: diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 517e987e..abb06e17 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -80,7 +80,9 @@ source "$SCRIPT_DIR/versions.sh" # shellcheck source=./platforms/helper.sh source "$SCRIPT_DIR/helper.sh" -EDK2_ROOT="$(pwd)/toolchains/edk2" +TOOLCHAIN_DIR="$(pwd)/toolchains" + +EDK2_ROOT="$TOOLCHAIN_DIR/edk2" export EDK2_ROOT export WORKSPACE="$EDK2_ROOT" @@ -94,7 +96,7 @@ fi git -C "$EDK2_ROOT" checkout "$EDK2_RELEASE_TAG" git -C "$EDK2_ROOT" submodule update --init -EDK2_LIBC_ROOT="$(pwd)/toolchains/edk2-libc" +EDK2_LIBC_ROOT="$TOOLCHAIN_DIR/edk2-libc" export EDK2_LIBC_ROOT if [ ! -d "$EDK2_LIBC_ROOT" ]; then @@ -126,7 +128,7 @@ export BUILD_DIR="build/uefi" pushd "$EDK2_ROOT" -make -C BaseTools +make -C BaseTools --quiet >/dev/null 2>&1 set +u @@ -178,6 +180,39 @@ for EDK2_LIB_PACKAGE in "${EDK2_LIB_PACKAGES[@]}"; do done +LIBRARY_PKG_ROOT="$WORKSPACE/LibraryPkg" + +mkdir -p "$LIBRARY_PKG_ROOT" + +EDK2_PORT_NAMES=("SDL2Pkg" "SDL2MixerPkg" "SDL2ImagePkg") +EDK2_PORT_URLS=("https://github.com/Totto16/SDL2_UEFI" "TODO" "TODO ") +EDK2_PORT_TAGS=("uefi_port" "TODO" "TODO") + +for EDK2_PORT_KEY in "${!EDK2_PORT_NAMES[@]}"; do + + EDK2_PORT_NAME="${EDK2_PORT_NAMES[$EDK2_PORT_KEY]}" + EDK2_PORT_URL="${EDK2_PORT_URLS[$EDK2_PORT_KEY]}" + EDK2_PORT_TAG="${EDK2_PORT_TAGS[$EDK2_PORT_KEY]}" + + EDK2_PORT_ROOT="$TOOLCHAIN_DIR/$EDK2_PORT_NAME" + + #TODO: use after sdl2 packages are ported + continue + + if [ ! -d "$EDK2_PORT_ROOT" ]; then + git clone "$EDK2_PORT_URL" "$EDK2_PORT_ROOT" + else + git -C "$EDK2_PORT_ROOT" fetch + fi + + git -C "$EDK2_PORT_ROOT" checkout "$EDK2_PORT_TAG" + + if ! [ -e "$LIBRARY_PKG_ROOT/$EDK2_PORT_NAME" ]; then + link_files_checked "$EDK2_PORT_ROOT" "$LIBRARY_PKG_ROOT/$EDK2_PORT_NAME" + fi + +done + popd export PKG_CONFIG_PATH="$EDK2_ROOT/lib/pkgconfig" @@ -298,7 +333,7 @@ if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "$BUILD_DIR" ]; then "-Dbuildtype=$BUILDTYPE" \ -Ddefault_library=shared \ -Dtests=false \ - --force-fallback-for="fmt,nlohmann_json,magic_enum,utf8cpp,sdl2_ttf,freetype2,spdlog,argparse" \ + --force-fallback-for="fmt,nlohmann_json,magic_enum,utf8cpp,sdl2_ttf,freetype2,spdlog,argparse,sdl2_image,sdl2_mixer,ogg,vorbis,flac" \ --wrap-mode=nofallback \ "-Drun_in_ci=$RUN_IN_CI" #TODO: enable \ #--fatal-meson-warnings diff --git a/platforms/uefi/g++-wrapper.sh b/platforms/uefi/g++-wrapper.sh index cb72dfc7..f2c38d19 100755 --- a/platforms/uefi/g++-wrapper.sh +++ b/platforms/uefi/g++-wrapper.sh @@ -36,6 +36,9 @@ for ARG in "${ARGS[@]}"; do -c) change_mode "compile" ;; + -E) + change_mode "pass" + ;; -Wl,*) change_mode "link" LINK_ARG="${ARG:4}" @@ -122,7 +125,7 @@ for ARG in "${ARGS[@]}"; do -cpp) # ignore this for meson usage, even if gcc only uses this for fortran, but it doesn't complain about it ;; - -v | -E | - | -g | -MD | -pthread | -shared | -std=* | -f* | -m* | -D* | -U* | -W* | -O* | -I*) + -v | - | -g | -P | -MD | -pthread | -shared | -std=* | -f* | -m* | -D* | -U* | -W* | -O* | -I* | -L* | -l*) # ignore, valid arguments ;; -t:use-lib*) diff --git a/platforms/uefi/gcc-wrapper.sh b/platforms/uefi/gcc-wrapper.sh index 64d6b358..dfc2b0be 100755 --- a/platforms/uefi/gcc-wrapper.sh +++ b/platforms/uefi/gcc-wrapper.sh @@ -34,6 +34,9 @@ for ARG in "${ARGS[@]}"; do -c) change_mode "compile" ;; + -E) + change_mode "pass" + ;; -Wl,*) change_mode "link" LINK_ARG="${ARG:4}" @@ -120,7 +123,7 @@ for ARG in "${ARGS[@]}"; do -cpp) # ignore this for meson usage, even if gcc only uses this for fortran, but it doesn't complain about it ;; - -v | -E | - | -g | -MD | -pthread | -shared | -std=* | -f* | -m* | -D* | -U* | -W* | -O* | -I*) + -v | - | -g | -P | -MD | -pthread | -shared | -std=* | -f* | -m* | -D* | -U* | -W* | -O* | -I* | -L* | -l*) # ignore, valid arguments ;; -t:use-lib*) diff --git a/src/executables/platforms/3ds/meson.build b/src/executables/platforms/3ds/meson.build index 33b019e1..2a9e189b 100644 --- a/src/executables/platforms/3ds/meson.build +++ b/src/executables/platforms/3ds/meson.build @@ -6,7 +6,7 @@ _3ds_deps = _3ds_options[2] # libraries -_3ds_dependencies = ['flac', 'freetype2', 'ogg', 'ogg', 'opus', 'opusfile', 'vorbisidec', 'zlib'] +_3ds_dependencies = ['flac', 'freetype2', 'ogg', 'opus', 'opusfile', 'vorbisidec', 'zlib'] _3ds_dependencies_native = ['bz2', 'ctru', 'mad', 'mikmod', 'modplug', 'png16', 'SDL2main'] diff --git a/src/executables/platforms/uefi/libraries.json b/src/executables/platforms/uefi/libraries.json index c3f3d5ad..5a546ffc 100644 --- a/src/executables/platforms/uefi/libraries.json +++ b/src/executables/platforms/uefi/libraries.json @@ -3,12 +3,14 @@ "pkg": "SDL2Pkg", "version": "2.32.10" }, - "sdl2_image": { + "sdl2_image_TODO": { "pkg": "SDL2ImagePkg", - "version": "2.6.3" + "version": "2.6.3", + "comment": "maybe nor port needed?" }, - "sdl2_mixer": { + "sdl2_mixer_TODO": { "pkg": "SDL2MixerPkg", - "version": "2.6.2" + "version": "2.6.2", + "comment": "port this for sure, only use dummy output (no ogg etc needed), as uefi has no audio drivers" } } diff --git a/tools/dependencies/meson.build b/tools/dependencies/meson.build index 9d076437..54737f3a 100644 --- a/tools/dependencies/meson.build +++ b/tools/dependencies/meson.build @@ -332,6 +332,9 @@ if build_application 'SDL2_image', allow_fallback: not only_allow_native_libs, required: true, + default_options: { + 'test': false, + }, ) graphics_lib += { 'deps': [graphics_lib.get('deps'), sdl2_image_dep], From 10b69dfe7ea4f78e917d15c30ba67e1c652cf942 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 4 Aug 2026 03:12:43 +0200 Subject: [PATCH 064/112] fix: fix uefi wrapper scripts - support meson feature detection better --- platforms/uefi/g++-wrapper.sh | 18 ++++++++++++++++-- platforms/uefi/gcc-wrapper.sh | 18 ++++++++++++++++-- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/platforms/uefi/g++-wrapper.sh b/platforms/uefi/g++-wrapper.sh index f2c38d19..afb7afdd 100755 --- a/platforms/uefi/g++-wrapper.sh +++ b/platforms/uefi/g++-wrapper.sh @@ -34,7 +34,11 @@ for ARG in "${ARGS[@]}"; do change_mode "pass" ;; -c) - change_mode "compile" + if [[ "$MODE" == "pass_override" ]]; then + : + else + change_mode "compile" + fi ;; -E) change_mode "pass" @@ -82,6 +86,16 @@ for ARG in "${ARGS[@]}"; do if [[ "$NEXT_TYPE" == "output" ]]; then OUTPUT_FILE="$(normalize_file "$ARG")" reset_next_type + + case "$OUTPUT_FILE" in + *.obj) + # meson compatibility, .obj is used for cc.compiles and cc.sizeof calls + MODE="unknown" + change_mode "pass_override" + ;; + *) ;; + esac + elif [[ "$NEXT_TYPE" == "ignore" ]]; then reset_next_type elif [[ "$NEXT_TYPE" == "link" ]]; then @@ -149,7 +163,7 @@ for ARG in "${ARGS[@]}"; do esac done -if [[ "$MODE" == "pass" ]]; then +if [[ "$MODE" == "pass" ]] || [[ "$MODE" == "pass_override" ]]; then exec "$CXX" "${ARGS[@]}" elif [[ "$MODE" == "compile" ]]; then if [ -z "$OUTPUT_FILE" ]; then diff --git a/platforms/uefi/gcc-wrapper.sh b/platforms/uefi/gcc-wrapper.sh index dfc2b0be..8da4b00c 100755 --- a/platforms/uefi/gcc-wrapper.sh +++ b/platforms/uefi/gcc-wrapper.sh @@ -32,7 +32,11 @@ for ARG in "${ARGS[@]}"; do change_mode "pass" ;; -c) - change_mode "compile" + if [[ "$MODE" == "pass_override" ]]; then + : + else + change_mode "compile" + fi ;; -E) change_mode "pass" @@ -80,6 +84,16 @@ for ARG in "${ARGS[@]}"; do if [[ "$NEXT_TYPE" == "output" ]]; then OUTPUT_FILE="$(normalize_file "$ARG")" reset_next_type + + case "$OUTPUT_FILE" in + *.obj) + # meson compatibility, .obj is used for cc.compiles and cc.sizeof calls + MODE="unknown" + change_mode "pass_override" + ;; + *) ;; + esac + elif [[ "$NEXT_TYPE" == "ignore" ]]; then reset_next_type elif [[ "$NEXT_TYPE" == "link" ]]; then @@ -147,7 +161,7 @@ for ARG in "${ARGS[@]}"; do esac done -if [[ "$MODE" == "pass" ]]; then +if [[ "$MODE" == "pass" ]] || [[ "$MODE" == "pass_override" ]]; then exec "$CC" "${ARGS[@]}" elif [[ "$MODE" == "compile" ]]; then if [ -z "$OUTPUT_FILE" ]; then From 259e9ac5decfa537ecafdb750aa5d3f7d1a93123 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 4 Aug 2026 03:28:16 +0200 Subject: [PATCH 065/112] fix fix sdl2_mixer wrap compilation for uefi --- platforms/build-uefi.sh | 4 +- platforms/uefi/g++-wrapper.sh | 5 +- platforms/uefi/gcc-wrapper.sh | 5 +- src/executables/platforms/uefi/mappings.json | 22 +++++++++ .../sdl2_mixer-2.6.2_example_option.diff | 46 +++++++++++++++++++ subprojects/sdl2_mixer.wrap | 2 +- 6 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 subprojects/packagefiles/sdl2_mixer-2.6.2_example_option.diff diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index abb06e17..b9588fe2 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -236,10 +236,10 @@ export ENDIANESS="little" export ROMFS="platforms/romfs" -export COMMON_FLAGS="'-fexceptions', '-pthread', '-fshort-wchar', '-fno-builtin', '-fno-strict-aliasing', '-fno-common', '-fstack-protector', '-ffunction-sections', '-fdata-sections', '-m64', '-maccumulate-outgoing-args', '-mno-red-zone', '-mcmodel=small', '-fno-asynchronous-unwind-tables', '-fno-omit-frame-pointer'" +export COMMON_FLAGS="'-pthread', '-m64', '-maccumulate-outgoing-args', '-mno-red-zone', '-mcmodel=small'" export LINK_FLAGS="$COMMON_FLAGS" -export COMPILE_FLAGS="$COMMON_FLAGS ,'-D__UEFI__', '-DEFIAPI=__attribute__((ms_abi))', '-DAUDIO_PREFER_MP3'" +export COMPILE_FLAGS="$COMMON_FLAGS ,'-D__UEFI__', '-DEFIAPI=__attribute__((ms_abi))', '-fexceptions', '-fshort-wchar', '-fno-builtin', '-fno-strict-aliasing', '-fno-common', '-fstack-protector', '-ffunction-sections', '-fdata-sections', '-fno-asynchronous-unwind-tables', '-fno-omit-frame-pointer', '-DAUDIO_PREFER_MP3'" export CROSS_FILE="./platforms/crossbuild/uefi.ini" diff --git a/platforms/uefi/g++-wrapper.sh b/platforms/uefi/g++-wrapper.sh index afb7afdd..69c2c836 100755 --- a/platforms/uefi/g++-wrapper.sh +++ b/platforms/uefi/g++-wrapper.sh @@ -47,7 +47,7 @@ for ARG in "${ARGS[@]}"; do change_mode "link" LINK_ARG="${ARG:4}" case "$LINK_ARG" in - --as-needed | --no-undefined | -O* | -soname,* | -rpath,*) + --as-needed | --no-undefined | --whole-archive | --no-whole-archive | -O* | -soname,* | -rpath,*) # ignore, valid arguments ;; --start-group) @@ -100,6 +100,9 @@ for ARG in "${ARGS[@]}"; do reset_next_type elif [[ "$NEXT_TYPE" == "link" ]]; then case "$ARG" in + -pthread | -m*) + # ignore + ;; -l*) DEPENDENCIES_LINK+=("SYSTEM:${ARG:2}") ;; diff --git a/platforms/uefi/gcc-wrapper.sh b/platforms/uefi/gcc-wrapper.sh index 8da4b00c..3419a41d 100755 --- a/platforms/uefi/gcc-wrapper.sh +++ b/platforms/uefi/gcc-wrapper.sh @@ -45,7 +45,7 @@ for ARG in "${ARGS[@]}"; do change_mode "link" LINK_ARG="${ARG:4}" case "$LINK_ARG" in - --as-needed | --no-undefined | -O* | -soname,* | -rpath,*) + --as-needed | --no-undefined | --whole-archive | --no-whole-archive | -O* | -soname,* | -rpath,*) # ignore, valid arguments ;; --start-group) @@ -98,6 +98,9 @@ for ARG in "${ARGS[@]}"; do reset_next_type elif [[ "$NEXT_TYPE" == "link" ]]; then case "$ARG" in + -pthread | -m*) + # ignore + ;; -l*) DEPENDENCIES_LINK+=("SYSTEM:${ARG:2}") ;; diff --git a/src/executables/platforms/uefi/mappings.json b/src/executables/platforms/uefi/mappings.json index ef9bea72..52104f2f 100644 --- a/src/executables/platforms/uefi/mappings.json +++ b/src/executables/platforms/uefi/mappings.json @@ -54,6 +54,20 @@ "lib": "LibSpdlog", "guid": "dee047db-15c9-4d79-ab08-79d6244d9b0e", "version": "spdlog" + }, + "SDL2ImagePkg": { + "type": "library", + "name": "SDL2ImageLib", + "lib": "LibSDL2Image", + "guid": "80834111-5231-4b9d-b781-381bc4a7ac38", + "version": "sdl2_image" + }, + "SDL2MixerPkg": { + "type": "library", + "name": "SDL2MixerLib", + "lib": "LibSDL2Mixer", + "guid": "9a0df316-4a64-4336-99b2-09af1e8f7e53", + "version": "sdl2_mixer" } }, "name": { @@ -87,6 +101,14 @@ }, "oopetris": { "meson": "oopetris" + }, + "libsdl2image": { + "name": "SDL2ImagePkg", + "meson": "sdl2_image" + }, + "libsdl2mixer": { + "name": "SDL2MixerPkg", + "meson": "sdl2_mixer" } } } diff --git a/subprojects/packagefiles/sdl2_mixer-2.6.2_example_option.diff b/subprojects/packagefiles/sdl2_mixer-2.6.2_example_option.diff new file mode 100644 index 00000000..49100f08 --- /dev/null +++ b/subprojects/packagefiles/sdl2_mixer-2.6.2_example_option.diff @@ -0,0 +1,46 @@ +diff --git a/meson.build b/meson.build +index b354993..563c3cc 100644 +--- a/meson.build ++++ b/meson.build +@@ -73,14 +73,17 @@ sdl2_mixer_dep = declare_dependency( + link_with: sdl2_mixer_lib, + ) + +-if sdl2_dep.type_name() == 'internal' +- sdl2main_dep = dependency('sdl2main') +-else +- sdl2main_dep = cc.find_library('SDL2main') +-endif ++if get_option('example') ++ if sdl2_dep.type_name() == 'internal' ++ sdl2main_dep = dependency('sdl2main') ++ else ++ sdl2main_dep = cc.find_library('SDL2main') ++ endif + +-executable( +- 'playmus', +- 'playmus.c', +- dependencies: [sdl2_dep, sdl2main_dep, sdl2_mixer_dep], +-) ++ executable( ++ 'playmus', ++ 'playmus.c', ++ dependencies: [sdl2_dep, sdl2main_dep, sdl2_mixer_dep], ++ ) ++ ++endif +diff --git a/meson_options.txt b/meson_options.txt +index 34a5d2a..58ee5ab 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -15,3 +15,9 @@ option( + description: 'Opus support', + ) + ++option( ++ 'example', ++ type: 'boolean', ++ description: 'compile the example', ++ value: false ++) diff --git a/subprojects/sdl2_mixer.wrap b/subprojects/sdl2_mixer.wrap index 080986ec..86264017 100644 --- a/subprojects/sdl2_mixer.wrap +++ b/subprojects/sdl2_mixer.wrap @@ -8,7 +8,7 @@ patch_url = https://wrapdb.mesonbuild.com/v2/sdl2_mixer_2.6.2-4/get_patch patch_hash = 127025fa0666dd3ea66fb7c334182c393a748fb78810c6a44cdc1a85d619d934 source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/sdl2_mixer_2.6.2-4/SDL2_mixer-2.6.2.tar.gz wrapdb_version = 2.6.2-4 -diff_files = sdl2_mixer-2.6.2_correct_flac_wrap.diff +diff_files = sdl2_mixer-2.6.2_correct_flac_wrap.diff, sdl2_mixer-2.6.2_example_option.diff [provide] sdl2_mixer = sdl2_mixer_dep From a9c05860a6eb39481dc0371b26c384703fca4be7 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 4 Aug 2026 03:41:16 +0200 Subject: [PATCH 066/112] fix: add mappings for temporary packages for sdl2 mixer and image for uefi --- platforms/uefi/extract-definitions.sh | 2 +- src/executables/platforms/uefi/mappings.json | 50 ++++++++++++++++++-- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 7b756dc8..7169c6c4 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -260,7 +260,7 @@ elif [ "$MESON_TARGETS_INFO_LIB_TYPE" == "executable" ] || [ "$MESON_TARGETS_INF echo "TODO" # exit 34 else - echo "Error: invalid meson target type: $MESON_TARGETS_INFO_LIB_TYPE" >&2 + echo "Error: invalid meson target type fo '$SOURCE_FILE_ENTRY_MESON_NAME': $MESON_TARGETS_INFO_LIB_TYPE" >&2 exit 2 fi diff --git a/src/executables/platforms/uefi/mappings.json b/src/executables/platforms/uefi/mappings.json index 52104f2f..33690d11 100644 --- a/src/executables/platforms/uefi/mappings.json +++ b/src/executables/platforms/uefi/mappings.json @@ -62,12 +62,33 @@ "guid": "80834111-5231-4b9d-b781-381bc4a7ac38", "version": "sdl2_image" }, - "SDL2MixerPkg": { + "REMOVE_SDL2MixerPkg": { "type": "library", "name": "SDL2MixerLib", "lib": "LibSDL2Mixer", "guid": "9a0df316-4a64-4336-99b2-09af1e8f7e53", "version": "sdl2_mixer" + }, + "REMOVE_VorbisPkg": { + "type": "library", + "name": "VorbisLib", + "lib": "LibVorbis", + "guid": "9a0df316-4a64-4336-99b2-09af1e8f7e53", + "version": "vorbis" + }, + "REMOVE_OggPkg": { + "type": "library", + "name": "OggLib", + "lib": "LibOgg", + "guid": "9a0df316-4a64-4336-99b2-09af1e8f7e53", + "version": "ogg" + }, + "REMOVE_FlacPkg": { + "type": "library", + "name": "FlacLib", + "lib": "LibFlac", + "guid": "9a0df316-4a64-4336-99b2-09af1e8f7e53", + "version": "flac" } }, "name": { @@ -104,11 +125,32 @@ }, "libsdl2image": { "name": "SDL2ImagePkg", - "meson": "sdl2_image" + "meson": "sdl2image" }, "libsdl2mixer": { - "name": "SDL2MixerPkg", - "meson": "sdl2_mixer" + "name": "REMOVE_SDL2MixerPkg", + "meson": "sdl2mixer" + }, + "libvorbisfile": { + "name": "REMOVE_VorbisPkg", + "meson": "vorbisfile" + }, + "libvorbis": { + "name": "REMOVE_VorbisPkg", + "meson": "vorbis" + }, + "libogg": { + "name": "REMOVE_OggPkg", + "meson": "ogg" + }, + "libFLAC": { + "name": "REMOVE_FlacPkg", + "meson": "FLAC" + }, + "libflac_avx2": { + "name": "REMOVE_FlacPkg", + "meson": "flac_avx2", + "comment":"this is detect wrongly" } } } From 6b21effd613f8ad7926e7a6d463d9cb892fe957a Mon Sep 17 00:00:00 2001 From: Totto16 Date: Wed, 5 Aug 2026 16:48:37 +0200 Subject: [PATCH 067/112] fix: fix CXX and CC flags errors - use CCONLY flags for cc only argument (like c std) --- platforms/build-uefi.sh | 13 ++++------- platforms/uefi/cxx_compiler.diff | 33 ++++++++++++++++++++------- platforms/uefi/extract-definitions.sh | 6 ++--- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index b9588fe2..d78b70c0 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -14,7 +14,7 @@ export BUILDTYPE="debug" export RUN_IN_CI="false" -export RUNTIME_TARGET="emulator" +export RUNTIME_TARGET="hardware" if [ "$#" -eq 0 ]; then # nothing @@ -217,11 +217,8 @@ popd export PKG_CONFIG_PATH="$EDK2_ROOT/lib/pkgconfig" -export CC_WRAPPER="$SCRIPT_DIR/uefi/gcc-wrapper.sh" -export CXX_WRAPPER="$SCRIPT_DIR/uefi/g++-wrapper.sh" - -export CC="gcc-15" -export CXX="g++-15" +export CC="$SCRIPT_DIR/uefi/gcc-wrapper.sh" +export CXX="$SCRIPT_DIR/uefi/g++-wrapper.sh" export AR="$SCRIPT_DIR/uefi/ar-wrapper.sh" export RANLIB="" @@ -262,8 +259,8 @@ endian = '$ENDIANESS' edk2_root = '$EDK2_ROOT' [binaries] -c = '$CC_WRAPPER' -cpp = '$CXX_WRAPPER' +c = '$CC' +cpp = '$CXX' ar = '$AR' ranlib = '$RANLIB' strip = '$STRIP' diff --git a/platforms/uefi/cxx_compiler.diff b/platforms/uefi/cxx_compiler.diff index 4e46f91d..4ab79c0c 100644 --- a/platforms/uefi/cxx_compiler.diff +++ b/platforms/uefi/cxx_compiler.diff @@ -1,21 +1,38 @@ -diff --git a/BaseTools/Conf/build_rule.template b/BaseTools/Conf/build_rule.template -index 0c454ee3d5..4b9d63e912 100755 ---- a/BaseTools/Conf/build_rule.template -+++ b/BaseTools/Conf/build_rule.template -@@ -144,13 +144,13 @@ +diff --git a/BaseTools/Conf/build_rule.template b/BaseTools/Conf/build_rule.template +index 0c454ee3d5..9e13b638f8 100755 +--- a/BaseTools/Conf/build_rule.template ++++ b/BaseTools/Conf/build_rule.template +@@ -121,13 +121,13 @@ + $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj + + +- "$(CC)" /Fo${dst} $(DEPS_FLAGS) $(CC_FLAGS) $(INC) ${src} ++ "$(CC)" /Fo${dst} $(DEPS_FLAGS) $(CCONLY_FLAGS) $(CC_FLAGS) $(INC) ${src} + + +- "$(CC)" $(DEPS_FLAGS) $(CC_FLAGS) -c -o ${dst} $(INC) ${src} ++ "$(CC)" $(DEPS_FLAGS) $(CCONLY_FLAGS) $(CC_FLAGS) -c -o ${dst} $(INC) ${src} + + +- "$(CC)" $(DEPS_FLAGS) $(CC_FLAGS) -o ${dst} $(INC) ${src} ++ "$(CC)" $(DEPS_FLAGS) $(CCONLY_FLAGS) $(CC_FLAGS) -o ${dst} $(INC) ${src} + + [Cxx-Code-File] + +@@ -144,13 +144,13 @@ $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj - "$(CC)" /Fo${dst} $(DEPS_FLAGS) $(CC_FLAGS) $(CXX_FLAGS) $(INC) ${src} -+ "$(CXX)" /Fo${dst} $(DEPS_FLAGS) $(CXX_FLAGS) $(INC) ${src} ++ "$(CC)" /TODO:x=c++ /Fo${dst} $(DEPS_FLAGS) $(CC_FLAGS) $(CXX_FLAGS) $(INC) ${src} - "$(CC)" $(DEPS_FLAGS) $(CC_FLAGS) $(CXX_FLAGS) -c -o ${dst} $(INC) ${src} -+ "$(CXX)" $(DEPS_FLAGS) $(CXX_FLAGS) -c -o ${dst} $(INC) ${src} ++ "$(CC)" -x c++ $(DEPS_FLAGS) $(CC_FLAGS) $(CXX_FLAGS) -c -o ${dst} $(INC) ${src} - "$(CC)" $(DEPS_FLAGS) $(CC_FLAGS) $(CXX_FLAGS) -o ${dst} $(INC) ${src} -+ "$(CXX)" $(DEPS_FLAGS) $(CXX_FLAGS) -o ${dst} $(INC) ${src} ++ "$(CC)" -x c++ $(DEPS_FLAGS) $(CC_FLAGS) $(CXX_FLAGS) -o ${dst} $(INC) ${src} [C-Code-File.BASE.AARCH64,C-Code-File.SEC.AARCH64,C-Code-File.PEI_CORE.AARCH64,C-Code-File.PEIM.AARCH64] diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 7169c6c4..9e25d8e0 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -242,7 +242,7 @@ for MESON_TARGETS_INFO_LIB_PARAMATER in "${MESON_TARGETS_INFO_LIB_PARAMATERS[@]} DEP_INCLUDES+=("${MESON_TARGETS_INFO_LIB_PARAMATER:2}") ;; -D*) - DEP_BUILD_OPTIONS+=("*_*_*_*_FLAGS = ${MESON_TARGETS_INFO_LIB_PARAMATER}") + DEP_BUILD_OPTIONS+=("*_*_*_*_FLAGS = \"${MESON_TARGETS_INFO_LIB_PARAMATER}\"") ;; -t:use-lib:pkg=*) DEP_PACKAGE_NAME="${MESON_TARGETS_INFO_LIB_PARAMATER:15}" @@ -310,7 +310,7 @@ $(expand_array_inf "${DEP_PACKAGES[@]}") [Pcd] [BuildOptions] - *_*_*_CC_FLAGS = -std=c11 + *_*_*_CCONLY_FLAGS = -std=c11 *_*_*_CXX_FLAGS = -std=c++23 $(expand_array_inf "${DEP_BUILD_OPTIONS[@]}") @@ -348,7 +348,7 @@ $(expand_array_inf "${DEP_PACKAGES[@]}") UefiLib [BuildOptions] - *_*_*_CC_FLAGS = -std=c11 + *_*_*_CCONLY_FLAGS = -std=c11 *_*_*_CXX_FLAGS = -std=c++23 $(expand_array_inf "${DEP_BUILD_OPTIONS[@]}") From 0898cfc258a123eaff42b7bb142aa78f01df6e30 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Wed, 5 Aug 2026 18:09:07 +0200 Subject: [PATCH 068/112] fix: fix some c++ and cc related issues in the uefi compilation --- platforms/build-uefi.sh | 23 +++++++++++++++++------ platforms/uefi/extract-definitions.sh | 23 +++++++++++++++++++---- platforms/uefi/g++-wrapper.sh | 4 ++-- platforms/uefi/gcc-wrapper.sh | 4 ++-- src/lobby/credentials/secret.hpp | 4 ++-- 5 files changed, 42 insertions(+), 16 deletions(-) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index d78b70c0..04b5964c 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -215,8 +215,6 @@ done popd -export PKG_CONFIG_PATH="$EDK2_ROOT/lib/pkgconfig" - export CC="$SCRIPT_DIR/uefi/gcc-wrapper.sh" export CXX="$SCRIPT_DIR/uefi/g++-wrapper.sh" @@ -235,8 +233,17 @@ export ROMFS="platforms/romfs" export COMMON_FLAGS="'-pthread', '-m64', '-maccumulate-outgoing-args', '-mno-red-zone', '-mcmodel=small'" +export SYS_ROOT="$EDK2_ROOT" + +export PKG_CONFIG_PATH="$SYS_ROOT/lib/pkgconfig" + export LINK_FLAGS="$COMMON_FLAGS" -export COMPILE_FLAGS="$COMMON_FLAGS ,'-D__UEFI__', '-DEFIAPI=__attribute__((ms_abi))', '-fexceptions', '-fshort-wchar', '-fno-builtin', '-fno-strict-aliasing', '-fno-common', '-fstack-protector', '-ffunction-sections', '-fdata-sections', '-fno-asynchronous-unwind-tables', '-fno-omit-frame-pointer', '-DAUDIO_PREFER_MP3'" +export COMPILE_FLAGS="$COMMON_FLAGS ,'--sysroot=${SYS_ROOT}', '-D__UEFI__', '-DEFIAPI=__attribute__((ms_abi))', '-fexceptions', '-fshort-wchar', '-fno-builtin', '-fno-strict-aliasing', '-fno-common', '-fstack-protector', '-ffunction-sections', '-fdata-sections', '-fno-asynchronous-unwind-tables', '-fno-omit-frame-pointer', '-DAUDIO_PREFER_MP3'" + +export CC_COMPILE_FLAGS="'-nostdinc', '-isystem=$WORKSPACE/StdLib/Include', '-isystem=$WORKSPACE/StdLib/Include/$EDK2_TARGET_PROPERTIES_ARCH'," + +#TODO use libc++ built for UEFI +export CXX_COMPILE_FLAGS="'-fno-exceptions', '-fno-rtti', '-fno-threadsafe-statics', '-fno-use-cxa-atexit', '-fno-unwind-tables', '-fno-asynchronous-unwind-tables'" export CROSS_FILE="./platforms/crossbuild/uefi.ini" @@ -273,13 +280,16 @@ cmake = '' [built-in options] c_std = 'c11' cpp_std = 'c++23' -c_args = [$COMPILE_FLAGS] -cpp_args = [$COMPILE_FLAGS] +c_args = [$COMPILE_FLAGS, $CC_COMPILE_FLAGS] +cpp_args = [$COMPILE_FLAGS, $CXX_COMPILE_FLAGS] c_link_args = [$LINK_FLAGS] cpp_link_args = [$LINK_FLAGS] +prefix = '$SYS_ROOT' + [properties] pkg_config_libdir = '$PKG_CONFIG_PATH' +sys_root = '${SYS_ROOT}' needs_exe_wrapper = true APP_ROMFS='$ROMFS/assets/' @@ -291,7 +301,7 @@ CMAKE_FIND_ROOT_PATH_MODE_LIBRARY = 'ONLY' CMAKE_FIND_ROOT_PATH_MODE_INCLUDE = 'ONLY' CMAKE_FIND_ROOT_PATH_MODE_PACKAGE = 'ONLY' -CMAKE_FIND_ROOT_PATH = '' +CMAKE_FIND_ROOT_PATH = '$SYS_ROOT/usr/lib/cmake' EOF @@ -325,6 +335,7 @@ EOF if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "$BUILD_DIR" ]; then meson setup "$BUILD_DIR" \ + "--prefix=$SYS_ROOT" \ "--wipe" \ --cross-file "$CROSS_FILE" \ "-Dbuildtype=$BUILDTYPE" \ diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 9e25d8e0..c4ae5ade 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -241,15 +241,26 @@ for MESON_TARGETS_INFO_LIB_PARAMATER in "${MESON_TARGETS_INFO_LIB_PARAMATERS[@]} -I*) DEP_INCLUDES+=("${MESON_TARGETS_INFO_LIB_PARAMATER:2}") ;; - -D*) - DEP_BUILD_OPTIONS+=("*_*_*_*_FLAGS = \"${MESON_TARGETS_INFO_LIB_PARAMATER}\"") + -W*) + # TODO: include warnings + ;; + -nostdinc | -D* | --sysroot=* | -isystem=*) + DEP_BUILD_OPTIONS+=("*_*_*_CC_FLAGS = \"${MESON_TARGETS_INFO_LIB_PARAMATER}\"") ;; -t:use-lib:pkg=*) DEP_PACKAGE_NAME="${MESON_TARGETS_INFO_LIB_PARAMATER:15}" DEP_PACKAGES+=("LibraryPkg/$DEP_PACKAGE_NAME/$DEP_PACKAGE_NAME.dec") ;; - - *) ;; + -t:use-lib:name=*) + #ignore + ;; + -g | -pthread | -std=* | -f* | -m* | -O*) + #ignore + ;; + *) + echo "Invalid argument detected for compiling '$SOURCE_FILE_ENTRY_MESON_NAME': '$MESON_TARGETS_INFO_LIB_PARAMATER'" >&2 + exit 6 + ;; esac done @@ -277,6 +288,10 @@ fi if [ "$MAPPING_TYPE" == "application" ]; then + # add include directories to the build options + for DEP_INCLUDE in "${DEP_INCLUDES[@]}"; do + DEP_BUILD_OPTIONS+=("*_*_*_CC_FLAGS = \"-I${DEP_INCLUDE}\"") + done validate_parent_dir "$DEST_FILE" cat <"$DEST_FILE" diff --git a/platforms/uefi/g++-wrapper.sh b/platforms/uefi/g++-wrapper.sh index 69c2c836..11bdd8c0 100755 --- a/platforms/uefi/g++-wrapper.sh +++ b/platforms/uefi/g++-wrapper.sh @@ -68,7 +68,7 @@ for ARG in "${ARGS[@]}"; do -o) change_next_type "output" ;; - -MQ | -MF) + -MQ | -MF | -isystem) change_next_type "ignore" ;; --version | -dM) @@ -142,7 +142,7 @@ for ARG in "${ARGS[@]}"; do -cpp) # ignore this for meson usage, even if gcc only uses this for fortran, but it doesn't complain about it ;; - -v | - | -g | -P | -MD | -pthread | -shared | -std=* | -f* | -m* | -D* | -U* | -W* | -O* | -I* | -L* | -l*) + -v | - | -g | -P | -MD | -pthread | -shared | -nostdinc | -isystem=* | --sysroot=* | -std=* | -f* | -m* | -D* | -U* | -W* | -O* | -I* | -L* | -l*) # ignore, valid arguments ;; -t:use-lib*) diff --git a/platforms/uefi/gcc-wrapper.sh b/platforms/uefi/gcc-wrapper.sh index 3419a41d..115f41f2 100755 --- a/platforms/uefi/gcc-wrapper.sh +++ b/platforms/uefi/gcc-wrapper.sh @@ -66,7 +66,7 @@ for ARG in "${ARGS[@]}"; do -o) change_next_type "output" ;; - -MQ | -MF) + -MQ | -MF | -isystem) change_next_type "ignore" ;; --version | -dM) @@ -140,7 +140,7 @@ for ARG in "${ARGS[@]}"; do -cpp) # ignore this for meson usage, even if gcc only uses this for fortran, but it doesn't complain about it ;; - -v | - | -g | -P | -MD | -pthread | -shared | -std=* | -f* | -m* | -D* | -U* | -W* | -O* | -I* | -L* | -l*) + -v | - | -g | -P | -MD | -pthread | -shared | -nostdinc | -isystem=* | --sysroot=* | -std=* | -f* | -m* | -D* | -U* | -W* | -O* | -I* | -L* | -l*) # ignore, valid arguments ;; -t:use-lib*) diff --git a/src/lobby/credentials/secret.hpp b/src/lobby/credentials/secret.hpp index 71b231b3..2297ddda 100644 --- a/src/lobby/credentials/secret.hpp +++ b/src/lobby/credentials/secret.hpp @@ -11,7 +11,7 @@ #include "helper/export_symbols.hpp" #include "manager/service_provider.hpp" -#if defined(__linux__) +#if defined(__linux__) && !defined(__UEFI__) #if defined(__GNUC__) #pragma GCC diagnostic push @@ -43,7 +43,7 @@ namespace secret { [[maybe_unused]] ServiceProvider* m_service_provider; KeyringType m_type; -#if defined(__linux__) || defined(__ANDROID__) +#if (defined(__linux__) && !defined(__UEFI__)) || defined(__ANDROID__) key_serial_t m_ring_id; #elif defined(__CONSOLE__) || defined(__APPLE__) std::string m_file_path; From a6e6ec4c15211c750652dfdee2cf95696197ba4b Mon Sep 17 00:00:00 2001 From: Totto16 Date: Wed, 5 Aug 2026 18:13:41 +0200 Subject: [PATCH 069/112] feat: add simple uefi main --- src/executables/game/main.cpp | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/executables/game/main.cpp b/src/executables/game/main.cpp index d07dc7cf..8ea2ae0b 100644 --- a/src/executables/game/main.cpp +++ b/src/executables/game/main.cpp @@ -71,9 +71,11 @@ namespace { if (not created_log_dir.has_value()) { - sinks.push_back(std::make_shared( - fmt::format("{}/oopetris.log", logs_path.string()), 1024 * 1024 * 10, 5, true - )); + sinks.push_back( + std::make_shared( + fmt::format("{}/oopetris.log", logs_path.string()), 1024 * 1024 * 10, 5, true + ) + ); } #endif @@ -174,3 +176,26 @@ namespace { int main(int argc, char** argv) { return main_no_sdl_replace(argc, argv); } + +#if defined(__UEFI__) + +#include +#include +#include + +extern "C" { + +EFI_STATUS EFIAPI UefiMain(IN EFI_HANDLE imgHandle, IN EFI_SYSTEM_TABLE* sysTable) { + //TODO: correctly initialize every systems, even that edk2 supports constructors for used libraries + gST = sysTable; + gBS = sysTable->BootServices; + gImageHandle = imgHandle; + + int result = main(0, nullptr); + + return result == 0 ? EFI_SUCCESS : RETURN_LOAD_ERROR; +} +} + + +#endif From 3f2cb90c8f7d3a0ae36a63c4f071ac65487b3480 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Wed, 5 Aug 2026 18:45:04 +0200 Subject: [PATCH 070/112] fix: fix librares includes for uefi build system --- platforms/build-uefi.sh | 12 +++- platforms/uefi/extract-definitions.sh | 64 ++++++++++++++++++- platforms/uefi/pkg-config-wrapper.sh | 2 + src/executables/platforms/uefi/libraries.json | 3 + 4 files changed, 77 insertions(+), 4 deletions(-) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 04b5964c..495d08d8 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -150,6 +150,16 @@ else exit 1 fi +# add stdlib to active platform + +STDLIB_PACKAGE_INCLUDE="!include StdLib/StdLib.inc" + +if grep -q "$STDLIB_PACKAGE_INCLUDE" "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM"; then + : # found already, do nothing +else + echo -e "$STDLIB_PACKAGE_INCLUDE\n" >>"$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" +fi + EDK2_TARGET_PROPERTIES_BUILDTYPE="$(echo "$BUILDTYPE" | tr "[:lower:]" "[:upper:]")" EDK2_TARGET_PROPERTIES_ARCH="X64" @@ -170,7 +180,7 @@ export EDK2_BUILD_COMMAND="$EDK2_POSIX_BIN_PATH/build" # add links to needed packages -EDK2_LIB_PACKAGES=("StdLib" "StdLibPrivateInternalFiles") +EDK2_LIB_PACKAGES=("AppPkg" "StdLib" "StdLibPrivateInternalFiles") for EDK2_LIB_PACKAGE in "${EDK2_LIB_PACKAGES[@]}"; do diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index c4ae5ade..49cabc4e 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -105,8 +105,29 @@ add_component_to_platform() { if grep -q "$FINAL_PKG_NAME" "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM"; then : # found already, do nothing else - echo "[Components]" >>"$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" - echo " $FINAL_PKG_NAME" >>"$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" + cat <>"$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" +[Components] + $FINAL_PKG_NAME + +EOF + + fi + +} + +add_include_to_platform() { + local PACKAGE_NAME="$1" + + local FINAL_PKG_INC_NAME="GeneratedPackages/$PACKAGE_NAME" + + if grep -q "$FINAL_PKG_INC_NAME" "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM"; then + : # found already, do nothing + else + cat <>"$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" +!include $FINAL_PKG_INC_NAME + +EOF + fi } @@ -131,6 +152,8 @@ link_package() { add_component_to_platform "$PACKAGE_NAME" elif [ "$SOURCE_FILE_EXT" == "dec" ]; then : + elif [ "$SOURCE_FILE_EXT" == "inc" ]; then + add_include_to_platform "$PACKAGE_NAME" else echo "Invalid package extension in link_package '$SOURCE_FILE_EXT'" >&2 exit 2 @@ -140,6 +163,7 @@ link_package() { DEP_SOURCES=() DEP_PACKAGES=() +DEP_CLASSES=() DEP_BUILD_OPTIONS=() for FILE_DEPENDENCY in "${FILE_DEPENDENCIES[@]}"; do @@ -178,6 +202,20 @@ for FILE_DEPENDENCY in "${FILE_DEPENDENCIES[@]}"; do exit 2 fi + MAPPING_ENTRY_FOR_LIB="$(jq -M -r -c ".[\"file\"][\"${MAPPING_ENTRY_DEP_NAME}\"]" "$MAPPINGS_FILE")" + + if [ "$MAPPING_ENTRY_FOR_LIB" = "null" ]; then + echo "Error: invalid name '$MAPPING_ENTRY_DEP_NAME': not found in mappings 'file'" >&2 + exit 2 + fi + + MAPPING_ENTRY_DEP_LIB="$(echo "$MAPPING_ENTRY_FOR_LIB" | jq -M -r -c ".[\"lib\"]")" + + if [ "$MAPPING_ENTRY_DEP_LIB" = "null" ]; then + echo "Error: invalid lib name '$MAPPING_ENTRY_DEP_LIB': not found in dependency mapping 'lib'" >&2 + exit 2 + fi + PACKAGE_NAME="GeneratedPackages/Lib/$MAPPING_ENTRY_DEP_NAME.dec" DEP_OUTPUT_FILE="$DEST_FILE_DIR/$MAPPING_ENTRY_DEP_NAME.inf" @@ -187,6 +225,7 @@ for FILE_DEPENDENCY in "${FILE_DEPENDENCIES[@]}"; do fi DEP_PACKAGES+=("$PACKAGE_NAME") + DEP_CLASSES+=("$MAPPING_ENTRY_DEP_LIB") else echo "Error: invalid source file type: $FILE_DEPENDENCY_TYPE" >&2 exit 2 @@ -254,6 +293,10 @@ for MESON_TARGETS_INFO_LIB_PARAMATER in "${MESON_TARGETS_INFO_LIB_PARAMATERS[@]} -t:use-lib:name=*) #ignore ;; + -t:use-lib:lib=*) + DEP_PACKAGE_LIB="${MESON_TARGETS_INFO_LIB_PARAMATER:15}" + DEP_CLASSES+=("$DEP_PACKAGE_LIB") + ;; -g | -pthread | -std=* | -f* | -m* | -O*) #ignore ;; @@ -308,11 +351,14 @@ $(expand_array_inf "${DEP_SOURCES[@]}") [Packages] MdePkg/MdePkg.dec + StdLib/StdLib.dec $(expand_array_inf "${DEP_PACKAGES[@]}") [LibraryClasses] UefiApplicationEntryPoint UefiLib + LibC +$(expand_array_inf "${DEP_CLASSES[@]}") [Guids] @@ -357,10 +403,13 @@ $(expand_array_inf "${DEP_SOURCES[@]}") [Packages] MdePkg/MdePkg.dec + StdLib/StdLib.dec $(expand_array_inf "${DEP_PACKAGES[@]}") [LibraryClasses] UefiLib + LibC +$(expand_array_inf "${DEP_CLASSES[@]}") [BuildOptions] *_*_*_CCONLY_FLAGS = -std=c11 @@ -384,11 +433,20 @@ EOF $(expand_array_inf "${DEP_INCLUDES[@]}") [LibraryClasses] - ##TODO +# None # TODO, also add dsc? with ,.inf mappings EOF link_package "Lib/$DEST_FILE_STEM.dec" "$LIB_DEST_FILE_DEC" + LIB_DEST_FILE_INC="$LIB_DEST_DIR/$DEST_FILE_STEM.inc" + + cat <"$LIB_DEST_FILE_INC" +[LibraryClasses.common] + $MAPPING_LIB_NAME|GeneratedPackages/Lib/$DEST_FILE_STEM.inf +EOF + + link_package "Lib/$DEST_FILE_STEM.inc" "$LIB_DEST_FILE_INC" + else echo "Error: invalid mapping type: $MAPPING_TYPE" >&2 exit 2 diff --git a/platforms/uefi/pkg-config-wrapper.sh b/platforms/uefi/pkg-config-wrapper.sh index 25f336f2..9c361795 100755 --- a/platforms/uefi/pkg-config-wrapper.sh +++ b/platforms/uefi/pkg-config-wrapper.sh @@ -90,10 +90,12 @@ elif [[ "$MODE" == "get" ]]; then elif [[ "$WHAT" == "cflags" ]]; then echo "-t:use-lib:name=$PACKAGE_NAME" echo "-t:use-lib:pkg=$(echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"pkg\"]")" + echo "-t:use-lib:lib=$(echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"lib\"]")" exit 0 elif [[ "$WHAT" == "libflags" ]]; then echo "-Wl,-t:use-lib:name=$PACKAGE_NAME" echo "-Wl,-t:use-lib:pkg=$(echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"pkg\"]")" + echo "-Wl,-t:use-lib:lib=$(echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"lib\"]")" exit 0 else echo "<$TOOL> ${ARGS[*]}" >&2 diff --git a/src/executables/platforms/uefi/libraries.json b/src/executables/platforms/uefi/libraries.json index 5a546ffc..e0a2fe5f 100644 --- a/src/executables/platforms/uefi/libraries.json +++ b/src/executables/platforms/uefi/libraries.json @@ -1,15 +1,18 @@ { "sdl2": { "pkg": "SDL2Pkg", + "lib": "SDL2Lib", "version": "2.32.10" }, "sdl2_image_TODO": { "pkg": "SDL2ImagePkg", + "lib": "sdl2_image_TODO", "version": "2.6.3", "comment": "maybe nor port needed?" }, "sdl2_mixer_TODO": { "pkg": "SDL2MixerPkg", + "lib": "sdl2_mixer_TODO", "version": "2.6.2", "comment": "port this for sure, only use dummy output (no ogg etc needed), as uefi has no audio drivers" } From 85f625a4c470e782a060c3767165457ca04942c1 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Wed, 5 Aug 2026 19:07:42 +0200 Subject: [PATCH 071/112] fix: also generate inc files for pkg-config dependencies, that are not compiled by us --- platforms/uefi/pkg-config-wrapper.sh | 55 +++++++++++++++++-- src/executables/platforms/uefi/libraries.json | 2 +- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/platforms/uefi/pkg-config-wrapper.sh b/platforms/uefi/pkg-config-wrapper.sh index 9c361795..9a737a33 100755 --- a/platforms/uefi/pkg-config-wrapper.sh +++ b/platforms/uefi/pkg-config-wrapper.sh @@ -36,6 +36,41 @@ change_mode() { fi } +UEFI_INFO_FILE="$(realpath "$SCRIPT_DIR/../crossbuild/uefi_info.json")" +EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM="$(jq -M -r -c '.["platform"]' "$UEFI_INFO_FILE")" + +link_built_libray() { + local PACKAGE_NAME="$1" + local PACKAGE_NAME_PKG="$2" + local PACKAGE_NAME_LIB="$3" + + local FINAL_PKG_NAME="LibraryPkg/$PACKAGE_NAME_PKG/$PACKAGE_NAME_PKG.inf" + + if grep -q "$FINAL_PKG_NAME" "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM"; then + : # found already, do nothing + else + cat <>"$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" +[Components] + $FINAL_PKG_NAME + +EOF + + fi + + local FINAL_PKG_INC_NAME="LibraryPkg/$PACKAGE_NAME_PKG/$PACKAGE_NAME_PKG.inc" + + if grep -q "$FINAL_PKG_INC_NAME" "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM"; then + : # found already, do nothing + else + cat <>"$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" +!include $FINAL_PKG_INC_NAME + +EOF + + fi + +} + WHAT="" PACKAGE_NAME="" NEXT_IS_PACKAGE_NAME="false" @@ -88,14 +123,26 @@ elif [[ "$MODE" == "get" ]]; then echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"version\"]" exit 0 elif [[ "$WHAT" == "cflags" ]]; then + PACKAGE_NAME_PKG="$(echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"pkg\"]")" + PACKAGE_NAME_LIB="$(echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"lib\"]")" + echo "-t:use-lib:name=$PACKAGE_NAME" - echo "-t:use-lib:pkg=$(echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"pkg\"]")" - echo "-t:use-lib:lib=$(echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"lib\"]")" + echo "-t:use-lib:pkg=$PACKAGE_NAME_PKG" + echo "-t:use-lib:lib=$PACKAGE_NAME_LIB" + + link_built_libray "$PACKAGE_NAME" "$PACKAGE_NAME_PKG" "$PACKAGE_NAME_LIB" + exit 0 elif [[ "$WHAT" == "libflags" ]]; then + PACKAGE_NAME_PKG="$(echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"pkg\"]")" + PACKAGE_NAME_LIB="$(echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"lib\"]")" + echo "-Wl,-t:use-lib:name=$PACKAGE_NAME" - echo "-Wl,-t:use-lib:pkg=$(echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"pkg\"]")" - echo "-Wl,-t:use-lib:lib=$(echo "$LIBRARY_ENTRY" | jq -M -r -c ".[\"lib\"]")" + echo "-Wl,-t:use-lib:pkg=$PACKAGE_NAME_PKG" + echo "-Wl,-t:use-lib:lib=$PACKAGE_NAME_LIB" + + link_built_libray "$PACKAGE_NAME" "$PACKAGE_NAME_PKG" "$PACKAGE_NAME_LIB" + exit 0 else echo "<$TOOL> ${ARGS[*]}" >&2 diff --git a/src/executables/platforms/uefi/libraries.json b/src/executables/platforms/uefi/libraries.json index e0a2fe5f..f3cd9c68 100644 --- a/src/executables/platforms/uefi/libraries.json +++ b/src/executables/platforms/uefi/libraries.json @@ -1,7 +1,7 @@ { "sdl2": { "pkg": "SDL2Pkg", - "lib": "SDL2Lib", + "lib": "LibSDL2", "version": "2.32.10" }, "sdl2_image_TODO": { From 135929bd34dec40e3be0e6cf570f14e07a172d2c Mon Sep 17 00:00:00 2001 From: Totto16 Date: Wed, 5 Aug 2026 21:26:03 +0200 Subject: [PATCH 072/112] feat: also add a libcxx port for c++ support for uefi --- platforms/build-uefi.sh | 31 ++++++++++++++++++++++++------- platforms/versions.sh | 2 ++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 495d08d8..d0fd951e 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -81,9 +81,9 @@ source "$SCRIPT_DIR/versions.sh" source "$SCRIPT_DIR/helper.sh" TOOLCHAIN_DIR="$(pwd)/toolchains" +export TOOLCHAIN_DIR -EDK2_ROOT="$TOOLCHAIN_DIR/edk2" -export EDK2_ROOT +export EDK2_ROOT="$TOOLCHAIN_DIR/edk2" export WORKSPACE="$EDK2_ROOT" @@ -96,8 +96,7 @@ fi git -C "$EDK2_ROOT" checkout "$EDK2_RELEASE_TAG" git -C "$EDK2_ROOT" submodule update --init -EDK2_LIBC_ROOT="$TOOLCHAIN_DIR/edk2-libc" -export EDK2_LIBC_ROOT +export EDK2_LIBC_ROOT="$TOOLCHAIN_DIR/edk2-libc" if [ ! -d "$EDK2_LIBC_ROOT" ]; then git clone https://github.com/tianocore/edk2-libc "$EDK2_LIBC_ROOT" @@ -107,6 +106,20 @@ fi git -C "$EDK2_LIBC_ROOT" checkout "$EDK2_LIBC_COMMIT_HASH" +export EDK2_LLVM_ROOT="$TOOLCHAIN_DIR/llvm-project" + +if [ ! -d "$EDK2_LLVM_ROOT" ]; then + + git clone --filter=blob:none --sparse https://github.com/llvm/llvm-project.git "$EDK2_LLVM_ROOT" + git -C "$EDK2_LLVM_ROOT" sparse-checkout set libcxx +else + git -C "$EDK2_LLVM_ROOT" fetch +fi + +git -C "$EDK2_LLVM_ROOT" checkout "$EDK2_LIBCXX_RELEASE_TAG" + +export EDK2_LIBCXX_ROOT="$EDK2_LLVM_ROOT/libcxx" + export EDK_TOOLS_PATH="$EDK2_ROOT/BaseTools" export PACKAGES_PATH="$EDK2_ROOT" @@ -190,6 +203,10 @@ for EDK2_LIB_PACKAGE in "${EDK2_LIB_PACKAGES[@]}"; do done +if ! [ -e "$WORKSPACE/LibCXX" ]; then + link_files_checked "$EDK2_LIBCXX_ROOT" "$WORKSPACE/LibCXX" +fi + LIBRARY_PKG_ROOT="$WORKSPACE/LibraryPkg" mkdir -p "$LIBRARY_PKG_ROOT" @@ -243,17 +260,17 @@ export ROMFS="platforms/romfs" export COMMON_FLAGS="'-pthread', '-m64', '-maccumulate-outgoing-args', '-mno-red-zone', '-mcmodel=small'" -export SYS_ROOT="$EDK2_ROOT" +export SYS_ROOT="$WORKSPACE" export PKG_CONFIG_PATH="$SYS_ROOT/lib/pkgconfig" export LINK_FLAGS="$COMMON_FLAGS" export COMPILE_FLAGS="$COMMON_FLAGS ,'--sysroot=${SYS_ROOT}', '-D__UEFI__', '-DEFIAPI=__attribute__((ms_abi))', '-fexceptions', '-fshort-wchar', '-fno-builtin', '-fno-strict-aliasing', '-fno-common', '-fstack-protector', '-ffunction-sections', '-fdata-sections', '-fno-asynchronous-unwind-tables', '-fno-omit-frame-pointer', '-DAUDIO_PREFER_MP3'" -export CC_COMPILE_FLAGS="'-nostdinc', '-isystem=$WORKSPACE/StdLib/Include', '-isystem=$WORKSPACE/StdLib/Include/$EDK2_TARGET_PROPERTIES_ARCH'," +export CC_COMPILE_FLAGS="'-nostdinc', '-isystem=/StdLib/Include', '-isystem=/StdLib/Include/$EDK2_TARGET_PROPERTIES_ARCH'" #TODO use libc++ built for UEFI -export CXX_COMPILE_FLAGS="'-fno-exceptions', '-fno-rtti', '-fno-threadsafe-statics', '-fno-use-cxa-atexit', '-fno-unwind-tables', '-fno-asynchronous-unwind-tables'" +export CXX_COMPILE_FLAGS="'-fno-exceptions', '-fno-rtti', '-fno-threadsafe-statics', '-fno-use-cxa-atexit', '-fno-unwind-tables', '-fno-asynchronous-unwind-tables', '-nostdinc++', '-nodefaultlibs', '-isystem=/LibCXX/include'" export CROSS_FILE="./platforms/crossbuild/uefi.ini" diff --git a/platforms/versions.sh b/platforms/versions.sh index 45d278b6..cc03e27b 100755 --- a/platforms/versions.sh +++ b/platforms/versions.sh @@ -36,3 +36,5 @@ export EMSDK_EXECUTE_NODE_VERSION="24.7.0" export EDK2_RELEASE_TAG="edk2-stable202605" export EDK2_LIBC_COMMIT_HASH="c8313c11c2dc43647aa4c9f73baf3b323c68ecba" + +export EDK2_LIBCXX_RELEASE_TAG="llvmorg-22.1.8" From b5eb18558484f5d7154a006b8881e2241ab64feb Mon Sep 17 00:00:00 2001 From: Totto16 Date: Wed, 5 Aug 2026 21:27:11 +0200 Subject: [PATCH 073/112] fix: fix some c++ things in the uefi compiler wrappers --- platforms/uefi/extract-definitions.sh | 2 +- platforms/uefi/g++-wrapper.sh | 2 +- platforms/uefi/gcc-wrapper.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 49cabc4e..9fb610cb 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -283,7 +283,7 @@ for MESON_TARGETS_INFO_LIB_PARAMATER in "${MESON_TARGETS_INFO_LIB_PARAMATERS[@]} -W*) # TODO: include warnings ;; - -nostdinc | -D* | --sysroot=* | -isystem=*) + -nostdinc | -nostdinc++ | -nodefaultlibs | -D* | --sysroot=* | -isystem=*) DEP_BUILD_OPTIONS+=("*_*_*_CC_FLAGS = \"${MESON_TARGETS_INFO_LIB_PARAMATER}\"") ;; -t:use-lib:pkg=*) diff --git a/platforms/uefi/g++-wrapper.sh b/platforms/uefi/g++-wrapper.sh index 11bdd8c0..16e54b85 100755 --- a/platforms/uefi/g++-wrapper.sh +++ b/platforms/uefi/g++-wrapper.sh @@ -142,7 +142,7 @@ for ARG in "${ARGS[@]}"; do -cpp) # ignore this for meson usage, even if gcc only uses this for fortran, but it doesn't complain about it ;; - -v | - | -g | -P | -MD | -pthread | -shared | -nostdinc | -isystem=* | --sysroot=* | -std=* | -f* | -m* | -D* | -U* | -W* | -O* | -I* | -L* | -l*) + -v | - | -g | -P | -MD | -pthread | -shared | -nostdinc | -nostdinc++ | -nodefaultlibs | -isystem=* | --sysroot=* | -std=* | -f* | -m* | -D* | -U* | -W* | -O* | -I* | -L* | -l*) # ignore, valid arguments ;; -t:use-lib*) diff --git a/platforms/uefi/gcc-wrapper.sh b/platforms/uefi/gcc-wrapper.sh index 115f41f2..088f2b8b 100755 --- a/platforms/uefi/gcc-wrapper.sh +++ b/platforms/uefi/gcc-wrapper.sh @@ -140,7 +140,7 @@ for ARG in "${ARGS[@]}"; do -cpp) # ignore this for meson usage, even if gcc only uses this for fortran, but it doesn't complain about it ;; - -v | - | -g | -P | -MD | -pthread | -shared | -nostdinc | -isystem=* | --sysroot=* | -std=* | -f* | -m* | -D* | -U* | -W* | -O* | -I* | -L* | -l*) + -v | - | -g | -P | -MD | -pthread | -shared | -nostdinc | -nodefaultlibs | -isystem=* | --sysroot=* | -std=* | -f* | -m* | -D* | -U* | -W* | -O* | -I* | -L* | -l*) # ignore, valid arguments ;; -t:use-lib*) From 770ce5dce9308d720399a06c657280ea97407c68 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Wed, 5 Aug 2026 21:27:25 +0200 Subject: [PATCH 074/112] fix: fix __linux__ detection for uefi --- src/discord/core.hpp | 6 +++--- src/helper/platform.cpp | 6 +++++- src/lobby/credentials/secret.cpp | 2 +- src/lobby/credentials/secret.hpp | 8 ++++++-- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/discord/core.hpp b/src/discord/core.hpp index 7eb8efae..e95b87d6 100644 --- a/src/discord/core.hpp +++ b/src/discord/core.hpp @@ -28,7 +28,7 @@ namespace constants::discord { //TODO(Totto): this isn't correct for all platforms and needs to be tested #if defined(__ANDROID__) constexpr const char* platform_dependent_launch_arguments = "TODO"; -#elif defined(__CONSOLE__) +#elif defined(__CONSOLE__) || defined(__UEFI__) #error "Not supported" #elif defined(FLATPAK_BUILD) constexpr const char* platform_dependent_launch_arguments = @@ -45,10 +45,10 @@ namespace constants::discord { #if defined(__ANDROID__) constexpr const discordpp::ActivityGamePlatforms supported_platforms = discordpp::ActivityGamePlatforms::Android; -#elif defined(__CONSOLE__) +#elif defined(__CONSOLE__) || defined(__UEFI__) #error "Not supported" #elif defined(FLATPAK_BUILD) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) \ - || defined(__APPLE__) || defined(__linux__) + || defined(__APPLE__) || defined(__linux__) || defined(__UEFI__) constexpr const discordpp::ActivityGamePlatforms supported_platforms = discordpp::ActivityGamePlatforms::Desktop; #else #error "Unsupported platform" diff --git a/src/helper/platform.cpp b/src/helper/platform.cpp index 3b70f7dd..38e8b0b9 100644 --- a/src/helper/platform.cpp +++ b/src/helper/platform.cpp @@ -49,6 +49,8 @@ namespace { return "Nintendo Switch"; #elif defined(__3DS__) return "Nintendo 3DS"; +#elif defined(__UEFI__) + return "UEFI"; #elif defined(FLATPAK_BUILD) return "Linux (Flatpak)"; #elif defined(__linux__) @@ -76,7 +78,9 @@ namespace { } return true; - +#elif defined(__UEFI__) + UNUSED(url); + return false; #elif defined(__CONSOLE__) auto result = console::open_url(url); spdlog::info("Returned string from url open was: {}", result); diff --git a/src/lobby/credentials/secret.cpp b/src/lobby/credentials/secret.cpp index 8ea5373c..309788da 100644 --- a/src/lobby/credentials/secret.cpp +++ b/src/lobby/credentials/secret.cpp @@ -1,7 +1,7 @@ #include "./secret.hpp" -#if defined(__linux__) || defined(__ANDROID__) +#if defined(_HAVE_KEYUTILS) #include #include diff --git a/src/lobby/credentials/secret.hpp b/src/lobby/credentials/secret.hpp index 2297ddda..343e163a 100644 --- a/src/lobby/credentials/secret.hpp +++ b/src/lobby/credentials/secret.hpp @@ -11,7 +11,11 @@ #include "helper/export_symbols.hpp" #include "manager/service_provider.hpp" -#if defined(__linux__) && !defined(__UEFI__) +#if (defined(__linux__) && !defined(__UEFI__)) || defined(__ANDROID__) +#define _HAVE_KEYUTILS +#endif + +#if defined(_HAVE_KEYUTILS) #if defined(__GNUC__) #pragma GCC diagnostic push @@ -43,7 +47,7 @@ namespace secret { [[maybe_unused]] ServiceProvider* m_service_provider; KeyringType m_type; -#if (defined(__linux__) && !defined(__UEFI__)) || defined(__ANDROID__) +#if defined(_HAVE_KEYUTILS) key_serial_t m_ring_id; #elif defined(__CONSOLE__) || defined(__APPLE__) std::string m_file_path; From 98ad3860c52055542cd29ef299f479964349892f Mon Sep 17 00:00:00 2001 From: Totto16 Date: Wed, 5 Aug 2026 22:47:04 +0200 Subject: [PATCH 075/112] fix: fix many uefi related problems --- platforms/build-uefi.sh | 4 +-- platforms/uefi/base.sh | 2 +- platforms/uefi/extract-definitions.sh | 35 ++++++++++++++++++-- platforms/uefi/g++-wrapper.sh | 4 +-- platforms/uefi/gcc-wrapper.sh | 4 +-- src/executables/platforms/uefi/mappings.json | 7 ++-- 6 files changed, 44 insertions(+), 12 deletions(-) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index d0fd951e..503546bf 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -267,10 +267,10 @@ export PKG_CONFIG_PATH="$SYS_ROOT/lib/pkgconfig" export LINK_FLAGS="$COMMON_FLAGS" export COMPILE_FLAGS="$COMMON_FLAGS ,'--sysroot=${SYS_ROOT}', '-D__UEFI__', '-DEFIAPI=__attribute__((ms_abi))', '-fexceptions', '-fshort-wchar', '-fno-builtin', '-fno-strict-aliasing', '-fno-common', '-fstack-protector', '-ffunction-sections', '-fdata-sections', '-fno-asynchronous-unwind-tables', '-fno-omit-frame-pointer', '-DAUDIO_PREFER_MP3'" -export CC_COMPILE_FLAGS="'-nostdinc', '-isystem=/StdLib/Include', '-isystem=/StdLib/Include/$EDK2_TARGET_PROPERTIES_ARCH'" +export CC_COMPILE_FLAGS="'-nostdinc', '-I$WORKSPACE/StdLib/Include', '-I$WORKSPACE/StdLib/Include/$EDK2_TARGET_PROPERTIES_ARCH'" #TODO use libc++ built for UEFI -export CXX_COMPILE_FLAGS="'-fno-exceptions', '-fno-rtti', '-fno-threadsafe-statics', '-fno-use-cxa-atexit', '-fno-unwind-tables', '-fno-asynchronous-unwind-tables', '-nostdinc++', '-nodefaultlibs', '-isystem=/LibCXX/include'" +export CXX_COMPILE_FLAGS="'-fno-exceptions', '-fno-rtti', '-fno-threadsafe-statics', '-fno-use-cxa-atexit', '-fno-unwind-tables', '-fno-asynchronous-unwind-tables', '-nostdinc++', '-nodefaultlibs', '-I$WORKSPACE/LibCXX/include'" export CROSS_FILE="./platforms/crossbuild/uefi.ini" diff --git a/platforms/uefi/base.sh b/platforms/uefi/base.sh index b26da359..b7868784 100755 --- a/platforms/uefi/base.sh +++ b/platforms/uefi/base.sh @@ -70,7 +70,7 @@ require_empty_array() { local ARRAY=("$@") if [ "${#ARRAY[@]}" -ne 0 ]; then - echo "Array is nto empty but ${#ARRAY[@]} long" >&2 + echo "Array is not empty but ${#ARRAY[@]} long" >&2 exit 9 fi } diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 9fb610cb..fd254e1e 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -272,7 +272,17 @@ fi MESON_TARGETS_INFO_LIB_TYPE="$(echo "$MESON_TARGETS_INFO_LIB" | jq -M -r -c ".[\"type\"]")" -mapfile -t MESON_TARGETS_INFO_LIB_PARAMATERS < <(echo "$MESON_TARGETS_INFO_LIB" | jq '.["target_sources"][] | select( has("compiler") ) | .["parameters"][]' -M -r -c) +mapfile -t MESON_TARGETS_INFO_LIB_COMPILER_TARGETS < <(echo "$MESON_TARGETS_INFO_LIB" | jq '.["target_sources"][] | select( has("compiler") )' -M -r -c) + +if [ "${#MESON_TARGETS_INFO_LIB_COMPILER_TARGETS[@]}" -ne 1 ]; then + echo "Array is not one element long but ${#MESON_TARGETS_INFO_LIB_COMPILER_TARGETS[@]} long" >&2 + printf '%s\n' "${MESON_TARGETS_INFO_LIB_COMPILER_TARGETS[@]}" >&2 + exit 9 +fi + +MESON_TARGETS_INFO_LIB_COMPILER_TARGET="${MESON_TARGETS_INFO_LIB_COMPILER_TARGETS[0]}" + +mapfile -t MESON_TARGETS_INFO_LIB_PARAMATERS < <(echo "$MESON_TARGETS_INFO_LIB_COMPILER_TARGET" | jq '.["parameters"][]' -M -r -c) for MESON_TARGETS_INFO_LIB_PARAMATER in "${MESON_TARGETS_INFO_LIB_PARAMATERS[@]}"; do @@ -283,7 +293,7 @@ for MESON_TARGETS_INFO_LIB_PARAMATER in "${MESON_TARGETS_INFO_LIB_PARAMATERS[@]} -W*) # TODO: include warnings ;; - -nostdinc | -nostdinc++ | -nodefaultlibs | -D* | --sysroot=* | -isystem=*) + -nostdinc | -nostdinc++ | -nodefaultlibs | -D* | --sysroot=* | -isystem*) DEP_BUILD_OPTIONS+=("*_*_*_CC_FLAGS = \"${MESON_TARGETS_INFO_LIB_PARAMATER}\"") ;; -t:use-lib:pkg=*) @@ -331,10 +341,11 @@ fi if [ "$MAPPING_TYPE" == "application" ]; then - # add include directories to the build options + # add include directories to the build options (as the files build inside the application need that) for DEP_INCLUDE in "${DEP_INCLUDES[@]}"; do DEP_BUILD_OPTIONS+=("*_*_*_CC_FLAGS = \"-I${DEP_INCLUDE}\"") done + validate_parent_dir "$DEST_FILE" cat <"$DEST_FILE" @@ -381,6 +392,24 @@ EOF elif [ "$MAPPING_TYPE" == "library" ]; then + # add include directories to the build options (as the files build inside the library need that) + # NOTE: we also define these as [Include], which is not entirely correct, but it didn't lead to problems until now + # TODO: ^ these should be private include dirs not public ones + for DEP_INCLUDE in "${DEP_INCLUDES[@]}"; do + DEP_BUILD_OPTIONS+=("*_*_*_CC_FLAGS = \"-I${DEP_INCLUDE}\"") + done + + # add custom options, that override fix dependencies + MAPPING_OPTIONS="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"options\"]")" + + if [ "$MAPPING_OPTIONS" != "null" ]; then + mapfile -t MAPPING_OPTIONS_ENTRIES < <(echo "$MAPPING_OPTIONS" | jq -e '.[]' -M -r -c) + + for MAPPING_OPTIONS_ENTRY in "${MAPPING_OPTIONS_ENTRIES[@]}"; do + DEP_BUILD_OPTIONS+=("*_*_*_CC_FLAGS = \"${MAPPING_OPTIONS_ENTRY}\"") + done + fi + MAPPING_LIB_NAME="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"lib\"]")" LIB_DEST_DIR="$DEST_FILE_DIR/Lib" diff --git a/platforms/uefi/g++-wrapper.sh b/platforms/uefi/g++-wrapper.sh index 16e54b85..ae1073f3 100755 --- a/platforms/uefi/g++-wrapper.sh +++ b/platforms/uefi/g++-wrapper.sh @@ -40,7 +40,7 @@ for ARG in "${ARGS[@]}"; do change_mode "compile" fi ;; - -E) + -E | -H) change_mode "pass" ;; -Wl,*) @@ -142,7 +142,7 @@ for ARG in "${ARGS[@]}"; do -cpp) # ignore this for meson usage, even if gcc only uses this for fortran, but it doesn't complain about it ;; - -v | - | -g | -P | -MD | -pthread | -shared | -nostdinc | -nostdinc++ | -nodefaultlibs | -isystem=* | --sysroot=* | -std=* | -f* | -m* | -D* | -U* | -W* | -O* | -I* | -L* | -l*) + -v | - | -g | -P | -MD | -pthread | -shared | -nostdinc | -nostdinc++ | -nodefaultlibs | -isystem* | --sysroot=* | -std=* | -f* | -m* | -D* | -U* | -W* | -O* | -I* | -L* | -l*) # ignore, valid arguments ;; -t:use-lib*) diff --git a/platforms/uefi/gcc-wrapper.sh b/platforms/uefi/gcc-wrapper.sh index 088f2b8b..02bf2342 100755 --- a/platforms/uefi/gcc-wrapper.sh +++ b/platforms/uefi/gcc-wrapper.sh @@ -38,7 +38,7 @@ for ARG in "${ARGS[@]}"; do change_mode "compile" fi ;; - -E) + -E | -H) change_mode "pass" ;; -Wl,*) @@ -140,7 +140,7 @@ for ARG in "${ARGS[@]}"; do -cpp) # ignore this for meson usage, even if gcc only uses this for fortran, but it doesn't complain about it ;; - -v | - | -g | -P | -MD | -pthread | -shared | -nostdinc | -nodefaultlibs | -isystem=* | --sysroot=* | -std=* | -f* | -m* | -D* | -U* | -W* | -O* | -I* | -L* | -l*) + -v | - | -g | -P | -MD | -pthread | -shared | -nostdinc | -nodefaultlibs | -isystem* | --sysroot=* | -std=* | -f* | -m* | -D* | -U* | -W* | -O* | -I* | -L* | -l*) # ignore, valid arguments ;; -t:use-lib*) diff --git a/src/executables/platforms/uefi/mappings.json b/src/executables/platforms/uefi/mappings.json index 33690d11..336c9209 100644 --- a/src/executables/platforms/uefi/mappings.json +++ b/src/executables/platforms/uefi/mappings.json @@ -60,7 +60,10 @@ "name": "SDL2ImageLib", "lib": "LibSDL2Image", "guid": "80834111-5231-4b9d-b781-381bc4a7ac38", - "version": "sdl2_image" + "version": "sdl2_image", + "options": [ + "-Wno-misleading-indentation" + ] }, "REMOVE_SDL2MixerPkg": { "type": "library", @@ -150,7 +153,7 @@ "libflac_avx2": { "name": "REMOVE_FlacPkg", "meson": "flac_avx2", - "comment":"this is detect wrongly" + "comment": "this is detect wrongly" } } } From 72420130e406728051433537a9892f7422690611 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 7 Aug 2026 22:10:11 +0200 Subject: [PATCH 076/112] fix: fix many uefi errors - use external sdl2_image build --- platforms/build-uefi.sh | 10 +-- platforms/uefi/extract-definitions.sh | 12 +++- src/executables/platforms/uefi/libraries.json | 13 +--- src/executables/platforms/uefi/mappings.json | 64 +++---------------- .../packagefiles/zlib-1.3.2_uefi_fix.diff | 15 +++++ subprojects/zlib.wrap | 1 + 6 files changed, 44 insertions(+), 71 deletions(-) create mode 100644 subprojects/packagefiles/zlib-1.3.2_uefi_fix.diff diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 503546bf..04a8f7be 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -211,9 +211,9 @@ LIBRARY_PKG_ROOT="$WORKSPACE/LibraryPkg" mkdir -p "$LIBRARY_PKG_ROOT" -EDK2_PORT_NAMES=("SDL2Pkg" "SDL2MixerPkg" "SDL2ImagePkg") -EDK2_PORT_URLS=("https://github.com/Totto16/SDL2_UEFI" "TODO" "TODO ") -EDK2_PORT_TAGS=("uefi_port" "TODO" "TODO") +EDK2_PORT_NAMES=("SDL2Pkg" "SDL2MixerPkg") +EDK2_PORT_URLS=("https://github.com/Totto16/SDL2_UEFI" "https://github.com/Totto16/SDL2_mixer_UEFI") +EDK2_PORT_TAGS=("uefi_port" "uefi_port") for EDK2_PORT_KEY in "${!EDK2_PORT_NAMES[@]}"; do @@ -258,7 +258,7 @@ export ENDIANESS="little" export ROMFS="platforms/romfs" -export COMMON_FLAGS="'-pthread', '-m64', '-maccumulate-outgoing-args', '-mno-red-zone', '-mcmodel=small'" +export COMMON_FLAGS="'-m64', '-maccumulate-outgoing-args', '-mno-red-zone', '-mcmodel=small'" export SYS_ROOT="$WORKSPACE" @@ -368,7 +368,7 @@ if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "$BUILD_DIR" ]; then "-Dbuildtype=$BUILDTYPE" \ -Ddefault_library=shared \ -Dtests=false \ - --force-fallback-for="fmt,nlohmann_json,magic_enum,utf8cpp,sdl2_ttf,freetype2,spdlog,argparse,sdl2_image,sdl2_mixer,ogg,vorbis,flac" \ + --force-fallback-for="fmt,nlohmann_json,magic_enum,utf8cpp,sdl2_ttf,freetype2,spdlog,argparse,sdl2_image" \ --wrap-mode=nofallback \ "-Drun_in_ci=$RUN_IN_CI" #TODO: enable \ #--fatal-meson-warnings diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index fd254e1e..f9b3c239 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -288,12 +288,14 @@ for MESON_TARGETS_INFO_LIB_PARAMATER in "${MESON_TARGETS_INFO_LIB_PARAMATERS[@]} case "$MESON_TARGETS_INFO_LIB_PARAMATER" in -I*) + #TODO: if it is cpp this should be modified to CXX_FLAGS DEP_INCLUDES+=("${MESON_TARGETS_INFO_LIB_PARAMATER:2}") ;; -W*) # TODO: include warnings ;; -nostdinc | -nostdinc++ | -nodefaultlibs | -D* | --sysroot=* | -isystem*) + #TODO: if it is cpp this should be modified to CXX_FLAGS DEP_BUILD_OPTIONS+=("*_*_*_CC_FLAGS = \"${MESON_TARGETS_INFO_LIB_PARAMATER}\"") ;; -t:use-lib:pkg=*) @@ -307,7 +309,13 @@ for MESON_TARGETS_INFO_LIB_PARAMATER in "${MESON_TARGETS_INFO_LIB_PARAMATERS[@]} DEP_PACKAGE_LIB="${MESON_TARGETS_INFO_LIB_PARAMATER:15}" DEP_CLASSES+=("$DEP_PACKAGE_LIB") ;; - -g | -pthread | -std=* | -f* | -m* | -O*) + -pthread) + # ignore pthread + ;; + -f* | -m*) + DEP_BUILD_OPTIONS+=("*_*_*_CC_FLAGS = \"${MESON_TARGETS_INFO_LIB_PARAMATER}\"") + ;; + -g | -std=* | -O*) #ignore ;; *) @@ -343,6 +351,7 @@ if [ "$MAPPING_TYPE" == "application" ]; then # add include directories to the build options (as the files build inside the application need that) for DEP_INCLUDE in "${DEP_INCLUDES[@]}"; do + #TODO: if it is cpp this should be modified to CXX_FLAGS DEP_BUILD_OPTIONS+=("*_*_*_CC_FLAGS = \"-I${DEP_INCLUDE}\"") done @@ -396,6 +405,7 @@ elif [ "$MAPPING_TYPE" == "library" ]; then # NOTE: we also define these as [Include], which is not entirely correct, but it didn't lead to problems until now # TODO: ^ these should be private include dirs not public ones for DEP_INCLUDE in "${DEP_INCLUDES[@]}"; do + #TODO: if it is cpp this should be modified to CXX_FLAGS DEP_BUILD_OPTIONS+=("*_*_*_CC_FLAGS = \"-I${DEP_INCLUDE}\"") done diff --git a/src/executables/platforms/uefi/libraries.json b/src/executables/platforms/uefi/libraries.json index f3cd9c68..37d4c567 100644 --- a/src/executables/platforms/uefi/libraries.json +++ b/src/executables/platforms/uefi/libraries.json @@ -4,16 +4,9 @@ "lib": "LibSDL2", "version": "2.32.10" }, - "sdl2_image_TODO": { - "pkg": "SDL2ImagePkg", - "lib": "sdl2_image_TODO", - "version": "2.6.3", - "comment": "maybe nor port needed?" - }, - "sdl2_mixer_TODO": { + "sdl2_mixer": { "pkg": "SDL2MixerPkg", - "lib": "sdl2_mixer_TODO", - "version": "2.6.2", - "comment": "port this for sure, only use dummy output (no ogg etc needed), as uefi has no audio drivers" + "lib": "LibSDL2Mixer", + "version": "2.8.2" } } diff --git a/src/executables/platforms/uefi/mappings.json b/src/executables/platforms/uefi/mappings.json index 336c9209..bab2330f 100644 --- a/src/executables/platforms/uefi/mappings.json +++ b/src/executables/platforms/uefi/mappings.json @@ -53,7 +53,12 @@ "name": "SpdlogLib", "lib": "LibSpdlog", "guid": "dee047db-15c9-4d79-ab08-79d6244d9b0e", - "version": "spdlog" + "version": "spdlog", + "options": [ + "-DFMT_USE_LOCALE=0", + "-DSPDLOG_NO_EXCEPTIONS=1", + "-DSPDLOG_NO_TLS=1" + ] }, "SDL2ImagePkg": { "type": "library", @@ -62,36 +67,10 @@ "guid": "80834111-5231-4b9d-b781-381bc4a7ac38", "version": "sdl2_image", "options": [ - "-Wno-misleading-indentation" + "-Wno-misleading-indentation", + "-DSTBI_NO_SIMD", + "-Wno-unused-but-set-variable" ] - }, - "REMOVE_SDL2MixerPkg": { - "type": "library", - "name": "SDL2MixerLib", - "lib": "LibSDL2Mixer", - "guid": "9a0df316-4a64-4336-99b2-09af1e8f7e53", - "version": "sdl2_mixer" - }, - "REMOVE_VorbisPkg": { - "type": "library", - "name": "VorbisLib", - "lib": "LibVorbis", - "guid": "9a0df316-4a64-4336-99b2-09af1e8f7e53", - "version": "vorbis" - }, - "REMOVE_OggPkg": { - "type": "library", - "name": "OggLib", - "lib": "LibOgg", - "guid": "9a0df316-4a64-4336-99b2-09af1e8f7e53", - "version": "ogg" - }, - "REMOVE_FlacPkg": { - "type": "library", - "name": "FlacLib", - "lib": "LibFlac", - "guid": "9a0df316-4a64-4336-99b2-09af1e8f7e53", - "version": "flac" } }, "name": { @@ -129,31 +108,6 @@ "libsdl2image": { "name": "SDL2ImagePkg", "meson": "sdl2image" - }, - "libsdl2mixer": { - "name": "REMOVE_SDL2MixerPkg", - "meson": "sdl2mixer" - }, - "libvorbisfile": { - "name": "REMOVE_VorbisPkg", - "meson": "vorbisfile" - }, - "libvorbis": { - "name": "REMOVE_VorbisPkg", - "meson": "vorbis" - }, - "libogg": { - "name": "REMOVE_OggPkg", - "meson": "ogg" - }, - "libFLAC": { - "name": "REMOVE_FlacPkg", - "meson": "FLAC" - }, - "libflac_avx2": { - "name": "REMOVE_FlacPkg", - "meson": "flac_avx2", - "comment": "this is detect wrongly" } } } diff --git a/subprojects/packagefiles/zlib-1.3.2_uefi_fix.diff b/subprojects/packagefiles/zlib-1.3.2_uefi_fix.diff new file mode 100644 index 00000000..852e5dbf --- /dev/null +++ b/subprojects/packagefiles/zlib-1.3.2_uefi_fix.diff @@ -0,0 +1,15 @@ +diff --git a/deflate.c b/deflate.c +index d7d2c7c..4eaa3f6 100644 +--- a/deflate.c ++++ b/deflate.c +@@ -1647,6 +1647,10 @@ local void check_match(deflate_state *s, IPos start, IPos match, int length) { + /* Maximum stored block length in deflate format (not including header). */ + #define MAX_STORED 65535 + ++#if defined(__UEFI__) ++#undef MIN ++#endif ++ + /* Minimum of a and b. */ + #define MIN(a, b) ((a) > (b) ? (b) : (a)) + diff --git a/subprojects/zlib.wrap b/subprojects/zlib.wrap index 0626401a..e1d21b9d 100644 --- a/subprojects/zlib.wrap +++ b/subprojects/zlib.wrap @@ -9,6 +9,7 @@ patch_url = https://wrapdb.mesonbuild.com/v2/zlib_1.3.2-1/get_patch patch_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/zlib_1.3.2-1/zlib_1.3.2-1_patch.zip patch_hash = 5ae7a2e92f823df118cfb8c1b23d94e3117864392b3446581d669049b2fba6dd wrapdb_version = 1.3.2-1 +diff_files = zlib-1.3.2_uefi_fix.diff [provide] dependency_names = zlib From 0344fd164539e5cd709b938e90742476476b6891 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 7 Aug 2026 22:10:24 +0200 Subject: [PATCH 077/112] fix: fix cxx compiler for edk2 --- platforms/uefi/cxx_compiler.diff | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platforms/uefi/cxx_compiler.diff b/platforms/uefi/cxx_compiler.diff index 4ab79c0c..222930d1 100644 --- a/platforms/uefi/cxx_compiler.diff +++ b/platforms/uefi/cxx_compiler.diff @@ -24,15 +24,15 @@ index 0c454ee3d5..9e13b638f8 100755 - "$(CC)" /Fo${dst} $(DEPS_FLAGS) $(CC_FLAGS) $(CXX_FLAGS) $(INC) ${src} -+ "$(CC)" /TODO:x=c++ /Fo${dst} $(DEPS_FLAGS) $(CC_FLAGS) $(CXX_FLAGS) $(INC) ${src} ++ "$(CC)" /TODO:x=c++ /Fo${dst} $(DEPS_FLAGS) $(CXX_FLAGS) $(CC_FLAGS) $(INC) ${src} - "$(CC)" $(DEPS_FLAGS) $(CC_FLAGS) $(CXX_FLAGS) -c -o ${dst} $(INC) ${src} -+ "$(CC)" -x c++ $(DEPS_FLAGS) $(CC_FLAGS) $(CXX_FLAGS) -c -o ${dst} $(INC) ${src} ++ "$(CC)" -x c++ $(DEPS_FLAGS) $(CXX_FLAGS) $(CC_FLAGS) -c -o ${dst} $(INC) ${src} - "$(CC)" $(DEPS_FLAGS) $(CC_FLAGS) $(CXX_FLAGS) -o ${dst} $(INC) ${src} -+ "$(CC)" -x c++ $(DEPS_FLAGS) $(CC_FLAGS) $(CXX_FLAGS) -o ${dst} $(INC) ${src} ++ "$(CC)" -x c++ $(DEPS_FLAGS) $(CXX_FLAGS) $(CC_FLAGS)-o ${dst} $(INC) ${src} [C-Code-File.BASE.AARCH64,C-Code-File.SEC.AARCH64,C-Code-File.PEI_CORE.AARCH64,C-Code-File.PEIM.AARCH64] From 6c0d4d031e319eb7d1cbe8b1ecf2f79f7ccaf2f3 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 7 Aug 2026 22:11:10 +0200 Subject: [PATCH 078/112] fix: fix spdlog for uefi --- .../spdlog_1.17.0_uefi_support.diff | 111 ++++++++++++++++++ subprojects/spdlog.wrap | 2 +- 2 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 subprojects/packagefiles/spdlog_1.17.0_uefi_support.diff diff --git a/subprojects/packagefiles/spdlog_1.17.0_uefi_support.diff b/subprojects/packagefiles/spdlog_1.17.0_uefi_support.diff new file mode 100644 index 00000000..100438bf --- /dev/null +++ b/subprojects/packagefiles/spdlog_1.17.0_uefi_support.diff @@ -0,0 +1,111 @@ +diff --git a/include/spdlog/cfg/helpers-inl.h b/include/spdlog/cfg/helpers-inl.h +index 6ed8695..6d4a55b 100644 +--- a/include/spdlog/cfg/helpers-inl.h ++++ b/include/spdlog/cfg/helpers-inl.h +@@ -54,6 +54,7 @@ inline std::pair extract_kv_(char sep, const std::stri + return std::make_pair(trim_(k), trim_(v)); + } + ++#if !defined(__UEFI__) + // return vector of key/value pairs from a sequence of "K1=V1,K2=V2,.." + // "a=AAA,b=BBB,c=CCC,.." => {("a","AAA"),("b","BBB"),("c", "CCC"),...} + inline std::unordered_map extract_key_vals_(const std::string &str) { +@@ -69,6 +70,29 @@ inline std::unordered_map extract_key_vals_(const std: + } + return rv; + } ++#else ++inline std::unordered_map extract_key_vals_(const std::string &str) { ++ std::unordered_map rv{}; ++ ++ size_t start = 0; ++ while (start < str.size()) { ++ size_t end = str.find(',', start); ++ if (end == std::string::npos) { ++ end = str.size(); ++ } ++ ++ if (end > start) { ++ auto token = str.substr(start, end - start); ++ auto kv = extract_kv_('=', token); ++ rv[kv.first] = kv.second; ++ } ++ ++ start = end + 1; ++ } ++ ++ return rv; ++} ++#endif + + SPDLOG_INLINE void load_levels(const std::string &input) { + if (input.empty() || input.size() >= 32768) { +diff --git a/include/spdlog/details/os-inl.h b/include/spdlog/details/os-inl.h +index b4bfe83..6a5f408 100644 +--- a/include/spdlog/details/os-inl.h ++++ b/include/spdlog/details/os-inl.h +@@ -42,7 +42,7 @@ + #include + #include + +-#ifdef __linux__ ++#if defined(__linux__) && !defined(__UEFI__) + #include //Use gettid() syscall under linux to get thread id + + #elif defined(_AIX) +@@ -88,6 +88,9 @@ SPDLOG_INLINE std::tm localtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT { + #ifdef _WIN32 + std::tm tm; + ::localtime_s(&tm, &time_tt); ++#elif defined(__UEFI__) ++ std::tm* tm_p = ::localtime(&time_tt); ++ std::tm tm = *tm_p; + #else + std::tm tm; + ::localtime_r(&time_tt, &tm); +@@ -104,6 +107,9 @@ SPDLOG_INLINE std::tm gmtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT { + #ifdef _WIN32 + std::tm tm; + ::gmtime_s(&tm, &time_tt); ++#elif defined(__UEFI__) ++ std::tm* tm_p = ::gmtime(&time_tt); ++ std::tm tm = *tm_p; + #else + std::tm tm; + ::gmtime_r(&time_tt, &tm); +@@ -216,7 +222,7 @@ SPDLOG_INLINE size_t filesize(FILE *f) { + + #else // unix + // OpenBSD and AIX doesn't compile with :: before the fileno(..) +-#if defined(__OpenBSD__) || defined(_AIX) ++#if defined(__OpenBSD__) || defined(_AIX) || defined(__UEFI__) + int fd = fileno(f); + #else + int fd = ::fileno(f); +@@ -260,7 +266,7 @@ SPDLOG_INLINE int utc_minutes_offset(const std::tm &tm) { + auto offset_seconds = utc_time_t - local_time_t; + return static_cast(offset_seconds / 60); + } +-#elif defined(__3DS__) || defined(__SWITCH__) ++#elif defined(__3DS__) || defined(__SWITCH__) || defined(__UEFI__) + SPDLOG_INLINE int utc_minutes_offset(const std::tm &/* tm */) { + throw_spdlog_ex("Not implemented yet on this platform", errno); + } +@@ -278,6 +284,8 @@ SPDLOG_INLINE int utc_minutes_offset(const std::tm &tm) { + SPDLOG_INLINE size_t _thread_id() SPDLOG_NOEXCEPT { + #ifdef _WIN32 + return static_cast(::GetCurrentThreadId()); ++#elif defined(__UEFI__) ++ return std::hash{}(std::this_thread::get_id()); + #elif defined(__linux__) + #if defined(__ANDROID__) && defined(__ANDROID_API__) && (__ANDROID_API__ < 21) + #define SYS_gettid __NR_gettid +@@ -552,6 +560,8 @@ std::string SPDLOG_INLINE getenv(const char *field) { + SPDLOG_INLINE bool fsync(FILE *fp) { + #ifdef _WIN32 + return FlushFileBuffers(reinterpret_cast(_get_osfhandle(_fileno(fp)))) != 0; ++#elif defined(__UEFI__) ++ return fflush(fp) == 0; + #else + return ::fsync(fileno(fp)) == 0; + #endif diff --git a/subprojects/spdlog.wrap b/subprojects/spdlog.wrap index 9b7b4bcf..82083f0f 100644 --- a/subprojects/spdlog.wrap +++ b/subprojects/spdlog.wrap @@ -9,7 +9,7 @@ patch_url = https://wrapdb.mesonbuild.com/v2/spdlog_1.17.0-1/get_patch patch_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/spdlog_1.17.0-1/spdlog_1.17.0-1_patch.zip patch_hash = 295bcca990facdca84256b60aaa86ba2e2320895cad30bee997d7a463a30b40c wrapdb_version = 1.17.0-1 -diff_files = spdlog_1.17.0_fmt_12.0.0_compatibility.diff, spdlog_1.17.0_no_tls_option.diff, spdlog_1.17.0_nintendo_time_fix.diff, spdlog_1.17.0_std_format_detection_fix.diff +diff_files = spdlog_1.17.0_fmt_12.0.0_compatibility.diff, spdlog_1.17.0_no_tls_option.diff, spdlog_1.17.0_nintendo_time_fix.diff, spdlog_1.17.0_std_format_detection_fix.diff, spdlog_1.17.0_uefi_support.diff [provide] From 817774f4102334e2e660d22438798b889f6c76d9 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 7 Aug 2026 23:02:20 +0200 Subject: [PATCH 079/112] feat: fix some hpp and cpp code for uefi --- platforms/build-uefi.sh | 2 +- src/libs/core/helper/color.hpp | 6 ++-- src/libs/core/helper/const_utils.hpp | 10 ++++++ src/libs/core/helper/utils.hpp | 33 +++++++++++++++++++ .../utility/additional_information.cpp | 21 +++++++----- src/libs/recordings/utility/helper.hpp | 18 +++++----- tools/dependencies/meson.build | 8 +++++ 7 files changed, 77 insertions(+), 21 deletions(-) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 04a8f7be..b9cb5529 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -270,7 +270,7 @@ export COMPILE_FLAGS="$COMMON_FLAGS ,'--sysroot=${SYS_ROOT}', '-D__UEFI__', '-DE export CC_COMPILE_FLAGS="'-nostdinc', '-I$WORKSPACE/StdLib/Include', '-I$WORKSPACE/StdLib/Include/$EDK2_TARGET_PROPERTIES_ARCH'" #TODO use libc++ built for UEFI -export CXX_COMPILE_FLAGS="'-fno-exceptions', '-fno-rtti', '-fno-threadsafe-statics', '-fno-use-cxa-atexit', '-fno-unwind-tables', '-fno-asynchronous-unwind-tables', '-nostdinc++', '-nodefaultlibs', '-I$WORKSPACE/LibCXX/include'" +export CXX_COMPILE_FLAGS="'-fno-exceptions', '-fno-threadsafe-statics', '-fno-use-cxa-atexit', '-fno-unwind-tables', '-fno-asynchronous-unwind-tables', '-nostdinc++', '-nodefaultlibs', '-I$WORKSPACE/LibCXX/include'" export CROSS_FILE="./platforms/crossbuild/uefi.ini" diff --git a/src/libs/core/helper/color.hpp b/src/libs/core/helper/color.hpp index 580c4b4d..f845c715 100644 --- a/src/libs/core/helper/color.hpp +++ b/src/libs/core/helper/color.hpp @@ -46,14 +46,14 @@ struct HSVColor { } else { if (h < 0.0 || h > 360.0) { - throw std::runtime_error{ fmt::format("h has to be in range 0.0 - 360.0 but was: {}", h) }; + utils::throw_(std::runtime_error{ fmt::format("h has to be in range 0.0 - 360.0 but was: {}", h) }); } if (s < 0.0 || s > 1.0) { - throw std::runtime_error{ fmt::format("s has to be in range 0.0 - 1.0 but was: {}", s) }; + utils::throw_(std::runtime_error{ fmt::format("s has to be in range 0.0 - 1.0 but was: {}", s) }); } if (v < 0.0 || v > 1.0) { - throw std::runtime_error{ fmt::format("v has to be in range 0.0 - 1.0 but was: {}", v) }; + utils::throw_(std::runtime_error{ fmt::format("v has to be in range 0.0 - 1.0 but was: {}", v) }); } } } diff --git a/src/libs/core/helper/const_utils.hpp b/src/libs/core/helper/const_utils.hpp index 233348b6..7e741e6f 100644 --- a/src/libs/core/helper/const_utils.hpp +++ b/src/libs/core/helper/const_utils.hpp @@ -20,6 +20,15 @@ (if constexpr (!(CHECK)) { static_assert(false, MSG); }()) s*/ +#else +#if defined(__OOPETRIS_NO_EXCEPTIONS) + +#define CONSTEVAL_ONLY_STATIC_ASSERT(CHECK, MSG) /*NOLINT(cppcoreguidelines-macro-usage)*/ \ + ((CHECK) ? void(0) : [] { \ + /* If you see this really bad c++ error message, follow the origin of MSG, to see the real error message, c++ error messages suck xD */ \ + /* MSG*/ \ + abort(); \ + }()) #else #define CONSTEVAL_ONLY_STATIC_ASSERT(CHECK, MSG) /*NOLINT(cppcoreguidelines-macro-usage)*/ \ ((CHECK) ? void(0) : [] { \ @@ -27,6 +36,7 @@ s*/ throw(MSG); \ }()) #endif +#endif #define CONSTEVAL_STATIC_ASSERT(CHECK, MSG) /*NOLINT(cppcoreguidelines-macro-usage)*/ \ do { /*NOLINT(cppcoreguidelines-avoid-do-while)*/ \ diff --git a/src/libs/core/helper/utils.hpp b/src/libs/core/helper/utils.hpp index 6895009e..3d52b579 100644 --- a/src/libs/core/helper/utils.hpp +++ b/src/libs/core/helper/utils.hpp @@ -15,6 +15,10 @@ #include #include +#if defined(__UEFI__) +#include +#endif + namespace helper { template @@ -124,6 +128,20 @@ namespace utils { #define STATIC_ASSERT_WITH_MESSAGE(check, msg) static_assert(check); // NOLINT(cppcoreguidelines-macro-usage) #endif + template + inline void throw_(E&& exc) { +#if defined(__OOPETRIS_NO_EXCEPTIONS) +#if defined(__UEFI__) + DebugPrint(DEBUG_ERROR, "Exception: %s", exc.what()); +#else + std::cerr << "Exception: " << exc.what() << "\n"; +#endif + abort(); +#else + throw std::forward(exc); +#endif + } + } // namespace utils @@ -137,6 +155,13 @@ namespace utils { #endif #if !defined(NDEBUG) +#if defined(__UEFI__) +#define UNREACHABLE() /* NOLINT(cppcoreguidelines-macro-usage)*/ \ + do { /* NOLINT(cppcoreguidelines-avoid-do-while)*/ \ + DebugPrint(DEBUG_ERROR, "UNREACHABLE %s:%d - %s\n", __FILE__, __LINE__, __FUNCTION__); \ + utils::unreachable(); \ + } while (false) +#else #define UNREACHABLE() /* NOLINT(cppcoreguidelines-macro-usage)*/ \ do { /* NOLINT(cppcoreguidelines-avoid-do-while)*/ \ std::cerr << "UNREACHABLE " << (__FILE__) /* NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay)*/ \ @@ -145,12 +170,20 @@ namespace utils { << "\n"; \ utils::unreachable(); \ } while (false) +#endif #else #define UNREACHABLE() utils::unreachable() // NOLINT(cppcoreguidelines-macro-usage) #endif // NOLINT(cppcoreguidelines-macro-usage) +#if defined(__UEFI__) +#ifdef ASSERT +#undef ASSERT +#endif +#endif + + #if defined(NDEBUG) #define ASSERT(x) (UNUSED(x)) // NOLINT(cppcoreguidelines-macro-usage) #else diff --git a/src/libs/recordings/utility/additional_information.cpp b/src/libs/recordings/utility/additional_information.cpp index e4104f31..698fdaba 100644 --- a/src/libs/recordings/utility/additional_information.cpp +++ b/src/libs/recordings/utility/additional_information.cpp @@ -6,7 +6,8 @@ #include #include -[[nodiscard]] std::string recorder::InformationValue::to_string(u32 recursion_depth // NOLINT(misc-no-recursion) +[[nodiscard]] std::string recorder::InformationValue::to_string( + u32 recursion_depth // NOLINT(misc-no-recursion) ) const { return std::visit( helper::Overloaded{ @@ -20,12 +21,16 @@ [](const i32& value) { return std::to_string(value); }, [](const u64& value) { return std::to_string(value); }, [](const i64& value) { return std::to_string(value); }, - [recursion_depth](const std::vector& value // NOLINT(misc-no-recursion) + [recursion_depth]( + const std::vector& value // NOLINT(misc-no-recursion) ) { if (recursion_depth >= max_recursion_depth) { - throw std::runtime_error{ fmt::format( - "Reached maximum recursion depth of {} while printing vectors!", max_recursion_depth - ) }; + utils::throw_( + std::runtime_error{ fmt::format( + "Reached maximum recursion depth of {} while printing vectors!", + max_recursion_depth + ) } + ); } std::vector strings{}; @@ -461,7 +466,7 @@ helper::expected recorder::Additio void recorder::AdditionalInformation::add_value(const std::string& key, const InformationValue& value, bool overwrite) { if (m_values.contains(key) and not overwrite) { - throw std::runtime_error("Can't overwrite already existing key"); + utils::throw_(std::runtime_error("Can't overwrite already existing key")); } m_values.insert_or_assign(key, value); @@ -519,8 +524,8 @@ std::optional recorder::AdditionalInformation::get(c return bytes; } -[[nodiscard]] helper::expected recorder::AdditionalInformation::get_checksum( -) const { +[[nodiscard]] helper::expected +recorder::AdditionalInformation::get_checksum() const { Sha256Stream sha256_creator{}; static_assert(sizeof(u32) == 4); diff --git a/src/libs/recordings/utility/helper.hpp b/src/libs/recordings/utility/helper.hpp index d5f362b5..d9d075af 100644 --- a/src/libs/recordings/utility/helper.hpp +++ b/src/libs/recordings/utility/helper.hpp @@ -31,7 +31,7 @@ namespace helper { template [[nodiscard]] ReadResult> read_integral_from_file(std::ifstream& file) { - if (not file) { + if (file.fail()) { return helper::unexpected{ { ReadErrorType::InvalidStream, "failed to read data from file (before reading)" } }; @@ -43,7 +43,7 @@ namespace helper { sizeof(little_endian_data) ); - if (not file) { + if (file.fail()) { return helper::unexpected{ { ReadErrorType::Incomplete, "failed to read data from file (after reading)" } }; @@ -54,7 +54,7 @@ namespace helper { template [[nodiscard]] ReadResult> read_array_from_file(std::ifstream& file) { - if (not file) { + if (file.fail()) { return helper::unexpected{ { ReadErrorType::InvalidStream, "failed to read data from file (before reading)" } }; @@ -69,7 +69,7 @@ namespace helper { result.at(i) = read_data.value(); } - if (not file) { + if (file.fail()) { return helper::unexpected{ { ReadErrorType::Incomplete, "failed to read data from file (after reading)" } }; @@ -80,7 +80,7 @@ namespace helper { template [[nodiscard]] std::optional read_from_istream(std::istream& istream) { - if (not istream) { + if (istream.fail()) { return std::nullopt; } auto value = Integral{}; @@ -89,7 +89,7 @@ namespace helper { sizeof(Integral) ); - if (not istream) { + if (istream.fail()) { return std::nullopt; } @@ -98,7 +98,7 @@ namespace helper { template [[nodiscard]] std::optional> read_array_from_istream(std::istream& istream) { - if (not istream) { + if (istream.fail()) { return std::nullopt; } @@ -111,7 +111,7 @@ namespace helper { result.at(i) = read_data.value(); } - if (not istream) { + if (istream.fail()) { return std::nullopt; } @@ -125,7 +125,7 @@ namespace helper { template helper::expected write_integral_to_file(std::ofstream& file, const Integral data) { - if (not file) { + if (file.fail()) { return helper::unexpected{ fmt::format("failed to write data \"{}\"", data) }; } diff --git a/tools/dependencies/meson.build b/tools/dependencies/meson.build index 54737f3a..67568d1d 100644 --- a/tools/dependencies/meson.build +++ b/tools/dependencies/meson.build @@ -149,6 +149,14 @@ if ( or host_machine.system() == 'uefi') ) fmt_use_header_only = true + + temp = core_lib.get('compile_args') + temp += '-DFMT_USE_LOCALE=0' + temp += '-D__OOPETRIS_NO_EXCEPTIONS=1' + core_lib += { + 'compile_args': temp, + } + temp = 0 endif if fmt_use_header_only From 3d225b66e548ea9ee13c64e12b1064f5d52b1e56 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 7 Aug 2026 23:48:21 +0200 Subject: [PATCH 080/112] feat: add small compat for ifstream --- src/libs/core/helper/compat.cpp | 109 ++++++++++++++++++++++++++++ src/libs/core/helper/compat.hpp | 39 ++++++++++ src/libs/core/helper/meson.build | 2 + src/libs/core/helper/parse_json.hpp | 16 +++- src/ui/layouts/focus_layout.hpp | 16 ++-- tools/dependencies/meson.build | 1 + 6 files changed, 173 insertions(+), 10 deletions(-) create mode 100644 src/libs/core/helper/compat.cpp create mode 100644 src/libs/core/helper/compat.hpp diff --git a/src/libs/core/helper/compat.cpp b/src/libs/core/helper/compat.cpp new file mode 100644 index 00000000..b368e9f8 --- /dev/null +++ b/src/libs/core/helper/compat.cpp @@ -0,0 +1,109 @@ +#include "./compat.hpp" + + +#if defined(__OOPETRIS_NO_STREAMS) + +#include +#include + + +static helper::expected read_file(const char* file_path) { + FILE* file = fopen(file_path, "rb"); + + if (file == NULL) { + + return helper::unexpected{ + fmt::format("Couldn't open file for reading '{}': {}", file_path, strerror(errno)) + }; + } + + const int fseek_res = fseek(file, 0, SEEK_END); + + if (fseek_res != 0) { + return helper::unexpected{ + fmt::format("Couldn't seek to end of file '{}': {}", file_path, strerror(errno)) + }; + } + + const long file_size = ftell(file); + + if (file_size < 0) { + return helper::unexpected{ fmt::format("File size is negative: '{}': {}", file_path, file_size) }; + } + + const int fseek_res2 = fseek(file, 0, SEEK_SET); + + if (fseek_res2 != 0) { + return helper::unexpected{ + fmt::format("Couldn't seek to start of file '{}': {}", file_path, strerror(errno)) + }; + } + + uint8_t* file_data = (uint8_t*) malloc((size_t) file_size * sizeof(uint8_t)); + + if (!file_data) { + fclose(file); + return helper::unexpected{ "Couldn't allocate bytes" }; + } + + const size_t fread_result = fread(file_data, 1, (size_t) file_size, file); + + if (fread_result != (size_t) file_size) { + const char* error_msg = strerror(errno); + + fclose(file); + free(file_data); + + return helper::unexpected{ + fmt::format("Couldn't read the correct amount of bytes from file '{}': {}", file_path, error_msg) + }; + } + + const int fclose_result = fclose(file); + + if (fclose_result != 0) { + const char* error_msg = strerror(errno); + + free(file_data); + return helper::unexpected{ fmt::format("Couldn't close file '{}': {}", file_path, error_msg) }; + } + + return compat::Buffer{ file_data, (size_t) file_size }; +} + + +compat::ifstream::ifstream(const std::filesystem::path& path) { + auto data = read_file(path.string().c_str()); + + if (not data.has_value()) { + m_fail = true; + return; + } + + auto ok = data.value(); + + m_data = ok; + m_open = true; +} + +compat::ifstream::~ifstream() noexcept { + free(m_data.data); +} + +std::string compat::ifstream::copied_data() { + return std::string{ (char*)m_data.data, m_data.size }; +} + +bool compat::ifstream::is_open() const { + return m_open; +} + +bool compat::ifstream::fail() const { + return m_fail; +} + +void compat::ifstream::close() { + m_open = false; +} + +#endif diff --git a/src/libs/core/helper/compat.hpp b/src/libs/core/helper/compat.hpp new file mode 100644 index 00000000..9a74d47d --- /dev/null +++ b/src/libs/core/helper/compat.hpp @@ -0,0 +1,39 @@ +#pragma once + +#if defined(__OOPETRIS_NO_STREAMS) + +#include "./types.hpp" + +#include + + +namespace compat { + + struct Buffer { + uint8_t* data; + size_t size; + }; + + class ifstream { + public: + explicit ifstream(const std::filesystem::path& path); + + bool is_open() const; + bool fail() const; + void close(); + + std::string copied_data(); + + ~ifstream() noexcept; + + private: + bool m_open = false; + bool m_fail = false; + + Buffer m_data; + }; + +} // namespace compat + + +#endif diff --git a/src/libs/core/helper/meson.build b/src/libs/core/helper/meson.build index c440546a..dbbeb0ef 100644 --- a/src/libs/core/helper/meson.build +++ b/src/libs/core/helper/meson.build @@ -1,5 +1,6 @@ core_src_files += files( 'color.cpp', + 'compat.cpp', 'date.cpp', 'errors.cpp', 'parse_json.cpp', @@ -13,6 +14,7 @@ _header_files = files( 'bool_wrapper.hpp', 'color.hpp', 'color_literals.hpp', + 'compat.hpp', 'const_utils.hpp', 'date.hpp', 'errors.hpp', diff --git a/src/libs/core/helper/parse_json.hpp b/src/libs/core/helper/parse_json.hpp index 09022614..5f4e766c 100644 --- a/src/libs/core/helper/parse_json.hpp +++ b/src/libs/core/helper/parse_json.hpp @@ -85,7 +85,11 @@ namespace json { ) }; } +#if defined(__OOPETRIS_NO_STREAMS) + compat::ifstream file_stream{ file }; +#else std::ifstream file_stream{ file }; +#endif if (not file_stream.is_open()) { return helper::unexpected>{ std::make_pair( @@ -93,8 +97,14 @@ namespace json { ) }; } - std::stringstream result; - result << file_stream.rdbuf(); + std::string result; +#if defined(__OOPETRIS_NO_STREAMS) + result = std::move(file_stream.copied_data()); +#else + std::stringstream result_str; + result_str << file_stream.rdbuf(); + result = result_str.str(); +#endif file_stream.close(); @@ -104,7 +114,7 @@ namespace json { ) }; } - auto parse_result = try_parse_json(result.str()); + auto parse_result = try_parse_json(result); if (not parse_result.has_value()) { return helper::unexpected>{ std::make_pair(std::move(parse_result.error()), ParseError::FormatError) diff --git a/src/ui/layouts/focus_layout.hpp b/src/ui/layouts/focus_layout.hpp index 2240e4a4..92b0d8c1 100644 --- a/src/ui/layouts/focus_layout.hpp +++ b/src/ui/layouts/focus_layout.hpp @@ -76,15 +76,17 @@ namespace ui { template [[nodiscard]] T* get(const u32 index) { if (index >= m_widgets.size()) { - throw std::runtime_error{ fmt::format( - "Invalid get of FocusLayout item: index out of bound: {} is not in range [{} - {})", index, 0, - m_widgets.size() - ) }; + utils::throw_( + std::runtime_error{ fmt::format( + "Invalid get of FocusLayout item: index out of bound: {} is not in range [{} - {})", + index, 0, m_widgets.size() + ) } + ); } auto item = utils::is_child_class(m_widgets.at(index)); if (not item.has_value()) { - throw std::runtime_error("Invalid get of FocusLayout item!"); + utils::throw_(std::runtime_error("Invalid get of FocusLayout item!")); } return item.value(); @@ -93,12 +95,12 @@ namespace ui { template [[nodiscard]] const T* get(const u32 index) const { if (index >= m_widgets.size()) { - throw std::runtime_error("Invalid get of FocusLayout item: index out of bound!"); + utils::throw_(std::runtime_error("Invalid get of FocusLayout item: index out of bound!")); } const auto item = utils::is_child_class(m_widgets.at(index).get()); if (item == nullptr) { - throw std::runtime_error("Invalid get of FocusLayout item!"); + utils::throw_(std::runtime_error("Invalid get of FocusLayout item!")); } return item.value(); diff --git a/tools/dependencies/meson.build b/tools/dependencies/meson.build index 67568d1d..4ad7a81d 100644 --- a/tools/dependencies/meson.build +++ b/tools/dependencies/meson.build @@ -153,6 +153,7 @@ if ( temp = core_lib.get('compile_args') temp += '-DFMT_USE_LOCALE=0' temp += '-D__OOPETRIS_NO_EXCEPTIONS=1' + temp += '-D__OOPETRIS_NO_STREAMS=1' core_lib += { 'compile_args': temp, } From 3fec6f4af4ade466ce40b639f86af1bc645d55c4 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 8 Aug 2026 00:05:17 +0200 Subject: [PATCH 081/112] feat: try to use compat for ifstreams and ofstreams --- src/libs/core/helper/compat.cpp | 12 ++++---- src/libs/core/helper/compat.hpp | 28 +++++++++++++++++-- src/libs/core/helper/date.cpp | 9 +++++- src/libs/core/helper/parse_json.hpp | 11 +++++++- .../utility/additional_information.hpp | 8 +++--- src/libs/recordings/utility/helper.hpp | 26 +++++++++++++---- .../recordings/utility/recording_reader.cpp | 16 +++++------ .../recordings/utility/recording_reader.hpp | 6 ++-- .../recordings/utility/recording_writer.cpp | 8 +++--- .../recordings/utility/recording_writer.hpp | 8 +++--- 10 files changed, 93 insertions(+), 39 deletions(-) diff --git a/src/libs/core/helper/compat.cpp b/src/libs/core/helper/compat.cpp index b368e9f8..b770afe9 100644 --- a/src/libs/core/helper/compat.cpp +++ b/src/libs/core/helper/compat.cpp @@ -72,7 +72,7 @@ static helper::expected read_file(const char* file_ } -compat::ifstream::ifstream(const std::filesystem::path& path) { +compat::ifstream_basic::ifstream_basic(const std::filesystem::path& path) { auto data = read_file(path.string().c_str()); if (not data.has_value()) { @@ -86,23 +86,23 @@ compat::ifstream::ifstream(const std::filesystem::path& path) { m_open = true; } -compat::ifstream::~ifstream() noexcept { +compat::ifstream_basic::~ifstream_basic() noexcept { free(m_data.data); } -std::string compat::ifstream::copied_data() { +std::string compat::ifstream_basic::copied_data() { return std::string{ (char*)m_data.data, m_data.size }; } -bool compat::ifstream::is_open() const { +bool compat::ifstream_basic::is_open() const { return m_open; } -bool compat::ifstream::fail() const { +bool compat::ifstream_basic::fail() const { return m_fail; } -void compat::ifstream::close() { +void compat::ifstream_basic::close() { m_open = false; } diff --git a/src/libs/core/helper/compat.hpp b/src/libs/core/helper/compat.hpp index 9a74d47d..d0d61378 100644 --- a/src/libs/core/helper/compat.hpp +++ b/src/libs/core/helper/compat.hpp @@ -14,9 +14,9 @@ namespace compat { size_t size; }; - class ifstream { + class ifstream_basic { public: - explicit ifstream(const std::filesystem::path& path); + explicit ifstream_basic(const std::filesystem::path& path); bool is_open() const; bool fail() const; @@ -24,7 +24,7 @@ namespace compat { std::string copied_data(); - ~ifstream() noexcept; + ~ifstream_basic() noexcept; private: bool m_open = false; @@ -33,6 +33,28 @@ namespace compat { Buffer m_data; }; + + class ifstream_seekable { + public: + explicit ifstream_seekable(const std::filesystem::path& path); + + bool is_open() const; + bool fail() const; + void close(); + + ifstream_seekable& read(char* s, size_t count); + + private: + FILE* m_file; + }; + + + class ofstream { + public: + private: + }; + + } // namespace compat diff --git a/src/libs/core/helper/date.cpp b/src/libs/core/helper/date.cpp index 301e3bf5..b6e7233d 100644 --- a/src/libs/core/helper/date.cpp +++ b/src/libs/core/helper/date.cpp @@ -1,5 +1,6 @@ #include "./date.hpp" +#include "./utils.hpp" #include #include @@ -13,7 +14,7 @@ date::ISO8601Date::ISO8601Date(std::tm time_struct) { const std::time_t time = std::mktime(&time_struct); if (time < 0) { - throw std::runtime_error("Couldn't convert std::tm to std::time_t"); + utils::throw_(std::runtime_error("Couldn't convert std::tm to std::time_t")); } m_value = static_cast(time); @@ -72,6 +73,12 @@ helper::expected date::ISO8601Date::from_string( if (gmtime_s(&time_struct, &value) != 0) { return helper::unexpected{ "error calling gmtime_s" }; } +#elif defined(__UEFI__) + std::tm* tm_p = ::localtime(&value); + if (tm_p == nullptr) { + return helper::unexpected{ fmt::format("error calling gmtime: {}", std::strerror(errno)) }; + } + time_struct = *tm_p; #else if (gmtime_r(&value, &time_struct) == nullptr) { return helper::unexpected{ fmt::format("error calling gmtime_r: {}", std::strerror(errno)) }; diff --git a/src/libs/core/helper/parse_json.hpp b/src/libs/core/helper/parse_json.hpp index 5f4e766c..42b58fcb 100644 --- a/src/libs/core/helper/parse_json.hpp +++ b/src/libs/core/helper/parse_json.hpp @@ -18,6 +18,10 @@ #include #include +#if defined(__OOPETRIS_NO_STREAMS) +#include "./compat.hpp" +#endif + // START: general json parser helper //helper for std::optional json conversion @@ -86,7 +90,7 @@ namespace json { } #if defined(__OOPETRIS_NO_STREAMS) - compat::ifstream file_stream{ file }; + compat::ifstream_basic file_stream{ file }; #else std::ifstream file_stream{ file }; #endif @@ -178,7 +182,12 @@ namespace json { return fmt::format("unable to convert settings to json: {}", result.error()); } +#if defined(__OOPETRIS_NO_STREAMS) + compat::ofstream file_stream{ file }; +#else std::ofstream file_stream{ file }; +#endif + if (not file_stream.is_open()) { return fmt::format("File '{}' couldn't be opened!", file.string()); diff --git a/src/libs/recordings/utility/additional_information.hpp b/src/libs/recordings/utility/additional_information.hpp index 16feca03..b7912ecf 100644 --- a/src/libs/recordings/utility/additional_information.hpp +++ b/src/libs/recordings/utility/additional_information.hpp @@ -46,7 +46,7 @@ namespace recorder { template [[nodiscard]] T& as() { if (!is()) { - throw std::runtime_error(fmt::format("Bad cast: can't cast to type '{}' !", typeid(T).name())); + utils::throw_(std::runtime_error(fmt::format("Bad cast: can't cast to type '{}' !", typeid(T).name()))); } return std::get(m_value); @@ -55,7 +55,7 @@ namespace recorder { template [[nodiscard]] const T& as() const { if (!is()) { - throw std::runtime_error(fmt::format("Bad cast: can't cast to type '{}' !", typeid(T).name())); + utils::throw_(std::runtime_error(fmt::format("Bad cast: can't cast to type '{}' !", typeid(T).name()))); } return std::get(m_value); @@ -180,8 +180,8 @@ namespace recorder { [[nodiscard]] OOPETRIS_RECORDINGS_EXPORTED helper::expected, std::string> to_bytes() const; - [[nodiscard]] OOPETRIS_RECORDINGS_EXPORTED helper::expected get_checksum( - ) const; + [[nodiscard]] OOPETRIS_RECORDINGS_EXPORTED helper::expected + get_checksum() const; // iterator trait using iterator = UnderlyingContainer::iterator; //NOLINT(readability-identifier-naming) diff --git a/src/libs/recordings/utility/helper.hpp b/src/libs/recordings/utility/helper.hpp index d9d075af..7c74960c 100644 --- a/src/libs/recordings/utility/helper.hpp +++ b/src/libs/recordings/utility/helper.hpp @@ -14,6 +14,21 @@ #include #include + +#if defined(__OOPETRIS_NO_STREAMS) +#include +namespace recordings { + using ifstream = compat::ifstream_seekable; + using ofstream = compat::ofstream; +}; // namespace recordings +#else +namespace recordings { + using ifstream = std::ifstream; + using ofstream = std::ofstream; +}; // namespace recordings +#endif + + namespace helper { namespace reader { @@ -30,7 +45,7 @@ namespace helper { using ReadResult = helper::expected; template - [[nodiscard]] ReadResult> read_integral_from_file(std::ifstream& file) { + [[nodiscard]] ReadResult> read_integral_from_file(recordings::ifstream& file) { if (file.fail()) { return helper::unexpected{ { ReadErrorType::InvalidStream, "failed to read data from file (before reading)" } @@ -53,7 +68,7 @@ namespace helper { } template - [[nodiscard]] ReadResult> read_array_from_file(std::ifstream& file) { + [[nodiscard]] ReadResult> read_array_from_file(recordings::ifstream& file) { if (file.fail()) { return helper::unexpected{ { ReadErrorType::InvalidStream, "failed to read data from file (before reading)" } @@ -97,7 +112,7 @@ namespace helper { } template - [[nodiscard]] std::optional> read_array_from_istream(std::istream& istream) { + [[nodiscard]] std::optional> read_array_from_istream(recordings::istream& istream) { if (istream.fail()) { return std::nullopt; } @@ -124,7 +139,7 @@ namespace helper { namespace writer { template - helper::expected write_integral_to_file(std::ofstream& file, const Integral data) { + helper::expected write_integral_to_file(recordings::ofstream& file, const Integral data) { if (file.fail()) { return helper::unexpected{ fmt::format("failed to write data \"{}\"", data) }; } @@ -141,7 +156,8 @@ namespace helper { } template - helper::expected write_vector_to_file(std::ofstream& file, const std::vector& values) { + helper::expected + write_vector_to_file(recordings::ofstream& file, const std::vector& values) { helper::expected result{}; for (const auto& value : values) { result = write_integral_to_file(file, value); diff --git a/src/libs/recordings/utility/recording_reader.cpp b/src/libs/recordings/utility/recording_reader.cpp index a908ccbe..64d4f854 100644 --- a/src/libs/recordings/utility/recording_reader.cpp +++ b/src/libs/recordings/utility/recording_reader.cpp @@ -25,12 +25,12 @@ recorder::RecordingReader::RecordingReader(RecordingReader&& old) noexcept helper::expected< - std::tuple, recorder::AdditionalInformation>, + std::tuple, recorder::AdditionalInformation>, std::string> recorder::RecordingReader::get_header_from_path(const std::filesystem::path& path) { - std::ifstream file{ path, std::ios::in | std::ios::binary }; - if (not file) { + recordings::ifstream file{ path, std::ios::in | std::ios::binary }; + if (file.fail()) { return helper::unexpected{ fmt::format("unable to load recording from file \"{}\"", path.string()) }; @@ -98,7 +98,7 @@ recorder::RecordingReader::get_header_from_path(const std::filesystem::path& pat ) }; } - return std::make_tuple, AdditionalInformation>( + return std::make_tuple, AdditionalInformation>( std::move(file), std::move(tetrion_headers), std::move(information.value()) ); } @@ -209,8 +209,8 @@ helper::expected recorder::RecordingRead [[nodiscard]] helper::reader::ReadResult -recorder::RecordingReader::read_tetrion_header_from_file(std::ifstream& file) { - if (not file) { +recorder::RecordingReader::read_tetrion_header_from_file(recordings::ifstream& file) { + if (file.fail()) { return helper::unexpected{ { helper::reader::ReadErrorType::InvalidStream, "failed to read data from file" } }; @@ -235,9 +235,9 @@ recorder::RecordingReader::read_tetrion_header_from_file(std::ifstream& file) { } [[nodiscard]] helper::reader::ReadResult recorder::RecordingReader::read_record_from_file( - std::ifstream& file + recordings::ifstream& file ) { - if (not file) { + if (file.fail()) { return helper::unexpected{ { helper::reader::ReadErrorType::InvalidStream, "invalid input file stream while trying to read record" } }; diff --git a/src/libs/recordings/utility/recording_reader.hpp b/src/libs/recordings/utility/recording_reader.hpp index 5e353f17..36c355ed 100644 --- a/src/libs/recordings/utility/recording_reader.hpp +++ b/src/libs/recordings/utility/recording_reader.hpp @@ -63,15 +63,15 @@ namespace recorder { private: [[nodiscard]] static helper::expected< - std::tuple, recorder::AdditionalInformation>, + std::tuple, recorder::AdditionalInformation>, std::string> get_header_from_path(const std::filesystem::path& path); - [[nodiscard]] static helper::reader::ReadResult read_tetrion_header_from_file(std::ifstream& file + [[nodiscard]] static helper::reader::ReadResult read_tetrion_header_from_file(recordings::ifstream& file ); - [[nodiscard]] static helper::reader::ReadResult read_record_from_file(std::ifstream& file); + [[nodiscard]] static helper::reader::ReadResult read_record_from_file(recordings::ifstream& file); }; STATIC_ASSERT_WITH_MESSAGE(utils::IsIterator::value, "RecordingReader has to be an iterator"); diff --git a/src/libs/recordings/utility/recording_writer.cpp b/src/libs/recordings/utility/recording_writer.cpp index ad2f8231..a08757cc 100644 --- a/src/libs/recordings/utility/recording_writer.cpp +++ b/src/libs/recordings/utility/recording_writer.cpp @@ -3,7 +3,7 @@ #include "./tetrion_snapshot.hpp" recorder::RecordingWriter::RecordingWriter( - std::ofstream&& output_file, + recordings::ofstream&& output_file, std::vector&& tetrion_headers, AdditionalInformation&& information ) @@ -34,7 +34,7 @@ helper::expected recorder::RecordingWrit } - auto output_file = std::ofstream{ path, mode }; + auto output_file = recordings::ofstream{ path, mode }; if (not output_file) { return helper::unexpected{ fmt::format("failed to open output file \"{}\"", path.string()) }; @@ -143,7 +143,7 @@ helper::expected recorder::RecordingWriter::add_snapshot( helper::expected -recorder::RecordingWriter::write_tetrion_header_to_file(std::ofstream& file, const TetrionHeader& header) { +recorder::RecordingWriter::write_tetrion_header_to_file(recordings::ofstream& file, const TetrionHeader& header) { helper::expected result{}; static_assert(sizeof(decltype(header.seed)) == 8); @@ -162,7 +162,7 @@ recorder::RecordingWriter::write_tetrion_header_to_file(std::ofstream& file, con } helper::expected recorder::RecordingWriter::write_checksum_to_file( - std::ofstream& file, + recordings::ofstream& file, const std::vector& tetrion_headers, const AdditionalInformation& information ) { diff --git a/src/libs/recordings/utility/recording_writer.hpp b/src/libs/recordings/utility/recording_writer.hpp index 22e01eff..debb3d55 100644 --- a/src/libs/recordings/utility/recording_writer.hpp +++ b/src/libs/recordings/utility/recording_writer.hpp @@ -14,10 +14,10 @@ namespace recorder { struct RecordingWriter : public Recording { private: - std::ofstream m_output_file; + recordings::ofstream m_output_file; explicit RecordingWriter( - std::ofstream&& output_file, + recordings::ofstream&& output_file, std::vector&& tetrion_headers, AdditionalInformation&& information ); @@ -43,10 +43,10 @@ namespace recorder { private: static helper::expected - write_tetrion_header_to_file(std::ofstream& file, const TetrionHeader& header); + write_tetrion_header_to_file(recordings::ofstream& file, const TetrionHeader& header); static helper::expected write_checksum_to_file( - std::ofstream& file, + recordings::ofstream& file, const std::vector& tetrion_headers, const AdditionalInformation& information ); From b9936ee0d29ae51e532c7bd26d54f878b9809c04 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 8 Aug 2026 00:50:10 +0200 Subject: [PATCH 082/112] feat: use locale in uefi - I fixed libcxx locale support (just stubbed out for the most part, except ASCII things) --- src/executables/platforms/uefi/mappings.json | 1 - src/libs/core/helper/compat.cpp | 109 ------------------ src/libs/core/helper/compat.hpp | 61 ---------- src/libs/core/helper/meson.build | 2 - src/libs/core/helper/parse_json.hpp | 24 +--- src/libs/recordings/utility/helper.hpp | 24 +--- .../recordings/utility/recording_reader.cpp | 10 +- .../recordings/utility/recording_reader.hpp | 6 +- tools/dependencies/meson.build | 2 - 9 files changed, 16 insertions(+), 223 deletions(-) delete mode 100644 src/libs/core/helper/compat.cpp delete mode 100644 src/libs/core/helper/compat.hpp diff --git a/src/executables/platforms/uefi/mappings.json b/src/executables/platforms/uefi/mappings.json index bab2330f..49197bd5 100644 --- a/src/executables/platforms/uefi/mappings.json +++ b/src/executables/platforms/uefi/mappings.json @@ -55,7 +55,6 @@ "guid": "dee047db-15c9-4d79-ab08-79d6244d9b0e", "version": "spdlog", "options": [ - "-DFMT_USE_LOCALE=0", "-DSPDLOG_NO_EXCEPTIONS=1", "-DSPDLOG_NO_TLS=1" ] diff --git a/src/libs/core/helper/compat.cpp b/src/libs/core/helper/compat.cpp deleted file mode 100644 index b770afe9..00000000 --- a/src/libs/core/helper/compat.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include "./compat.hpp" - - -#if defined(__OOPETRIS_NO_STREAMS) - -#include -#include - - -static helper::expected read_file(const char* file_path) { - FILE* file = fopen(file_path, "rb"); - - if (file == NULL) { - - return helper::unexpected{ - fmt::format("Couldn't open file for reading '{}': {}", file_path, strerror(errno)) - }; - } - - const int fseek_res = fseek(file, 0, SEEK_END); - - if (fseek_res != 0) { - return helper::unexpected{ - fmt::format("Couldn't seek to end of file '{}': {}", file_path, strerror(errno)) - }; - } - - const long file_size = ftell(file); - - if (file_size < 0) { - return helper::unexpected{ fmt::format("File size is negative: '{}': {}", file_path, file_size) }; - } - - const int fseek_res2 = fseek(file, 0, SEEK_SET); - - if (fseek_res2 != 0) { - return helper::unexpected{ - fmt::format("Couldn't seek to start of file '{}': {}", file_path, strerror(errno)) - }; - } - - uint8_t* file_data = (uint8_t*) malloc((size_t) file_size * sizeof(uint8_t)); - - if (!file_data) { - fclose(file); - return helper::unexpected{ "Couldn't allocate bytes" }; - } - - const size_t fread_result = fread(file_data, 1, (size_t) file_size, file); - - if (fread_result != (size_t) file_size) { - const char* error_msg = strerror(errno); - - fclose(file); - free(file_data); - - return helper::unexpected{ - fmt::format("Couldn't read the correct amount of bytes from file '{}': {}", file_path, error_msg) - }; - } - - const int fclose_result = fclose(file); - - if (fclose_result != 0) { - const char* error_msg = strerror(errno); - - free(file_data); - return helper::unexpected{ fmt::format("Couldn't close file '{}': {}", file_path, error_msg) }; - } - - return compat::Buffer{ file_data, (size_t) file_size }; -} - - -compat::ifstream_basic::ifstream_basic(const std::filesystem::path& path) { - auto data = read_file(path.string().c_str()); - - if (not data.has_value()) { - m_fail = true; - return; - } - - auto ok = data.value(); - - m_data = ok; - m_open = true; -} - -compat::ifstream_basic::~ifstream_basic() noexcept { - free(m_data.data); -} - -std::string compat::ifstream_basic::copied_data() { - return std::string{ (char*)m_data.data, m_data.size }; -} - -bool compat::ifstream_basic::is_open() const { - return m_open; -} - -bool compat::ifstream_basic::fail() const { - return m_fail; -} - -void compat::ifstream_basic::close() { - m_open = false; -} - -#endif diff --git a/src/libs/core/helper/compat.hpp b/src/libs/core/helper/compat.hpp deleted file mode 100644 index d0d61378..00000000 --- a/src/libs/core/helper/compat.hpp +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -#if defined(__OOPETRIS_NO_STREAMS) - -#include "./types.hpp" - -#include - - -namespace compat { - - struct Buffer { - uint8_t* data; - size_t size; - }; - - class ifstream_basic { - public: - explicit ifstream_basic(const std::filesystem::path& path); - - bool is_open() const; - bool fail() const; - void close(); - - std::string copied_data(); - - ~ifstream_basic() noexcept; - - private: - bool m_open = false; - bool m_fail = false; - - Buffer m_data; - }; - - - class ifstream_seekable { - public: - explicit ifstream_seekable(const std::filesystem::path& path); - - bool is_open() const; - bool fail() const; - void close(); - - ifstream_seekable& read(char* s, size_t count); - - private: - FILE* m_file; - }; - - - class ofstream { - public: - private: - }; - - -} // namespace compat - - -#endif diff --git a/src/libs/core/helper/meson.build b/src/libs/core/helper/meson.build index dbbeb0ef..c440546a 100644 --- a/src/libs/core/helper/meson.build +++ b/src/libs/core/helper/meson.build @@ -1,6 +1,5 @@ core_src_files += files( 'color.cpp', - 'compat.cpp', 'date.cpp', 'errors.cpp', 'parse_json.cpp', @@ -14,7 +13,6 @@ _header_files = files( 'bool_wrapper.hpp', 'color.hpp', 'color_literals.hpp', - 'compat.hpp', 'const_utils.hpp', 'date.hpp', 'errors.hpp', diff --git a/src/libs/core/helper/parse_json.hpp b/src/libs/core/helper/parse_json.hpp index 42b58fcb..263aa4c8 100644 --- a/src/libs/core/helper/parse_json.hpp +++ b/src/libs/core/helper/parse_json.hpp @@ -18,10 +18,6 @@ #include #include -#if defined(__OOPETRIS_NO_STREAMS) -#include "./compat.hpp" -#endif - // START: general json parser helper //helper for std::optional json conversion @@ -89,11 +85,7 @@ namespace json { ) }; } -#if defined(__OOPETRIS_NO_STREAMS) - compat::ifstream_basic file_stream{ file }; -#else std::ifstream file_stream{ file }; -#endif if (not file_stream.is_open()) { return helper::unexpected>{ std::make_pair( @@ -101,14 +93,8 @@ namespace json { ) }; } - std::string result; -#if defined(__OOPETRIS_NO_STREAMS) - result = std::move(file_stream.copied_data()); -#else - std::stringstream result_str; - result_str << file_stream.rdbuf(); - result = result_str.str(); -#endif + std::stringstream result; + result << file_stream.rdbuf(); file_stream.close(); @@ -118,7 +104,7 @@ namespace json { ) }; } - auto parse_result = try_parse_json(result); + auto parse_result = try_parse_json(result.str()); if (not parse_result.has_value()) { return helper::unexpected>{ std::make_pair(std::move(parse_result.error()), ParseError::FormatError) @@ -182,11 +168,7 @@ namespace json { return fmt::format("unable to convert settings to json: {}", result.error()); } -#if defined(__OOPETRIS_NO_STREAMS) - compat::ofstream file_stream{ file }; -#else std::ofstream file_stream{ file }; -#endif if (not file_stream.is_open()) { diff --git a/src/libs/recordings/utility/helper.hpp b/src/libs/recordings/utility/helper.hpp index 7c74960c..077dafe3 100644 --- a/src/libs/recordings/utility/helper.hpp +++ b/src/libs/recordings/utility/helper.hpp @@ -15,20 +15,6 @@ #include -#if defined(__OOPETRIS_NO_STREAMS) -#include -namespace recordings { - using ifstream = compat::ifstream_seekable; - using ofstream = compat::ofstream; -}; // namespace recordings -#else -namespace recordings { - using ifstream = std::ifstream; - using ofstream = std::ofstream; -}; // namespace recordings -#endif - - namespace helper { namespace reader { @@ -45,7 +31,7 @@ namespace helper { using ReadResult = helper::expected; template - [[nodiscard]] ReadResult> read_integral_from_file(recordings::ifstream& file) { + [[nodiscard]] ReadResult> read_integral_from_file(std::ifstream& file) { if (file.fail()) { return helper::unexpected{ { ReadErrorType::InvalidStream, "failed to read data from file (before reading)" } @@ -68,7 +54,7 @@ namespace helper { } template - [[nodiscard]] ReadResult> read_array_from_file(recordings::ifstream& file) { + [[nodiscard]] ReadResult> read_array_from_file(std::ifstream& file) { if (file.fail()) { return helper::unexpected{ { ReadErrorType::InvalidStream, "failed to read data from file (before reading)" } @@ -112,7 +98,7 @@ namespace helper { } template - [[nodiscard]] std::optional> read_array_from_istream(recordings::istream& istream) { + [[nodiscard]] std::optional> read_array_from_istream(std::istream& istream) { if (istream.fail()) { return std::nullopt; } @@ -139,7 +125,7 @@ namespace helper { namespace writer { template - helper::expected write_integral_to_file(recordings::ofstream& file, const Integral data) { + helper::expected write_integral_to_file(std::ofstream& file, const Integral data) { if (file.fail()) { return helper::unexpected{ fmt::format("failed to write data \"{}\"", data) }; } @@ -157,7 +143,7 @@ namespace helper { template helper::expected - write_vector_to_file(recordings::ofstream& file, const std::vector& values) { + write_vector_to_file(std::ofstream& file, const std::vector& values) { helper::expected result{}; for (const auto& value : values) { result = write_integral_to_file(file, value); diff --git a/src/libs/recordings/utility/recording_reader.cpp b/src/libs/recordings/utility/recording_reader.cpp index 64d4f854..077a0ada 100644 --- a/src/libs/recordings/utility/recording_reader.cpp +++ b/src/libs/recordings/utility/recording_reader.cpp @@ -25,11 +25,11 @@ recorder::RecordingReader::RecordingReader(RecordingReader&& old) noexcept helper::expected< - std::tuple, recorder::AdditionalInformation>, + std::tuple, recorder::AdditionalInformation>, std::string> recorder::RecordingReader::get_header_from_path(const std::filesystem::path& path) { - recordings::ifstream file{ path, std::ios::in | std::ios::binary }; + std::ifstream file{ path, std::ios::in | std::ios::binary }; if (file.fail()) { return helper::unexpected{ fmt::format("unable to load recording from file \"{}\"", path.string()) @@ -98,7 +98,7 @@ recorder::RecordingReader::get_header_from_path(const std::filesystem::path& pat ) }; } - return std::make_tuple, AdditionalInformation>( + return std::make_tuple, AdditionalInformation>( std::move(file), std::move(tetrion_headers), std::move(information.value()) ); } @@ -209,7 +209,7 @@ helper::expected recorder::RecordingRead [[nodiscard]] helper::reader::ReadResult -recorder::RecordingReader::read_tetrion_header_from_file(recordings::ifstream& file) { +recorder::RecordingReader::read_tetrion_header_from_file(std::ifstream& file) { if (file.fail()) { return helper::unexpected{ { helper::reader::ReadErrorType::InvalidStream, "failed to read data from file" } @@ -235,7 +235,7 @@ recorder::RecordingReader::read_tetrion_header_from_file(recordings::ifstream& f } [[nodiscard]] helper::reader::ReadResult recorder::RecordingReader::read_record_from_file( - recordings::ifstream& file + std::ifstream& file ) { if (file.fail()) { return helper::unexpected{ diff --git a/src/libs/recordings/utility/recording_reader.hpp b/src/libs/recordings/utility/recording_reader.hpp index 36c355ed..5e353f17 100644 --- a/src/libs/recordings/utility/recording_reader.hpp +++ b/src/libs/recordings/utility/recording_reader.hpp @@ -63,15 +63,15 @@ namespace recorder { private: [[nodiscard]] static helper::expected< - std::tuple, recorder::AdditionalInformation>, + std::tuple, recorder::AdditionalInformation>, std::string> get_header_from_path(const std::filesystem::path& path); - [[nodiscard]] static helper::reader::ReadResult read_tetrion_header_from_file(recordings::ifstream& file + [[nodiscard]] static helper::reader::ReadResult read_tetrion_header_from_file(std::ifstream& file ); - [[nodiscard]] static helper::reader::ReadResult read_record_from_file(recordings::ifstream& file); + [[nodiscard]] static helper::reader::ReadResult read_record_from_file(std::ifstream& file); }; STATIC_ASSERT_WITH_MESSAGE(utils::IsIterator::value, "RecordingReader has to be an iterator"); diff --git a/tools/dependencies/meson.build b/tools/dependencies/meson.build index 4ad7a81d..1f804a84 100644 --- a/tools/dependencies/meson.build +++ b/tools/dependencies/meson.build @@ -151,9 +151,7 @@ if ( fmt_use_header_only = true temp = core_lib.get('compile_args') - temp += '-DFMT_USE_LOCALE=0' temp += '-D__OOPETRIS_NO_EXCEPTIONS=1' - temp += '-D__OOPETRIS_NO_STREAMS=1' core_lib += { 'compile_args': temp, } From 03db88411c709d207e022d49f9b44b96772639f6 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 8 Aug 2026 01:13:14 +0200 Subject: [PATCH 083/112] fix: more uefi related cpp fixes --- src/libs/core/hash-library/sha256.cpp | 2 ++ src/libs/core/helper/parse_json.cpp | 15 +++++++++++---- src/libs/core/helper/parse_json.hpp | 8 ++++++++ src/libs/recordings/utility/recording.cpp | 2 +- src/libs/recordings/utility/recording_writer.cpp | 8 ++++---- src/lobby/api.cpp | 5 +++-- tools/dependencies/meson.build | 2 +- 7 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/libs/core/hash-library/sha256.cpp b/src/libs/core/hash-library/sha256.cpp index d085a97e..2c588ed3 100644 --- a/src/libs/core/hash-library/sha256.cpp +++ b/src/libs/core/hash-library/sha256.cpp @@ -29,6 +29,8 @@ #endif #elif defined(__APPLE__) #include +#elif defined(__UEFI__) +#include #else #include #endif diff --git a/src/libs/core/helper/parse_json.cpp b/src/libs/core/helper/parse_json.cpp index 34b5f6ba..a2af52bf 100644 --- a/src/libs/core/helper/parse_json.cpp +++ b/src/libs/core/helper/parse_json.cpp @@ -3,6 +3,9 @@ #include "./parse_json.hpp" +#include "./utils.hpp" + + std::string json::get_json_type(const nlohmann::json::value_t& type) { switch (type) { @@ -41,8 +44,10 @@ bool json::is_meta_key(const std::string& key) { void json::check_for_no_additional_keys(const nlohmann::json& obj, const std::vector& keys) { if (not obj.is_object()) { - throw nlohmann::json::type_error::create( - 302, fmt::format("expected an object, but got type '{}'", get_json_type(obj.type())), &obj + utils::throw_( + nlohmann::json::type_error::create( + 302, fmt::format("expected an object, but got type '{}'", get_json_type(obj.type())), &obj + ) ); } @@ -54,8 +59,10 @@ void json::check_for_no_additional_keys(const nlohmann::json& obj, const std::ve continue; } if (std::ranges::find(keys, key) == keys.cend()) { - throw nlohmann::json::type_error::create( - 302, fmt::format("object may only contain expected keys, but contained '{}'", key), &obj + utils::throw_( + nlohmann::json::type_error::create( + 302, fmt::format("object may only contain expected keys, but contained '{}'", key), &obj + ) ); } } diff --git a/src/libs/core/helper/parse_json.hpp b/src/libs/core/helper/parse_json.hpp index 263aa4c8..917e73e8 100644 --- a/src/libs/core/helper/parse_json.hpp +++ b/src/libs/core/helper/parse_json.hpp @@ -58,9 +58,16 @@ namespace json { template [[nodiscard]] helper::expected try_parse_json(const std::string& content) noexcept { +#if defined(__OOPETRIS_NO_EXCEPTIONS) + T result = nlohmann::json::parse(content, nullptr, false); + return result; +#else try { T result = nlohmann::json::parse(content); + if (result.is_discarded()) { + return helper::unexpected{ "A JSON error occurred, but no further details available" }; + } return result; } catch (nlohmann::json::parse_error& parse_error) { @@ -72,6 +79,7 @@ namespace json { } catch (std::exception& exception) { return helper::unexpected{ fmt::format("unknown exception: {}", exception.what()) }; } +#endif } template diff --git a/src/libs/recordings/utility/recording.cpp b/src/libs/recordings/utility/recording.cpp index 9fd11033..6a580114 100644 --- a/src/libs/recordings/utility/recording.cpp +++ b/src/libs/recordings/utility/recording.cpp @@ -42,7 +42,7 @@ recorder::TetrionHeader::TetrionHeader( const auto information_checksum = information.get_checksum(); if (not information_checksum.has_value()) { - throw std::runtime_error(information_checksum.error()); + utils::throw_(std::runtime_error(information_checksum.error())); } sha256_creator << information_checksum.value(); diff --git a/src/libs/recordings/utility/recording_writer.cpp b/src/libs/recordings/utility/recording_writer.cpp index a08757cc..ad2f8231 100644 --- a/src/libs/recordings/utility/recording_writer.cpp +++ b/src/libs/recordings/utility/recording_writer.cpp @@ -3,7 +3,7 @@ #include "./tetrion_snapshot.hpp" recorder::RecordingWriter::RecordingWriter( - recordings::ofstream&& output_file, + std::ofstream&& output_file, std::vector&& tetrion_headers, AdditionalInformation&& information ) @@ -34,7 +34,7 @@ helper::expected recorder::RecordingWrit } - auto output_file = recordings::ofstream{ path, mode }; + auto output_file = std::ofstream{ path, mode }; if (not output_file) { return helper::unexpected{ fmt::format("failed to open output file \"{}\"", path.string()) }; @@ -143,7 +143,7 @@ helper::expected recorder::RecordingWriter::add_snapshot( helper::expected -recorder::RecordingWriter::write_tetrion_header_to_file(recordings::ofstream& file, const TetrionHeader& header) { +recorder::RecordingWriter::write_tetrion_header_to_file(std::ofstream& file, const TetrionHeader& header) { helper::expected result{}; static_assert(sizeof(decltype(header.seed)) == 8); @@ -162,7 +162,7 @@ recorder::RecordingWriter::write_tetrion_header_to_file(recordings::ofstream& fi } helper::expected recorder::RecordingWriter::write_checksum_to_file( - recordings::ofstream& file, + std::ofstream& file, const std::vector& tetrion_headers, const AdditionalInformation& information ) { diff --git a/src/lobby/api.cpp b/src/lobby/api.cpp index c9692434..6b87b53a 100644 --- a/src/lobby/api.cpp +++ b/src/lobby/api.cpp @@ -68,7 +68,7 @@ lobby::API::API(ServiceProvider* service_provider, const std::string& api_url) if (value.has_value()) { if (not this->setup_authentication(value.value().as_string())) { - throw std::runtime_error("Couldn't setup authentication"); + utils::throw_(std::runtime_error("Couldn't setup authentication")); } } else { spdlog::info("API: Key not found, so probably not logged in already: {}", value.error()); @@ -238,7 +238,8 @@ helper::expected lobby::API::start_lobby(int lobby_id) { return is_request_ok(res, 204); } -helper::expected lobby::API::create_lobby(const CreateLobbyRequest& arguments +helper::expected lobby::API::create_lobby( + const CreateLobbyRequest& arguments ) { if (not is_authenticated()) { return helper::unexpected{ diff --git a/tools/dependencies/meson.build b/tools/dependencies/meson.build index 1f804a84..3972ee32 100644 --- a/tools/dependencies/meson.build +++ b/tools/dependencies/meson.build @@ -468,7 +468,7 @@ if build_application online_multiplayer_system = 'uefi' graphics_lib += { - 'compile_args': [graphics_lib.get('compile_args'), '-D_OOPETRIS_ONLINE_SYSTEM=2'], + 'compile_args': [graphics_lib.get('compile_args'), '-D_OOPETRIS_ONLINE_SYSTEM=3'], } else From 7433cf7ae8a0d39e7a7f4d06fa1ec0074487806b Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 8 Aug 2026 01:32:11 +0200 Subject: [PATCH 084/112] feat: some more progress for uefi --- src/executables/game/application.cpp | 5 +- src/graphics/renderer.cpp | 13 +- src/graphics/sdl_context.cpp | 3 +- src/libs/core/helper/parse_json.hpp | 32 +-- src/libs/core/helper/sleep.cpp | 28 ++ .../utility/recording_json_wrapper.hpp | 2 + .../recordings/utility/recording_writer.hpp | 8 +- src/lobby/api.cpp | 6 + src/lobby/meson.build | 2 +- src/lobby/uefi_client.cpp | 270 ++++++++++++++++++ src/lobby/uefi_client.hpp | 74 +++++ tools/dependencies/meson.build | 1 + 12 files changed, 415 insertions(+), 29 deletions(-) create mode 100644 src/lobby/uefi_client.cpp create mode 100644 src/lobby/uefi_client.hpp diff --git a/src/executables/game/application.cpp b/src/executables/game/application.cpp index 109a8c18..6a7c8343 100644 --- a/src/executables/game/application.cpp +++ b/src/executables/game/application.cpp @@ -109,7 +109,9 @@ Application::Application(std::shared_ptr&& window, CommandLineArguments& #endif { initialize(); -} catch (const helper::GeneralError& general_error) { +} +#if !defined(__OOPETRIS_NO_EXCEPTIONS) +catch (const helper::GeneralError& general_error) { const auto severity = general_error.severity(); const auto notification_level = get_notification_level(severity); @@ -120,6 +122,7 @@ Application::Application(std::shared_ptr&& window, CommandLineArguments& throw general_error; } } +#endif Application::~Application() = default; diff --git a/src/graphics/renderer.cpp b/src/graphics/renderer.cpp index 5eb09c8f..cc767cf7 100644 --- a/src/graphics/renderer.cpp +++ b/src/graphics/renderer.cpp @@ -18,12 +18,15 @@ Renderer::Renderer(const Window& window, const VSync v_sync) ) } { if (m_renderer == nullptr) { - throw helper::InitializationError{ fmt::format("Failed creating a SDL Renderer: {}", SDL_GetError()) }; + utils::throw_(helper::InitializationError{ fmt::format("Failed creating a SDL Renderer: {}", SDL_GetError()) }); } auto result = SDL_SetRenderDrawBlendMode(m_renderer, SDL_BLENDMODE_BLEND); if (result < 0) { - throw helper::InitializationError{ fmt::format("Failed in setting BlendMode on Renderer: {}", SDL_GetError()) }; + utils::throw_( + helper::InitializationError{ + fmt::format("Failed in setting BlendMode on Renderer: {}", SDL_GetError()) } + ); } } @@ -65,7 +68,7 @@ Texture Renderer::get_texture_for_render_target(const shapes::UPoint& size) cons const auto supported = SDL_RenderTargetSupported(m_renderer); if (supported == SDL_FALSE) { - throw helper::FatalError{ "SDL does not support a target renderer, but we need one!" }; + utils::throw_(helper::FatalError{ "SDL does not support a target renderer, but we need one!" }); } return Texture::get_for_render_target(m_renderer, size); @@ -79,7 +82,9 @@ void Renderer::set_render_target(const Texture& texture) const { void Renderer::reset_render_target() const { const auto result = SDL_SetRenderTarget(m_renderer, nullptr); if (result < 0) { - throw helper::FatalError{ fmt::format("Failed to set render texture target with error: {}", SDL_GetError()) }; + utils::throw_( + helper::FatalError{ fmt::format("Failed to set render texture target with error: {}", SDL_GetError()) } + ); } } diff --git a/src/graphics/sdl_context.cpp b/src/graphics/sdl_context.cpp index e0c426f1..354f2a88 100644 --- a/src/graphics/sdl_context.cpp +++ b/src/graphics/sdl_context.cpp @@ -1,4 +1,5 @@ #include +#include #include "graphics/sdl_context.hpp" @@ -18,7 +19,7 @@ SdlContext::SdlContext() { if (SDL_Init(SDL_INIT_VIDEO) < 0) { - throw helper::InitializationError{ fmt::format("Failed in initializing sdl: {}", SDL_GetError()) }; + utils::throw_(helper::InitializationError{ fmt::format("Failed in initializing sdl: {}", SDL_GetError()) }); } if (TTF_Init() < 0) { diff --git a/src/libs/core/helper/parse_json.hpp b/src/libs/core/helper/parse_json.hpp index 917e73e8..03567364 100644 --- a/src/libs/core/helper/parse_json.hpp +++ b/src/libs/core/helper/parse_json.hpp @@ -125,6 +125,11 @@ namespace json { template [[nodiscard]] helper::expected try_convert_to_json(const T& input) noexcept { +#if defined(__OOPETRIS_NO_EXCEPTIONS) + nlohmann::json value = input; +#error "TODO" + return value; +#else try { nlohmann::json value = input; return value; @@ -135,33 +140,24 @@ namespace json { } catch (std::exception& exception) { return helper::unexpected{ fmt::format("unknown exception: {}", exception.what()) }; } +#endif } template [[nodiscard]] helper::expected try_json_to_string(const T& type, const bool pretty = false) noexcept { - try { - - auto value = try_convert_to_json(type); - - if (not value.has_value()) { - return helper::unexpected{ value.error() }; - } - - if (pretty) { - return value.value().dump(1, '\t'); - } + auto value = try_convert_to_json(type); - return value.value().dump(-1, ' '); + if (not value.has_value()) { + return helper::unexpected{ value.error() }; + } - } catch (nlohmann::json::type_error& type_error) { - return helper::unexpected{ fmt::format("type error: {}", type_error.what()) }; - } catch (nlohmann::json::exception& exception) { - return helper::unexpected{ fmt::format("unknown json exception: {}", exception.what()) }; - } catch (std::exception& exception) { - return helper::unexpected{ fmt::format("unknown exception: {}", exception.what()) }; + if (pretty) { + return value.value().dump(1, '\t'); } + + return value.value().dump(-1, ' '); } diff --git a/src/libs/core/helper/sleep.cpp b/src/libs/core/helper/sleep.cpp index 1d9f7693..a6a4ab7e 100644 --- a/src/libs/core/helper/sleep.cpp +++ b/src/libs/core/helper/sleep.cpp @@ -20,6 +20,34 @@ using namespace std::chrono_literals; #endif +#if defined(__UEFI__) + + +#include +#include + +static int nanosleep(const struct timespec* __req, struct timespec* __rem) { + // The nanosleep() function is not available on uefi. Therefore, we will call + // NanoSecondDelay + + if (__req == nullptr) { + return -1; + } + + UINT64 ns = (UINT64) __req->tv_sec * 1000000000ULL + (UINT64) __req->tv_nsec; + + NanoSecondDelay(ns); + + if (__rem != nullptr) { + __rem->tv_sec = 0; + __rem->tv_nsec = 0; + } + + return 0; +} + +#endif + bool helper::sleep_nanoseconds(std::chrono::nanoseconds nano_seconds) { #if defined(_MSC_VER) diff --git a/src/libs/recordings/utility/recording_json_wrapper.hpp b/src/libs/recordings/utility/recording_json_wrapper.hpp index 628ff6cb..10a45d67 100644 --- a/src/libs/recordings/utility/recording_json_wrapper.hpp +++ b/src/libs/recordings/utility/recording_json_wrapper.hpp @@ -11,6 +11,8 @@ #include "./recording_reader.hpp" #include "./tetrion_snapshot.hpp" +//TODO: for ALL json wrappers, make a api, that returns std::optional so that it can work without exceptions +// support nlohmann json per using a tenmoplate type, that make an adl_serializer for all these types! namespace nlohmann { template<> struct adl_serializer { diff --git a/src/libs/recordings/utility/recording_writer.hpp b/src/libs/recordings/utility/recording_writer.hpp index debb3d55..22e01eff 100644 --- a/src/libs/recordings/utility/recording_writer.hpp +++ b/src/libs/recordings/utility/recording_writer.hpp @@ -14,10 +14,10 @@ namespace recorder { struct RecordingWriter : public Recording { private: - recordings::ofstream m_output_file; + std::ofstream m_output_file; explicit RecordingWriter( - recordings::ofstream&& output_file, + std::ofstream&& output_file, std::vector&& tetrion_headers, AdditionalInformation&& information ); @@ -43,10 +43,10 @@ namespace recorder { private: static helper::expected - write_tetrion_header_to_file(recordings::ofstream& file, const TetrionHeader& header); + write_tetrion_header_to_file(std::ofstream& file, const TetrionHeader& header); static helper::expected write_checksum_to_file( - recordings::ofstream& file, + std::ofstream& file, const std::vector& tetrion_headers, const AdditionalInformation& information ); diff --git a/src/lobby/api.cpp b/src/lobby/api.cpp index 6b87b53a..5adb8e38 100644 --- a/src/lobby/api.cpp +++ b/src/lobby/api.cpp @@ -15,6 +15,8 @@ #include "./web_client.hpp" #elif _OOPETRIS_ONLINE_SYSTEM == 2 #include "./curl_client.hpp" +#elif _OOPETRIS_ONLINE_SYSTEM == 3 +#include "./uefi_client.hpp" #else #error "_OOPETRIS_ONLINE_SYSTEM has an invalid value" #endif @@ -92,7 +94,9 @@ lobby::API::~API() = default; helper::expected lobby::API::get_api(ServiceProvider* service_provider, const std::string& url) { +#if !defined(__OOPETRIS_NO_EXCEPTIONS) try { +#endif API api{ service_provider, url }; @@ -105,9 +109,11 @@ lobby::API::get_api(ServiceProvider* service_provider, const std::string& url) { //TODO(Totto): once version is standard, check here if the version is supported return api; +#if !defined(__OOPETRIS_NO_EXCEPTIONS) } catch (const std::exception& error) { return helper::unexpected{ error.what() }; } +#endif } void lobby::API::check_url( diff --git a/src/lobby/meson.build b/src/lobby/meson.build index 86427fa4..2b816bb5 100644 --- a/src/lobby/meson.build +++ b/src/lobby/meson.build @@ -5,7 +5,7 @@ elif online_multiplayer_system == 'httplib' elif online_multiplayer_system == 'web' graphics_src_files += files('web_client.cpp', 'web_client.hpp') elif online_multiplayer_system == 'uefi' - warning('TODO: implement') + graphics_src_files += files('uefi_client.cpp', 'uefi_client.hpp') else error('Unhandled online_multiplayer_system: \'' + online_multiplayer_system + '\'') endif diff --git a/src/lobby/uefi_client.cpp b/src/lobby/uefi_client.cpp new file mode 100644 index 00000000..177a39d8 --- /dev/null +++ b/src/lobby/uefi_client.cpp @@ -0,0 +1,270 @@ + +#include "./uefi_client.hpp" + +#include +#include + +// Note: this uses emscripten fetch +//see: https://emscripten.org/docs/api_reference/fetch.html + +//Note: Synchronous Emscripten Fetch operations are subject to a number of restrictions, depending on which Emscripten build mode (linker flags) is used: +// we use: -pthread: Synchronous Fetch operations are available on pthreads, but not on the main thread. + +#define TRANSFORM_RESULT(result) std::make_unique((result)) //NOLINT(cppcoreguidelines-macro-usage + +namespace { + using FetchHeader = oopetris::http::implementation::details::FetchHeader; + + FetchHeader get_headers(const std::unique_ptr& request) { + + auto header_length = emscripten_fetch_get_response_headers_length(request.get()); + + auto* headersRawDst = new char[header_length + 1]; + emscripten_fetch_get_response_headers(request.get(), headersRawDst, header_length + 1); + + char** unpackedHeaders = emscripten_fetch_unpack_response_headers(headersRawDst); + + FetchHeader result{}; + + u32 i = 0; + while (true) { + auto* headerKey = unpackedHeaders[i]; + + if (headerKey == nullptr) { + break; + } + + auto* headerValue = unpackedHeaders[i + 1]; + if (headerValue == nullptr) { + //this is an error, since this has to be a valid char* + //TODO: report that properly + break; + } + + result.at(headerKey) = std::string{ headerValue }; + + i += 2; + } + + delete[] headersRawDst; + + emscripten_fetch_free_unpacked_response_headers(unpackedHeaders); + + return result; + } + + // Specifies the readyState of the XHR request: + // 0: UNSENT: request not sent yet + // 1: OPENED: emscripten_fetch has been called. + // 2: HEADERS_RECEIVED: emscripten_fetch has been called, and headers and + // status are available. + // 3: LOADING: download in progress. + // 4: DONE: download finished. + // See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState + enum class FetchReadyState { + UNSENT = 0, + OPENED = 1, + HEADERS_RECEIVED = 2, + LOADING = 3, + DONE = 4, + }; + + const constexpr u32 max_method_size = 32; + +} // namespace + + +oopetris::http::implementation::ActualResult::ActualResult(std::unique_ptr&& request) + : m_request{ std::move(request) }, + m_response_headers{ get_headers(m_request) } { } + +oopetris::http::implementation::ActualResult::~ActualResult() { + if (m_request) { + emscripten_fetch_close(m_request.get()); + } +}; + + +oopetris::http::implementation::ActualResult::ActualResult(ActualResult&& other) noexcept + : m_request{ std::move(other.m_request) }, + m_response_headers{ std::move(other.m_response_headers) } { } + +[[nodiscard]] std::optional oopetris::http::implementation::ActualResult::get_header(const std::string& key +) const { + if (m_response_headers.contains(key)) { + return std::nullopt; + } + + return m_response_headers.at(key); +} + +[[nodiscard]] std::string oopetris::http::implementation::ActualResult::body() const { + + //TODO: test if this is correct + auto size = m_request->numBytes; + + std::string result{ m_request->data, m_request->data + size }; + + return result; +} + +[[nodiscard]] int oopetris::http::implementation::ActualResult::status() const { + return m_request->status; +} + +[[nodiscard]] std::optional oopetris::http::implementation::ActualResult::get_error() const { + + auto readyState = static_cast(m_request->readyState); + + if (readyState != FetchReadyState::DONE) { + return fmt::format("Invalid readyState: {}", magic_enum::enum_name(readyState)); + } + + return std::nullopt; +} + +namespace { + using FetchData = std::pair; + + std::string normalize_url(const std::string& value) { + if (value.ends_with("/")) { + return value.substr(0, value.size() - 1); + } + + return value; + } + + std::string concat_url(const std::string& normalized_base, const std::string& value) { + if (value.starts_with("/")) { + return normalized_base + value; + } + + return normalized_base + "/" + value; + } + + std::unique_ptr make_request_impl( + const std::string& method, + const std::string& url, + const FetchHeader& header, + const std::optional& data + ) { + emscripten_fetch_attr_t attr{}; + emscripten_fetch_attr_init(&attr); + + ASSERT(method.size() <= (max_method_size - 1)); + std::memcpy(attr.requestMethod, method.c_str(), method.size() + 1); + + //TODO(Totto): once the http Implementation "Interface" support async thing, use that: + // see: https://emscripten.org/docs/api_reference/fetch.html#synchronous-fetches + + attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY | EMSCRIPTEN_FETCH_SYNCHRONOUS; + + + std::vector raw_headers{}; + for (const auto& [key, value] : header) { + raw_headers.push_back(key.c_str()); + raw_headers.push_back(value.c_str()); + } + + raw_headers.push_back(nullptr); + + attr.requestHeaders = raw_headers.data(); + + if (data.has_value()) { + const auto& [mime_type, raw_data] = data.value(); + + attr.overriddenMimeType = mime_type.c_str(); + attr.requestData = raw_data.c_str(); + attr.requestDataSize = raw_data.size(); + } + + emscripten_fetch_t* result = emscripten_fetch(&attr, url.c_str()); + + return std::unique_ptr(result); + } + + std::unique_ptr + make_request(const std::string& method, const std::string& url, const FetchHeader& header) { + return make_request_impl(method, url, header, std::nullopt); + } + + std::unique_ptr make_request_with_data( + const std::string& method, + const std::string& url, + const FetchHeader& header, + const FetchData& data + ) { + return make_request_impl(method, url, header, data); + } +} // namespace + + +oopetris::http::implementation::ActualClient::ActualClient(ActualClient&& other) noexcept + : m_base_url{ std::move(other.m_base_url) }, + m_headers{ std::move(other.m_headers) } { } + +oopetris::http::implementation::ActualClient::~ActualClient() = default; + +oopetris::http::implementation::ActualClient::ActualClient(const std::string& api_url) + : m_base_url{ normalize_url(api_url) }, + m_headers{} { + + //NOTE: no Accept header or compression is set here, as emscriptens fetch does provide reasonable defaults (depending on what the browser supports) +} + +[[nodiscard]] std::unique_ptr oopetris::http::implementation::ActualClient::Get( + const std::string& url +) { + + const auto final_url = concat_url(m_base_url, url); + + return TRANSFORM_RESULT(make_request("GET", final_url, m_headers)); +} + +[[nodiscard]] std::unique_ptr oopetris::http::implementation::ActualClient::Delete( + const std::string& url +) { + const auto final_url = concat_url(m_base_url, url); + + return TRANSFORM_RESULT(make_request("DELETE", final_url, m_headers)); +} + +[[nodiscard]] std::unique_ptr oopetris::http::implementation::ActualClient::Post( + const std::string& url, + const std::optional>& payload +) { + const auto final_url = concat_url(m_base_url, url); + + if (not payload.has_value()) { + return TRANSFORM_RESULT(make_request("POST", final_url, m_headers)); + } + + auto [content, content_type] = payload.value(); + + return TRANSFORM_RESULT(make_request_with_data("POST", final_url, m_headers, payload.value())); +} + +[[nodiscard]] std::unique_ptr oopetris::http::implementation::ActualClient::Put( + const std::string& url, + const std::optional>& payload +) { + const auto final_url = concat_url(m_base_url, url); + + if (not payload.has_value()) { + return TRANSFORM_RESULT(make_request("PUT", final_url, m_headers)); + } + + auto [content, content_type] = payload.value(); + + return TRANSFORM_RESULT(make_request_with_data("PUT", final_url, m_headers, payload.value())); +} + +void oopetris::http::implementation::ActualClient::SetBearerAuth(const std::string& token) { + + m_headers.at("Authorization") = fmt::format("Bearer {}", token); +} + +void oopetris::http::implementation::ActualClient::ResetBearerAuth() { + + m_headers.erase("Authorization"); +} diff --git a/src/lobby/uefi_client.hpp b/src/lobby/uefi_client.hpp new file mode 100644 index 00000000..6dc7547a --- /dev/null +++ b/src/lobby/uefi_client.hpp @@ -0,0 +1,74 @@ + +#pragma once + + +#include "./client.hpp" + + +namespace oopetris::http::implementation { + + namespace details { + using FetchHeader = std::unordered_map; + } + + struct ActualResult : ::oopetris::http::Result { + private: + std::unique_ptr m_request; + details::FetchHeader m_response_headers; + + public: + OOPETRIS_GRAPHICS_EXPORTED explicit ActualResult(std::unique_ptr&& request); + + OOPETRIS_GRAPHICS_EXPORTED ~ActualResult() override; + + OOPETRIS_GRAPHICS_EXPORTED ActualResult(ActualResult&& other) noexcept; + OOPETRIS_GRAPHICS_EXPORTED ActualResult& operator=(ActualResult&& other) noexcept = delete; + + OOPETRIS_GRAPHICS_EXPORTED ActualResult(const ActualResult& other) = delete; + OOPETRIS_GRAPHICS_EXPORTED ActualResult& operator=(const ActualResult& other) = delete; + + [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::optional get_header(const std::string& key + ) const override; + + [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::string body() const override; + + [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED int status() const override; + + [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::optional get_error() const override; + }; + + + struct ActualClient : ::oopetris::http::Client { + + private: + std::string m_base_url; + details::FetchHeader m_headers; + + public: + OOPETRIS_GRAPHICS_EXPORTED ActualClient(ActualClient&& other) noexcept; + OOPETRIS_GRAPHICS_EXPORTED ActualClient& operator=(ActualClient&& other) noexcept = delete; + + OOPETRIS_GRAPHICS_EXPORTED ActualClient(const ActualClient& other) = delete; + OOPETRIS_GRAPHICS_EXPORTED ActualClient& operator=(const ActualClient& other) = delete; + + OOPETRIS_GRAPHICS_EXPORTED ~ActualClient() override; + + OOPETRIS_GRAPHICS_EXPORTED explicit ActualClient(const std::string& api_url); + + [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::unique_ptr Get(const std::string& url) override; + + [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::unique_ptr Delete(const std::string& url) override; + + [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::unique_ptr + Post(const std::string& url, const std::optional>& payload) override; + + [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::unique_ptr + Put(const std::string& url, const std::optional>& payload) override; + + OOPETRIS_GRAPHICS_EXPORTED void SetBearerAuth(const std::string& token) override; + + OOPETRIS_GRAPHICS_EXPORTED void ResetBearerAuth() override; + }; + + +} // namespace oopetris::http::implementation diff --git a/tools/dependencies/meson.build b/tools/dependencies/meson.build index 3972ee32..4125e3b0 100644 --- a/tools/dependencies/meson.build +++ b/tools/dependencies/meson.build @@ -152,6 +152,7 @@ if ( temp = core_lib.get('compile_args') temp += '-D__OOPETRIS_NO_EXCEPTIONS=1' + temp += '-DJSON_NOEXCEPTION=1' core_lib += { 'compile_args': temp, } From 635fbffdb457efbd619f3022db8510e354e837a0 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 8 Aug 2026 16:30:06 +0200 Subject: [PATCH 085/112] fix: add builtin package support for pkg-config for uefi --- platforms/uefi/extract-definitions.sh | 10 +- platforms/uefi/g++-wrapper.sh | 4 +- platforms/uefi/gcc-wrapper.sh | 4 +- platforms/uefi/pkg-config-wrapper.sh | 93 ++++++++++++++++--- src/executables/platforms/uefi/libraries.json | 32 +++++-- src/libs/core/helper/parse_json.hpp | 12 ++- src/lobby/uefi_client.cpp | 6 -- src/lobby/uefi_client.hpp | 17 ++-- tools/dependencies/meson.build | 6 ++ 9 files changed, 138 insertions(+), 46 deletions(-) diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index f9b3c239..4fd0fd5b 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -302,13 +302,21 @@ for MESON_TARGETS_INFO_LIB_PARAMATER in "${MESON_TARGETS_INFO_LIB_PARAMATERS[@]} DEP_PACKAGE_NAME="${MESON_TARGETS_INFO_LIB_PARAMATER:15}" DEP_PACKAGES+=("LibraryPkg/$DEP_PACKAGE_NAME/$DEP_PACKAGE_NAME.dec") ;; - -t:use-lib:name=*) + -t:use-pkg:pkg=*) + DEP_PACKAGE_NAME="${MESON_TARGETS_INFO_LIB_PARAMATER:15}" + DEP_PACKAGES+=("$DEP_PACKAGE_NAME") + ;; + -t:use-lib:name=* | -t:use-pkg:name=*) #ignore ;; -t:use-lib:lib=*) DEP_PACKAGE_LIB="${MESON_TARGETS_INFO_LIB_PARAMATER:15}" DEP_CLASSES+=("$DEP_PACKAGE_LIB") ;; + -t:use-pkg:lib=*) + DEP_PACKAGE_LIB="${MESON_TARGETS_INFO_LIB_PARAMATER:15}" + DEP_CLASSES+=("$DEP_PACKAGE_LIB") + ;; -pthread) # ignore pthread ;; diff --git a/platforms/uefi/g++-wrapper.sh b/platforms/uefi/g++-wrapper.sh index ae1073f3..e88adbb8 100755 --- a/platforms/uefi/g++-wrapper.sh +++ b/platforms/uefi/g++-wrapper.sh @@ -56,7 +56,7 @@ for ARG in "${ARGS[@]}"; do --end-group) reset_next_type ;; - -t:use-lib*) + -t:use-lib* | -t:use-pkg*) # ignore here, the extraction uses that for inf and dec dependencies ;; *) @@ -145,7 +145,7 @@ for ARG in "${ARGS[@]}"; do -v | - | -g | -P | -MD | -pthread | -shared | -nostdinc | -nostdinc++ | -nodefaultlibs | -isystem* | --sysroot=* | -std=* | -f* | -m* | -D* | -U* | -W* | -O* | -I* | -L* | -l*) # ignore, valid arguments ;; - -t:use-lib*) + -t:use-lib* | -t:use-pkg*) # ignore here, the extraction uses that for inf and dec dependencies ;; *) diff --git a/platforms/uefi/gcc-wrapper.sh b/platforms/uefi/gcc-wrapper.sh index 02bf2342..5a285f96 100755 --- a/platforms/uefi/gcc-wrapper.sh +++ b/platforms/uefi/gcc-wrapper.sh @@ -54,7 +54,7 @@ for ARG in "${ARGS[@]}"; do --end-group) reset_next_type ;; - -t:use-lib*) + -t:use-lib* | -t:use-pkg*) # ignore here, the extraction uses that for inf and dec dependencies ;; *) @@ -143,7 +143,7 @@ for ARG in "${ARGS[@]}"; do -v | - | -g | -P | -MD | -pthread | -shared | -nostdinc | -nodefaultlibs | -isystem* | --sysroot=* | -std=* | -f* | -m* | -D* | -U* | -W* | -O* | -I* | -L* | -l*) # ignore, valid arguments ;; - -t:use-lib*) + -t:use-lib* | -t:use-pkg*) # ignore here, the extraction uses that for inf and dec dependencies ;; *) diff --git a/platforms/uefi/pkg-config-wrapper.sh b/platforms/uefi/pkg-config-wrapper.sh index 9a737a33..cf0e1300 100755 --- a/platforms/uefi/pkg-config-wrapper.sh +++ b/platforms/uefi/pkg-config-wrapper.sh @@ -38,32 +38,28 @@ change_mode() { UEFI_INFO_FILE="$(realpath "$SCRIPT_DIR/../crossbuild/uefi_info.json")" EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM="$(jq -M -r -c '.["platform"]' "$UEFI_INFO_FILE")" +EDK2_WORKSPACE="$(jq -M -r -c '.["workspace"]' "$UEFI_INFO_FILE")" -link_built_libray() { - local PACKAGE_NAME="$1" - local PACKAGE_NAME_PKG="$2" - local PACKAGE_NAME_LIB="$3" - - local FINAL_PKG_NAME="LibraryPkg/$PACKAGE_NAME_PKG/$PACKAGE_NAME_PKG.inf" +link_uefi_libray() { + local LIB_NAME_INF="$1" + local PACKAGE_NAME_INC="$2" - if grep -q "$FINAL_PKG_NAME" "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM"; then + if grep -q "$LIB_NAME_INF" "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM"; then : # found already, do nothing else cat <>"$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" [Components] - $FINAL_PKG_NAME + $LIB_NAME_INF EOF fi - local FINAL_PKG_INC_NAME="LibraryPkg/$PACKAGE_NAME_PKG/$PACKAGE_NAME_PKG.inc" - - if grep -q "$FINAL_PKG_INC_NAME" "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM"; then + if grep -q "$PACKAGE_NAME_INC" "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM"; then : # found already, do nothing else cat <>"$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" -!include $FINAL_PKG_INC_NAME +!include $PACKAGE_NAME_INC EOF @@ -71,6 +67,17 @@ EOF } +link_built_libray() { + local PACKAGE_NAME_PKG="$1" + + local FINAL_PKG_NAME="LibraryPkg/$PACKAGE_NAME_PKG/$PACKAGE_NAME_PKG.inf" + + local FINAL_PKG_INC_NAME="LibraryPkg/$PACKAGE_NAME_PKG/$PACKAGE_NAME_PKG.inc" + + link_uefi_libray "$FINAL_PKG_NAME" "$FINAL_PKG_INC_NAME" + +} + WHAT="" PACKAGE_NAME="" NEXT_IS_PACKAGE_NAME="false" @@ -113,7 +120,63 @@ elif [[ "$MODE" == "get" ]]; then exit 2 fi - LIBRARY_ENTRY="$(jq -M -r -c ".[\"${PACKAGE_NAME}\"]" "$LIBRARIES_FILE")" + case "$PACKAGE_NAME" in + uefi:*) + # special handling + + LIB_ENTRY_NAME_UEFI="${PACKAGE_NAME:5}" + + LIBRARY_ENTRY_UEFI="$(jq -M -r -c ".[\"uefi\"][\"${LIB_ENTRY_NAME_UEFI}\"]" "$LIBRARIES_FILE")" + + if [ "$LIBRARY_ENTRY_UEFI" = "null" ]; then + exit 1 + fi + + PACKAGE_NAME_UEFI="$(echo "$LIBRARY_ENTRY_UEFI" | jq -M -r -c ".[\"pkg\"]")" + LIB_NAME_UEFI="$(echo "$LIBRARY_ENTRY_UEFI" | jq -M -r -c ".[\"lib\"]")" + INF_FILE_UEFI="$(echo "$LIBRARY_ENTRY_UEFI" | jq -M -r -c ".[\"inf\"]")" + INC_FILE_UEFI="$(echo "$LIBRARY_ENTRY_UEFI" | jq -M -r -c ".[\"inc\"]")" + + PACKAGE_NAME_DEC="$PACKAGE_NAME_UEFI.dec" + PACKAGE_DESC_FILE="$EDK2_WORKSPACE/$PACKAGE_NAME_DEC" + + if ! [ -e "$PACKAGE_DESC_FILE" ]; then + exit 1 + fi + + if [[ "$WHAT" == "version" ]]; then + PACKAGE_VERSION=$(grep -E '^[[:space:]]*PACKAGE_VERSION[[:space:]]*=' "$PACKAGE_DESC_FILE" | cut -d= -f2 | xargs) + echo "$PACKAGE_VERSION" + exit 0 + elif [[ "$WHAT" == "cflags" ]]; then + echo "-t:use-pkg:name=$PACKAGE_NAME_UEFI" + echo "-t:use-pkg:pkg=$PACKAGE_NAME_DEC" + echo "-t:use-pkg:lib=$LIB_NAME_UEFI" + + link_uefi_libray "$INF_FILE_UEFI" "$INC_FILE_UEFI" + + exit 0 + elif [[ "$WHAT" == "libflags" ]]; then + + echo "-Wl,-t:use-pkg:name=$PACKAGE_NAME_UEFI" + echo "-Wl,-t:use-pkg:pkg=$PACKAGE_NAME_DEC" + echo "-Wl,-t:use-pkg:lib=$LIB_NAME_UEFI" + + link_uefi_libray "$INF_FILE_UEFI" "$INC_FILE_UEFI" + + exit 0 + else + echo "<$TOOL> ${ARGS[*]}" >&2 + echo "Not recognized intent: $MODE" >&2 + exit 3 + fi + ;; + *) + # fall through + ;; + esac + + LIBRARY_ENTRY="$(jq -M -r -c ".[\"custom\"][\"${PACKAGE_NAME}\"]" "$LIBRARIES_FILE")" if [ "$LIBRARY_ENTRY" = "null" ]; then exit 1 @@ -130,7 +193,7 @@ elif [[ "$MODE" == "get" ]]; then echo "-t:use-lib:pkg=$PACKAGE_NAME_PKG" echo "-t:use-lib:lib=$PACKAGE_NAME_LIB" - link_built_libray "$PACKAGE_NAME" "$PACKAGE_NAME_PKG" "$PACKAGE_NAME_LIB" + link_built_libray "$PACKAGE_NAME_PKG" exit 0 elif [[ "$WHAT" == "libflags" ]]; then @@ -141,7 +204,7 @@ elif [[ "$MODE" == "get" ]]; then echo "-Wl,-t:use-lib:pkg=$PACKAGE_NAME_PKG" echo "-Wl,-t:use-lib:lib=$PACKAGE_NAME_LIB" - link_built_libray "$PACKAGE_NAME" "$PACKAGE_NAME_PKG" "$PACKAGE_NAME_LIB" + link_built_libray "$PACKAGE_NAME_PKG" exit 0 else diff --git a/src/executables/platforms/uefi/libraries.json b/src/executables/platforms/uefi/libraries.json index 37d4c567..281899bb 100644 --- a/src/executables/platforms/uefi/libraries.json +++ b/src/executables/platforms/uefi/libraries.json @@ -1,12 +1,28 @@ { - "sdl2": { - "pkg": "SDL2Pkg", - "lib": "LibSDL2", - "version": "2.32.10" + "custom": { + "sdl2": { + "pkg": "SDL2Pkg", + "lib": "LibSDL2", + "version": "2.32.10" + }, + "sdl2_mixer": { + "pkg": "SDL2MixerPkg", + "lib": "LibSDL2Mixer", + "version": "2.8.2" + } }, - "sdl2_mixer": { - "pkg": "SDL2MixerPkg", - "lib": "LibSDL2Mixer", - "version": "2.8.2" + "uefi": { + "HttpIoLib": { + "pkg": "NetworkPkg/NetworkPkg", + "lib": "HttpIoLib", + "inf": "NetworkPkg/Library/DxeHttpIoLib/DxeHttpIoLib.inf", + "inc": "NetworkPkg/Network.dsc.inc" + }, + "BaseCryptLib": { + "pkg": "CryptoPkg/CryptoPkg", + "lib": "BaseCryptLib", + "inf": "CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf", + "inc": "CryptoPkg/CryptoPkgCustom.dsc.inc" + } } } diff --git a/src/libs/core/helper/parse_json.hpp b/src/libs/core/helper/parse_json.hpp index 03567364..675439d3 100644 --- a/src/libs/core/helper/parse_json.hpp +++ b/src/libs/core/helper/parse_json.hpp @@ -60,14 +60,16 @@ namespace json { [[nodiscard]] helper::expected try_parse_json(const std::string& content) noexcept { #if defined(__OOPETRIS_NO_EXCEPTIONS) - T result = nlohmann::json::parse(content, nullptr, false); + auto result_j = nlohmann::json::parse(content, nullptr, false); + if (result_j.is_discarded()) { + return helper::unexpected{ "A JSON error occurred, but no further details available" }; + } + T result = result_j; + return result; #else try { T result = nlohmann::json::parse(content); - if (result.is_discarded()) { - return helper::unexpected{ "A JSON error occurred, but no further details available" }; - } return result; } catch (nlohmann::json::parse_error& parse_error) { @@ -127,7 +129,7 @@ namespace json { #if defined(__OOPETRIS_NO_EXCEPTIONS) nlohmann::json value = input; -#error "TODO" + //TODO: this may throw exceptions, but they just abort, which is not in the spirit of this function so either use another nlohmann json mechanism or another json library that supports return values for custom subparser return value; #else try { diff --git a/src/lobby/uefi_client.cpp b/src/lobby/uefi_client.cpp index 177a39d8..8818665e 100644 --- a/src/lobby/uefi_client.cpp +++ b/src/lobby/uefi_client.cpp @@ -4,11 +4,6 @@ #include #include -// Note: this uses emscripten fetch -//see: https://emscripten.org/docs/api_reference/fetch.html - -//Note: Synchronous Emscripten Fetch operations are subject to a number of restrictions, depending on which Emscripten build mode (linker flags) is used: -// we use: -pthread: Synchronous Fetch operations are available on pthreads, but not on the main thread. #define TRANSFORM_RESULT(result) std::make_unique((result)) //NOLINT(cppcoreguidelines-macro-usage @@ -100,7 +95,6 @@ oopetris::http::implementation::ActualResult::ActualResult(ActualResult&& other) [[nodiscard]] std::string oopetris::http::implementation::ActualResult::body() const { - //TODO: test if this is correct auto size = m_request->numBytes; std::string result{ m_request->data, m_request->data + size }; diff --git a/src/lobby/uefi_client.hpp b/src/lobby/uefi_client.hpp index 6dc7547a..72b12727 100644 --- a/src/lobby/uefi_client.hpp +++ b/src/lobby/uefi_client.hpp @@ -1,23 +1,25 @@ #pragma once +#include #include "./client.hpp" +#include -namespace oopetris::http::implementation { +namespace oopetris::http::implementation { namespace details { - using FetchHeader = std::unordered_map; + using HttpHeaders = std::vector; } + struct ActualResult : ::oopetris::http::Result { private: - std::unique_ptr m_request; - details::FetchHeader m_response_headers; + HTTP_IO_RESPONSE_DATA m_response; public: - OOPETRIS_GRAPHICS_EXPORTED explicit ActualResult(std::unique_ptr&& request); + OOPETRIS_GRAPHICS_EXPORTED explicit ActualResult(HTTP_IO_RESPONSE_DATA&& response); OOPETRIS_GRAPHICS_EXPORTED ~ActualResult() override; @@ -27,7 +29,8 @@ namespace oopetris::http::implementation { OOPETRIS_GRAPHICS_EXPORTED ActualResult(const ActualResult& other) = delete; OOPETRIS_GRAPHICS_EXPORTED ActualResult& operator=(const ActualResult& other) = delete; - [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::optional get_header(const std::string& key + [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::optional get_header( + const std::string& key ) const override; [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::string body() const override; @@ -42,7 +45,7 @@ namespace oopetris::http::implementation { private: std::string m_base_url; - details::FetchHeader m_headers; + details::HttpHeaders m_headers; public: OOPETRIS_GRAPHICS_EXPORTED ActualClient(ActualClient&& other) noexcept; diff --git a/tools/dependencies/meson.build b/tools/dependencies/meson.build index 4125e3b0..53400c48 100644 --- a/tools/dependencies/meson.build +++ b/tools/dependencies/meson.build @@ -468,9 +468,15 @@ if build_application elif meson.is_cross_build() and host_machine.system() == 'uefi' online_multiplayer_system = 'uefi' + uefi_network_lib_dep = dependency('uefi:HttpIoLib') + uefi_crypto_lib_dep = dependency('uefi:BaseCryptLib') + graphics_lib += { + 'deps': [graphics_lib.get('deps'), uefi_network_lib_dep, uefi_crypto_lib_dep], 'compile_args': [graphics_lib.get('compile_args'), '-D_OOPETRIS_ONLINE_SYSTEM=3'], } + + else online_multiplayer_system = 'curl' From 68b0093fa91d2d95e70fc6d0477a71f573c44798 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 8 Aug 2026 16:30:30 +0200 Subject: [PATCH 086/112] fix: fix some uefi compilation errors --- platforms/build-uefi.sh | 1 + platforms/uefi/ssl_lib.diff | 43 ++++++++++++++++++++++++++++++++++ src/lobby/uefi_client.hpp | 7 ++++++ tools/dependencies/meson.build | 1 + 4 files changed, 52 insertions(+) create mode 100644 platforms/uefi/ssl_lib.diff diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index b9cb5529..666c5d4a 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -133,6 +133,7 @@ if ! [ -e "$EDK2_PATCH_FILE" ]; then # and: https://github.com/emscripten-core/emscripten/pull/22946 git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/cxx_compiler.diff" + git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/ssl_lib.diff" touch "$EDK2_PATCH_FILE" fi diff --git a/platforms/uefi/ssl_lib.diff b/platforms/uefi/ssl_lib.diff new file mode 100644 index 00000000..28de1150 --- /dev/null +++ b/platforms/uefi/ssl_lib.diff @@ -0,0 +1,43 @@ +diff --git a/CryptoPkg/CryptoPkgCustom.dsc.inc b/CryptoPkg/CryptoPkgCustom.dsc.inc +new file mode 100644 +index 0000000000..b9279e9ce8 +--- /dev/null ++++ b/CryptoPkg/CryptoPkgCustom.dsc.inc +@@ -0,0 +1,25 @@ ++[LibraryClasses] ++ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf ++ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf ++ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf ++ SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf ++ SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf ++ TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf ++ RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf ++ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf ++ DebugLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf ++ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf ++ OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf ++ HashApiLib|CryptoPkg/Library/BaseHashApiLib/BaseHashApiLib.inf ++ OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf ++ IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf ++ ++[LibraryClasses.IA32, LibraryClasses.X64, LibraryClasses.AARCH64] ++ RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf ++ ++[LibraryClasses.AARCH64] ++ ArmLib|MdePkg/Library/ArmLib/ArmBaseLib.inf ++ ++[LibraryClasses.common] ++ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf ++ TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf +diff --git a/CryptoPkg/Library/OpensslLib/OpensslLib.inf b/CryptoPkg/Library/OpensslLib/OpensslLib.inf +index 094d4439b1..aa36664108 100644 +--- a/CryptoPkg/Library/OpensslLib/OpensslLib.inf ++++ b/CryptoPkg/Library/OpensslLib/OpensslLib.inf +@@ -775,6 +775,7 @@ + # -Werror=unused-but-set-variable: Warn whenever a local variable is assigned to, but otherwise unused (aside from its declaration). + # + GCC:RELEASE_*_*_CC_FLAGS = -DNDEBUG ++ *_*_*_CC_FLAGS = -D__STDC_NO_ATOMICS__ + GCC:*_*_IA32_CC_FLAGS = -U_WIN32 -UWIN32 -U_WIN64 -U_MSC_VER $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_NOASM) -Wno-error=maybe-uninitialized -Wno-error=unused-but-set-variable + GCC:*_*_X64_CC_FLAGS = -U_WIN32 -UWIN32 -U_WIN64 -U_MSC_VER $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_NOASM) -Wno-error=maybe-uninitialized -Wno-error=format -Wno-format -Wno-error=unused-but-set-variable -DNO_MSABI_VA_FUNCS + GCC:*_*_AARCH64_CC_FLAGS = $(OPENSSL_FLAGS) -Wno-error=maybe-uninitialized -Wno-format -Wno-error=unused-but-set-variable -Wno-error=format diff --git a/src/lobby/uefi_client.hpp b/src/lobby/uefi_client.hpp index 72b12727..37d88cd2 100644 --- a/src/lobby/uefi_client.hpp +++ b/src/lobby/uefi_client.hpp @@ -1,6 +1,13 @@ #pragma once +//this i needed to mix stdlib and openssl / crypto / tls libraries + +#undef NTOHL +#undef HTONL +#undef NTOHS +#undef HTONS + #include #include "./client.hpp" diff --git a/tools/dependencies/meson.build b/tools/dependencies/meson.build index 53400c48..80b0f5a8 100644 --- a/tools/dependencies/meson.build +++ b/tools/dependencies/meson.build @@ -153,6 +153,7 @@ if ( temp = core_lib.get('compile_args') temp += '-D__OOPETRIS_NO_EXCEPTIONS=1' temp += '-DJSON_NOEXCEPTION=1' + temp +='-DSPDLOG_NO_EXCEPTIONS=1' core_lib += { 'compile_args': temp, } From 3580f7c99533e3a3d72a7e639d8828221afad788 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 8 Aug 2026 16:49:20 +0200 Subject: [PATCH 087/112] fix: fix more exception related things for uefi --- src/helper/clock_source.cpp | 4 +- src/helper/clock_source.hpp | 5 +- src/libs/core/helper/utils.hpp | 2 +- src/lobby/client.cpp | 7 + .../settings_menu/color_setting_row.cpp | 18 +- .../utfcpp-4.0.8_no_exceptions.diff | 935 ++++++++++++++++++ subprojects/utfcpp.wrap | 1 + tools/dependencies/meson.build | 3 +- 8 files changed, 965 insertions(+), 10 deletions(-) create mode 100644 subprojects/packagefiles/utfcpp-4.0.8_no_exceptions.diff diff --git a/src/helper/clock_source.cpp b/src/helper/clock_source.cpp index 6c329f1b..986b197d 100644 --- a/src/helper/clock_source.cpp +++ b/src/helper/clock_source.cpp @@ -29,7 +29,7 @@ bool LocalClock::can_be_paused() { void LocalClock::pause() { if (m_paused_at) { - throw std::runtime_error("cannot pause if already paused"); + utils::throw_(std::runtime_error("cannot pause if already paused")); } m_paused_at = elapsed_time(); spdlog::info("pausing clock"); @@ -37,7 +37,7 @@ void LocalClock::pause() { double LocalClock::resume() { if (not m_paused_at) { - throw std::runtime_error("must have been paused before to be able to resume"); + utils::throw_(std::runtime_error("must have been paused before to be able to resume")); } const auto duration = elapsed_time() - *m_paused_at; m_start_time += duration; diff --git a/src/helper/clock_source.hpp b/src/helper/clock_source.hpp index d00d9835..2085378a 100644 --- a/src/helper/clock_source.hpp +++ b/src/helper/clock_source.hpp @@ -2,6 +2,7 @@ #include +#include #include "./export_symbols.hpp" @@ -15,7 +16,7 @@ struct ClockSource { [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED virtual bool can_be_paused() = 0; OOPETRIS_GRAPHICS_EXPORTED virtual void pause() { - throw std::runtime_error("not implemented"); + utils::throw_(std::runtime_error("not implemented")); } /** @@ -23,7 +24,7 @@ struct ClockSource { * @return The duration of the pause. */ OOPETRIS_GRAPHICS_EXPORTED virtual double resume() { - throw std::runtime_error("not implemented"); + utils::throw_(std::runtime_error("not implemented")); }; }; diff --git a/src/libs/core/helper/utils.hpp b/src/libs/core/helper/utils.hpp index 3d52b579..6b783b81 100644 --- a/src/libs/core/helper/utils.hpp +++ b/src/libs/core/helper/utils.hpp @@ -129,7 +129,7 @@ namespace utils { #endif template - inline void throw_(E&& exc) { + [[noreturn]] inline void throw_(E&& exc) { //NOLINT(readability-identifier-naming) #if defined(__OOPETRIS_NO_EXCEPTIONS) #if defined(__UEFI__) DebugPrint(DEBUG_ERROR, "Exception: %s", exc.what()); diff --git a/src/lobby/client.cpp b/src/lobby/client.cpp index 69455c74..e2845621 100644 --- a/src/lobby/client.cpp +++ b/src/lobby/client.cpp @@ -23,6 +23,13 @@ std::string oopetris::http::status_message([[maybe_unused]] int status) { #include "./curl_client.hpp" +std::string oopetris::http::status_message([[maybe_unused]] int status) { + return "Not Available"; +} +#elif _OOPETRIS_ONLINE_SYSTEM == 3 + +#include "./uefi_client.hpp" + std::string oopetris::http::status_message([[maybe_unused]] int status) { return "Not Available"; } diff --git a/src/scenes/settings_menu/color_setting_row.cpp b/src/scenes/settings_menu/color_setting_row.cpp index cfe8d981..98bb7132 100644 --- a/src/scenes/settings_menu/color_setting_row.cpp +++ b/src/scenes/settings_menu/color_setting_row.cpp @@ -91,8 +91,14 @@ detail::ColorPickerScene::ColorPickerScene( ) : Scene{ service_provider, layout - }, - m_color_picker{ service_provider, starting_color, std::move(callback), std::pair{ 0.95, 0.95 }, ui::Alignment{ ui::AlignmentHorizontal::Middle, ui::AlignmentVertical::Bottom }, layout, false } { } +}, + m_color_picker{ service_provider, + starting_color, + std::move(callback), + std::pair{ 0.95, 0.95 }, + ui::Alignment{ ui::AlignmentHorizontal::Middle, ui::AlignmentVertical::Bottom }, + layout, + false } { } [[nodiscard]] scenes::Scene::UpdateResult detail::ColorPickerScene::update() { if (m_should_exit) { @@ -142,7 +148,9 @@ custom_ui::ColorSettingRow::ColorSettingRow( const ui::Layout& layout, bool is_top_level ) - : ui::Widget{ layout, ui::WidgetType::Component, is_top_level }, + : ui::Widget{ + layout, ui::WidgetType::Component, is_top_level +}, ui::Focusable{ focus_id }, ui::Hoverable{ layout.get_rect() }, m_service_provider{ service_provider }, @@ -187,7 +195,9 @@ helper::BoolWrapper> custom_ui::Colo }; } - throw helper::FatalError(fmt::format("Unsupported Handle Type: {}", magic_enum::enum_name(additional->first))); + utils::throw_( + helper::FatalError(fmt::format("Unsupported Handle Type: {}", magic_enum::enum_name(additional->first))) + ); } return result; diff --git a/subprojects/packagefiles/utfcpp-4.0.8_no_exceptions.diff b/subprojects/packagefiles/utfcpp-4.0.8_no_exceptions.diff new file mode 100644 index 00000000..bd8958a1 --- /dev/null +++ b/subprojects/packagefiles/utfcpp-4.0.8_no_exceptions.diff @@ -0,0 +1,935 @@ +diff --git a/source/utf8/checked.h b/source/utf8/checked.h +index 96ceb4d..1d2cd97 100644 +--- a/source/utf8/checked.h ++++ b/source/utf8/checked.h +@@ -74,7 +74,7 @@ namespace utf8 + octet_iterator append(utfchar32_t cp, octet_iterator result) + { + if (!utf8::internal::is_code_point_valid(cp)) +- throw invalid_code_point(cp); ++ UTFCPP_THROW(invalid_code_point(cp)); + + return internal::append(cp, result); + } +@@ -88,7 +88,7 @@ namespace utf8 + word_iterator append16(utfchar32_t cp, word_iterator result) + { + if (!utf8::internal::is_code_point_valid(cp)) +- throw invalid_code_point(cp); ++ UTFCPP_THROW(invalid_code_point(cp)); + + return internal::append16(cp, result); + } +@@ -156,13 +156,13 @@ namespace utf8 + case internal::UTF8_OK : + break; + case internal::NOT_ENOUGH_ROOM : +- throw not_enough_room(); ++ UTFCPP_THROW(not_enough_room()); + case internal::INVALID_LEAD : + case internal::INCOMPLETE_SEQUENCE : + case internal::OVERLONG_SEQUENCE : +- throw invalid_utf8(static_cast(*it)); ++ UTFCPP_THROW(invalid_utf8(static_cast(*it))); + case internal::INVALID_CODE_POINT : +- throw invalid_code_point(cp); ++ UTFCPP_THROW(invalid_code_point(cp)); + } + return cp; + } +@@ -173,7 +173,7 @@ namespace utf8 + utfchar32_t cp = 0; + internal::utf_error err_code = utf8::internal::validate_next16(it, end, cp); + if (err_code == internal::NOT_ENOUGH_ROOM) +- throw not_enough_room(); ++ UTFCPP_THROW(not_enough_room()); + return cp; + } + +@@ -188,13 +188,13 @@ namespace utf8 + { + // can't do much if it == start + if (it == start) +- throw not_enough_room(); ++ UTFCPP_THROW(not_enough_room()); + + octet_iterator end = it; + // Go back until we hit either a lead octet or start + while (utf8::internal::is_trail(*(--it))) + if (it == start) +- throw invalid_utf8(*it); // error - no lead byte in the sequence ++ UTFCPP_THROW(invalid_utf8(*it)); // error - no lead byte in the sequence + return utf8::peek_next(it, end); + } + +@@ -235,15 +235,15 @@ namespace utf8 + if (utf8::internal::is_trail_surrogate(trail_surrogate)) + cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; + else +- throw invalid_utf16(static_cast(trail_surrogate)); ++ UTFCPP_THROW(invalid_utf16(static_cast(trail_surrogate))); + } + else +- throw invalid_utf16(static_cast(cp)); ++ UTFCPP_THROW(invalid_utf16(static_cast(cp))); + + } + // Lone trail surrogate + else if (utf8::internal::is_trail_surrogate(cp)) +- throw invalid_utf16(static_cast(cp)); ++ UTFCPP_THROW(invalid_utf16(static_cast(cp))); + + result = utf8::append(cp, result); + } +@@ -302,7 +302,7 @@ namespace utf8 + it(octet_it), range_start(rangestart), range_end(rangeend) + { + if (it < range_start || it > range_end) +- throw std::out_of_range("Invalid utf-8 iterator position"); ++ UTFCPP_THROW(std::out_of_range("Invalid utf-8 iterator position")); + } + // the default "big three" are OK + octet_iterator base () const { return it; } +@@ -314,7 +314,7 @@ namespace utf8 + bool operator == (const iterator& rhs) const + { + if (range_start != rhs.range_start || range_end != rhs.range_end) +- throw std::logic_error("Comparing utf-8 iterators defined with different ranges"); ++ UTFCPP_THROW(std::logic_error("Comparing utf-8 iterators defined with different ranges")); + return (it == rhs.it); + } + bool operator != (const iterator& rhs) const +diff --git a/source/utf8/core.h b/source/utf8/core.h +index 064f838..0dd1d99 100644 +--- a/source/utf8/core.h ++++ b/source/utf8/core.h +@@ -28,8 +28,8 @@ DEALINGS IN THE SOFTWARE. + #ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + #define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +-#include + #include ++#include + #include + + // Determine the C++ standard version. +@@ -37,412 +37,407 @@ DEALINGS IN THE SOFTWARE. + // Otherwise, trust the unreliable predefined macro __cplusplus + + #if !defined UTF_CPP_CPLUSPLUS +- #define UTF_CPP_CPLUSPLUS __cplusplus ++#define UTF_CPP_CPLUSPLUS __cplusplus + #endif + + #if UTF_CPP_CPLUSPLUS >= 201103L // C++ 11 or later +- #define UTF_CPP_OVERRIDE override +- #define UTF_CPP_NOEXCEPT noexcept +- #define UTF_CPP_STATIC_ASSERT(condition) static_assert(condition, "UTFCPP static assert"); ++#define UTF_CPP_OVERRIDE override ++#define UTF_CPP_NOEXCEPT noexcept ++#define UTF_CPP_STATIC_ASSERT(condition) static_assert(condition, "UTFCPP static assert"); + #else // C++ 98/03 +- #define UTF_CPP_OVERRIDE +- #define UTF_CPP_NOEXCEPT throw() +- // Simulate static_assert: +- template struct StaticAssert {static void utf8_static_assert() {char static_assert_impl[Condition ? 1 : 0]; } }; +- template <> struct StaticAssert {static void utf8_static_assert() {}}; +- #define UTF_CPP_STATIC_ASSERT(condition) StaticAssert::utf8_static_assert(); ++#define UTF_CPP_OVERRIDE ++#define UTF_CPP_NOEXCEPT throw() ++// Simulate static_assert: ++template ++struct StaticAssert { ++ static void utf8_static_assert() { ++ char static_assert_impl[Condition ? 1 : 0]; ++ } ++}; ++template<> ++struct StaticAssert { ++ static void utf8_static_assert() { } ++}; ++#define UTF_CPP_STATIC_ASSERT(condition) StaticAssert::utf8_static_assert(); + #endif // C++ 11 or later + + +-namespace utf8 +-{ ++namespace utf8 { + // The typedefs for 8-bit, 16-bit and 32-bit code units + #if UTF_CPP_CPLUSPLUS >= 201103L // C++ 11 or later +- #if UTF_CPP_CPLUSPLUS >= 202002L // C++ 20 or later +- typedef char8_t utfchar8_t; +- #else // C++ 11/14/17 +- typedef unsigned char utfchar8_t; +- #endif +- typedef char16_t utfchar16_t; +- typedef char32_t utfchar32_t; +-#else // C++ 98/03 +- typedef unsigned char utfchar8_t; +- typedef unsigned short utfchar16_t; +- typedef unsigned int utfchar32_t; ++#if UTF_CPP_CPLUSPLUS >= 202002L // C++ 20 or later ++ typedef char8_t utfchar8_t; ++#else // C++ 11/14/17 ++ typedef unsigned char utfchar8_t; ++#endif ++ typedef char16_t utfchar16_t; ++ typedef char32_t utfchar32_t; ++#else // C++ 98/03 ++ typedef unsigned char utfchar8_t; ++ typedef unsigned short utfchar16_t; ++ typedef unsigned int utfchar32_t; + #endif // C++ 11 or later + +-// Helper code - not intended to be directly called by the library users. May be changed at any time +-namespace internal +-{ +- // Unicode constants +- // Leading (high) surrogates: 0xd800 - 0xdbff +- // Trailing (low) surrogates: 0xdc00 - 0xdfff +- const utfchar16_t LEAD_SURROGATE_MIN = 0xd800u; +- const utfchar16_t LEAD_SURROGATE_MAX = 0xdbffu; +- const utfchar16_t TRAIL_SURROGATE_MIN = 0xdc00u; +- const utfchar16_t TRAIL_SURROGATE_MAX = 0xdfffu; +- const utfchar16_t LEAD_OFFSET = 0xd7c0u; // LEAD_SURROGATE_MIN - (0x10000 >> 10) +- const utfchar32_t SURROGATE_OFFSET = 0xfca02400u; // 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN +- +- // Maximum valid value for a Unicode code point +- const utfchar32_t CODE_POINT_MAX = 0x0010ffffu; +- +- template +- inline utfchar8_t mask8(octet_type oc) +- { +- return static_cast(0xff & oc); +- } +- +- template +- inline utfchar16_t mask16(u16_type oc) +- { +- return static_cast(0xffff & oc); +- } +- +- template +- inline bool is_trail(octet_type oc) +- { +- return ((utf8::internal::mask8(oc) >> 6) == 0x2); +- } +- +- inline bool is_lead_surrogate(utfchar32_t cp) +- { +- return (cp >= static_cast(LEAD_SURROGATE_MIN) && cp <= static_cast(LEAD_SURROGATE_MAX)); +- } ++ // Helper code - not intended to be directly called by the library users. May be changed at any time ++ namespace internal { ++ // Unicode constants ++ // Leading (high) surrogates: 0xd800 - 0xdbff ++ // Trailing (low) surrogates: 0xdc00 - 0xdfff ++ const utfchar16_t LEAD_SURROGATE_MIN = 0xd800u; ++ const utfchar16_t LEAD_SURROGATE_MAX = 0xdbffu; ++ const utfchar16_t TRAIL_SURROGATE_MIN = 0xdc00u; ++ const utfchar16_t TRAIL_SURROGATE_MAX = 0xdfffu; ++ const utfchar16_t LEAD_OFFSET = 0xd7c0u; // LEAD_SURROGATE_MIN - (0x10000 >> 10) ++ const utfchar32_t SURROGATE_OFFSET = 0xfca02400u; // 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN ++ ++ // Maximum valid value for a Unicode code point ++ const utfchar32_t CODE_POINT_MAX = 0x0010ffffu; ++ ++ template ++ inline utfchar8_t mask8(octet_type oc) { ++ return static_cast(0xff & oc); ++ } + +- inline bool is_trail_surrogate(utfchar32_t cp) +- { +- return (cp >= static_cast(TRAIL_SURROGATE_MIN) && cp <= static_cast(TRAIL_SURROGATE_MAX)); +- } ++ template ++ inline utfchar16_t mask16(u16_type oc) { ++ return static_cast(0xffff & oc); ++ } + +- inline bool is_surrogate(utfchar32_t cp) +- { +- return (cp >= static_cast(LEAD_SURROGATE_MIN) && cp <= static_cast(TRAIL_SURROGATE_MAX)); +- } ++ template ++ inline bool is_trail(octet_type oc) { ++ return ((utf8::internal::mask8(oc) >> 6) == 0x2); ++ } + +- inline bool is_code_point_valid(utfchar32_t cp) +- { +- return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp)); +- } ++ inline bool is_lead_surrogate(utfchar32_t cp) { ++ return (cp >= static_cast(LEAD_SURROGATE_MIN) ++ && cp <= static_cast(LEAD_SURROGATE_MAX)); ++ } + +- inline bool is_in_bmp(utfchar32_t cp) +- { +- return cp < utfchar32_t(0x10000); +- } ++ inline bool is_trail_surrogate(utfchar32_t cp) { ++ return (cp >= static_cast(TRAIL_SURROGATE_MIN) ++ && cp <= static_cast(TRAIL_SURROGATE_MAX)); ++ } + +- template +- int sequence_length(octet_iterator lead_it) +- { +- const utfchar8_t lead = utf8::internal::mask8(*lead_it); +- if (lead < 0x80) +- return 1; +- else if ((lead >> 5) == 0x6) +- return 2; +- else if ((lead >> 4) == 0xe) +- return 3; +- else if ((lead >> 3) == 0x1e) +- return 4; +- else +- return 0; +- } ++ inline bool is_surrogate(utfchar32_t cp) { ++ return (cp >= static_cast(LEAD_SURROGATE_MIN) ++ && cp <= static_cast(TRAIL_SURROGATE_MAX)); ++ } + +- inline bool is_overlong_sequence(utfchar32_t cp, int length) +- { +- if (cp < 0x80) { +- if (length != 1) +- return true; ++ inline bool is_code_point_valid(utfchar32_t cp) { ++ return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp)); + } +- else if (cp < 0x800) { +- if (length != 2) +- return true; ++ ++ inline bool is_in_bmp(utfchar32_t cp) { ++ return cp < utfchar32_t(0x10000); + } +- else if (cp < 0x10000) { +- if (length != 3) +- return true; ++ ++ template ++ int sequence_length(octet_iterator lead_it) { ++ const utfchar8_t lead = utf8::internal::mask8(*lead_it); ++ if (lead < 0x80) ++ return 1; ++ else if ((lead >> 5) == 0x6) ++ return 2; ++ else if ((lead >> 4) == 0xe) ++ return 3; ++ else if ((lead >> 3) == 0x1e) ++ return 4; ++ else ++ return 0; + } +- return false; +- } + +- enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT}; ++ inline bool is_overlong_sequence(utfchar32_t cp, int length) { ++ if (cp < 0x80) { ++ if (length != 1) ++ return true; ++ } else if (cp < 0x800) { ++ if (length != 2) ++ return true; ++ } else if (cp < 0x10000) { ++ if (length != 3) ++ return true; ++ } ++ return false; ++ } + +- /// Helper for get_sequence_x +- template +- utf_error increase_safely(octet_iterator& it, const octet_iterator end) +- { +- if (++it == end) +- return NOT_ENOUGH_ROOM; ++ enum utf_error { ++ UTF8_OK, ++ NOT_ENOUGH_ROOM, ++ INVALID_LEAD, ++ INCOMPLETE_SEQUENCE, ++ OVERLONG_SEQUENCE, ++ INVALID_CODE_POINT ++ }; + +- if (!utf8::internal::is_trail(*it)) +- return INCOMPLETE_SEQUENCE; ++ /// Helper for get_sequence_x ++ template ++ utf_error increase_safely(octet_iterator& it, const octet_iterator end) { ++ if (++it == end) ++ return NOT_ENOUGH_ROOM; + +- return UTF8_OK; +- } ++ if (!utf8::internal::is_trail(*it)) ++ return INCOMPLETE_SEQUENCE; + +- #define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) {utf_error ret = increase_safely(IT, END); if (ret != UTF8_OK) return ret;} ++ return UTF8_OK; ++ } + +- /// get_sequence_x functions decode utf-8 sequences of the length x +- template +- utf_error get_sequence_1(octet_iterator& it, octet_iterator end, utfchar32_t& code_point) +- { +- if (it == end) +- return NOT_ENOUGH_ROOM; ++#define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) \ ++ { \ ++ utf_error ret = increase_safely(IT, END); \ ++ if (ret != UTF8_OK) \ ++ return ret; \ ++ } + +- code_point = static_cast(utf8::internal::mask8(*it)); ++ /// get_sequence_x functions decode utf-8 sequences of the length x ++ template ++ utf_error get_sequence_1(octet_iterator& it, octet_iterator end, utfchar32_t& code_point) { ++ if (it == end) ++ return NOT_ENOUGH_ROOM; + +- return UTF8_OK; +- } ++ code_point = static_cast(utf8::internal::mask8(*it)); + +- template +- utf_error get_sequence_2(octet_iterator& it, octet_iterator end, utfchar32_t& code_point) +- { +- if (it == end) +- return NOT_ENOUGH_ROOM; ++ return UTF8_OK; ++ } + +- code_point = static_cast(utf8::internal::mask8(*it)); ++ template ++ utf_error get_sequence_2(octet_iterator& it, octet_iterator end, utfchar32_t& code_point) { ++ if (it == end) ++ return NOT_ENOUGH_ROOM; + +- UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) ++ code_point = static_cast(utf8::internal::mask8(*it)); + +- code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f); ++ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + +- return UTF8_OK; +- } ++ code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f); + +- template +- utf_error get_sequence_3(octet_iterator& it, octet_iterator end, utfchar32_t& code_point) +- { +- if (it == end) +- return NOT_ENOUGH_ROOM; ++ return UTF8_OK; ++ } + +- code_point = static_cast(utf8::internal::mask8(*it)); ++ template ++ utf_error get_sequence_3(octet_iterator& it, octet_iterator end, utfchar32_t& code_point) { ++ if (it == end) ++ return NOT_ENOUGH_ROOM; + +- UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) ++ code_point = static_cast(utf8::internal::mask8(*it)); + +- code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff); ++ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + +- UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) ++ code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff); + +- code_point = static_cast(code_point + ((*it) & 0x3f)); ++ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + +- return UTF8_OK; +- } ++ code_point = static_cast(code_point + ((*it) & 0x3f)); + +- template +- utf_error get_sequence_4(octet_iterator& it, octet_iterator end, utfchar32_t& code_point) +- { +- if (it == end) +- return NOT_ENOUGH_ROOM; ++ return UTF8_OK; ++ } + +- code_point = static_cast(utf8::internal::mask8(*it)); ++ template ++ utf_error get_sequence_4(octet_iterator& it, octet_iterator end, utfchar32_t& code_point) { ++ if (it == end) ++ return NOT_ENOUGH_ROOM; + +- UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) ++ code_point = static_cast(utf8::internal::mask8(*it)); + +- code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff); ++ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + +- UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) ++ code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff); + +- code_point = static_cast(code_point + ((utf8::internal::mask8(*it) << 6) & 0xfff)); ++ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + +- UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) ++ code_point = static_cast(code_point + ((utf8::internal::mask8(*it) << 6) & 0xfff)); + +- code_point = static_cast(code_point + ((*it) & 0x3f)); ++ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + +- return UTF8_OK; +- } ++ code_point = static_cast(code_point + ((*it) & 0x3f)); + +- #undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR +- +- template +- utf_error validate_next(octet_iterator& it, octet_iterator end, utfchar32_t& code_point) +- { +- if (it == end) +- return NOT_ENOUGH_ROOM; +- +- // Save the original value of it so we can go back in case of failure +- // Of course, it does not make much sense with i.e. stream iterators +- octet_iterator original_it = it; +- +- utfchar32_t cp = 0; +- // Determine the sequence length based on the lead octet +- const int length = utf8::internal::sequence_length(it); +- +- // Get trail octets and calculate the code point +- utf_error err = UTF8_OK; +- switch (length) { +- case 0: +- return INVALID_LEAD; +- case 1: +- err = utf8::internal::get_sequence_1(it, end, cp); +- break; +- case 2: +- err = utf8::internal::get_sequence_2(it, end, cp); +- break; +- case 3: +- err = utf8::internal::get_sequence_3(it, end, cp); +- break; +- case 4: +- err = utf8::internal::get_sequence_4(it, end, cp); +- break; ++ return UTF8_OK; + } + +- if (err == UTF8_OK) { +- // Decoding succeeded. Now, security checks... +- if (utf8::internal::is_code_point_valid(cp)) { +- if (!utf8::internal::is_overlong_sequence(cp, length)){ +- // Passed! Return here. +- code_point = cp; +- ++it; +- return UTF8_OK; +- } +- else +- err = OVERLONG_SEQUENCE; ++#undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR ++ ++ template ++ utf_error validate_next(octet_iterator& it, octet_iterator end, utfchar32_t& code_point) { ++ if (it == end) ++ return NOT_ENOUGH_ROOM; ++ ++ // Save the original value of it so we can go back in case of failure ++ // Of course, it does not make much sense with i.e. stream iterators ++ octet_iterator original_it = it; ++ ++ utfchar32_t cp = 0; ++ // Determine the sequence length based on the lead octet ++ const int length = utf8::internal::sequence_length(it); ++ ++ // Get trail octets and calculate the code point ++ utf_error err = UTF8_OK; ++ switch (length) { ++ case 0: ++ return INVALID_LEAD; ++ case 1: ++ err = utf8::internal::get_sequence_1(it, end, cp); ++ break; ++ case 2: ++ err = utf8::internal::get_sequence_2(it, end, cp); ++ break; ++ case 3: ++ err = utf8::internal::get_sequence_3(it, end, cp); ++ break; ++ case 4: ++ err = utf8::internal::get_sequence_4(it, end, cp); ++ break; + } +- else +- err = INVALID_CODE_POINT; +- } + +- // Failure branch - restore the original value of the iterator +- it = original_it; +- return err; +- } ++ if (err == UTF8_OK) { ++ // Decoding succeeded. Now, security checks... ++ if (utf8::internal::is_code_point_valid(cp)) { ++ if (!utf8::internal::is_overlong_sequence(cp, length)) { ++ // Passed! Return here. ++ code_point = cp; ++ ++it; ++ return UTF8_OK; ++ } else ++ err = OVERLONG_SEQUENCE; ++ } else ++ err = INVALID_CODE_POINT; ++ } + +- template +- inline utf_error validate_next(octet_iterator& it, octet_iterator end) { +- utfchar32_t ignored; +- return utf8::internal::validate_next(it, end, ignored); +- } ++ // Failure branch - restore the original value of the iterator ++ it = original_it; ++ return err; ++ } + +- template +- utf_error validate_next16(word_iterator& it, word_iterator end, utfchar32_t& code_point) +- { +- // Make sure the iterator dereferences a large enough type +- typedef typename std::iterator_traits::value_type word_type; +- UTF_CPP_STATIC_ASSERT(sizeof(word_type) >= sizeof(utfchar16_t)); +- // Check the edge case: +- if (it == end) +- return NOT_ENOUGH_ROOM; +- // Save the original value of it so we can go back in case of failure +- // Of course, it does not make much sense with i.e. stream iterators +- word_iterator original_it = it; +- +- utf_error err = UTF8_OK; +- +- const utfchar16_t first_word = *it++; +- if (!is_surrogate(first_word)) { +- code_point = first_word; +- return UTF8_OK; ++ template ++ inline utf_error validate_next(octet_iterator& it, octet_iterator end) { ++ utfchar32_t ignored; ++ return utf8::internal::validate_next(it, end, ignored); + } +- else { ++ ++ template ++ utf_error validate_next16(word_iterator& it, word_iterator end, utfchar32_t& code_point) { ++ // Make sure the iterator dereferences a large enough type ++ typedef typename std::iterator_traits::value_type word_type; ++ UTF_CPP_STATIC_ASSERT(sizeof(word_type) >= sizeof(utfchar16_t)); ++ // Check the edge case: + if (it == end) +- err = NOT_ENOUGH_ROOM; +- else if (is_lead_surrogate(first_word)) { +- const utfchar16_t second_word = *it++; +- if (is_trail_surrogate(static_cast(second_word))) { +- code_point = static_cast(first_word << 10) + static_cast(second_word) + SURROGATE_OFFSET; +- return UTF8_OK; +- } else +- err = INCOMPLETE_SEQUENCE; ++ return NOT_ENOUGH_ROOM; ++ // Save the original value of it so we can go back in case of failure ++ // Of course, it does not make much sense with i.e. stream iterators ++ word_iterator original_it = it; ++ ++ utf_error err = UTF8_OK; + ++ const utfchar16_t first_word = *it++; ++ if (!is_surrogate(first_word)) { ++ code_point = first_word; ++ return UTF8_OK; + } else { +- err = INVALID_LEAD; ++ if (it == end) ++ err = NOT_ENOUGH_ROOM; ++ else if (is_lead_surrogate(first_word)) { ++ const utfchar16_t second_word = *it++; ++ if (is_trail_surrogate(static_cast(second_word))) { ++ code_point = static_cast(first_word << 10) + static_cast(second_word) ++ + SURROGATE_OFFSET; ++ return UTF8_OK; ++ } else ++ err = INCOMPLETE_SEQUENCE; ++ ++ } else { ++ err = INVALID_LEAD; ++ } + } ++ // error branch ++ it = original_it; ++ return err; + } +- // error branch +- it = original_it; +- return err; +- } + +- // Internal implementation of both checked and unchecked append() function +- // This function will be invoked by the overloads below, as they will know +- // the octet_type. +- template +- octet_iterator append(utfchar32_t cp, octet_iterator result) { +- if (cp < 0x80) // one octet +- *(result++) = static_cast(cp); +- else if (cp < 0x800) { // two octets +- *(result++) = static_cast((cp >> 6) | 0xc0); +- *(result++) = static_cast((cp & 0x3f) | 0x80); +- } +- else if (cp < 0x10000) { // three octets +- *(result++) = static_cast((cp >> 12) | 0xe0); +- *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); +- *(result++) = static_cast((cp & 0x3f) | 0x80); +- } +- else { // four octets +- *(result++) = static_cast((cp >> 18) | 0xf0); +- *(result++) = static_cast(((cp >> 12) & 0x3f)| 0x80); +- *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); +- *(result++) = static_cast((cp & 0x3f) | 0x80); ++ // Internal implementation of both checked and unchecked append() function ++ // This function will be invoked by the overloads below, as they will know ++ // the octet_type. ++ template ++ octet_iterator append(utfchar32_t cp, octet_iterator result) { ++ if (cp < 0x80) // one octet ++ *(result++) = static_cast(cp); ++ else if (cp < 0x800) { // two octets ++ *(result++) = static_cast((cp >> 6) | 0xc0); ++ *(result++) = static_cast((cp & 0x3f) | 0x80); ++ } else if (cp < 0x10000) { // three octets ++ *(result++) = static_cast((cp >> 12) | 0xe0); ++ *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); ++ *(result++) = static_cast((cp & 0x3f) | 0x80); ++ } else { // four octets ++ *(result++) = static_cast((cp >> 18) | 0xf0); ++ *(result++) = static_cast(((cp >> 12) & 0x3f) | 0x80); ++ *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); ++ *(result++) = static_cast((cp & 0x3f) | 0x80); ++ } ++ return result; + } +- return result; +- } + +- // One of the following overloads will be invoked from the API calls ++ // One of the following overloads will be invoked from the API calls + +- // A simple (but dangerous) case: the caller appends byte(s) to a char array +- inline char* append(utfchar32_t cp, char* result) { +- return append(cp, result); +- } ++ // A simple (but dangerous) case: the caller appends byte(s) to a char array ++ inline char* append(utfchar32_t cp, char* result) { ++ return append(cp, result); ++ } + +- // Hopefully, most common case: the caller uses back_inserter +- // i.e. append(cp, std::back_inserter(str)); +- template +- std::back_insert_iterator append +- (utfchar32_t cp, std::back_insert_iterator result) { +- return append, +- typename container_type::value_type>(cp, result); +- } ++ // Hopefully, most common case: the caller uses back_inserter ++ // i.e. append(cp, std::back_inserter(str)); ++ template ++ std::back_insert_iterator ++ append(utfchar32_t cp, std::back_insert_iterator result) { ++ return append, typename container_type::value_type>(cp, result); ++ } + +- // The caller uses some other kind of output operator - not covered above +- // Note that in this case we are not able to determine octet_type +- // so we assume it's utfchar8_t; that can cause a conversion warning if we are wrong. +- template +- octet_iterator append(utfchar32_t cp, octet_iterator result) { +- return append(cp, result); +- } ++ // The caller uses some other kind of output operator - not covered above ++ // Note that in this case we are not able to determine octet_type ++ // so we assume it's utfchar8_t; that can cause a conversion warning if we are wrong. ++ template ++ octet_iterator append(utfchar32_t cp, octet_iterator result) { ++ return append(cp, result); ++ } + +- // Internal implementation of both checked and unchecked append16() function +- // This function will be invoked by the overloads below, as they will know +- // the word_type. +- template +- word_iterator append16(utfchar32_t cp, word_iterator result) { +- UTF_CPP_STATIC_ASSERT(sizeof(word_type) >= sizeof(utfchar16_t)); +- if (is_in_bmp(cp)) +- *(result++) = static_cast(cp); +- else { +- // Code points from the supplementary planes are encoded via surrogate pairs +- *(result++) = static_cast(LEAD_OFFSET + (cp >> 10)); +- *(result++) = static_cast(TRAIL_SURROGATE_MIN + (cp & 0x3FF)); ++ // Internal implementation of both checked and unchecked append16() function ++ // This function will be invoked by the overloads below, as they will know ++ // the word_type. ++ template ++ word_iterator append16(utfchar32_t cp, word_iterator result) { ++ UTF_CPP_STATIC_ASSERT(sizeof(word_type) >= sizeof(utfchar16_t)); ++ if (is_in_bmp(cp)) ++ *(result++) = static_cast(cp); ++ else { ++ // Code points from the supplementary planes are encoded via surrogate pairs ++ *(result++) = static_cast(LEAD_OFFSET + (cp >> 10)); ++ *(result++) = static_cast(TRAIL_SURROGATE_MIN + (cp & 0x3FF)); ++ } ++ return result; + } +- return result; +- } + +- // Hopefully, most common case: the caller uses back_inserter +- // i.e. append16(cp, std::back_inserter(str)); +- template +- std::back_insert_iterator append16 +- (utfchar32_t cp, std::back_insert_iterator result) { +- return append16, +- typename container_type::value_type>(cp, result); +- } ++ // Hopefully, most common case: the caller uses back_inserter ++ // i.e. append16(cp, std::back_inserter(str)); ++ template ++ std::back_insert_iterator ++ append16(utfchar32_t cp, std::back_insert_iterator result) { ++ return append16, typename container_type::value_type>(cp, result); ++ } + +- // The caller uses some other kind of output operator - not covered above +- // Note that in this case we are not able to determine word_type +- // so we assume it's utfchar16_t; that can cause a conversion warning if we are wrong. +- template +- word_iterator append16(utfchar32_t cp, word_iterator result) { +- return append16(cp, result); +- } ++ // The caller uses some other kind of output operator - not covered above ++ // Note that in this case we are not able to determine word_type ++ // so we assume it's utfchar16_t; that can cause a conversion warning if we are wrong. ++ template ++ word_iterator append16(utfchar32_t cp, word_iterator result) { ++ return append16(cp, result); ++ } + +-} // namespace internal ++ } // namespace internal + + /// The library API - functions intended to be called by the users + + // Byte order mark +- const utfchar8_t bom[] = {0xef, 0xbb, 0xbf}; ++ const utfchar8_t bom[] = { 0xef, 0xbb, 0xbf }; + +- template +- octet_iterator find_invalid(octet_iterator start, octet_iterator end) +- { ++ template ++ octet_iterator find_invalid(octet_iterator start, octet_iterator end) { + octet_iterator result = start; + while (result != end) { + utf8::internal::utf_error err_code = utf8::internal::validate_next(result, end); +@@ -452,51 +447,60 @@ namespace internal + return result; + } + +- inline const char* find_invalid(const char* str) +- { ++ inline const char* find_invalid(const char* str) { + const char* end = str + std::strlen(str); + return find_invalid(str, end); + } + +- inline std::size_t find_invalid(const std::string& s) +- { ++ inline std::size_t find_invalid(const std::string& s) { + std::string::const_iterator invalid = find_invalid(s.begin(), s.end()); + return (invalid == s.end()) ? std::string::npos : static_cast(invalid - s.begin()); + } + +- template +- inline bool is_valid(octet_iterator start, octet_iterator end) +- { ++ template ++ inline bool is_valid(octet_iterator start, octet_iterator end) { + return (utf8::find_invalid(start, end) == end); + } + +- inline bool is_valid(const char* str) +- { ++ inline bool is_valid(const char* str) { + return (*(utf8::find_invalid(str)) == '\0'); + } + +- inline bool is_valid(const std::string& s) +- { ++ inline bool is_valid(const std::string& s) { + return is_valid(s.begin(), s.end()); + } + + +- +- template +- inline bool starts_with_bom (octet_iterator it, octet_iterator end) +- { +- return ( +- ((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) && +- ((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) && +- ((it != end) && (utf8::internal::mask8(*it)) == bom[2]) +- ); ++ template ++ inline bool starts_with_bom(octet_iterator it, octet_iterator end) { ++ return (((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) ++ && ((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) ++ && ((it != end) && (utf8::internal::mask8(*it)) == bom[2])); + } + +- inline bool starts_with_bom(const std::string& s) +- { ++ inline bool starts_with_bom(const std::string& s) { + return starts_with_bom(s.begin(), s.end()); + } + } // namespace utf8 + +-#endif // header guard + ++#if defined(UTFCPP_NO_EXCEPTIONS) ++#if defined(__UEFI__) ++#define UTFCPP_THROW(exc) \ ++ do { \ ++ DebugPrint(DEBUG_ERROR, "THROW %s:%d - %s: %s\n", __FILE__, __LINE__, __FUNCTION__, exc.what()); \ ++ abort(); \ ++ } while (false) ++#else ++#define UTFCPP_THROW(exc) \ ++ do { \ ++ std::cerr << "THROW " << (__FILE__) << ":" << (__LINE__) << " - " << (__FUNCTION__) << ": " << (exc.what()) \ ++ << "\n"; \ ++ abort(); \ ++ } while (false) ++#endif ++#else ++#define UTFCPP_THROW(exc) throw exc ++#endif ++ ++#endif // header guard diff --git a/subprojects/utfcpp.wrap b/subprojects/utfcpp.wrap index 3ecb8f76..9207c894 100644 --- a/subprojects/utfcpp.wrap +++ b/subprojects/utfcpp.wrap @@ -8,6 +8,7 @@ patch_filename = utfcpp_4.0.8-1_patch.zip patch_url = https://wrapdb.mesonbuild.com/v2/utfcpp_4.0.8-1/get_patch patch_hash = 83888527bbd2ee13f49f3d791ecdc698b95c614da3e23c44b87c185bd5c19989 wrapdb_version = 4.0.8-1 +diff_files = utfcpp-4.0.8_no_exceptions.diff [provide] dependency_names = utf8cpp diff --git a/tools/dependencies/meson.build b/tools/dependencies/meson.build index 80b0f5a8..b626bf04 100644 --- a/tools/dependencies/meson.build +++ b/tools/dependencies/meson.build @@ -153,7 +153,8 @@ if ( temp = core_lib.get('compile_args') temp += '-D__OOPETRIS_NO_EXCEPTIONS=1' temp += '-DJSON_NOEXCEPTION=1' - temp +='-DSPDLOG_NO_EXCEPTIONS=1' + temp += '-DSPDLOG_NO_EXCEPTIONS=1' + temp += '-DUTFCPP_NO_EXCEPTIONS=1' core_lib += { 'compile_args': temp, } From 34eeea092932a91437cc59b8f268ae640c5cb94d Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 8 Aug 2026 17:06:08 +0200 Subject: [PATCH 088/112] feat: more exception cleanup for uefi --- src/helper/graphic_utils.cpp | 4 ++ src/input/controller_input.cpp | 17 ++++--- src/input/controller_input.hpp | 2 +- src/input/input.cpp | 12 ++--- src/input/input_creator.cpp | 12 +++-- src/input/joystick_input.hpp | 50 ++++++++++++--------- src/input/keyboard_input.hpp | 34 ++++++++------ src/input/touch_input.hpp | 18 ++++---- src/manager/font.cpp | 2 +- src/manager/font.hpp | 2 + src/manager/settings.hpp | 2 +- src/scenes/single_player_game/game_over.cpp | 50 ++++++++++++--------- src/ui/layouts/focus_layout.cpp | 6 +-- src/ui/layouts/grid_layout.cpp | 34 +++++++------- 14 files changed, 144 insertions(+), 101 deletions(-) diff --git a/src/helper/graphic_utils.cpp b/src/helper/graphic_utils.cpp index 9debe74c..d3b33a6a 100644 --- a/src/helper/graphic_utils.cpp +++ b/src/helper/graphic_utils.cpp @@ -163,7 +163,9 @@ std::optional utils::create_directory(const std::filesystem::path& return std::nullopt; } +#if !defined(__OOPETRIS_NO_EXCEPTIONS) try { +#endif if (recursive) { auto result = std::filesystem::create_directories(folder); if (not result) { @@ -178,9 +180,11 @@ std::optional utils::create_directory(const std::filesystem::path& return "an unknown error occurred"; } return std::nullopt; +#if !defined(__OOPETRIS_NO_EXCEPTIONS) } catch (const std::exception& error) { return error.what(); } +#endif } void utils::exit(int status_code) { diff --git a/src/input/controller_input.cpp b/src/input/controller_input.cpp index 9f14cf02..7fb6da31 100644 --- a/src/input/controller_input.cpp +++ b/src/input/controller_input.cpp @@ -77,7 +77,8 @@ input::ControllerInput::get_by_device_index(int device_index) { } -[[nodiscard]] std::optional input::ControllerInput::get_navigation_event(const SDL_Event& event +[[nodiscard]] std::optional input::ControllerInput::get_navigation_event( + const SDL_Event& event ) const { if (event.type == SDL_CONTROLLERBUTTONDOWN) { @@ -123,7 +124,7 @@ input::ControllerInput::get_by_device_index(int device_index) { case NavigationEvent::RIGHT: return "Right"; case NavigationEvent::TAB: - throw std::runtime_error("Tab is not supported"); + utils::throw_(std::runtime_error("Tab is not supported")); default: UNREACHABLE(); } @@ -238,7 +239,8 @@ input::ControllerGameInput::ControllerGameInput( } -[[nodiscard]] std::optional input::ControllerGameInput::sdl_event_to_input_event(const SDL_Event& event +[[nodiscard]] std::optional input::ControllerGameInput::sdl_event_to_input_event( + const SDL_Event& event ) const { if (event.type == SDL_CONTROLLERBUTTONDOWN) { @@ -314,9 +316,12 @@ sdl::ControllerKey json_helper::get_controller_key(const nlohmann::json& obj, co const auto& value = sdl::ControllerKey::from_string(string::to_lower_case(input)); if (not value.has_value()) { - throw nlohmann::json::type_error::create( - 302, fmt::format("Expected a valid Key for key '{}', but got '{}': {}", name, input, value.error()), - &context + utils::throw_( + nlohmann::json::type_error::create( + 302, + fmt::format("Expected a valid Key for key '{}', but got '{}': {}", name, input, value.error()), + &context + ) ); } return value.value(); diff --git a/src/input/controller_input.hpp b/src/input/controller_input.hpp index 7e9b385a..0ab0dc34 100644 --- a/src/input/controller_input.hpp +++ b/src/input/controller_input.hpp @@ -142,7 +142,7 @@ namespace nlohmann { const auto is_valid = settings.validate(); if (not is_valid.has_value()) { - throw std::runtime_error(is_valid.error()); + utils::throw_(std::runtime_error(is_valid.error())); } return settings; diff --git a/src/input/input.cpp b/src/input/input.cpp index 10f9cb4b..b1b5f9f1 100644 --- a/src/input/input.cpp +++ b/src/input/input.cpp @@ -96,7 +96,8 @@ input::InputManager::InputManager(const std::shared_ptr& window) { } -[[nodiscard]] std::optional input::InputManager::get_navigation_event(const SDL_Event& event +[[nodiscard]] std::optional input::InputManager::get_navigation_event( + const SDL_Event& event ) const { for (const auto& input : m_inputs) { @@ -108,7 +109,8 @@ input::InputManager::InputManager(const std::shared_ptr& window) { return std::nullopt; } -[[nodiscard]] std::optional input::InputManager::get_pointer_event(const SDL_Event& event +[[nodiscard]] std::optional input::InputManager::get_pointer_event( + const SDL_Event& event ) const { for (const auto& input : m_inputs) { if (const auto pointer_input = utils::is_child_class(input); pointer_input.has_value()) { @@ -122,8 +124,8 @@ input::InputManager::InputManager(const std::shared_ptr& window) { } -[[nodiscard]] SDL_Event input::InputManager::offset_pointer_event(const SDL_Event& event, const shapes::IPoint& point) - const { +[[nodiscard]] SDL_Event +input::InputManager::offset_pointer_event(const SDL_Event& event, const shapes::IPoint& point) const { for (const auto& input : m_inputs) { if (const auto pointer_input = utils::is_child_class(input); pointer_input.has_value()) { if (const auto pointer_event = pointer_input.value()->get_pointer_event(event); pointer_event.has_value()) { @@ -132,7 +134,7 @@ input::InputManager::InputManager(const std::shared_ptr& window) { } } - throw std::runtime_error("Tried to offset event, that is no pointer event"); + utils::throw_(std::runtime_error("Tried to offset event, that is no pointer event")); } diff --git a/src/input/input_creator.cpp b/src/input/input_creator.cpp index 2e7906bc..44463d7e 100644 --- a/src/input/input_creator.cpp +++ b/src/input/input_creator.cpp @@ -34,7 +34,7 @@ namespace { SDL_DisplayMode mode{}; const int mode_result = SDL_GetCurrentDisplayMode(0, &mode); if (mode_result != 0) { - throw helper::FatalError{ fmt::format("failed in getting display mode: {}", SDL_GetError()) }; + utils::throw_(helper::FatalError{ fmt::format("failed in getting display mode: {}", SDL_GetError()) }); } if (mode.refresh_rate != 0) { target_fps = static_cast(mode.refresh_rate); @@ -61,8 +61,10 @@ input::get_game_parameters_for_replay( auto maybe_recording_reader = recorder::RecordingReader::from_path(recording_path); if (not maybe_recording_reader.has_value()) { - throw std::runtime_error( - fmt::format("an error occurred while reading recording: {}", maybe_recording_reader.error()) + utils::throw_( + std::runtime_error( + fmt::format("an error occurred while reading recording: {}", maybe_recording_reader.error()) + ) ); } @@ -131,7 +133,9 @@ input::get_game_parameters_for_replay( const auto date_time_str = date.to_string(); if (not date_time_str.has_value()) { - throw std::runtime_error{ fmt::format("Erro in date to string conversion: {}", date_time_str.error()) }; + utils::throw_( + std::runtime_error{ fmt::format("Erro in date to string conversion: {}", date_time_str.error()) } + ); } const auto filename = fmt::format("{}.{}", date_time_str.value(), constants::recording::extension); diff --git a/src/input/joystick_input.hpp b/src/input/joystick_input.hpp index 87356cee..459eacba 100644 --- a/src/input/joystick_input.hpp +++ b/src/input/joystick_input.hpp @@ -254,7 +254,8 @@ namespace input { [[nodiscard]] JoystickLikeGameInput& operator=(const JoystickLikeGameInput& input) = delete; OOPETRIS_GRAPHICS_EXPORTED JoystickLikeGameInput(JoystickLikeGameInput&& input) noexcept; - [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED JoystickLikeGameInput& operator=(JoystickLikeGameInput&& input + [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED JoystickLikeGameInput& operator=( + JoystickLikeGameInput&& input ) noexcept; OOPETRIS_GRAPHICS_EXPORTED void handle_event(const SDL_Event& event) override; @@ -360,8 +361,11 @@ namespace nlohmann { const auto& value = sdl::GUID::from_string(input); if (not value.has_value()) { - throw nlohmann::json::type_error::create( - 302, fmt::format("Expected a valid GUID but got '{}': {}", input, value.error()), &context + utils::throw_( + nlohmann::json::type_error::create( + 302, fmt::format("Expected a valid GUID but got '{}': {}", input, value.error()), + &context + ) ); } @@ -375,10 +379,12 @@ namespace nlohmann { } static void to_json(json& obj, const input::JoystickIdentification& identification) { - obj = nlohmann::json::object({ - { "guid", identification.guid.to_string() }, - { "name", identification.name } - }); + obj = nlohmann::json::object( + { + { "guid", identification.guid.to_string() }, + { "name", identification.name } + } + ); } }; @@ -422,7 +428,7 @@ namespace nlohmann { const auto is_valid = settings.validate(); if (not is_valid.has_value()) { - throw std::runtime_error(is_valid.error()); + utils::throw_(std::runtime_error(is_valid.error())); } return settings; @@ -433,18 +439,22 @@ namespace nlohmann { auto identification = nlohmann::json::object(); adl_serializer::to_json(identification, settings.identification); - obj = nlohmann::json::object({ - { "identification", identification }, - { "rotate_left", settings.rotate_left }, - { "rotate_right", settings.rotate_right }, - { "move_left", settings.move_left }, - { "move_right", settings.move_right }, - { "move_down", settings.move_down }, - { "drop", settings.drop }, - { "hold", settings.hold }, - { "menu", nlohmann::json::object({ { "pause", settings.pause }, - { "open_settings", settings.open_settings } }) } - }); + obj = nlohmann::json::object( + { + { "identification",identification }, + { "rotate_left", settings.rotate_left }, + { "rotate_right", settings.rotate_right }, + { "move_left", settings.move_left }, + { "move_right", settings.move_right }, + { "move_down", settings.move_down }, + { "drop", settings.drop }, + { "hold", settings.hold }, + { "menu", + nlohmann::json::object( + { { "pause", settings.pause }, { "open_settings", settings.open_settings } } + ) } + } + ); } }; } // namespace nlohmann diff --git a/src/input/keyboard_input.hpp b/src/input/keyboard_input.hpp index 2b541058..564139a6 100644 --- a/src/input/keyboard_input.hpp +++ b/src/input/keyboard_input.hpp @@ -24,7 +24,8 @@ namespace input { const SDL_Event& event ) const override; - [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::string describe_navigation_event(NavigationEvent event + [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::string describe_navigation_event( + NavigationEvent event ) const override; }; @@ -82,7 +83,8 @@ namespace input { OOPETRIS_GRAPHICS_EXPORTED void update(SimulationStep simulation_step_index) override; - [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::optional get_menu_event(const SDL_Event& event + [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::optional get_menu_event( + const SDL_Event& event ) const override; [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::string describe_menu_event(MenuEvent event) const override; @@ -140,24 +142,28 @@ namespace nlohmann { const auto is_valid = settings.validate(); if (not is_valid.has_value()) { - throw std::runtime_error(is_valid.error()); + utils::throw_(std::runtime_error(is_valid.error())); } return settings; } static void to_json(json& obj, const input::KeyboardSettings& settings) { - obj = nlohmann::json::object({ - { "rotate_left", settings.rotate_left.to_string() }, - { "rotate_right", settings.rotate_right.to_string() }, - { "move_left", settings.move_left.to_string() }, - { "move_right", settings.move_right.to_string() }, - { "move_down", settings.move_down.to_string() }, - { "drop", settings.drop.to_string() }, - { "hold", settings.hold.to_string() }, - { "menu", nlohmann::json::object({ { "pause", settings.pause.to_string() }, - { "open_settings", settings.open_settings.to_string() } }) } - }); + obj = nlohmann::json::object( + { + { "rotate_left", settings.rotate_left.to_string() }, + { "rotate_right", settings.rotate_right.to_string() }, + { "move_left", settings.move_left.to_string() }, + { "move_right", settings.move_right.to_string() }, + { "move_down", settings.move_down.to_string() }, + { "drop", settings.drop.to_string() }, + { "hold", settings.hold.to_string() }, + { "menu", nlohmann::json::object( + { { "pause", settings.pause.to_string() }, + { "open_settings", settings.open_settings.to_string() } } + ) } + } + ); } }; } // namespace nlohmann diff --git a/src/input/touch_input.hpp b/src/input/touch_input.hpp index 3e99b76c..b8654b56 100644 --- a/src/input/touch_input.hpp +++ b/src/input/touch_input.hpp @@ -156,13 +156,15 @@ namespace json_helper { if (not error.has_value()) { - throw nlohmann::json::type_error::create( - 302, - fmt::format( - "Expected a valid number of type '{}' for key '{}' but an error occurred: {}", - typeid(T).name(), name, error.error() - ), - &context + utils::throw_( + nlohmann::json::type_error::create( + 302, + fmt::format( + "Expected a valid number of type '{}' for key '{}' but an error occurred: {}", + typeid(T).name(), name, error.error() + ), + &context + ) ); } @@ -206,7 +208,7 @@ namespace nlohmann { const auto is_valid = settings.validate(); if (not is_valid.has_value()) { - throw std::runtime_error(is_valid.error()); + utils::throw_(std::runtime_error(is_valid.error())); } return settings; diff --git a/src/manager/font.cpp b/src/manager/font.cpp index 6f04ff07..949bf0df 100644 --- a/src/manager/font.cpp +++ b/src/manager/font.cpp @@ -13,7 +13,7 @@ Font::Font(const std::filesystem::path& path, int size) if (not std::filesystem::exists(path)) { error = "path '" + path.string() + "' doesn't exist!"; } - throw FontLoadingError{ "error loading font: '" + error + "'" }; + utils::throw_(FontLoadingError{ "error loading font: '" + error + "'" }); } } diff --git a/src/manager/font.hpp b/src/manager/font.hpp index af721268..71b13b06 100644 --- a/src/manager/font.hpp +++ b/src/manager/font.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include #include #include diff --git a/src/manager/settings.hpp b/src/manager/settings.hpp index 425baf8a..b8a36ca4 100644 --- a/src/manager/settings.hpp +++ b/src/manager/settings.hpp @@ -36,7 +36,7 @@ namespace nlohmann { return Controls{ nlohmann::adl_serializer::from_json(obj) }; } - throw std::runtime_error{ fmt::format("unsupported control type '{}'", to_string(type)) }; + utils::throw_(std::runtime_error{ fmt::format("unsupported control type '{}'", to_string(type)) }); } static void to_json(json& obj, Controls controls) { // NOLINT(misc-no-recursion) diff --git a/src/scenes/single_player_game/game_over.cpp b/src/scenes/single_player_game/game_over.cpp index 9b04d836..46831991 100644 --- a/src/scenes/single_player_game/game_over.cpp +++ b/src/scenes/single_player_game/game_over.cpp @@ -11,28 +11,34 @@ namespace scenes { - SinglePlayerGameOver::SinglePlayerGameOver(ServiceProvider* service_provider, const ui::Layout& layout, const std::shared_ptr& game_input) - : Scene{ service_provider, layout }, - m_text{ - service_provider, - fmt::format( - "Game Over, Press {} to continue", - game_input->underlying_input()->describe_navigation_event(input::NavigationEvent::BACK) - ), - service_provider->font_manager().get(FontId::Default), - Color::white(), - utils::get_orientation() == utils::Orientation::Landscape - ? std::pair{ 0.7, 0.07 } - : std::pair{ 0.95, 0.07 }, - ui::Alignment{ ui::AlignmentHorizontal::Middle, ui::AlignmentVertical::Center }, - layout, - true - } ,m_game_input{game_input}{ - service_provider->music_manager() - .load_and_play_music( - utils::get_assets_folder() / "music" / utils::get_supported_music_extension("05. Results") - ) - .and_then(utils::log_error); + SinglePlayerGameOver::SinglePlayerGameOver( + ServiceProvider* service_provider, + const ui::Layout& layout, + const std::shared_ptr& game_input + ) + : Scene{ + service_provider, layout + }, + m_text{ service_provider, + fmt::format( + "Game Over, Press {} to continue", + game_input->underlying_input()->describe_navigation_event(input::NavigationEvent::BACK) + ), + service_provider->font_manager().get(FontId::Default), + Color::white(), + utils::get_orientation() == utils::Orientation::Landscape ? std::pair{ 0.7, 0.07 } + : std::pair{ 0.95, 0.07 }, + ui::Alignment{ ui::AlignmentHorizontal::Middle, ui::AlignmentVertical::Center }, + layout, + true }, + m_game_input{ game_input } { + auto _ignore = service_provider->music_manager() + .load_and_play_music( + utils::get_assets_folder() / "music" + / utils::get_supported_music_extension("05. Results") + ) + .and_then(utils::log_error); + UNUSED(_ignore); } [[nodiscard]] Scene::UpdateResult SinglePlayerGameOver::update() { diff --git a/src/ui/layouts/focus_layout.cpp b/src/ui/layouts/focus_layout.cpp index aa87dd5e..d5bc963a 100644 --- a/src/ui/layouts/focus_layout.cpp +++ b/src/ui/layouts/focus_layout.cpp @@ -140,7 +140,7 @@ ui::FocusLayout::handle_event_result(const std::optional case ui::EventHandleType::RequestFocus: { const auto focusable = as_focusable(widget); if (not focusable.has_value()) { - throw std::runtime_error("Only Focusables can request focus!"); + utils::throw_(std::runtime_error("Only Focusables can request focus!")); } if (not m_focus_id.has_value()) { @@ -174,7 +174,7 @@ ui::FocusLayout::handle_event_result(const std::optional const auto focusable = as_focusable(widget); if (not focusable.has_value()) { - throw std::runtime_error("Only Focusables can request un-focus!"); + utils::throw_(std::runtime_error("Only Focusables can request un-focus!")); } @@ -235,7 +235,7 @@ ui::FocusLayout::handle_event_result(const std::optional // this works, since result is sorted already const auto duplicates = std::ranges::adjacent_find(result); if (duplicates != result.cend()) { - throw std::runtime_error("Focusables have duplicates: " + std::to_string(*duplicates)); + utils::throw_(std::runtime_error("Focusables have duplicates: " + std::to_string(*duplicates))); } #endif std::ranges::sort(result); diff --git a/src/ui/layouts/grid_layout.cpp b/src/ui/layouts/grid_layout.cpp index e5533916..72e2f690 100644 --- a/src/ui/layouts/grid_layout.cpp +++ b/src/ui/layouts/grid_layout.cpp @@ -3,21 +3,23 @@ ui::GridLayout::GridLayout( - u32 focus_id, // NOLINT(bugprone-easily-swappable-parameters) - u32 size, - Direction direction, - Margin gap, - std::pair margin, - const Layout& layout, - bool is_top_level - ) - : FocusLayout{ layout, focus_id, FocusOptions{ .wrap_around=is_top_level, .allow_tab=is_top_level }, is_top_level }, - m_size{ size }, - m_direction{ direction }, - m_gap{ gap }, - m_margin{ static_cast(margin.first * layout.get_rect().width()), - static_cast(margin.second * layout.get_rect().height()) } { - } + u32 focus_id, // NOLINT(bugprone-easily-swappable-parameters) + u32 size, + Direction direction, + Margin gap, + std::pair margin, + const Layout& layout, + bool is_top_level +) + : FocusLayout{ + layout, focus_id, FocusOptions{ .wrap_around = is_top_level, .allow_tab = is_top_level }, + is_top_level +}, + m_size{ size }, + m_direction{ direction }, + m_gap{ gap }, + m_margin{ static_cast(margin.first * layout.get_rect().width()), + static_cast(margin.second * layout.get_rect().height()) } { } [[nodiscard]] u32 ui::GridLayout::total_size() const { return m_size; @@ -32,7 +34,7 @@ void ui::GridLayout::render(const ServiceProvider& service_provider) const { [[nodiscard]] ui::Layout ui::GridLayout::get_layout_for_index(u32 index) { if (index >= this->m_size) { - throw std::runtime_error("GridLayout is already full"); + utils::throw_(std::runtime_error("GridLayout is already full")); } const auto start_point = layout().get_rect().top_left; From f61399e34f0969852eff19ad715bc22b0cfc6c5e Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 8 Aug 2026 17:25:42 +0200 Subject: [PATCH 089/112] feat: more exception cleanup for uefi --- src/helper/message_box.cpp | 4 +- src/input/input_creator.cpp | 2 +- src/input/joystick_input.cpp | 27 ++++-- src/input/keyboard_input.cpp | 16 ++-- src/input/mouse_input.cpp | 15 +-- .../utility/recording_json_wrapper.hpp | 96 +++++++++++-------- src/manager/music_manager.cpp | 34 ++++--- src/manager/sdl_key.hpp | 7 +- src/scenes/main_menu/main_menu.cpp | 26 +++-- src/scenes/online_lobby/online_lobby.cpp | 28 +++--- .../recording_selector/recording_selector.cpp | 24 ++--- src/scenes/replay_game/replay_game.cpp | 23 +++-- 12 files changed, 178 insertions(+), 124 deletions(-) diff --git a/src/helper/message_box.cpp b/src/helper/message_box.cpp index d1277ef0..d06b971c 100644 --- a/src/helper/message_box.cpp +++ b/src/helper/message_box.cpp @@ -1,6 +1,8 @@ #include "message_box.hpp" +#include + #include #include @@ -17,6 +19,6 @@ void helper::MessageBox::show_simple( const int result = SDL_ShowSimpleMessageBox(flags, title.c_str(), content.c_str(), window); if (result < 0) { - throw std::runtime_error{ fmt::format("Failed to show Simple MessageBox: {}", SDL_GetError()) }; + utils::throw_(std::runtime_error{ fmt::format("Failed to show Simple MessageBox: {}", SDL_GetError()) }); } } diff --git a/src/input/input_creator.cpp b/src/input/input_creator.cpp index 44463d7e..6cbc6e0d 100644 --- a/src/input/input_creator.cpp +++ b/src/input/input_creator.cpp @@ -145,7 +145,7 @@ input::get_game_parameters_for_replay( auto recording_writer_create_result = recorder::RecordingWriter::get_writer(file_path, std::move(tetrion_headers), std::move(information)); if (not recording_writer_create_result.has_value()) { - throw std::runtime_error(recording_writer_create_result.error()); + utils::throw_(std::runtime_error(recording_writer_create_result.error())); } const auto recording_writer = diff --git a/src/input/joystick_input.cpp b/src/input/joystick_input.cpp index 53913535..aa46cf4d 100644 --- a/src/input/joystick_input.cpp +++ b/src/input/joystick_input.cpp @@ -75,7 +75,7 @@ input::JoystickInput& input::JoystickInput::operator=(JoystickInput&& input) noe const auto guid = sdl::GUID{ SDL_JoystickGetGUID(m_joystick) }; if (guid == sdl::GUID{}) { - throw std::runtime_error{ fmt::format("Failed to get joystick GUID: {}", SDL_GetError()) }; + utils::throw_(std::runtime_error{ fmt::format("Failed to get joystick GUID: {}", SDL_GetError()) }); } return guid; @@ -268,10 +268,12 @@ void input::JoyStickInputManager::remove_device( } //this happens way to often, since Sdl outputs both SDL_JOYDEVICEREMOVED and SDL_CONTROLLERDEVICEREMOVED at the same time, in case of a controller, so the second time, this is reached :( - spdlog::debug(fmt::format( - "Failed to remove removed {} from internal input vector", - type == input::JoystickLikeType::Joystick ? "joystick" : "controller" - )); + spdlog::debug( + fmt::format( + "Failed to remove removed {} from internal input vector", + type == input::JoystickLikeType::Joystick ? "joystick" : "controller" + ) + ); } [[nodiscard]] bool input::JoyStickInputManager::process_special_inputs( @@ -673,7 +675,8 @@ input::JoystickLikeGameInput::~JoystickLikeGameInput() { } input::JoystickLikeGameInput::JoystickLikeGameInput(JoystickLikeGameInput&& input) noexcept = default; -[[nodiscard]] input::JoystickLikeGameInput& input::JoystickLikeGameInput::operator=(JoystickLikeGameInput&& input +[[nodiscard]] input::JoystickLikeGameInput& input::JoystickLikeGameInput::operator=( + JoystickLikeGameInput&& input ) noexcept = default; void input::JoystickLikeGameInput::handle_event(const SDL_Event& event) { @@ -742,7 +745,9 @@ input::JoystickGameInput::get_game_input_by_settings( if (const auto joystick_input = utils::is_child_class(input); joystick_input.has_value()) { +#if !defined(__OOPETRIS_NO_EXCEPTIONS) try { +#endif auto result = get_game_joystick_by_guid( settings.identification.guid, settings, event_dispatcher, joystick_input.value() ); @@ -750,10 +755,11 @@ input::JoystickGameInput::get_game_input_by_settings( if (result.has_value()) { return result.value(); } - +#if !defined(__OOPETRIS_NO_EXCEPTIONS) } catch (const std::exception& exception) { spdlog::warn("Couldn't construct JoystickGameInput: {}", exception.what()); } +#endif } } @@ -775,8 +781,8 @@ input::ConsoleJoystickInput::ConsoleJoystickInput( : JoystickInput{ joystick, instance_id, name }, m_key_mappings{ key_mappings } { } -[[nodiscard]] const input::MappingType& input::ConsoleJoystickInput::key_mappings( -) const { +[[nodiscard]] const input::MappingType& +input::ConsoleJoystickInput::key_mappings() const { return m_key_mappings; } @@ -925,7 +931,8 @@ std::optional input::ConsoleJoystickGameInput::sdl_event_to_input_ev return std::nullopt; } -[[nodiscard]] std::optional input::ConsoleJoystickGameInput::get_menu_event(const SDL_Event& event +[[nodiscard]] std::optional input::ConsoleJoystickGameInput::get_menu_event( + const SDL_Event& event ) const { if (event.type == SDL_JOYBUTTONDOWN) { diff --git a/src/input/keyboard_input.cpp b/src/input/keyboard_input.cpp index da37ce6e..7a4412ce 100644 --- a/src/input/keyboard_input.cpp +++ b/src/input/keyboard_input.cpp @@ -8,7 +8,8 @@ input::KeyboardInput::KeyboardInput() : input::Input{ "keyboard", InputType::Keyboard } { } -[[nodiscard]] std::optional input::KeyboardInput::get_navigation_event(const SDL_Event& event +[[nodiscard]] std::optional input::KeyboardInput::get_navigation_event( + const SDL_Event& event ) const { @@ -159,8 +160,8 @@ input::KeyboardGameInput::~KeyboardGameInput() { input::KeyboardGameInput::KeyboardGameInput(KeyboardGameInput&& input) noexcept = default; -[[nodiscard]] input::KeyboardGameInput& input::KeyboardGameInput::operator=(KeyboardGameInput&& input -) noexcept = default; +[[nodiscard]] input::KeyboardGameInput& input::KeyboardGameInput::operator=(KeyboardGameInput&& input) noexcept = + default; [[nodiscard]] helper::expected input::KeyboardSettings::validate() const { @@ -181,9 +182,12 @@ sdl::Key json_helper::get_key(const nlohmann::json& obj, const std::string& name const auto& value = sdl::Key::from_string(input); if (not value.has_value()) { - throw nlohmann::json::type_error::create( - 302, fmt::format("Expected a valid Key for key '{}', but got '{}': {}", name, input, value.error()), - &context + utils::throw_( + nlohmann::json::type_error::create( + 302, + fmt::format("Expected a valid Key for key '{}', but got '{}': {}", name, input, value.error()), + &context + ) ); } return value.value(); diff --git a/src/input/mouse_input.cpp b/src/input/mouse_input.cpp index f286b75d..b19430a5 100644 --- a/src/input/mouse_input.cpp +++ b/src/input/mouse_input.cpp @@ -8,8 +8,8 @@ input::MouseInput::MouseInput() : PointerInput("mouse") { } -[[nodiscard]] SDL_Event input::MouseInput::offset_pointer_event(const SDL_Event& event, const shapes::IPoint& point) - const { +[[nodiscard]] SDL_Event +input::MouseInput::offset_pointer_event(const SDL_Event& event, const shapes::IPoint& point) const { auto new_event = event; @@ -28,23 +28,24 @@ input::MouseInput::MouseInput() : PointerInput("mouse") { } new_event.button.y = event.button.y + point.y; break; default: - throw std::runtime_error("Tried to offset event, that is no pointer event: in Mouse Input"); + utils::throw_(std::runtime_error("Tried to offset event, that is no pointer event: in Mouse Input")); } return new_event; } -[[nodiscard]] std::optional input::MouseInput::get_navigation_event(const SDL_Event& /*event*/) - const { +[[nodiscard]] std::optional +input::MouseInput::get_navigation_event(const SDL_Event& /*event*/) const { return std::nullopt; } [[nodiscard]] std::string input::MouseInput::describe_navigation_event(NavigationEvent /*event*/) const { - throw std::runtime_error("not supported"); + utils::throw_(std::runtime_error("not supported")); } -[[nodiscard]] std::optional input::MouseInput::get_pointer_event(const SDL_Event& event +[[nodiscard]] std::optional input::MouseInput::get_pointer_event( + const SDL_Event& event ) const { auto pointer_event = input::PointerEvent::PointerUp; diff --git a/src/libs/recordings/utility/recording_json_wrapper.hpp b/src/libs/recordings/utility/recording_json_wrapper.hpp index 10a45d67..ca0dd5a0 100644 --- a/src/libs/recordings/utility/recording_json_wrapper.hpp +++ b/src/libs/recordings/utility/recording_json_wrapper.hpp @@ -18,7 +18,7 @@ namespace nlohmann { struct adl_serializer { static recorder::InformationValue from_json(const json& /* obj */) { //TODO(Totto): Implement - throw std::runtime_error{ "NOT IMPLEMENTED" }; + utils::throw_(std::runtime_error{ "NOT IMPLEMENTED" }); } static void to_json(json& obj, const recorder::InformationValue& information) { // NOLINT(misc-no-recursion) @@ -42,7 +42,7 @@ namespace nlohmann { struct adl_serializer { static recorder::AdditionalInformation from_json(const json& /* obj */) { //TODO(Totto): Implement - throw std::runtime_error{ "NOT IMPLEMENTED" }; + utils::throw_(std::runtime_error{ "NOT IMPLEMENTED" }); } static void to_json(json& obj, const recorder::AdditionalInformation& information) { @@ -62,14 +62,16 @@ namespace nlohmann { struct adl_serializer { static recorder::TetrionHeader from_json(const json& /* obj */) { //TODO(Totto): Implement - throw std::runtime_error{ "NOT IMPLEMENTED" }; + utils::throw_(std::runtime_error{ "NOT IMPLEMENTED" }); } static void to_json(json& obj, const recorder::TetrionHeader& tetrion_header) { - obj = nlohmann::json::object({ - { "seed", tetrion_header.seed }, - { "starting_level", tetrion_header.starting_level } - }); + obj = nlohmann::json::object( + { + { "seed", tetrion_header.seed }, + { "starting_level", tetrion_header.starting_level } + } + ); } }; @@ -77,7 +79,7 @@ namespace nlohmann { struct adl_serializer { static InputEvent from_json(const json& /* obj */) { //TODO(Totto): Implement - throw std::runtime_error{ "NOT IMPLEMENTED" }; + utils::throw_(std::runtime_error{ "NOT IMPLEMENTED" }); } static void to_json(json& obj, const InputEvent& event) { @@ -90,16 +92,18 @@ namespace nlohmann { struct adl_serializer { static recorder::Record from_json(const json& /* obj */) { //TODO(Totto): Implement - throw std::runtime_error{ "NOT IMPLEMENTED" }; + utils::throw_(std::runtime_error{ "NOT IMPLEMENTED" }); } static void to_json(json& obj, const recorder::Record& record) { - obj = nlohmann::json::object({ - { "tetrion_index", record.tetrion_index }, - { "simulation_step_index", record.simulation_step_index }, - { "event", record.event } - }); + obj = nlohmann::json::object( + { + { "tetrion_index", record.tetrion_index }, + { "simulation_step_index", record.simulation_step_index }, + { "event", record.event } + } + ); } }; @@ -108,14 +112,16 @@ namespace nlohmann { struct adl_serializer> { static shapes::AbstractPoint from_json(const json& /* obj */) { //TODO(Totto): Implement - throw std::runtime_error{ "NOT IMPLEMENTED" }; + utils::throw_(std::runtime_error{ "NOT IMPLEMENTED" }); } static void to_json(json& obj, const shapes::AbstractPoint& point) { - obj = nlohmann::json::object({ - { "x", point.x }, - { "y", point.y } - }); + obj = nlohmann::json::object( + { + { "x", point.x }, + { "y", point.y } + } + ); } }; @@ -124,7 +130,7 @@ namespace nlohmann { struct adl_serializer { static helper::TetrominoType from_json(const json& /* obj */) { //TODO(Totto): Implement - throw std::runtime_error{ "NOT IMPLEMENTED" }; + utils::throw_(std::runtime_error{ "NOT IMPLEMENTED" }); } static void to_json(json& obj, const helper::TetrominoType& type) { @@ -137,14 +143,16 @@ namespace nlohmann { struct adl_serializer { static Mino from_json(const json& /* obj */) { //TODO(Totto): Implement - throw std::runtime_error{ "NOT IMPLEMENTED" }; + utils::throw_(std::runtime_error{ "NOT IMPLEMENTED" }); } static void to_json(json& obj, const Mino& mino) { - obj = nlohmann::json::object({ - { "position", mino.position() }, - { "type", mino.type() } - }); + obj = nlohmann::json::object( + { + { "position", mino.position() }, + { "type", mino.type() } + } + ); } }; @@ -153,7 +161,7 @@ namespace nlohmann { struct adl_serializer { static TetrionSnapshot from_json(const json& /* obj */) { //TODO(Totto): Implement - throw std::runtime_error{ "NOT IMPLEMENTED" }; + utils::throw_(std::runtime_error{ "NOT IMPLEMENTED" }); } static void to_json(json& obj, const TetrionSnapshot& snapshot) { @@ -162,14 +170,16 @@ namespace nlohmann { nlohmann::adl_serializer>::to_json(mino_stack_json, snapshot.mino_stack().minos()); - obj = nlohmann::json::object({ - { "tetrion_index", snapshot.tetrion_index() }, - { "level", snapshot.level() }, - { "score", snapshot.score() }, - { "lines_cleared", snapshot.lines_cleared() }, - { "simulation_step_index", snapshot.simulation_step_index() }, - { "mino_stack", mino_stack_json } - }); + obj = nlohmann::json::object( + { + { "tetrion_index", snapshot.tetrion_index() }, + { "level", snapshot.level() }, + { "score", snapshot.score() }, + { "lines_cleared", snapshot.lines_cleared() }, + { "simulation_step_index", snapshot.simulation_step_index() }, + { "mino_stack", mino_stack_json } + } + ); } }; @@ -178,7 +188,7 @@ namespace nlohmann { struct adl_serializer { static recorder::RecordingReader from_json(const json& /* obj */) { //TODO(Totto): Implement - throw std::runtime_error{ "NOT IMPLEMENTED" }; + utils::throw_(std::runtime_error{ "NOT IMPLEMENTED" }); } static void to_json(json& obj, const recorder::RecordingReader& recording_reader) { @@ -201,13 +211,15 @@ namespace nlohmann { snapshots_json, recording_reader.snapshots() ); - obj = nlohmann::json::object({ - { "version", recorder::Recording::current_supported_version_number }, - { "information", information_json }, - { "tetrion_headers", tetrion_headers_json }, - { "records", records_json }, - { "snapshots", snapshots_json }, - }); + obj = nlohmann::json::object( + { + { "version", recorder::Recording::current_supported_version_number }, + { "information", information_json }, + { "tetrion_headers", tetrion_headers_json }, + { "records", records_json }, + { "snapshots", snapshots_json }, + } + ); } }; } // namespace nlohmann diff --git a/src/manager/music_manager.cpp b/src/manager/music_manager.cpp index 5c9eee52..e8966c4c 100644 --- a/src/manager/music_manager.cpp +++ b/src/manager/music_manager.cpp @@ -30,13 +30,17 @@ MusicManager::MusicManager(ServiceProvider* service_provider, u8 channel_size) const auto result = SDL_InitSubSystem(SDL_INIT_AUDIO); if (result != 0) { - throw helper::InitializationError{ fmt::format("Failed to initialize the audio system: {}", SDL_GetError()) }; + utils::throw_( + helper::InitializationError{ fmt::format("Failed to initialize the audio system: {}", SDL_GetError()) } + ); } //TODO(Totto): dynamically handle codecs const auto initialized_codecs = Mix_Init(MIX_INIT_FLAC | MIX_INIT_MP3); if (initialized_codecs == 0) { - throw helper::InitializationError{ fmt::format("Failed to initialize any audio codec: {}", SDL_GetError()) }; + utils::throw_( + helper::InitializationError{ fmt::format("Failed to initialize any audio codec: {}", SDL_GetError()) } + ); } // retrieve allocated channels @@ -49,10 +53,12 @@ MusicManager::MusicManager(ServiceProvider* service_provider, u8 channel_size) // see: https://wiki.libsdl.org/SDL2_mixer/Mix_AllocateChannels auto newly_allocated_channels = Mix_AllocateChannels(channel_size); if (newly_allocated_channels != channel_size) { - throw helper::InitializationError{ fmt::format( - "Failed to initialize the requested channels, requested {} but only got {}: {}", channel_size, - newly_allocated_channels, SDL_GetError() - ) }; + utils::throw_( + helper::InitializationError{ fmt::format( + "Failed to initialize the requested channels, requested {} but only got {}: {}", + channel_size, newly_allocated_channels, SDL_GetError() + ) } + ); } } @@ -69,7 +75,7 @@ MusicManager::MusicManager(ServiceProvider* service_provider, u8 channel_size) if (audio_result != 0) { - throw helper::InitializationError{ fmt::format("Failed to open an audio device: {}", SDL_GetError()) }; + utils::throw_(helper::InitializationError{ fmt::format("Failed to open an audio device: {}", SDL_GetError()) }); } #endif @@ -238,7 +244,7 @@ void MusicManager::hook_music_finished() { } if (m_queued_music == nullptr) { - throw std::runtime_error{ "implementation error: m_queued_music is null but it shouldn't be" }; + utils::throw_(std::runtime_error{ "implementation error: m_queued_music is null but it shouldn't be" }); } if (m_music != nullptr) { @@ -247,8 +253,10 @@ void MusicManager::hook_music_finished() { const int result = Mix_FadeInMusic(m_queued_music, -1, static_cast(m_delay)); if (result != 0) { - throw std::runtime_error( - "an error occurred while trying to play the music (fading in): " + std::string{ Mix_GetError() } + utils::throw_( + std::runtime_error( + "an error occurred while trying to play the music (fading in): " + std::string{ Mix_GetError() } + ) ); } m_music = m_queued_music; @@ -313,8 +321,10 @@ void MusicManager::set_volume( if (m_music != nullptr) { const int result = Mix_PlayMusic(m_music, -1); if (result != 0) { - throw std::runtime_error( - "an error occurred while trying to play the music: " + std::string{ Mix_GetError() } + utils::throw_( + std::runtime_error( + "an error occurred while trying to play the music: " + std::string{ Mix_GetError() } + ) ); } } diff --git a/src/manager/sdl_key.hpp b/src/manager/sdl_key.hpp index 899245e6..c4b07a5d 100644 --- a/src/manager/sdl_key.hpp +++ b/src/manager/sdl_key.hpp @@ -98,13 +98,14 @@ namespace sdl { * @param ignore_special_modifiers * @return bool */ - [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED bool is_equal(const Key& other, bool ignore_special_modifiers = true) - const; + [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED bool + is_equal(const Key& other, bool ignore_special_modifiers = true) const; [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::string to_string() const; private: - [[nodiscard]] static helper::expected sdl_keycode_from_string(const std::string& value + [[nodiscard]] static helper::expected sdl_keycode_from_string( + const std::string& value ); [[nodiscard]] static UnderlyingModifierType sdl_modifier_from_modifiers(const std::vector& modifiers); diff --git a/src/scenes/main_menu/main_menu.cpp b/src/scenes/main_menu/main_menu.cpp index 931c90c6..03c0ae10 100644 --- a/src/scenes/main_menu/main_menu.cpp +++ b/src/scenes/main_menu/main_menu.cpp @@ -10,10 +10,16 @@ namespace scenes { - MainMenu::MainMenu(ServiceProvider* service_provider, const ui::Layout& layout) - : Scene{service_provider, layout}, - m_main_grid{ 0,6,ui::Direction::Vertical, ui::RelativeMargin{layout,ui::Direction::Vertical, 0.05}, std::pair{ 0.05, 0.05 - } ,ui::RelativeLayout{ layout, 0.0, 0.1, 1.0, 0.8 }} { + MainMenu::MainMenu(ServiceProvider* service_provider, const ui::Layout& layout) + : Scene{ + service_provider, layout + }, + m_main_grid{ 0, + 6, + ui::Direction::Vertical, + ui::RelativeMargin{ layout, ui::Direction::Vertical, 0.05 }, + std::pair{ 0.05, 0.05 }, + ui::RelativeLayout{ layout, 0.0, 0.1, 1.0, 0.8 } } { auto focus_helper = ui::FocusHelper{ 1 }; @@ -99,11 +105,13 @@ namespace scenes { #endif - service_provider->music_manager() - .load_and_play_music( - utils::get_assets_folder() / "music" / utils::get_supported_music_extension("01. Main Menu") - ) - .and_then(utils::log_error); + auto _ignore = service_provider->music_manager() + .load_and_play_music( + utils::get_assets_folder() / "music" + / utils::get_supported_music_extension("01. Main Menu") + ) + .and_then(utils::log_error); + UNUSED(_ignore); } [[nodiscard]] Scene::UpdateResult MainMenu::update() { diff --git a/src/scenes/online_lobby/online_lobby.cpp b/src/scenes/online_lobby/online_lobby.cpp index 072f3340..12ee92b0 100644 --- a/src/scenes/online_lobby/online_lobby.cpp +++ b/src/scenes/online_lobby/online_lobby.cpp @@ -17,16 +17,16 @@ namespace scenes { OnlineLobby::OnlineLobby(ServiceProvider* service_provider, const ui::Layout& layout) - : Scene{ service_provider, layout }, - m_main_layout{ - utils::SizeIdentity<3>(), - 0, - ui::Direction::Vertical, - { 0.1, 0.9 }, - ui::AbsolutMargin{ 10 }, - std::pair{ 0.05, 0.03 }, - layout - } { + : Scene{ + service_provider, layout + }, + m_main_layout{ utils::SizeIdentity<3>(), + 0, + ui::Direction::Vertical, + { 0.1, 0.9 }, + ui::AbsolutMargin{ 10 }, + std::pair{ 0.05, 0.03 }, + layout } { auto focus_helper = ui::FocusHelper{ 1 }; m_main_layout.add( @@ -134,11 +134,13 @@ namespace scenes { } - throw std::runtime_error("Requested action on unknown widget, this is a fatal error"); + utils::throw_(std::runtime_error("Requested action on unknown widget, this is a fatal error")); } - throw helper::FatalError( - fmt::format("Unsupported Handle Type: {}", magic_enum::enum_name(additional->first)) + utils::throw_( + helper::FatalError( + fmt::format("Unsupported Handle Type: {}", magic_enum::enum_name(additional->first)) + ) ); } diff --git a/src/scenes/recording_selector/recording_selector.cpp b/src/scenes/recording_selector/recording_selector.cpp index 9f82116b..cc5cbbaa 100644 --- a/src/scenes/recording_selector/recording_selector.cpp +++ b/src/scenes/recording_selector/recording_selector.cpp @@ -28,16 +28,16 @@ namespace scenes { using namespace details::recording::selector; //NOLINT(google-build-using-namespace) RecordingSelector::RecordingSelector(ServiceProvider* service_provider, const ui::Layout& layout) - : Scene{ service_provider, layout }, - m_main_layout{ - utils::SizeIdentity<3>(), - 0, - ui::Direction::Vertical, - { 0.1, 0.9 }, - ui::AbsolutMargin{ 10 }, - std::pair{ 0.05, 0.03 }, - layout - } { + : Scene{ + service_provider, layout + }, + m_main_layout{ utils::SizeIdentity<3>(), + 0, + ui::Direction::Vertical, + { 0.1, 0.9 }, + ui::AbsolutMargin{ 10 }, + std::pair{ 0.05, 0.03 }, + layout } { auto focus_helper = ui::FocusHelper{ 1 }; @@ -118,7 +118,9 @@ namespace scenes { } #endif - throw std::runtime_error("Requested action on unknown widget, this is a fatal error"); + utils::throw_( + std::runtime_error("Requested action on unknown widget, this is a fatal error") + ); } }, m_next_command.value().m_value ); diff --git a/src/scenes/replay_game/replay_game.cpp b/src/scenes/replay_game/replay_game.cpp index 15b02e28..8058ef40 100644 --- a/src/scenes/replay_game/replay_game.cpp +++ b/src/scenes/replay_game/replay_game.cpp @@ -25,7 +25,7 @@ namespace scenes { layouts.reserve(parameters.size()); if (parameters.empty()) { - throw std::runtime_error("An empty recording file isn't supported"); + utils::throw_(std::runtime_error("An empty recording file isn't supported")); } else if (parameters.size() == 1) { // NOLINT(readability-else-after-return,llvm-else-after-return) layouts.push_back(ui::RelativeLayout{ layout, 0.02, 0.01, 0.96, 0.98 }); } else if (parameters.size() == 2) { @@ -47,9 +47,12 @@ namespace scenes { for (decltype(parameters.size()) i = 0; i < parameters.size(); ++i) { auto [input, starting_parameters] = std::move(parameters.at(i)); - m_games.emplace_back(std::make_unique( - service_provider, std::move(input), starting_parameters, simulation_frequency, layouts.at(i), false - )); + m_games.emplace_back( + std::make_unique( + service_provider, std::move(input), starting_parameters, simulation_frequency, + layouts.at(i), false + ) + ); } @@ -67,11 +70,13 @@ namespace scenes { #endif - m_service_provider->music_manager() - .load_and_play_music( - utils::get_assets_folder() / "music" / utils::get_supported_music_extension("02. Game Theme") - ) - .and_then(utils::log_error); + auto _ignore = m_service_provider->music_manager() + .load_and_play_music( + utils::get_assets_folder() / "music" + / utils::get_supported_music_extension("02. Game Theme") + ) + .and_then(utils::log_error); + UNUSED(_ignore); } From a62ce69a094e4ada3d1f0234514ef326d0cb0110 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 8 Aug 2026 17:37:34 +0200 Subject: [PATCH 090/112] feat: more exception cleanup for uefi --- src/game/simulated_tetrion.cpp | 14 ++++---- src/graphics/sdl_context.cpp | 9 ++--- src/input/replay_input.cpp | 4 +-- src/lobby/credentials/secret.cpp | 5 +-- src/lobby/credentials/secret.hpp | 6 +++- src/manager/sdl_controller_key.cpp | 13 ++++--- src/manager/sdl_key.cpp | 12 ++++--- src/scenes/replay_game/replay_game.cpp | 2 +- src/scenes/scene.cpp | 2 +- src/scenes/settings_menu/settings_menu.cpp | 35 ++++++++++++------- .../single_player_game/single_player_game.cpp | 25 ++++++++----- src/ui/layouts/scroll_layout.cpp | 2 +- 12 files changed, 81 insertions(+), 48 deletions(-) diff --git a/src/game/simulated_tetrion.cpp b/src/game/simulated_tetrion.cpp index 5806bc9c..7054ece1 100644 --- a/src/game/simulated_tetrion.cpp +++ b/src/game/simulated_tetrion.cpp @@ -306,12 +306,14 @@ void SimulatedTetrion::clear_fully_occupied_lines() { spdlog::info("new level: {}", m_level); if (level == constants::music_change_level) { if (m_service_provider != nullptr) { - m_service_provider->music_manager() - .load_and_play_music( - utils::get_assets_folder() / "music" - / utils::get_supported_music_extension("03. Game Theme (50 Left)") - ) - .and_then(utils::log_error); + auto _ignore = + m_service_provider->music_manager() + .load_and_play_music( + utils::get_assets_folder() / "music" + / utils::get_supported_music_extension("03. Game Theme (50 Left)") + ) + .and_then(utils::log_error); + UNUSED(_ignore); } } } diff --git a/src/graphics/sdl_context.cpp b/src/graphics/sdl_context.cpp index 354f2a88..b68ef926 100644 --- a/src/graphics/sdl_context.cpp +++ b/src/graphics/sdl_context.cpp @@ -23,7 +23,7 @@ SdlContext::SdlContext() { } if (TTF_Init() < 0) { - throw helper::InitializationError{ fmt::format("Failed in initializing sdl ttf: {}", TTF_GetError()) }; + utils::throw_(helper::InitializationError{ fmt::format("Failed in initializing sdl ttf: {}", TTF_GetError()) }); } #if defined(__CONSOLE__) @@ -32,9 +32,10 @@ SdlContext::SdlContext() { #if defined(_HAVE_FILE_DIALOGS) if (NFD::Init() != NFD_OKAY) { - throw helper::InitializationError{ - fmt::format("Failed to initialize the file dialog library: {}", NFD::GetError()) - }; + utils::throw_( + helper::InitializationError{ + fmt::format("Failed to initialize the file dialog library: {}", NFD::GetError()) } + ); } #endif diff --git a/src/input/replay_input.cpp b/src/input/replay_input.cpp index 1b3cb8b8..c95d5985 100644 --- a/src/input/replay_input.cpp +++ b/src/input/replay_input.cpp @@ -73,7 +73,7 @@ void input::ReplayGameInput::late_update(const SimulationStep simulation_step_in spdlog::info("snapshots are equal"); } else { spdlog::error("{}", compare_result.error()); - throw std::runtime_error{ "snapshots are not equal" }; + utils::throw_(std::runtime_error{ "snapshots are not equal" }); } ++m_next_snapshot_index; @@ -86,7 +86,7 @@ void input::ReplayGameInput::late_update(const SimulationStep simulation_step_in } [[nodiscard]] std::string input::ReplayGameInput::describe_menu_event(MenuEvent /*event*/) const { - throw std::runtime_error("not supported"); + utils::throw_(std::runtime_error("not supported")); } [[nodiscard]] bool input::ReplayGameInput::is_end_of_recording() const { diff --git a/src/lobby/credentials/secret.cpp b/src/lobby/credentials/secret.cpp index 309788da..b11de088 100644 --- a/src/lobby/credentials/secret.cpp +++ b/src/lobby/credentials/secret.cpp @@ -45,7 +45,8 @@ secret::SecretStorage::SecretStorage(ServiceProvider* service_provider, KeyringT // -1 stands for current uid, 0 stands for: do not create a link to another keyring auto result = keyctl_get_persistent(-1, 0); if (result < 0) { - throw std::runtime_error(fmt::format("Error while getting the persistent keyring: {}", strerror(errno)) + throw std::runtime_error( + fmt::format("Error while getting the persistent keyring: {}", strerror(errno)) ); } @@ -373,7 +374,7 @@ secret::SecretStorage::store(const std::string& key, const Buffer& value, bool u return std::nullopt; } -#elif defined(__CONSOLE__) || defined(__APPLE__) +#elif defined(_SECRET_USE_JSON_FILE) #include "helper/graphic_utils.hpp" #include diff --git a/src/lobby/credentials/secret.hpp b/src/lobby/credentials/secret.hpp index 343e163a..154b04f3 100644 --- a/src/lobby/credentials/secret.hpp +++ b/src/lobby/credentials/secret.hpp @@ -38,6 +38,10 @@ namespace oopetris::secret::details { #endif +#if defined(__CONSOLE__) || defined(__APPLE__) || defined(__UEFI__) +#define _SECRET_USE_JSON_FILE +#endif + namespace secret { enum class KeyringType : u8 { User, Session, Persistent }; @@ -49,7 +53,7 @@ namespace secret { #if defined(_HAVE_KEYUTILS) key_serial_t m_ring_id; -#elif defined(__CONSOLE__) || defined(__APPLE__) +#elif defined(_SECRET_USE_JSON_FILE) std::string m_file_path; #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) oopetris::secret::details::NCRYPT_PROV_HANDLE m_phProvider; diff --git a/src/manager/sdl_controller_key.cpp b/src/manager/sdl_controller_key.cpp index 7655879a..d72b0d9e 100644 --- a/src/manager/sdl_controller_key.cpp +++ b/src/manager/sdl_controller_key.cpp @@ -1,6 +1,7 @@ #include "sdl_controller_key.hpp" +#include sdl::ControllerKey::ControllerKey(SDL_GameControllerButton button) : m_button{ button } { } @@ -25,10 +26,14 @@ helper::expected sdl::ControllerKey::from_strin const auto* name = SDL_GameControllerGetStringForButton(m_button); if (name == nullptr or std::strlen(name) == 0) { - throw std::runtime_error(fmt::format( - "No name for the SDL key {}: {}", static_cast>(m_button), - SDL_GetError() - )); + utils::throw_( + std::runtime_error( + fmt::format( + "No name for the SDL key {}: {}", + static_cast>(m_button), SDL_GetError() + ) + ) + ); } return std::string{ name }; } diff --git a/src/manager/sdl_key.cpp b/src/manager/sdl_key.cpp index a5e6e20d..b542cea7 100644 --- a/src/manager/sdl_key.cpp +++ b/src/manager/sdl_key.cpp @@ -151,10 +151,14 @@ namespace { [[nodiscard]] std::string sdl_key_name(SDL_KeyCode keycode) { const auto* name = SDL_GetKeyName(keycode); if (name == nullptr or std::strlen(name) == 0) { - throw std::runtime_error(fmt::format( - "No name for the SDL key {}: {}", static_cast>(keycode), - SDL_GetError() - )); + utils::throw_( + std::runtime_error( + fmt::format( + "No name for the SDL key {}: {}", + static_cast>(keycode), SDL_GetError() + ) + ) + ); } return std::string{ name }; } diff --git a/src/scenes/replay_game/replay_game.cpp b/src/scenes/replay_game/replay_game.cpp index 8058ef40..d0fdf4e7 100644 --- a/src/scenes/replay_game/replay_game.cpp +++ b/src/scenes/replay_game/replay_game.cpp @@ -34,7 +34,7 @@ namespace scenes { } else { //TODO(Totto): support bigger layouts than just 2 - throw std::runtime_error("At the moment only replays from up to two players are supported"); + utils::throw_(std::runtime_error("At the moment only replays from up to two players are supported")); } u32 simulation_frequency = constants::simulation_frequency; diff --git a/src/scenes/scene.cpp b/src/scenes/scene.cpp index 0e2cc551..18128c42 100644 --- a/src/scenes/scene.cpp +++ b/src/scenes/scene.cpp @@ -46,7 +46,7 @@ namespace scenes { case SceneId::AchievementsPage: return std::make_unique(&service_provider, layout); */ default: - throw std::runtime_error("Not implemented ID"); + utils::throw_(std::runtime_error("Not implemented ID")); } } diff --git a/src/scenes/settings_menu/settings_menu.cpp b/src/scenes/settings_menu/settings_menu.cpp index b0982dc6..2506a6f9 100644 --- a/src/scenes/settings_menu/settings_menu.cpp +++ b/src/scenes/settings_menu/settings_menu.cpp @@ -29,17 +29,25 @@ namespace scenes { ) : SettingsMenu{ service_provider, layout, std::optional>{ game_input } } { } - SettingsMenu::SettingsMenu(ServiceProvider* service_provider, const ui::Layout& layout, const std::optional>& game_input) : Scene{service_provider, layout} - , m_main_layout{ utils::SizeIdentity<3>(), - 0, - ui::Direction::Vertical, - { 0.1, 0.9 }, - ui::AbsolutMargin{ 10 }, - std::pair{ 0.05, 0.03 }, - layout + SettingsMenu::SettingsMenu( + ServiceProvider* service_provider, + const ui::Layout& layout, + const std::optional>& game_input + ) + : Scene{ + service_provider, layout }, - m_colors{COLOR_LITERAL("#FF33FF"), COLOR_LITERAL("hsv(281.71, 0.70085, 0.45882)"), COLOR_LITERAL("rgb(246, 255, 61)"),COLOR_LITERAL("hsv(103.12, 0.39024, 0.32157)")},m_game_input{game_input},m_settings{m_service_provider->settings_manager().settings()} -{ + m_main_layout{ utils::SizeIdentity<3>(), + 0, + ui::Direction::Vertical, + { 0.1, 0.9 }, + ui::AbsolutMargin{ 10 }, + std::pair{ 0.05, 0.03 }, + layout }, + m_colors{ COLOR_LITERAL("#FF33FF"), COLOR_LITERAL("hsv(281.71, 0.70085, 0.45882)"), + COLOR_LITERAL("rgb(246, 255, 61)"), COLOR_LITERAL("hsv(103.12, 0.39024, 0.32157)") }, + m_game_input{ game_input }, + m_settings{ m_service_provider->settings_manager().settings() } { auto focus_helper = ui::FocusHelper{ 1 }; m_main_layout.add( @@ -83,8 +91,7 @@ namespace scenes { ); service_provider->music_manager().add_volume_listener( - listener_name, - [this, scroll_layout_index, slider_index](std::optional) { + listener_name, [this, scroll_layout_index, slider_index](std::optional) { auto* volume_scroll_layout = this->m_main_layout.get(scroll_layout_index); volume_scroll_layout->get(slider_index)->on_change(); @@ -224,7 +231,9 @@ namespace scenes { } - throw std::runtime_error("Requested action on unknown widget, this is a fatal error"); + utils::throw_( + std::runtime_error("Requested action on unknown widget, this is a fatal error") + ); } }, m_next_command.value().m_value ); diff --git a/src/scenes/single_player_game/single_player_game.cpp b/src/scenes/single_player_game/single_player_game.cpp index 73d5bc30..71c5d14c 100644 --- a/src/scenes/single_player_game/single_player_game.cpp +++ b/src/scenes/single_player_game/single_player_game.cpp @@ -35,10 +35,15 @@ namespace scenes { input::get_single_player_game_parameters(service_provider, std::move(additional_information), date); if (not result.has_value()) { - throw helper::MajorError(fmt::format( - "No suitable input was configured, go into the settings to select a suitable input: {}", - result.error() - )); + utils::throw_( + helper::MajorError( + fmt::format( + "No suitable input was configured, go into the settings to select a suitable " + "input: {}", + result.error() + ) + ) + ); } auto [input, starting_parameters] = result.value(); @@ -61,11 +66,13 @@ namespace scenes { #endif - m_service_provider->music_manager() - .load_and_play_music( - utils::get_assets_folder() / "music" / utils::get_supported_music_extension("02. Game Theme") - ) - .and_then(utils::log_error); + auto _ignore = m_service_provider->music_manager() + .load_and_play_music( + utils::get_assets_folder() / "music" + / utils::get_supported_music_extension("02. Game Theme") + ) + .and_then(utils::log_error); + UNUSED(_ignore); } diff --git a/src/ui/layouts/scroll_layout.cpp b/src/ui/layouts/scroll_layout.cpp index ddeda908..a32a3e53 100644 --- a/src/ui/layouts/scroll_layout.cpp +++ b/src/ui/layouts/scroll_layout.cpp @@ -294,7 +294,7 @@ void ui::ScrollLayout::clear_widgets() { [[nodiscard]] ui::Layout ui::ScrollLayout::get_layout_for_index(u32 /*index*/) { // see TODO comment over handle_event in header file - throw std::runtime_error("NOT SUPPORTED"); + utils::throw_(std::runtime_error("NOT SUPPORTED")); } [[nodiscard]] ui::Layout ui::ScrollLayout::get_layout_for_new(ItemSize size) { From 2027e0cbd1d76bc443d6e825b23a308a2fe969b5 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 8 Aug 2026 17:42:23 +0200 Subject: [PATCH 091/112] feat: more exception cleanup for uefi --- src/graphics/texture.cpp | 27 +++++++++++++++++++-------- src/input/touch_input.cpp | 23 ++++++++++++----------- src/ui/components/textinput.cpp | 16 +++++++++------- src/ui/layouts/tile_layout.cpp | 2 +- 4 files changed, 41 insertions(+), 27 deletions(-) diff --git a/src/graphics/texture.cpp b/src/graphics/texture.cpp index 40f15e88..3b9e64de 100644 --- a/src/graphics/texture.cpp +++ b/src/graphics/texture.cpp @@ -10,8 +10,13 @@ Texture Texture::from_image(SDL_Renderer* renderer, const std::filesystem::path& SDL_Texture* image = IMG_LoadTexture(renderer, image_path.string().c_str()); if (image == nullptr) { - throw std::runtime_error( - fmt::format("Failed to load image from path '{}' with error: {}", image_path.string(), SDL_GetError()) + utils::throw_( + std::runtime_error( + fmt::format( + "Failed to load image from path '{}' with error: {}", image_path.string(), + SDL_GetError() + ) + ) ); } return Texture{ image }; @@ -40,13 +45,17 @@ Texture Texture::prerender_text( UNREACHABLE(); } if (surface == nullptr) { - throw std::runtime_error(fmt::format("Failed to pre-render text into surface with error: {}", SDL_GetError())); + utils::throw_( + std::runtime_error(fmt::format("Failed to pre-render text into surface with error: {}", SDL_GetError())) + ); } SDL_Texture* const texture = SDL_CreateTextureFromSurface(renderer, surface); SDL_FreeSurface(surface); if (texture == nullptr) { - throw std::runtime_error(fmt::format("Failed to pre-render text into texture with error: {}", SDL_GetError())); + utils::throw_( + std::runtime_error(fmt::format("Failed to pre-render text into texture with error: {}", SDL_GetError())) + ); } @@ -58,19 +67,19 @@ Texture Texture::get_for_render_target(SDL_Renderer* renderer, const shapes::UPo SDL_DisplayMode mode{}; const int result = SDL_GetCurrentDisplayMode(0, &mode); if (result != 0) { - throw std::runtime_error{ "failed in getting display mode: " + std::string{ SDL_GetError() } }; + utils::throw_(std::runtime_error{ "failed in getting display mode: " + std::string{ SDL_GetError() } }); } auto* const texture = SDL_CreateTexture( renderer, mode.format, SDL_TEXTUREACCESS_TARGET, static_cast(size.x), static_cast(size.y) ); if (texture == nullptr) { - throw std::runtime_error(fmt::format("Failed to create texture with error: {}", SDL_GetError())); + utils::throw_(std::runtime_error(fmt::format("Failed to create texture with error: {}", SDL_GetError()))); } const auto target_result = SDL_SetRenderTarget(renderer, texture); if (target_result < 0) { - throw std::runtime_error(fmt::format("Failed to set render target with error: {}", SDL_GetError())); + utils::throw_(std::runtime_error(fmt::format("Failed to set render target with error: {}", SDL_GetError()))); } @@ -113,6 +122,8 @@ Texture::~Texture() { void Texture::set_as_render_target(SDL_Renderer* renderer) const { const auto result = SDL_SetRenderTarget(renderer, m_raw_texture); if (result < 0) { - throw std::runtime_error(fmt::format("Failed to set render texture target with error: {}", SDL_GetError())); + utils::throw_( + std::runtime_error(fmt::format("Failed to set render texture target with error: {}", SDL_GetError())) + ); } } diff --git a/src/input/touch_input.cpp b/src/input/touch_input.cpp index b8812042..244b604e 100644 --- a/src/input/touch_input.cpp +++ b/src/input/touch_input.cpp @@ -52,9 +52,8 @@ std::optional input::TouchGameInput::sdl_event_to_input_event(const const auto timestamp = event.tfinger.timestamp; m_finger_state.insert_or_assign( - finger_id, - std::optional{ - PressedState{ timestamp, x_pos, y_pos } + finger_id, std::optional{ + PressedState{ timestamp, x_pos, y_pos } } ); } @@ -176,7 +175,7 @@ input::TouchGameInput::TouchGameInput(TouchGameInput&& input) noexcept = default case input::MenuEvent::Pause: return "Back"; case input::MenuEvent::OpenSettings: - throw std::runtime_error("Open Settings is not supported"); + utils::throw_(std::runtime_error("Open Settings is not supported")); default: UNREACHABLE(); } @@ -213,7 +212,8 @@ input::TouchInput::get_by_device_index(const std::shared_ptr& window, in } -[[nodiscard]] std::optional input::TouchInput::get_navigation_event(const SDL_Event& event +[[nodiscard]] std::optional input::TouchInput::get_navigation_event( + const SDL_Event& event ) const { //technically no touch event, but it's a navigation event, and by APi design it can also handle those if (event.type == SDL_KEYDOWN and event.key.keysym.sym == SDLK_AC_BACK) { @@ -239,7 +239,8 @@ input::TouchInput::get_by_device_index(const std::shared_ptr& window, in } } -[[nodiscard]] std::optional input::TouchInput::get_pointer_event(const SDL_Event& event +[[nodiscard]] std::optional input::TouchInput::get_pointer_event( + const SDL_Event& event ) const { auto pointer_event = input::PointerEvent::PointerUp; @@ -276,14 +277,14 @@ input::TouchInput::get_by_device_index(const std::shared_ptr& window, in } -[[nodiscard]] SDL_Event input::TouchInput::offset_pointer_event(const SDL_Event& event, const shapes::IPoint& point) - const { +[[nodiscard]] SDL_Event +input::TouchInput::offset_pointer_event(const SDL_Event& event, const shapes::IPoint& point) const { auto new_event = event; if (event.type != SDL_FINGERMOTION and event.type != SDL_FINGERDOWN and event.type != SDL_FINGERUP) { - throw std::runtime_error("Tried to offset event, that is no pointer event: in Touch Input"); + utils::throw_(std::runtime_error("Tried to offset event, that is no pointer event: in Touch Input")); } using FloatType = decltype(event.tfinger.x); @@ -293,8 +294,8 @@ input::TouchInput::get_by_device_index(const std::shared_ptr& window, in const auto window_size = m_window->size(); - new_event.tfinger.x = x_percent + static_cast(point.x) / static_cast(window_size.x); - new_event.tfinger.y = y_percent + static_cast(point.y) / static_cast(window_size.y); + new_event.tfinger.x = x_percent + (static_cast(point.x) / static_cast(window_size.x)); + new_event.tfinger.y = y_percent + (static_cast(point.y) / static_cast(window_size.y)); return new_event; } diff --git a/src/ui/components/textinput.cpp b/src/ui/components/textinput.cpp index 2223980b..1c6cdfa2 100644 --- a/src/ui/components/textinput.cpp +++ b/src/ui/components/textinput.cpp @@ -231,9 +231,10 @@ ui::TextInput::handle_event( //NOLINT(readability-function-cognitive-complexity) if (ctrl_pressed) { const int result = SDL_SetClipboardText(m_text.c_str()); if (result != 0) { - throw helper::MinorError{ - fmt::format("failed in setting the clipboard text: {}", SDL_GetError()) - }; + utils::throw_( + helper::MinorError{ + fmt::format("failed in setting the clipboard text: {}", SDL_GetError()) } + ); } return true; } @@ -302,7 +303,8 @@ void ui::TextInput::recalculate_textures(bool text_changed) { if (text_changed) { - m_text_texture = renderer.get_texture_for_render_target(shapes::UPoint(1, 1) // this is a dummy point! + m_text_texture = renderer.get_texture_for_render_target( + shapes::UPoint(1, 1) // this is a dummy point! ); m_scaled_text_size = 0; } @@ -348,7 +350,7 @@ void ui::TextInput::recalculate_textures(bool text_changed) { const int result = TTF_SizeUTF8(m_font.get(), sub_string.c_str(), &width, &height); if (result < 0) { - throw helper::FatalError{ fmt::format("Error during SDL_TTF_SizeUTF8: {}", SDL_GetError()) }; + utils::throw_(helper::FatalError{ fmt::format("Error during SDL_TTF_SizeUTF8: {}", SDL_GetError()) }); } const double ratio_sub_string = static_cast(height) / static_cast(fill_rect().height()); @@ -414,7 +416,7 @@ bool ui::TextInput::add_string(const std::string& add) { // cursor_position is the range [0, length] (inclusively !) if (m_cursor_position > current_string_length) { - throw std::runtime_error("cursor_postion is invalid!"); + utils::throw_(std::runtime_error("cursor_postion is invalid!")); } std::string result{}; @@ -460,7 +462,7 @@ bool ui::TextInput::remove_at_cursor(RemoveMode remove_mode) { // cursor_position is the range [0, length] (inclusively !) if (m_cursor_position > current_string_length) { - throw std::runtime_error("cursor_postion is invalid!"); + utils::throw_( std::runtime_error("cursor_postion is invalid!")); } diff --git a/src/ui/layouts/tile_layout.cpp b/src/ui/layouts/tile_layout.cpp index 2a4baaa5..858a8cfe 100644 --- a/src/ui/layouts/tile_layout.cpp +++ b/src/ui/layouts/tile_layout.cpp @@ -11,7 +11,7 @@ void ui::TileLayout::render(const ServiceProvider& service_provider) const { [[nodiscard]] ui::Layout ui::TileLayout::get_layout_for_index(u32 index) { if (index >= this->m_size) { - throw std::runtime_error("TileLayout is already full"); + utils::throw_(std::runtime_error("TileLayout is already full")); } const auto start_point = layout().get_rect().top_left; From d8fbf890b76fea6bb9cfc2c7ae8eba14e45a2ae6 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 8 Aug 2026 20:54:42 +0200 Subject: [PATCH 092/112] feat: add uefi network requests and http implementation --- src/lobby/api.cpp | 11 +- src/lobby/curl_client.cpp | 5 +- src/lobby/uefi_client.cpp | 496 +++++++++++++++++++++++++++++--------- src/lobby/uefi_client.hpp | 46 +++- src/lobby/web_client.cpp | 7 +- 5 files changed, 436 insertions(+), 129 deletions(-) diff --git a/src/lobby/api.cpp b/src/lobby/api.cpp index 5adb8e38..481ff56c 100644 --- a/src/lobby/api.cpp +++ b/src/lobby/api.cpp @@ -63,7 +63,16 @@ helper::expected lobby::API::check_reachability() { } lobby::API::API(ServiceProvider* service_provider, const std::string& api_url) - : m_client{ std::make_unique(api_url) }, + : m_client{ + +#if defined(__UEFI__) + oopetris::http::implementation::ActualClient::construct(api_url) +#else + std::make_unique(api_url) + +#endif + + }, m_secret_storage{ std::make_unique(service_provider, secret::KeyringType::User) } { auto value = m_secret_storage->load(token::constants::api_token_key); diff --git a/src/lobby/curl_client.cpp b/src/lobby/curl_client.cpp index 22cf9231..5532adab 100644 --- a/src/lobby/curl_client.cpp +++ b/src/lobby/curl_client.cpp @@ -107,6 +107,7 @@ void oopetris::http::implementation::ActualClient::set_url(const std::string& ur auto [content, content_type] = payload.value(); + //TODO: set content_type m_session->SetBody(cpr::Body{ content }); return TRANSFORM_RESULT(m_session->Post()); @@ -123,7 +124,7 @@ void oopetris::http::implementation::ActualClient::set_url(const std::string& ur } auto [content, content_type] = payload.value(); - + //TODO: set content_type m_session->SetBody(cpr::Body{ content }); return TRANSFORM_RESULT(m_session->Put()); @@ -144,7 +145,7 @@ void oopetris::http::implementation::ActualClient::ResetBearerAuth() { #if CPR_LIBCURL_VERSION_NUM >= 0x073D00 - m_session->SetBearer(cpr::Bearer{""}); + m_session->SetBearer(cpr::Bearer{ "" }); #else m_session->SetHeader(); #endif diff --git a/src/lobby/uefi_client.cpp b/src/lobby/uefi_client.cpp index 8818665e..c2b4d31a 100644 --- a/src/lobby/uefi_client.cpp +++ b/src/lobby/uefi_client.cpp @@ -4,121 +4,268 @@ #include #include +#include +#include +#include -#define TRANSFORM_RESULT(result) std::make_unique((result)) //NOLINT(cppcoreguidelines-macro-usage +#include -namespace { - using FetchHeader = oopetris::http::implementation::details::FetchHeader; - - FetchHeader get_headers(const std::unique_ptr& request) { - - auto header_length = emscripten_fetch_get_response_headers_length(request.get()); - - auto* headersRawDst = new char[header_length + 1]; - emscripten_fetch_get_response_headers(request.get(), headersRawDst, header_length + 1); - - char** unpackedHeaders = emscripten_fetch_unpack_response_headers(headersRawDst); - - FetchHeader result{}; - - u32 i = 0; - while (true) { - auto* headerKey = unpackedHeaders[i]; - - if (headerKey == nullptr) { - break; - } +#define TRANSFORM_RESULT(result) \ + std::make_unique((result).first, (result).second) //NOLINT(cppcoreguidelines-macro-usage - auto* headerValue = unpackedHeaders[i + 1]; - if (headerValue == nullptr) { - //this is an error, since this has to be a valid char* - //TODO: report that properly - break; - } - - result.at(headerKey) = std::string{ headerValue }; +namespace { - i += 2; + using HttpHeaders = oopetris::http::implementation::details::HttpHeaders; + + [[nodiscard]] int map_status_code_enum(EFI_HTTP_STATUS_CODE code) { + switch (code) { + case HTTP_STATUS_UNSUPPORTED_STATUS: + return -1; + case HTTP_STATUS_100_CONTINUE: + return 100; + case HTTP_STATUS_101_SWITCHING_PROTOCOLS: + return 101; + case HTTP_STATUS_200_OK: + return 200; + case HTTP_STATUS_201_CREATED: + return 201; + case HTTP_STATUS_202_ACCEPTED: + return 202; + case HTTP_STATUS_203_NON_AUTHORITATIVE_INFORMATION: + return 203; + case HTTP_STATUS_204_NO_CONTENT: + return 204; + case HTTP_STATUS_205_RESET_CONTENT: + return 205; + case HTTP_STATUS_206_PARTIAL_CONTENT: + return 206; + case HTTP_STATUS_300_MULTIPLE_CHOICES: + return 300; + case HTTP_STATUS_301_MOVED_PERMANENTLY: + return 301; + case HTTP_STATUS_302_FOUND: + return 302; + case HTTP_STATUS_303_SEE_OTHER: + return 303; + case HTTP_STATUS_304_NOT_MODIFIED: + return 304; + case HTTP_STATUS_305_USE_PROXY: + return 305; + case HTTP_STATUS_307_TEMPORARY_REDIRECT: + return 307; + case HTTP_STATUS_400_BAD_REQUEST: + return 400; + case HTTP_STATUS_401_UNAUTHORIZED: + return 401; + case HTTP_STATUS_402_PAYMENT_REQUIRED: + return 402; + case HTTP_STATUS_403_FORBIDDEN: + return 403; + case HTTP_STATUS_404_NOT_FOUND: + return 404; + case HTTP_STATUS_405_METHOD_NOT_ALLOWED: + return 405; + case HTTP_STATUS_406_NOT_ACCEPTABLE: + return 406; + case HTTP_STATUS_407_PROXY_AUTHENTICATION_REQUIRED: + return 407; + case HTTP_STATUS_408_REQUEST_TIME_OUT: + return 408; + case HTTP_STATUS_409_CONFLICT: + return 409; + case HTTP_STATUS_410_GONE: + return 410; + case HTTP_STATUS_411_LENGTH_REQUIRED: + return 411; + case HTTP_STATUS_412_PRECONDITION_FAILED: + return 412; + case HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE: + return 413; + case HTTP_STATUS_414_REQUEST_URI_TOO_LARGE: + return 414; + case HTTP_STATUS_415_UNSUPPORTED_MEDIA_TYPE: + return 415; + case HTTP_STATUS_416_REQUESTED_RANGE_NOT_SATISFIED: + return 416; + case HTTP_STATUS_417_EXPECTATION_FAILED: + return 417; + case HTTP_STATUS_500_INTERNAL_SERVER_ERROR: + return 500; + case HTTP_STATUS_501_NOT_IMPLEMENTED: + return 501; + case HTTP_STATUS_502_BAD_GATEWAY: + return 502; + case HTTP_STATUS_503_SERVICE_UNAVAILABLE: + return 503; + case HTTP_STATUS_504_GATEWAY_TIME_OUT: + return 504; + case HTTP_STATUS_505_HTTP_VERSION_NOT_SUPPORTED: + return 505; + case HTTP_STATUS_308_PERMANENT_REDIRECT: + return 308; + case HTTP_STATUS_429_TOO_MANY_REQUESTS: + return 429; + default: + return -1; } - - delete[] headersRawDst; - - emscripten_fetch_free_unpacked_response_headers(unpackedHeaders); - - return result; } - // Specifies the readyState of the XHR request: - // 0: UNSENT: request not sent yet - // 1: OPENED: emscripten_fetch has been called. - // 2: HEADERS_RECEIVED: emscripten_fetch has been called, and headers and - // status are available. - // 3: LOADING: download in progress. - // 4: DONE: download finished. - // See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState - enum class FetchReadyState { - UNSENT = 0, - OPENED = 1, - HEADERS_RECEIVED = 2, - LOADING = 3, - DONE = 4, - }; - - const constexpr u32 max_method_size = 32; + [[nodiscard]] std::string map_efi_status_to_string(EFI_STATUS status) { + + switch (status) { + case EFI_SUCCESS: + return "SUCCESS"; + case EFI_LOAD_ERROR: + return "LOAD_ERROR"; + case EFI_INVALID_PARAMETER: + return "INVALID_PARAMETER"; + case EFI_UNSUPPORTED: + return "UNSUPPORTED"; + case EFI_BAD_BUFFER_SIZE: + return "BAD_BUFFER_SIZE"; + case EFI_BUFFER_TOO_SMALL: + return "BUFFER_TOO_SMALL"; + case EFI_NOT_READY: + return "NOT_READY"; + case EFI_DEVICE_ERROR: + return "DEVICE_ERROR"; + case EFI_WRITE_PROTECTED: + return "WRITE_PROTECTED"; + case EFI_OUT_OF_RESOURCES: + return "OUT_OF_RESOURCES"; + case EFI_VOLUME_CORRUPTED: + return "VOLUME_CORRUPTED"; + case EFI_VOLUME_FULL: + return "VOLUME_FULL"; + case EFI_NO_MEDIA: + return "NO_MEDIA"; + case EFI_MEDIA_CHANGED: + return "MEDIA_CHANGED"; + case EFI_NOT_FOUND: + return "NOT_FOUND"; + case EFI_ACCESS_DENIED: + return "ACCESS_DENIED"; + case EFI_NO_RESPONSE: + return "NO_RESPONSE"; + case EFI_NO_MAPPING: + return "NO_MAPPING"; + case EFI_TIMEOUT: + return "TIMEOUT"; + case EFI_NOT_STARTED: + return "NOT_STARTED"; + case EFI_ALREADY_STARTED: + return "ALREADY_STARTED"; + case EFI_ABORTED: + return "ABORTED"; + case EFI_ICMP_ERROR: + return "ICMP_ERROR"; + case EFI_TFTP_ERROR: + return "TFTP_ERROR"; + case EFI_PROTOCOL_ERROR: + return "PROTOCOL_ERROR"; + case EFI_INCOMPATIBLE_VERSION: + return "INCOMPATIBLE_VERSION"; + case EFI_SECURITY_VIOLATION: + return "SECURITY_VIOLATION"; + case EFI_CRC_ERROR: + return "CRC_ERROR"; + case EFI_END_OF_MEDIA: + return "END_OF_MEDIA"; + case EFI_END_OF_FILE: + return "END_OF_FILE"; + case EFI_INVALID_LANGUAGE: + return "INVALID_LANGUAGE"; + case EFI_COMPROMISED_DATA: + return "COMPROMISED_DATA"; + case EFI_IP_ADDRESS_CONFLICT: + return "IP_ADDRESS_CONFLICT"; + case EFI_HTTP_ERROR: + return "HTTP_ERROR"; + case EFI_WARN_UNKNOWN_GLYPH: + return "WARN_UNKNOWN_GLYPH"; + case EFI_WARN_DELETE_FAILURE: + return "WARN_DELETE_FAILURE"; + case EFI_WARN_WRITE_FAILURE: + return "WARN_WRITE_FAILURE"; + case EFI_WARN_BUFFER_TOO_SMALL: + return "WARN_BUFFER_TOO_SMALL"; + case EFI_WARN_STALE_DATA: + return "WARN_STALE_DATA"; + case EFI_WARN_FILE_SYSTEM: + return "WARN_FILE_SYSTEM"; + case EFI_WARN_RESET_REQUIRED: + return "WARN_RESET_REQUIRED"; + default: + return ""; + } + } } // namespace +oopetris::http::implementation::ActualResult::ActualResult( + HTTP_IO_RESPONSE_DATA&& response, + std::unique_ptr&& io +) + : m_response{ std::move(response) }, + m_io{ std::move(io) } { } -oopetris::http::implementation::ActualResult::ActualResult(std::unique_ptr&& request) - : m_request{ std::move(request) }, - m_response_headers{ get_headers(m_request) } { } oopetris::http::implementation::ActualResult::~ActualResult() { - if (m_request) { - emscripten_fetch_close(m_request.get()); + if (m_io == nullptr) { + HttpIoDestroyIo(m_io.get()); + m_io = nullptr; } }; oopetris::http::implementation::ActualResult::ActualResult(ActualResult&& other) noexcept - : m_request{ std::move(other.m_request) }, - m_response_headers{ std::move(other.m_response_headers) } { } + : m_response{ std::move(other.m_response) }, + m_io{ std::move(other.m_io) } { + other.m_io = nullptr; +} -[[nodiscard]] std::optional oopetris::http::implementation::ActualResult::get_header(const std::string& key +[[nodiscard]] std::optional oopetris::http::implementation::ActualResult::get_header( + const std::string& key ) const { - if (m_response_headers.contains(key)) { - return std::nullopt; + for (size_t i = 0; i < m_response.HeaderCount; ++i) { + const EFI_HTTP_HEADER& header = m_response.Headers[i]; + if (header.FieldName == key) { + return std::string{ header.FieldValue }; + } } - return m_response_headers.at(key); + return std::nullopt; } [[nodiscard]] std::string oopetris::http::implementation::ActualResult::body() const { - auto size = m_request->numBytes; + if (m_response.Body == nullptr) { + return ""; + } + - std::string result{ m_request->data, m_request->data + size }; + std::string result{ m_response.Body, m_response.Body + m_response.BodyLength }; return result; } [[nodiscard]] int oopetris::http::implementation::ActualResult::status() const { - return m_request->status; + return map_status_code_enum(m_response.Response.StatusCode); } [[nodiscard]] std::optional oopetris::http::implementation::ActualResult::get_error() const { - auto readyState = static_cast(m_request->readyState); - if (readyState != FetchReadyState::DONE) { - return fmt::format("Invalid readyState: {}", magic_enum::enum_name(readyState)); + if (m_response.Status != EFI_SUCCESS) { + return fmt::format("Invalid EFI status: {}", map_efi_status_to_string(m_response.Status)); } return std::nullopt; } namespace { - using FetchData = std::pair; + using HttpData = std::pair; + using RequestResponse = std::pair>; std::string normalize_url(const std::string& value) { if (value.ends_with("/")) { @@ -136,74 +283,192 @@ namespace { return normalized_base + "/" + value; } - std::unique_ptr make_request_impl( - const std::string& method, + CHAR16* ToChar16(const std::string& Str) { + CHAR16* Result = (CHAR16*) AllocateZeroPool((Str.size() + 1) * sizeof(CHAR16)); + + if (Result == nullptr) { + return nullptr; + } + + for (size_t i = 0; i < Str.size(); ++i) { + Result[i] = (CHAR16) (UINT8) Str[i]; + } + + return Result; + } + + RequestResponse make_request_impl( + EFI_HTTP_METHOD method, const std::string& url, - const FetchHeader& header, - const std::optional& data + const HttpHeaders& header, + const std::optional& data, + EFI_HANDLE image_handle, + EFI_HANDLE controller_handle ) { - emscripten_fetch_attr_t attr{}; - emscripten_fetch_attr_init(&attr); - ASSERT(method.size() <= (max_method_size - 1)); - std::memcpy(attr.requestMethod, method.c_str(), method.size() + 1); - //TODO(Totto): once the http Implementation "Interface" support async thing, use that: - // see: https://emscripten.org/docs/api_reference/fetch.html#synchronous-fetches + std::unique_ptr HttpIo = std::make_unique(); + HTTP_IO_CONFIG_DATA ConfigData; + EFI_HTTP_REQUEST_DATA Request; + + HTTP_IO_RESPONSE_DATA Response; - attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY | EMSCRIPTEN_FETCH_SYNCHRONOUS; + ZeroMem(HttpIo.get(), sizeof(HttpIo)); + ZeroMem(&ConfigData, sizeof(ConfigData)); + ZeroMem(&Request, sizeof(Request)); + ZeroMem(&Response, sizeof(Response)); - std::vector raw_headers{}; + ConfigData.Config4.HttpVersion = HttpVersion11; + ConfigData.Config4.RequestTimeOut = 5000; + ConfigData.Config4.ResponseTimeOut = 5000; + ConfigData.Config4.UseDefaultAddress = TRUE; + ConfigData.Config4.LocalPort = 0; + + EFI_STATUS Status = + HttpIoCreateIo(image_handle, controller_handle, IP_VERSION_4, &ConfigData, NULL, NULL, HttpIo.get()); + if (EFI_ERROR(Status)) { + Response.Status = Status; + return RequestResponse{ Response, std::move(HttpIo) }; + } + + Request.Method = method; + Request.Url = ToChar16(url.c_str()); + + if (Request.Url == nullptr) { + Response.Status = EFI_OUT_OF_RESOURCES; + return RequestResponse{ Response, std::move(HttpIo) }; + } + + std::vector raw_headers{}; for (const auto& [key, value] : header) { - raw_headers.push_back(key.c_str()); - raw_headers.push_back(value.c_str()); + raw_headers.push_back(EFI_HTTP_HEADER{ strdup(key.c_str()), strdup(value.c_str()) }); } - raw_headers.push_back(nullptr); - attr.requestHeaders = raw_headers.data(); + UINTN BodyLength = 0; + VOID* Body = NULL; if (data.has_value()) { const auto& [mime_type, raw_data] = data.value(); - attr.overriddenMimeType = mime_type.c_str(); - attr.requestData = raw_data.c_str(); - attr.requestDataSize = raw_data.size(); + Body = const_cast(raw_data.data()); + BodyLength = raw_data.size(); + raw_headers.push_back(EFI_HTTP_HEADER{ strdup("Content-Type"), strdup(mime_type.c_str()) }); + } + + UINTN HeaderCount = raw_headers.size(); + EFI_HTTP_HEADER* Headers = raw_headers.data(); + + Status = HttpIoSendRequest(HttpIo.get(), &Request, HeaderCount, Headers, BodyLength, Body); + if (EFI_ERROR(Status)) { + Response.Status = Status; + return RequestResponse{ Response, std::move(HttpIo) }; } - emscripten_fetch_t* result = emscripten_fetch(&attr, url.c_str()); + //TODO: I am not sure who allocates the body here? do in eed to set bodylength and allocate body and make this call again with FALSE and new space? + + Status = HttpIoRecvResponse(HttpIo.get(), TRUE, &Response); + if (EFI_ERROR(Status)) { + Response.Status = Status; + return RequestResponse{ Response, std::move(HttpIo) }; + } - return std::unique_ptr(result); + for (const auto& raw_header : raw_headers) { + free(raw_header.FieldName); + free(raw_header.FieldValue); + } + + FreePool(Request.Url); + + + return RequestResponse{ Response, std::move(HttpIo) }; } - std::unique_ptr - make_request(const std::string& method, const std::string& url, const FetchHeader& header) { - return make_request_impl(method, url, header, std::nullopt); + RequestResponse make_request( + EFI_HTTP_METHOD method, + const std::string& url, + const HttpHeaders& header, + EFI_HANDLE image_handle, + EFI_HANDLE controller_handle + ) { + return make_request_impl(method, url, header, std::nullopt, image_handle, controller_handle); } - std::unique_ptr make_request_with_data( - const std::string& method, + RequestResponse make_request_with_data( + EFI_HTTP_METHOD method, const std::string& url, - const FetchHeader& header, - const FetchData& data + const HttpHeaders& header, + const HttpData& data, + EFI_HANDLE image_handle, + EFI_HANDLE controller_handle ) { - return make_request_impl(method, url, header, data); + return make_request_impl(method, url, header, data, image_handle, controller_handle); } } // namespace oopetris::http::implementation::ActualClient::ActualClient(ActualClient&& other) noexcept : m_base_url{ std::move(other.m_base_url) }, - m_headers{ std::move(other.m_headers) } { } + m_headers{ std::move(other.m_headers) }, + m_image_handle{ std::move(other.m_image_handle) }, + m_controller_handle{ std::move(other.m_controller_handle) } { } oopetris::http::implementation::ActualClient::~ActualClient() = default; -oopetris::http::implementation::ActualClient::ActualClient(const std::string& api_url) +oopetris::http::implementation::ActualClient::ActualClient( + const std::string& api_url, + EFI_HANDLE image_handle, + EFI_HANDLE controller_handle +) : m_base_url{ normalize_url(api_url) }, - m_headers{} { + m_headers{}, + m_image_handle{ image_handle }, + m_controller_handle{ controller_handle } { + + //NOTE: no Accept header or compression is set here, as uefi http request doesn't support gzip (at least I think it doesn#t support it) +} + +static EFI_STATUS FindNetworkController(OUT EFI_HANDLE* Controller) { + EFI_HANDLE* Handles = NULL; + UINTN HandleCount = 0; + + EFI_STATUS Status = gBS->LocateHandleBuffer( + ByProtocol, &gEfiManagedNetworkServiceBindingProtocolGuid, NULL, &HandleCount, &Handles + ); + + if (EFI_ERROR(Status)) { + return Status; + } + + if (HandleCount == 0) { + FreePool(Handles); + return EFI_NOT_FOUND; + } + + // + // For now, just use the first network controller. + // + *Controller = Handles[0]; - //NOTE: no Accept header or compression is set here, as emscriptens fetch does provide reasonable defaults (depending on what the browser supports) + FreePool(Handles); + + return EFI_SUCCESS; +} + +OOPETRIS_GRAPHICS_EXPORTED std::unique_ptr +oopetris::http::implementation::ActualClient::construct(const std::string& api_url) { + EFI_HANDLE controller_handle = nullptr; + EFI_STATUS status = FindNetworkController(&controller_handle); + + if (EFI_ERROR(status)) { + utils::throw_( + std::runtime_error{ + fmt::format("couldn't get network controller: {}", map_efi_status_to_string(status)) } + ); + } + + return std::make_unique(api_url, gImageHandle, controller_handle); } [[nodiscard]] std::unique_ptr oopetris::http::implementation::ActualClient::Get( @@ -212,7 +477,7 @@ oopetris::http::implementation::ActualClient::ActualClient(const std::string& ap const auto final_url = concat_url(m_base_url, url); - return TRANSFORM_RESULT(make_request("GET", final_url, m_headers)); + return TRANSFORM_RESULT(make_request(HttpMethodGet, final_url, m_headers, m_image_handle, m_controller_handle)); } [[nodiscard]] std::unique_ptr oopetris::http::implementation::ActualClient::Delete( @@ -220,7 +485,7 @@ oopetris::http::implementation::ActualClient::ActualClient(const std::string& ap ) { const auto final_url = concat_url(m_base_url, url); - return TRANSFORM_RESULT(make_request("DELETE", final_url, m_headers)); + return TRANSFORM_RESULT(make_request(HttpMethodDelete, final_url, m_headers, m_image_handle, m_controller_handle)); } [[nodiscard]] std::unique_ptr oopetris::http::implementation::ActualClient::Post( @@ -230,12 +495,14 @@ oopetris::http::implementation::ActualClient::ActualClient(const std::string& ap const auto final_url = concat_url(m_base_url, url); if (not payload.has_value()) { - return TRANSFORM_RESULT(make_request("POST", final_url, m_headers)); + return TRANSFORM_RESULT( + make_request(HttpMethodPost, final_url, m_headers, m_image_handle, m_controller_handle) + ); } - auto [content, content_type] = payload.value(); - - return TRANSFORM_RESULT(make_request_with_data("POST", final_url, m_headers, payload.value())); + return TRANSFORM_RESULT(make_request_with_data( + HttpMethodPost, final_url, m_headers, payload.value(), m_image_handle, m_controller_handle + )); } [[nodiscard]] std::unique_ptr oopetris::http::implementation::ActualClient::Put( @@ -245,12 +512,13 @@ oopetris::http::implementation::ActualClient::ActualClient(const std::string& ap const auto final_url = concat_url(m_base_url, url); if (not payload.has_value()) { - return TRANSFORM_RESULT(make_request("PUT", final_url, m_headers)); + return TRANSFORM_RESULT(make_request(HttpMethodPut, final_url, m_headers, m_image_handle, m_controller_handle)); } - auto [content, content_type] = payload.value(); - return TRANSFORM_RESULT(make_request_with_data("PUT", final_url, m_headers, payload.value())); + return TRANSFORM_RESULT(make_request_with_data( + HttpMethodPut, final_url, m_headers, payload.value(), m_image_handle, m_controller_handle + )); } void oopetris::http::implementation::ActualClient::SetBearerAuth(const std::string& token) { diff --git a/src/lobby/uefi_client.hpp b/src/lobby/uefi_client.hpp index 37d88cd2..99e2ce60 100644 --- a/src/lobby/uefi_client.hpp +++ b/src/lobby/uefi_client.hpp @@ -1,6 +1,20 @@ #pragma once + +#if defined(__GNUC__) +#pragma GCC diagnostic push +//TODO +//#pragma GCC diagnostic ignored "-fpermissive" + +#endif + +extern "C" { +#include + +#include +} + //this i needed to mix stdlib and openssl / crypto / tls libraries #undef NTOHL @@ -8,25 +22,33 @@ #undef NTOHS #undef HTONS -#include +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif -#include "./client.hpp" -#include +#include "./client.hpp" +#include +#include namespace oopetris::http::implementation { namespace details { - using HttpHeaders = std::vector; - } + using HttpHeaders = std::unordered_map; + } // namespace details struct ActualResult : ::oopetris::http::Result { private: HTTP_IO_RESPONSE_DATA m_response; + std::unique_ptr m_io; + public: - OOPETRIS_GRAPHICS_EXPORTED explicit ActualResult(HTTP_IO_RESPONSE_DATA&& response); + OOPETRIS_GRAPHICS_EXPORTED explicit ActualResult( + HTTP_IO_RESPONSE_DATA&& response, + std::unique_ptr&& io + ); OOPETRIS_GRAPHICS_EXPORTED ~ActualResult() override; @@ -53,6 +75,8 @@ namespace oopetris::http::implementation { private: std::string m_base_url; details::HttpHeaders m_headers; + EFI_HANDLE m_image_handle; + EFI_HANDLE m_controller_handle; public: OOPETRIS_GRAPHICS_EXPORTED ActualClient(ActualClient&& other) noexcept; @@ -63,7 +87,15 @@ namespace oopetris::http::implementation { OOPETRIS_GRAPHICS_EXPORTED ~ActualClient() override; - OOPETRIS_GRAPHICS_EXPORTED explicit ActualClient(const std::string& api_url); + OOPETRIS_GRAPHICS_EXPORTED explicit ActualClient( + const std::string& api_url, + EFI_HANDLE image_handle, + EFI_HANDLE controller_handle + ); + + OOPETRIS_GRAPHICS_EXPORTED static std::unique_ptr construct( + const std::string& api_url + ); [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::unique_ptr Get(const std::string& url) override; diff --git a/src/lobby/web_client.cpp b/src/lobby/web_client.cpp index bac2dac3..38e1bdfb 100644 --- a/src/lobby/web_client.cpp +++ b/src/lobby/web_client.cpp @@ -89,7 +89,8 @@ oopetris::http::implementation::ActualResult::ActualResult(ActualResult&& other) : m_request{ std::move(other.m_request) }, m_response_headers{ std::move(other.m_response_headers) } { } -[[nodiscard]] std::optional oopetris::http::implementation::ActualResult::get_header(const std::string& key +[[nodiscard]] std::optional oopetris::http::implementation::ActualResult::get_header( + const std::string& key ) const { if (m_response_headers.contains(key)) { return std::nullopt; @@ -239,8 +240,6 @@ oopetris::http::implementation::ActualClient::ActualClient(const std::string& ap return TRANSFORM_RESULT(make_request("POST", final_url, m_headers)); } - auto [content, content_type] = payload.value(); - return TRANSFORM_RESULT(make_request_with_data("POST", final_url, m_headers, payload.value())); } @@ -254,8 +253,6 @@ oopetris::http::implementation::ActualClient::ActualClient(const std::string& ap return TRANSFORM_RESULT(make_request("PUT", final_url, m_headers)); } - auto [content, content_type] = payload.value(); - return TRANSFORM_RESULT(make_request_with_data("PUT", final_url, m_headers, payload.value())); } From fced5458580a50b35bf2f42db6bed44811ee66ed Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 8 Aug 2026 20:56:36 +0200 Subject: [PATCH 093/112] fix: fix small uefi error --- src/graphics/window.cpp | 6 ++++-- src/lobby/uefi_client.cpp | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/graphics/window.cpp b/src/graphics/window.cpp index 72d8368f..20a98b45 100644 --- a/src/graphics/window.cpp +++ b/src/graphics/window.cpp @@ -3,6 +3,8 @@ #include #include +#include + Window::Window(const std::string& title, WindowPosition position, u32 width, u32 height) : Window{ title, static_cast(position), static_cast(position), width, height } { } @@ -24,11 +26,11 @@ Window::Window(const std::string& title, u32 x_pos, u32 y_pos) { SDL_DisplayMode mode{}; const int result = SDL_GetCurrentDisplayMode(0, &mode); if (result != 0) { - throw std::runtime_error{ "failed in getting display mode: " + std::string{ SDL_GetError() } }; + utils::throw_(std::runtime_error{ "failed in getting display mode: " + std::string{ SDL_GetError() } }); } m_window = SDL_CreateWindow(title.c_str(), static_cast(x_pos), static_cast(y_pos), mode.w, mode.h, 0); if (m_window == nullptr) { - throw std::runtime_error{ "failed in creating window: " + std::string{ SDL_GetError() } }; + utils::throw_(std::runtime_error{ "failed in creating window: " + std::string{ SDL_GetError() } }); } } diff --git a/src/lobby/uefi_client.cpp b/src/lobby/uefi_client.cpp index c2b4d31a..68307c07 100644 --- a/src/lobby/uefi_client.cpp +++ b/src/lobby/uefi_client.cpp @@ -352,7 +352,7 @@ namespace { if (data.has_value()) { const auto& [mime_type, raw_data] = data.value(); - Body = const_cast(raw_data.data()); + Body = const_cast(raw_data.data()); BodyLength = raw_data.size(); raw_headers.push_back(EFI_HTTP_HEADER{ strdup("Content-Type"), strdup(mime_type.c_str()) }); } From 63acf6ff9eb1f651dde6714bb6312e3839fb540c Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 8 Aug 2026 21:05:15 +0200 Subject: [PATCH 094/112] fix: detect language for CC_FLAGS and set the appropriate flags for uefi --- platforms/uefi/extract-definitions.sh | 29 ++++++++++++++++++--------- src/lobby/uefi_client.hpp | 10 ++++++++- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 4fd0fd5b..49b9f710 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -282,21 +282,32 @@ fi MESON_TARGETS_INFO_LIB_COMPILER_TARGET="${MESON_TARGETS_INFO_LIB_COMPILER_TARGETS[0]}" +MESON_TARGETS_INFO_LIB_LANGUAGE="$(echo "$MESON_TARGETS_INFO_LIB_COMPILER_TARGET" | jq -M -r -c ".[\"language\"]")" + +FLAGS_TARGET="CC" + +if [ "$MESON_TARGETS_INFO_LIB_LANGUAGE" == "cpp" ]; then + FLAGS_TARGET="CXX" +elif [ "$MESON_TARGETS_INFO_LIB_LANGUAGE" == "c" ]; then + FLAGS_TARGET="CC" +else + echo "Error: invalid meson target language: $MESON_TARGETS_INFO_LIB_LANGUAGE" >&2 + exit 2 +fi + mapfile -t MESON_TARGETS_INFO_LIB_PARAMATERS < <(echo "$MESON_TARGETS_INFO_LIB_COMPILER_TARGET" | jq '.["parameters"][]' -M -r -c) for MESON_TARGETS_INFO_LIB_PARAMATER in "${MESON_TARGETS_INFO_LIB_PARAMATERS[@]}"; do case "$MESON_TARGETS_INFO_LIB_PARAMATER" in -I*) - #TODO: if it is cpp this should be modified to CXX_FLAGS DEP_INCLUDES+=("${MESON_TARGETS_INFO_LIB_PARAMATER:2}") ;; -W*) # TODO: include warnings ;; -nostdinc | -nostdinc++ | -nodefaultlibs | -D* | --sysroot=* | -isystem*) - #TODO: if it is cpp this should be modified to CXX_FLAGS - DEP_BUILD_OPTIONS+=("*_*_*_CC_FLAGS = \"${MESON_TARGETS_INFO_LIB_PARAMATER}\"") + DEP_BUILD_OPTIONS+=("*_*_*_${FLAGS_TARGET}_FLAGS = \"${MESON_TARGETS_INFO_LIB_PARAMATER}\"") ;; -t:use-lib:pkg=*) DEP_PACKAGE_NAME="${MESON_TARGETS_INFO_LIB_PARAMATER:15}" @@ -321,7 +332,7 @@ for MESON_TARGETS_INFO_LIB_PARAMATER in "${MESON_TARGETS_INFO_LIB_PARAMATERS[@]} # ignore pthread ;; -f* | -m*) - DEP_BUILD_OPTIONS+=("*_*_*_CC_FLAGS = \"${MESON_TARGETS_INFO_LIB_PARAMATER}\"") + DEP_BUILD_OPTIONS+=("*_*_*_${FLAGS_TARGET}_FLAGS = \"${MESON_TARGETS_INFO_LIB_PARAMATER}\"") ;; -g | -std=* | -O*) #ignore @@ -340,7 +351,7 @@ elif [ "$MESON_TARGETS_INFO_LIB_TYPE" == "executable" ] || [ "$MESON_TARGETS_INF echo "TODO" # exit 34 else - echo "Error: invalid meson target type fo '$SOURCE_FILE_ENTRY_MESON_NAME': $MESON_TARGETS_INFO_LIB_TYPE" >&2 + echo "Error: invalid meson target type for '$SOURCE_FILE_ENTRY_MESON_NAME': $MESON_TARGETS_INFO_LIB_TYPE" >&2 exit 2 fi @@ -359,8 +370,7 @@ if [ "$MAPPING_TYPE" == "application" ]; then # add include directories to the build options (as the files build inside the application need that) for DEP_INCLUDE in "${DEP_INCLUDES[@]}"; do - #TODO: if it is cpp this should be modified to CXX_FLAGS - DEP_BUILD_OPTIONS+=("*_*_*_CC_FLAGS = \"-I${DEP_INCLUDE}\"") + DEP_BUILD_OPTIONS+=("*_*_*_${FLAGS_TARGET}_FLAGS = \"-I${DEP_INCLUDE}\"") done validate_parent_dir "$DEST_FILE" @@ -413,8 +423,7 @@ elif [ "$MAPPING_TYPE" == "library" ]; then # NOTE: we also define these as [Include], which is not entirely correct, but it didn't lead to problems until now # TODO: ^ these should be private include dirs not public ones for DEP_INCLUDE in "${DEP_INCLUDES[@]}"; do - #TODO: if it is cpp this should be modified to CXX_FLAGS - DEP_BUILD_OPTIONS+=("*_*_*_CC_FLAGS = \"-I${DEP_INCLUDE}\"") + DEP_BUILD_OPTIONS+=("*_*_*_${FLAGS_TARGET}_FLAGS = \"-I${DEP_INCLUDE}\"") done # add custom options, that override fix dependencies @@ -424,7 +433,7 @@ elif [ "$MAPPING_TYPE" == "library" ]; then mapfile -t MAPPING_OPTIONS_ENTRIES < <(echo "$MAPPING_OPTIONS" | jq -e '.[]' -M -r -c) for MAPPING_OPTIONS_ENTRY in "${MAPPING_OPTIONS_ENTRIES[@]}"; do - DEP_BUILD_OPTIONS+=("*_*_*_CC_FLAGS = \"${MAPPING_OPTIONS_ENTRY}\"") + DEP_BUILD_OPTIONS+=("*_*_*_${FLAGS_TARGET}_FLAGS = \"${MAPPING_OPTIONS_ENTRY}\"") done fi diff --git a/src/lobby/uefi_client.hpp b/src/lobby/uefi_client.hpp index 99e2ce60..e9f92400 100644 --- a/src/lobby/uefi_client.hpp +++ b/src/lobby/uefi_client.hpp @@ -12,10 +12,18 @@ extern "C" { #include + +//this is needed to mix stdlib and openssl / crypto / tls libraries + +#undef NTOHL +#undef HTONL +#undef NTOHS +#undef HTONS + #include } -//this i needed to mix stdlib and openssl / crypto / tls libraries +//this is needed to mix stdlib and openssl / crypto / tls libraries #undef NTOHL #undef HTONL From f1876ac8e73e5e39e58af2f09ec306be82cc6f2f Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 8 Aug 2026 21:10:49 +0200 Subject: [PATCH 095/112] feat: more exception cleanup for uefi --- src/executables/game/application.cpp | 14 +++++++++++--- src/executables/game/main.cpp | 17 +++++++++++------ src/executables/game/parser.cpp | 5 +++++ 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/executables/game/application.cpp b/src/executables/game/application.cpp index 6a7c8343..e357bca4 100644 --- a/src/executables/game/application.cpp +++ b/src/executables/game/application.cpp @@ -32,7 +32,7 @@ namespace { - [[nodiscard]] helper::MessageBox::Type get_notification_level(helper::error::Severity severity) { + [[nodiscard]] [[maybe_unused]] helper::MessageBox::Type get_notification_level(helper::error::Severity severity) { return severity == helper::error::Severity::Fatal ? helper::MessageBox::Type::Error : severity == helper::error::Severity::Major ? helper::MessageBox::Type::Warning : helper::MessageBox::Type::Information; @@ -96,7 +96,12 @@ helper::LoadingInfo::LoadingInfo( return m_load_everything_thread; } -Application::Application(std::shared_ptr&& window, CommandLineArguments&& arguments) try +Application::Application(std::shared_ptr&& window, CommandLineArguments&& arguments) + +#if !defined(__OOPETRIS_NO_EXCEPTIONS) + try +#endif + : m_command_line_arguments{ std::move(arguments) }, m_window{ std::move(window) }, m_renderer{ *m_window, m_command_line_arguments.target_fps.has_value() ? Renderer::VSync::Disabled @@ -372,7 +377,9 @@ void Application::update() { for (usize i = 0; i < num_scenes; ++i) { const auto index = num_scenes - i - 1; +#if !defined(__OOPETRIS_NO_EXCEPTIONS) try { +#endif auto [scene_update, scene_change] = m_scene_stack.at(index)->update(); if (scene_change) { @@ -424,7 +431,7 @@ void Application::update() { // if an error occurred on: // - creation: the creation wasn't finished, so just not pushing / switching to the scene // -update: the update failed in the middle, and the scene, that caused the error, has to make sure, that ignoring it, (and not crashing) resets the state, so that this doesn't occur on every frame - +#if !defined(__OOPETRIS_NO_EXCEPTIONS) } catch (const std::runtime_error& error) { m_window->show_simple(helper::MessageBox::Type::Error, "Error on Scene Initialization", error.what()); } catch (const helper::GeneralError& general_error) { @@ -432,6 +439,7 @@ void Application::update() { m_window->show_simple(notification_level, "Error on Scene Initialization", general_error.message()); } +#endif } #if defined(_HAVE_DISCORD_SOCIAL_SDK) diff --git a/src/executables/game/main.cpp b/src/executables/game/main.cpp index 8ea2ae0b..adc2fa36 100644 --- a/src/executables/game/main.cpp +++ b/src/executables/game/main.cpp @@ -94,8 +94,9 @@ namespace { std::shared_ptr window{ nullptr }; +#if !defined(__OOPETRIS_NO_EXCEPTIONS) try { - +#endif initialize_spdlog(); std::vector arguments_vector{}; @@ -120,18 +121,21 @@ namespace { [[maybe_unused]] constexpr auto window_name = constants::program_name.c_str(); - +#if !defined(__OOPETRIS_NO_EXCEPTIONS) try { +#endif #if defined(__ANDROID__) or defined(__CONSOLE__) or defined(__SERENITY__) or defined(__EMSCRIPTEN__) window = std::make_shared(window_name, WindowPosition::Centered); #else - [[maybe_unused]] static constexpr int width = 1280; - [[maybe_unused]] static constexpr int height = 720; - window = std::make_shared(window_name, WindowPosition::Centered, width, height); + [[maybe_unused]] static constexpr int width = 1280; + [[maybe_unused]] static constexpr int height = 720; + window = std::make_shared(window_name, WindowPosition::Centered, width, height); #endif +#if !defined(__OOPETRIS_NO_EXCEPTIONS) } catch (const helper::GeneralError& general_error) { spdlog::error("Couldn't initialize window: {}", general_error.message()); } +#endif if (window == nullptr) { helper::MessageBox::show_simple( @@ -144,7 +148,7 @@ namespace { app.run(); return EXIT_SUCCESS; - +#if !defined(__OOPETRIS_NO_EXCEPTIONS) } catch (const helper::GeneralError& general_error) { spdlog::error("{}", general_error.message()); @@ -167,6 +171,7 @@ namespace { std::cerr << error.what(); return EXIT_FAILURE; } +#endif } diff --git a/src/executables/game/parser.cpp b/src/executables/game/parser.cpp index e855ab28..af69fe0d 100644 --- a/src/executables/game/parser.cpp +++ b/src/executables/game/parser.cpp @@ -22,7 +22,10 @@ helper::expected helper::parse_args(const std .scan<'i', CommandLineArguments::Level>() .default_value(CommandLineArguments::default_starting_level); parser.add_argument("-s", "--silent").help("disable audio output").default_value(false).implicit_value(true); + +#if !defined(__OOPETRIS_NO_EXCEPTIONS) try { +#endif parser.parse_args(arguments); CommandLineArguments result{ std::nullopt, std::nullopt }; @@ -63,7 +66,9 @@ helper::expected helper::parse_args(const std result.silent = parser.get("--silent"); return result; +#if !defined(__OOPETRIS_NO_EXCEPTIONS) } catch (const std::exception& error) { return helper::unexpected{ error.what() }; } +#endif } From 805027d367307d6e79232149cbca6aec0662cd8e Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 8 Aug 2026 21:20:35 +0200 Subject: [PATCH 096/112] feat: exclude argparse for uefi, as we don't need to parse arguments and it used many exception based things ( throw and catch) --- src/executables/game/parser.cpp | 12 ++++++++---- src/executables/utility/command_line_arguments.hpp | 3 +++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/executables/game/parser.cpp b/src/executables/game/parser.cpp index af69fe0d..48d09968 100644 --- a/src/executables/game/parser.cpp +++ b/src/executables/game/parser.cpp @@ -10,10 +10,15 @@ #include "helper/spdlog_wrapper.hpp" -#include +#if !defined(__UEFI__) +#include +#endif helper::expected helper::parse_args(const std::vector& arguments) { +#if defined(__UEFI__) + return CommandLineArguments{ std::nullopt, std::nullopt }; +#else argparse::ArgumentParser parser{ constants::program_name, constants::version, argparse::default_arguments::all }; parser.add_argument("-r", "--recording").help("the path of a recorded game used for replay"); parser.add_argument("-f", "--target-fps").help("the number of simulation steps per second").scan<'i', u32>(); @@ -23,9 +28,8 @@ helper::expected helper::parse_args(const std .default_value(CommandLineArguments::default_starting_level); parser.add_argument("-s", "--silent").help("disable audio output").default_value(false).implicit_value(true); -#if !defined(__OOPETRIS_NO_EXCEPTIONS) try { -#endif + parser.parse_args(arguments); CommandLineArguments result{ std::nullopt, std::nullopt }; @@ -66,7 +70,7 @@ helper::expected helper::parse_args(const std result.silent = parser.get("--silent"); return result; -#if !defined(__OOPETRIS_NO_EXCEPTIONS) + } catch (const std::exception& error) { return helper::unexpected{ error.what() }; } diff --git a/src/executables/utility/command_line_arguments.hpp b/src/executables/utility/command_line_arguments.hpp index 58871af4..5fbe23e6 100644 --- a/src/executables/utility/command_line_arguments.hpp +++ b/src/executables/utility/command_line_arguments.hpp @@ -2,7 +2,10 @@ #include +#if !defined(__UEFI__) #include +#endif + #include #include #include From 4eee1b1da1a1acee4fd18fa21859f3c70f9366f6 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 8 Aug 2026 21:34:37 +0200 Subject: [PATCH 097/112] feat: add debug sink for spdlog for uefi --- src/executables/game/main.cpp | 7 ++++++ src/helper/meson.build | 2 ++ src/helper/uefi_utils.cpp | 40 +++++++++++++++++++++++++++++++++++ src/helper/uefi_utils.hpp | 27 +++++++++++++++++++++++ src/helper/web_utils.cpp | 2 +- 5 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 src/helper/uefi_utils.cpp create mode 100644 src/helper/uefi_utils.hpp diff --git a/src/executables/game/main.cpp b/src/executables/game/main.cpp index adc2fa36..4d4acaae 100644 --- a/src/executables/game/main.cpp +++ b/src/executables/game/main.cpp @@ -24,6 +24,11 @@ #include "helper/console_helpers.hpp" #endif +#if defined(__UEFI__) +#include "helper/uefi_utils.hpp" +#endif + + #if defined(__EMSCRIPTEN__) #include "helper/web_utils.hpp" #endif @@ -52,6 +57,8 @@ namespace { sinks.push_back(std::make_shared(constants::program_name.c_str())); #elif defined(__CONSOLE__) sinks.push_back(std::make_shared()); +#elif defined(__UEFI__) + sinks.push_back(uefi::get_debug_sink()); #elif defined(__EMSCRIPTEN__) sinks.push_back(web::get_console_sink()); #else diff --git a/src/helper/meson.build b/src/helper/meson.build index 49f745a0..3a47c129 100644 --- a/src/helper/meson.build +++ b/src/helper/meson.build @@ -14,6 +14,8 @@ graphics_src_files += files( 'platform.cpp', 'platform.hpp', 'spdlog_wrapper.hpp', + 'uefi_utils.cpp', + 'uefi_utils.hpp', 'web_utils.cpp', 'web_utils.hpp', ) diff --git a/src/helper/uefi_utils.cpp b/src/helper/uefi_utils.cpp new file mode 100644 index 00000000..fa1c3057 --- /dev/null +++ b/src/helper/uefi_utils.cpp @@ -0,0 +1,40 @@ + + +#if defined(__UEFI__) + +#include + +#include "./uefi_utils.hpp" + +#include +#include + + +std::shared_ptr uefi::get_debug_sink() { + return std::make_shared([](const spdlog::details::log_msg& msg) { + const auto message = std::string{ msg.payload.begin(), msg.payload.end() }; + + switch (msg.level) { + case spdlog::level::off: + return; + case spdlog::level::trace: + case spdlog::level::debug: + DebugPrint(DEBUG_VERBOSE, "%s", message); + break; + case spdlog::level::info: + DebugPrint(DEBUG_INFO, "%s", message); + break; + case spdlog::level::warn: + DebugPrint(DEBUG_WARN, "%s", message); + break; + case spdlog::level::err: + case spdlog::level::critical: + DebugPrint(DEBUG_ERROR, "%s", message); + break; + default: + return; + } + }); +} + +#endif diff --git a/src/helper/uefi_utils.hpp b/src/helper/uefi_utils.hpp new file mode 100644 index 00000000..6d5971ca --- /dev/null +++ b/src/helper/uefi_utils.hpp @@ -0,0 +1,27 @@ + + +#pragma once + + +#if !defined(__UEFI__) +#error "this header is for uefi only" +#endif + + +#include "manager/service_provider.hpp" + +#include "helper/spdlog_wrapper.hpp" +#include +#include +#include + + +#include + +namespace uefi { + + + [[nodiscard]] std::shared_ptr get_debug_sink(); + + +}; // namespace uefi diff --git a/src/helper/web_utils.cpp b/src/helper/web_utils.cpp index d463a68e..29deaa7c 100644 --- a/src/helper/web_utils.cpp +++ b/src/helper/web_utils.cpp @@ -4,7 +4,7 @@ #include -#include "web_utils.hpp" +#include "./web_utils.hpp" #include #include From d3cf29509801c985fe4884b2140f1605631425d1 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 8 Aug 2026 21:39:09 +0200 Subject: [PATCH 098/112] feat: add libcxx library to the needed libs for cpp libraries --- platforms/build-uefi.sh | 10 ++++++++++ platforms/uefi/extract-definitions.sh | 2 ++ 2 files changed, 12 insertions(+) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 666c5d4a..13f457a4 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -174,6 +174,16 @@ else echo -e "$STDLIB_PACKAGE_INCLUDE\n" >>"$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" fi +# add libcxx to active platform + +LIBCXX_PACKAGE_INCLUDE="!include LibCXX/LibCXXPkg.inc" + +if grep -q "$LIBCXX_PACKAGE_INCLUDE" "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM"; then + : # found already, do nothing +else + echo -e "$LIBCXX_PACKAGE_INCLUDE\n" >>"$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" +fi + EDK2_TARGET_PROPERTIES_BUILDTYPE="$(echo "$BUILDTYPE" | tr "[:lower:]" "[:upper:]")" EDK2_TARGET_PROPERTIES_ARCH="X64" diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 49b9f710..06e8b55c 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -288,6 +288,7 @@ FLAGS_TARGET="CC" if [ "$MESON_TARGETS_INFO_LIB_LANGUAGE" == "cpp" ]; then FLAGS_TARGET="CXX" + DEP_CLASSES+=("LibCXX") elif [ "$MESON_TARGETS_INFO_LIB_LANGUAGE" == "c" ]; then FLAGS_TARGET="CC" else @@ -396,6 +397,7 @@ $(expand_array_inf "${DEP_PACKAGES[@]}") UefiApplicationEntryPoint UefiLib LibC + LibCXX $(expand_array_inf "${DEP_CLASSES[@]}") [Guids] From e996498768e66c806562688e041d4077bcf2730a Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sun, 9 Aug 2026 18:51:00 +0200 Subject: [PATCH 099/112] feat: add llvm as a whole instead of only libcxx, as we also need libcxxabi --- platforms/build-uefi.sh | 23 ++++++++++------------- platforms/uefi/extract-definitions.sh | 2 ++ platforms/versions.sh | 2 +- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 13f457a4..da9c7abc 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -111,14 +111,12 @@ export EDK2_LLVM_ROOT="$TOOLCHAIN_DIR/llvm-project" if [ ! -d "$EDK2_LLVM_ROOT" ]; then git clone --filter=blob:none --sparse https://github.com/llvm/llvm-project.git "$EDK2_LLVM_ROOT" - git -C "$EDK2_LLVM_ROOT" sparse-checkout set libcxx + git -C "$EDK2_LLVM_ROOT" sparse-checkout set libcxx libc libcxxabi else git -C "$EDK2_LLVM_ROOT" fetch fi -git -C "$EDK2_LLVM_ROOT" checkout "$EDK2_LIBCXX_RELEASE_TAG" - -export EDK2_LIBCXX_ROOT="$EDK2_LLVM_ROOT/libcxx" +git -C "$EDK2_LLVM_ROOT" checkout "$EDK2_LLVM_RELEASE_TAG" export EDK_TOOLS_PATH="$EDK2_ROOT/BaseTools" export PACKAGES_PATH="$EDK2_ROOT" @@ -174,14 +172,14 @@ else echo -e "$STDLIB_PACKAGE_INCLUDE\n" >>"$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" fi -# add libcxx to active platform +# add llvm to active platform -LIBCXX_PACKAGE_INCLUDE="!include LibCXX/LibCXXPkg.inc" +LLVM_PACKAGE_INCLUDE="!include LLVM/LLVMPkg.inc" -if grep -q "$LIBCXX_PACKAGE_INCLUDE" "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM"; then +if grep -q "$LLVM_PACKAGE_INCLUDE" "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM"; then : # found already, do nothing else - echo -e "$LIBCXX_PACKAGE_INCLUDE\n" >>"$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" + echo -e "$LLVM_PACKAGE_INCLUDE\n" >>"$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" fi EDK2_TARGET_PROPERTIES_BUILDTYPE="$(echo "$BUILDTYPE" | tr "[:lower:]" "[:upper:]")" @@ -214,8 +212,8 @@ for EDK2_LIB_PACKAGE in "${EDK2_LIB_PACKAGES[@]}"; do done -if ! [ -e "$WORKSPACE/LibCXX" ]; then - link_files_checked "$EDK2_LIBCXX_ROOT" "$WORKSPACE/LibCXX" +if ! [ -e "$WORKSPACE/LLVM" ]; then + link_files_checked "$EDK2_LLVM_ROOT" "$WORKSPACE/LLVM" fi LIBRARY_PKG_ROOT="$WORKSPACE/LibraryPkg" @@ -278,10 +276,9 @@ export PKG_CONFIG_PATH="$SYS_ROOT/lib/pkgconfig" export LINK_FLAGS="$COMMON_FLAGS" export COMPILE_FLAGS="$COMMON_FLAGS ,'--sysroot=${SYS_ROOT}', '-D__UEFI__', '-DEFIAPI=__attribute__((ms_abi))', '-fexceptions', '-fshort-wchar', '-fno-builtin', '-fno-strict-aliasing', '-fno-common', '-fstack-protector', '-ffunction-sections', '-fdata-sections', '-fno-asynchronous-unwind-tables', '-fno-omit-frame-pointer', '-DAUDIO_PREFER_MP3'" -export CC_COMPILE_FLAGS="'-nostdinc', '-I$WORKSPACE/StdLib/Include', '-I$WORKSPACE/StdLib/Include/$EDK2_TARGET_PROPERTIES_ARCH'" +export CC_COMPILE_FLAGS="'-nostdinc', '-I$WORKSPACE/StdLib/Include', '-I$WORKSPACE/StdLib/Include/$EDK2_TARGET_PROPERTIES_ARCH', '-I$WORKSPACE/MdePkg/Include', '-I$WORKSPACE/MdePkg/Include/$EDK2_TARGET_PROPERTIES_ARCH'" -#TODO use libc++ built for UEFI -export CXX_COMPILE_FLAGS="'-fno-exceptions', '-fno-threadsafe-statics', '-fno-use-cxa-atexit', '-fno-unwind-tables', '-fno-asynchronous-unwind-tables', '-nostdinc++', '-nodefaultlibs', '-I$WORKSPACE/LibCXX/include'" +export CXX_COMPILE_FLAGS="'-fno-exceptions', '-fno-threadsafe-statics', '-fno-use-cxa-atexit', '-fno-unwind-tables', '-fno-asynchronous-unwind-tables', '-nostdinc++', '-nodefaultlibs', '-I$WORKSPACE/LLVM/libcxx/include', $CC_COMPILE_FLAGS" export CROSS_FILE="./platforms/crossbuild/uefi.ini" diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 06e8b55c..b170d18d 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -289,6 +289,7 @@ FLAGS_TARGET="CC" if [ "$MESON_TARGETS_INFO_LIB_LANGUAGE" == "cpp" ]; then FLAGS_TARGET="CXX" DEP_CLASSES+=("LibCXX") + DEP_CLASSES+=("LibCXXABI") elif [ "$MESON_TARGETS_INFO_LIB_LANGUAGE" == "c" ]; then FLAGS_TARGET="CC" else @@ -398,6 +399,7 @@ $(expand_array_inf "${DEP_PACKAGES[@]}") UefiLib LibC LibCXX + LibCXXABI $(expand_array_inf "${DEP_CLASSES[@]}") [Guids] diff --git a/platforms/versions.sh b/platforms/versions.sh index cc03e27b..225d9dbd 100755 --- a/platforms/versions.sh +++ b/platforms/versions.sh @@ -37,4 +37,4 @@ export EDK2_RELEASE_TAG="edk2-stable202605" export EDK2_LIBC_COMMIT_HASH="c8313c11c2dc43647aa4c9f73baf3b323c68ecba" -export EDK2_LIBCXX_RELEASE_TAG="llvmorg-22.1.8" +export EDK2_LLVM_RELEASE_TAG="llvmorg-22.1.8" From e562a755c851d93beb0385caaad85918c8d40a3f Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sun, 9 Aug 2026 18:53:20 +0200 Subject: [PATCH 100/112] feat: make the edk2 ssl library compatible with the StdLib from edk2-libc --- platforms/build-uefi.sh | 1 + platforms/uefi/ssl_lib_compile_with_libc.diff | 313 ++++++++++++++++++ 2 files changed, 314 insertions(+) create mode 100644 platforms/uefi/ssl_lib_compile_with_libc.diff diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index da9c7abc..1134df99 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -132,6 +132,7 @@ if ! [ -e "$EDK2_PATCH_FILE" ]; then git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/cxx_compiler.diff" git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/ssl_lib.diff" + git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/ssl_lib_compile_with_libc.diff" touch "$EDK2_PATCH_FILE" fi diff --git a/platforms/uefi/ssl_lib_compile_with_libc.diff b/platforms/uefi/ssl_lib_compile_with_libc.diff new file mode 100644 index 00000000..4c9b224b --- /dev/null +++ b/platforms/uefi/ssl_lib_compile_with_libc.diff @@ -0,0 +1,313 @@ +diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf +index 8190968a53..83d474e95a 100644 +--- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf ++++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf +@@ -112,3 +112,12 @@ + GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99 -Wno-error=incompatible-pointer-types + + XCODE:*_*_*_CC_FLAGS = -std=c99 ++ # define or undefine this based on the usage of StdLib ++ *_*_*_CC_FLAGS = -U__CRYPTO_COMPILE_STANDALONE ++ *_*_*_CC_FLAGS = -I$(WORKSPACE) ++ *_*_*_CC_FLAGS = -I$(WORKSPACE)/CryptoPkg/Library/Include ++ *_*_*_CC_FLAGS = -I$(WORKSPACE)/StdLib/Include ++ ++[BuildOptions.X64] ++ *_*_*_CC_FLAGS = -I$(WORKSPACE)/StdLib/Include/X64 ++ *_*_*_CC_FLAGS = -I$(WORKSPACE)/MdePkg/Include/X64 +diff --git a/CryptoPkg/Library/BaseCryptLib/Kdf/CryptHkdf.c b/CryptoPkg/Library/BaseCryptLib/Kdf/CryptHkdf.c +index 34e81246ed..8b260495a1 100644 +--- a/CryptoPkg/Library/BaseCryptLib/Kdf/CryptHkdf.c ++++ b/CryptoPkg/Library/BaseCryptLib/Kdf/CryptHkdf.c +@@ -73,7 +73,8 @@ HkdfMdExtractAndExpand ( + } + + if (Result) { +- Result = EVP_PKEY_derive (pHkdfCtx, Out, &OutSize) > 0; ++ _Static_assert(sizeof(UINTN) == sizeof(size_t)); ++ Result = EVP_PKEY_derive (pHkdfCtx, Out, (size_t*)&OutSize) > 0; + } + + EVP_PKEY_CTX_free (pHkdfCtx); +@@ -153,7 +154,8 @@ HkdfMdExtract ( + } + + if (Result) { +- Result = EVP_PKEY_derive (pHkdfCtx, PrkOut, &PrkOutSize) > 0; ++ _Static_assert(sizeof(UINTN) == sizeof(size_t)); ++ Result = EVP_PKEY_derive (pHkdfCtx, PrkOut, (size_t*)&PrkOutSize) > 0; + } + + EVP_PKEY_CTX_free (pHkdfCtx); +@@ -220,7 +222,8 @@ HkdfMdExpand ( + } + + if (Result) { +- Result = EVP_PKEY_derive (pHkdfCtx, Out, &OutSize) > 0; ++ _Static_assert(sizeof(UINTN) == sizeof(size_t)); ++ Result = EVP_PKEY_derive (pHkdfCtx, Out, (size_t*)&OutSize) > 0; + } + + EVP_PKEY_CTX_free (pHkdfCtx); +diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c +index 7634ab1f6f..e0c12dc264 100644 +--- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c ++++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c +@@ -166,7 +166,8 @@ InternalPkcs1v2Encrypt ( + // + // Determine the required buffer length for malloc'ing. + // +- if (EVP_PKEY_encrypt (PkeyCtx, NULL, &OutDataSize, InData, InDataSize) <= 0) { ++ _Static_assert(sizeof(UINTN) == sizeof(size_t)); ++ if (EVP_PKEY_encrypt (PkeyCtx, NULL, (size_t*)&OutDataSize, InData, InDataSize) <= 0) { + // + // Fail to determine output buffer size. + // +@@ -187,7 +188,8 @@ InternalPkcs1v2Encrypt ( + // + // Encrypt Data. + // +- if (EVP_PKEY_encrypt (PkeyCtx, OutData, &OutDataSize, InData, InDataSize) <= 0) { ++ _Static_assert(sizeof(UINTN) == sizeof(size_t)); ++ if (EVP_PKEY_encrypt (PkeyCtx, OutData, (size_t*)&OutDataSize, InData, InDataSize) <= 0) { + // + // Fail to encrypt data, need to free the output buffer. + // +@@ -514,7 +516,8 @@ InternalPkcs1v2Decrypt ( + // + // Determine the required buffer length for malloc'ing. + // +- ReturnCode = EVP_PKEY_decrypt (PkeyCtx, NULL, &TempDataSize, EncryptedData, EncryptedDataSize); ++ _Static_assert(sizeof(UINTN) == sizeof(size_t)); ++ ReturnCode = EVP_PKEY_decrypt (PkeyCtx, NULL, (size_t*)&TempDataSize, EncryptedData, EncryptedDataSize); + if (ReturnCode <= 0) { + // + // Fail to determine output buffer size. +@@ -537,7 +540,8 @@ InternalPkcs1v2Decrypt ( + // + // Decrypt Data. + // +- ReturnCode = EVP_PKEY_decrypt (PkeyCtx, TempData, &TempDataSize, EncryptedData, EncryptedDataSize); ++ _Static_assert(sizeof(UINTN) == sizeof(size_t)); ++ ReturnCode = EVP_PKEY_decrypt (PkeyCtx, TempData, (size_t*)&TempDataSize, EncryptedData, EncryptedDataSize); + if (ReturnCode <= 0) { + // + // Fail to decrypt data, need to free the output buffer. +diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c +index 4835f81168..cefa40b440 100644 +--- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c ++++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c +@@ -165,7 +165,8 @@ RsaPssSign ( + } + + if (Result) { +- Result = EVP_DigestSignFinal (EvpVerifyCtx, Signature, SigSize) > 0; ++ _Static_assert(sizeof(UINTN) == sizeof(size_t)); ++ Result = EVP_DigestSignFinal (EvpVerifyCtx, Signature, (size_t*)SigSize) > 0; + } + + _Exit: +@@ -284,10 +285,11 @@ RsaPssSignDigest ( + } + + if (Result) { ++ _Static_assert(sizeof(UINTN) == sizeof(size_t)); + Result = EVP_PKEY_sign ( + EvpSignCtx, + Signature, +- SigSize, ++ (size_t*)SigSize, + Digest, + (UINT32)DigestSize + ) > 0; +diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/BaseMemAllocation.c b/CryptoPkg/Library/BaseCryptLib/SysCall/BaseMemAllocation.c +index b7bed15c18..b1271166a5 100644 +--- a/CryptoPkg/Library/BaseCryptLib/SysCall/BaseMemAllocation.c ++++ b/CryptoPkg/Library/BaseCryptLib/SysCall/BaseMemAllocation.c +@@ -7,9 +7,14 @@ SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ + ++ ++ + #include + #include + ++#if defined(__CRYPTO_COMPILE_STANDALONE) ++ ++ + // + // Extra header to record the memory buffer size from malloc routine. + // +@@ -120,3 +125,5 @@ free ( + FreePool (PoolHdr); + } + } ++ ++#endif +diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c b/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c +index 8a8fdfefc7..0b9541267f 100644 +--- a/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c ++++ b/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c +@@ -9,6 +9,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent + + #include + ++#if defined(__CRYPTO_COMPILE_STANDALONE) ++ + int errno = 0; + + FILE *stderr = NULL; +@@ -22,6 +24,7 @@ int + IN VOID *Buffer2 + ); + ++ + // + // Duplicated from EDKII BaseSortLib for qsort() wrapper + // +@@ -651,3 +654,5 @@ printf ( + { + return 0; + } ++ ++#endif +diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c b/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c +index 894aeb016f..eca712b348 100644 +--- a/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c ++++ b/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c +@@ -12,6 +12,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent + #include + #include + ++#if defined(__CRYPTO_COMPILE_STANDALONE) ++ ++ + // + // -- Time Management Routines -- + // +@@ -249,3 +252,5 @@ gettimeofday ( + tv->tv_usec = 0; + return 0; + } ++ ++#endif +diff --git a/CryptoPkg/Library/Include/CrtLibSupport.h b/CryptoPkg/Library/Include/CrtLibSupport.h +index dc5a357d8f..6c4a32186f 100644 +--- a/CryptoPkg/Library/Include/CrtLibSupport.h ++++ b/CryptoPkg/Library/Include/CrtLibSupport.h +@@ -42,14 +42,34 @@ SPDX-License-Identifier: BSD-2-Clause-Patent + // SIXTY_FOUR_BIT, because 'long' is 32-bit and only 'long long' is + // 64-bit. Since using 'long long' works fine on GCC too, just do that. + // ++#define SSL_HAVE_ARCH_DEFINE + #define SIXTY_FOUR_BIT + #elif defined (MDE_CPU_IA32) || defined (MDE_CPU_EBC) + #define THIRTY_TWO_BIT ++#define SSL_HAVE_ARCH_DEFINE + #else + #error Unknown target architecture + #endif + #endif + ++#if !defined(__CRYPTO_COMPILE_STANDALONE) ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#else ++ + // + // Map all va_xxxx elements to VA_xxx defined in MdePkg/Include/Base.h + // +@@ -58,6 +78,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent + #define va_start VA_START + #define va_end VA_END + ++ ++ + // + // Definitions for global constants used by CRT library routines + // +@@ -492,3 +514,5 @@ memcpy ( + #else + #define UINTPTR_MAX 0xFFFFFFFFUL + #endif ++ ++#endif +diff --git a/CryptoPkg/Library/IntrinsicLib/CopyMem.c b/CryptoPkg/Library/IntrinsicLib/CopyMem.c +index 5e346728c5..666ecc61d1 100644 +--- a/CryptoPkg/Library/IntrinsicLib/CopyMem.c ++++ b/CryptoPkg/Library/IntrinsicLib/CopyMem.c +@@ -35,6 +35,8 @@ memcpy ( + ); + + #else ++ ++#if defined(__CRYPTO_COMPILE_STANDALONE) + /* Copies bytes between buffers */ + void * + memcpy ( +@@ -47,3 +49,5 @@ memcpy ( + } + + #endif ++ ++#endif +diff --git a/CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf b/CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf +index 6dd9f5d5b9..a80bfe2949 100644 +--- a/CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf ++++ b/CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf +@@ -84,3 +84,5 @@ + MSFT:DEBUG_*_X64_CC_FLAGS == /nologo /c /WX /GS- /X /W4 /Gs32768 /D UNICODE /O1b2s /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Zi /Gm + MSFT:RELEASE_*_X64_CC_FLAGS == /nologo /c /WX /GS- /X /W4 /Gs32768 /D UNICODE /O1b2s /Gy /FIAutoGen.h /EHs-c- /GR- /GF + INTEL:*_*_*_CC_FLAGS = /Oi- ++ # define or undefine this based on the usage of StdLib ++ *_*_*_CC_FLAGS = -U__CRYPTO_COMPILE_STANDALONE +diff --git a/CryptoPkg/Library/IntrinsicLib/MemoryIntrinsics.c b/CryptoPkg/Library/IntrinsicLib/MemoryIntrinsics.c +index 9b091f1901..faedee2d9e 100644 +--- a/CryptoPkg/Library/IntrinsicLib/MemoryIntrinsics.c ++++ b/CryptoPkg/Library/IntrinsicLib/MemoryIntrinsics.c +@@ -19,6 +19,8 @@ typedef UINTN size_t; + #define GLOBAL_USED + #endif + ++#if defined(__CRYPTO_COMPILE_STANDALONE) ++ + /* OpenSSL will use floating point support, and C compiler produces the _fltused + symbol by default. Simply define this symbol here to satisfy the linker. */ + int GLOBAL_USED _fltused = 1; +@@ -63,3 +65,4 @@ memcmp ( + { + return (int)CompareMem (buf1, buf2, count); + } ++#endif +diff --git a/CryptoPkg/Library/OpensslLib/OpensslLib.inf b/CryptoPkg/Library/OpensslLib/OpensslLib.inf +index 094d4439b1..f9ddaa4d26 100644 +--- a/CryptoPkg/Library/OpensslLib/OpensslLib.inf ++++ b/CryptoPkg/Library/OpensslLib/OpensslLib.inf +@@ -815,3 +815,13 @@ + # use floating point types, so clear the flags here. + # + GCC:*_*_AARCH64_CC_XIPFLAGS == ++ ++ # define or undefine this based on the usage of StdLib ++ *_*_*_CC_FLAGS = -U__CRYPTO_COMPILE_STANDALONE ++ *_*_*_CC_FLAGS = -I$(WORKSPACE) ++ *_*_*_CC_FLAGS = -I$(WORKSPACE)/CryptoPkg/Library/Include ++ *_*_*_CC_FLAGS = -I$(WORKSPACE)/StdLib/Include ++ ++[BuildOptions.X64] ++ *_*_*_CC_FLAGS = -I$(WORKSPACE)/StdLib/Include/X64 ++ *_*_*_CC_FLAGS = -I$(WORKSPACE)/MdePkg/Include/X64 From 746d21ca2b68c557326a67da0c92f3a7a8a321b7 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sun, 9 Aug 2026 21:59:49 +0200 Subject: [PATCH 101/112] feat: add more libc libraries from the stdlib to uefi libs - we needs the symbols, that they define --- platforms/uefi/extract-definitions.sh | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index b170d18d..0afedd8d 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -63,6 +63,9 @@ else exit 1 fi +C_LIBRARIES=("LibC" "LibCType" "LibLocale" "LibMath" "LibSignal" "LibStdio" "LibStdLib" "LibString" "LibTime" "LibUefi" "LibWchar") +CPP_LIBRARIES=("LibCXX" "LibCXXABI") + MAPPINGS_FILE="$(realpath "$SCRIPT_DIR/../../src/executables/platforms/uefi/mappings.json")" DEST_FILE_DIR=$(dirname -- "$DEST_FILE") @@ -288,8 +291,9 @@ FLAGS_TARGET="CC" if [ "$MESON_TARGETS_INFO_LIB_LANGUAGE" == "cpp" ]; then FLAGS_TARGET="CXX" - DEP_CLASSES+=("LibCXX") - DEP_CLASSES+=("LibCXXABI") + for CPP_LIBRARY in "${CPP_LIBRARIES[@]}"; do + DEP_CLASSES+=("$CPP_LIBRARY") + done elif [ "$MESON_TARGETS_INFO_LIB_LANGUAGE" == "c" ]; then FLAGS_TARGET="CC" else @@ -397,9 +401,7 @@ $(expand_array_inf "${DEP_PACKAGES[@]}") [LibraryClasses] UefiApplicationEntryPoint UefiLib - LibC - LibCXX - LibCXXABI +$(expand_array_inf "${C_LIBRARIES[@]}") $(expand_array_inf "${DEP_CLASSES[@]}") [Guids] @@ -468,7 +470,8 @@ $(expand_array_inf "${DEP_PACKAGES[@]}") [LibraryClasses] UefiLib - LibC +$(expand_array_inf "${C_LIBRARIES[@]}") +$(expand_array_inf "${CPP_LIBRARIES[@]}") $(expand_array_inf "${DEP_CLASSES[@]}") [BuildOptions] From a6a8d1c05178cf9ce6edf42a785b98b5171bb876 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sun, 9 Aug 2026 22:18:39 +0200 Subject: [PATCH 102/112] fix: some small uefi fixes --- platforms/build-uefi.sh | 2 ++ platforms/uefi/extract-definitions.sh | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 1134df99..13eda4a5 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -370,6 +370,8 @@ EOF if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "$BUILD_DIR" ]; then + rm -rf "$WORKSPACE/Build/" + meson setup "$BUILD_DIR" \ "--prefix=$SYS_ROOT" \ "--wipe" \ diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 0afedd8d..d2ef93d8 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -63,7 +63,7 @@ else exit 1 fi -C_LIBRARIES=("LibC" "LibCType" "LibLocale" "LibMath" "LibSignal" "LibStdio" "LibStdLib" "LibString" "LibTime" "LibUefi" "LibWchar") +C_LIBRARIES=("LibC" "LibCType" "LibLocale" "LibMath" "LibSignal" "LibStdio" "LibStdLib" "LibString" "LibTime" "LibUefi" "LibWchar" "LibGdtoa") CPP_LIBRARIES=("LibCXX" "LibCXXABI") MAPPINGS_FILE="$(realpath "$SCRIPT_DIR/../../src/executables/platforms/uefi/mappings.json")" From 31e0b36a898c627c56a4164c611166a9f65ab624 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sun, 9 Aug 2026 23:22:36 +0200 Subject: [PATCH 103/112] fix: fix int128 support for fmt with uefi --- src/executables/platforms/uefi/mappings.json | 3 ++- tools/dependencies/meson.build | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/executables/platforms/uefi/mappings.json b/src/executables/platforms/uefi/mappings.json index 49197bd5..47a9a7ac 100644 --- a/src/executables/platforms/uefi/mappings.json +++ b/src/executables/platforms/uefi/mappings.json @@ -56,7 +56,8 @@ "version": "spdlog", "options": [ "-DSPDLOG_NO_EXCEPTIONS=1", - "-DSPDLOG_NO_TLS=1" + "-DSPDLOG_NO_TLS=1", + "-DFMT_USE_INT128=0" ] }, "SDL2ImagePkg": { diff --git a/tools/dependencies/meson.build b/tools/dependencies/meson.build index b626bf04..a753b2c7 100644 --- a/tools/dependencies/meson.build +++ b/tools/dependencies/meson.build @@ -155,6 +155,7 @@ if ( temp += '-DJSON_NOEXCEPTION=1' temp += '-DSPDLOG_NO_EXCEPTIONS=1' temp += '-DUTFCPP_NO_EXCEPTIONS=1' + temp += '-DFMT_USE_INT128=0' core_lib += { 'compile_args': temp, } From abdf99f1f42c0a44de31b638b5cbfa8e5920a141 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Mon, 10 Aug 2026 13:23:02 +0200 Subject: [PATCH 104/112] fix: small uefi fixes --- platforms/build-uefi.sh | 16 ++- platforms/uefi/libc_cpp_compatibility.diff | 146 +++++++++++++++++++++ src/lobby/uefi_client.cpp | 4 + 3 files changed, 162 insertions(+), 4 deletions(-) create mode 100644 platforms/uefi/libc_cpp_compatibility.diff diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 13eda4a5..b3438c35 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -121,14 +121,12 @@ git -C "$EDK2_LLVM_ROOT" checkout "$EDK2_LLVM_RELEASE_TAG" export EDK_TOOLS_PATH="$EDK2_ROOT/BaseTools" export PACKAGES_PATH="$EDK2_ROOT" -EDK2_PATCH_FILE="$EDK2_ROOT/.patched_manually.meta" - PATCH_DIR="platforms/uefi" +EDK2_PATCH_FILE="$EDK2_ROOT/.patched_manually.meta" + if ! [ -e "$EDK2_PATCH_FILE" ]; then ##TODO: upstream those patches - # see: https://github.com/emscripten-core/emscripten/pull/18379 - # and: https://github.com/emscripten-core/emscripten/pull/22946 git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/cxx_compiler.diff" git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/ssl_lib.diff" @@ -137,6 +135,16 @@ if ! [ -e "$EDK2_PATCH_FILE" ]; then touch "$EDK2_PATCH_FILE" fi +EDK2_LIBC_PATCH_FILE="$EDK2_LIBC_ROOT/.patched_manually.meta" + +if ! [ -e "$EDK2_LIBC_PATCH_FILE" ]; then + ##TODO: upstream those patches + + git apply --unsafe-paths -p1 --directory="$EDK2_LIBC_ROOT" "$PATCH_DIR/libc_cpp_compatibility.diff" + + touch "$EDK2_LIBC_PATCH_FILE" +fi + export BUILD_DIR="build/uefi" pushd "$EDK2_ROOT" diff --git a/platforms/uefi/libc_cpp_compatibility.diff b/platforms/uefi/libc_cpp_compatibility.diff new file mode 100644 index 00000000..7d18690b --- /dev/null +++ b/platforms/uefi/libc_cpp_compatibility.diff @@ -0,0 +1,146 @@ +diff --git a/StdLib/Include/assert.h b/StdLib/Include/assert.h +index 26c7037..5296e9a 100644 +--- a/StdLib/Include/assert.h ++++ b/StdLib/Include/assert.h +@@ -25,6 +25,9 @@ + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + **/ ++ ++#ifndef _ASSERT_H_ ++#define _ASSERT_H_ + #include + + #undef assert ///< Remove any existing definition for assert. +@@ -49,6 +52,7 @@ + current application and returns to the environment that + the application was launched from. + **/ ++__BEGIN_DECLS + extern void + __assert(const char *file, const char *func, int line, const char *failedexpr); + +@@ -78,5 +82,8 @@ __assert(const char *file, const char *func, int line, const char *failedexpr); + #define assert(Expression) ((Expression) ? (void)0 :\ + __assert(__FILE__, __func__, __LINE__, #Expression) ) + #endif ++__END_DECLS + /// @} + /* END of file assert.h */ ++ ++#endif /* _ASSERT_H_ */ +diff --git a/StdLib/Include/math.h b/StdLib/Include/math.h +index 3041120..9eb0be2 100644 +--- a/StdLib/Include/math.h ++++ b/StdLib/Include/math.h +@@ -288,6 +288,14 @@ double sqrt(double Arg); + **/ + double ceil(double Arg); + ++/** Compute the smallest integer value not less than Arg. ++ ++ @param[in] Arg The value to compute the ceiling of. ++ ++ @return The ceiling of Arg expressed as a floating-point number. ++**/ ++float ceilf(float Arg); ++ + /** Compute the absolute value of Arg. + + @param[in] Arg The value to compute the absolute value of. +diff --git a/StdLib/Include/time.h b/StdLib/Include/time.h +index ecef1e2..7d7f70e 100644 +--- a/StdLib/Include/time.h ++++ b/StdLib/Include/time.h +@@ -138,6 +138,7 @@ + broken-down time. The first nine (9) members are as mandated by the + C95 standard. Additional fields have been added for EFI support. + **/ ++__BEGIN_DECLS + struct tm { + int tm_year; // years since 1900 + int tm_mon; // months since January [0, 11] +@@ -430,5 +431,5 @@ char *strptime(const char *, const char * format, struct tm*); + /* ################# Implementation Functions ########################### */ + + clock_t __getCPS(void); +- ++__END_DECLS + #endif /* _TIME_H */ +diff --git a/StdLib/Include/wchar.h b/StdLib/Include/wchar.h +index 3acc2a4..59e9d61 100644 +--- a/StdLib/Include/wchar.h ++++ b/StdLib/Include/wchar.h +@@ -455,6 +455,7 @@ struct tm; + transmitted, or a negative value if an output or encoding error + occurred. + **/ ++__BEGIN_DECLS + int fwprintf(FILE * __restrict stream, const wchar_t * __restrict format, ...); + + /** The fwscanf function reads input from the stream pointed to by stream, +@@ -1549,4 +1550,6 @@ size_t mbsrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t + **/ + size_t wcsrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t len, mbstate_t * __restrict ps); + ++__END_DECLS ++ + #endif /* _WCHAR_H */ +diff --git a/StdLib/LibC/Math/s_ceil.c b/StdLib/LibC/Math/s_ceil.c +index e9579fa..64611d4 100644 +--- a/StdLib/LibC/Math/s_ceil.c ++++ b/StdLib/LibC/Math/s_ceil.c +@@ -72,3 +72,7 @@ ceil(double x) + INSERT_WORDS(x,i0,i1); + return x; + } ++ ++float ceilf(float x){ ++ return (float)ceil((double)x); ++} +diff --git a/StdLib/LibC/Stdio/Stdio.inf b/StdLib/LibC/Stdio/Stdio.inf +index fe87242..df122fa 100644 +--- a/StdLib/LibC/Stdio/Stdio.inf ++++ b/StdLib/LibC/Stdio/Stdio.inf +@@ -90,6 +90,7 @@ + swprintf.c # + swscanf.c # + ungetwc.c # ++ vasprintf.c # + vfwscanf.c # + vswprintf.c # + vswscanf.c # +diff --git a/StdLib/LibC/Stdio/vasprintf.c b/StdLib/LibC/Stdio/vasprintf.c +index 3a36468..e8ba589 100644 +--- a/StdLib/LibC/Stdio/vasprintf.c ++++ b/StdLib/LibC/Stdio/vasprintf.c +@@ -39,12 +39,9 @@ __RCSID("$NetBSD: vasprintf.c,v 1.10 2005/02/09 21:35:47 kleink Exp $"); + #include "reentrant.h" + #include "local.h" + +-int +-vasprintf(str, fmt, ap) +- char **str; +- const char *fmt; +- _BSD_VA_LIST_ ap; +-{ ++#include ++ ++int vasprintf( char **str, const char *fmt, va_list ap){ + int ret; + FILE f; + struct __sfileext fext; +diff --git a/StdLib/LibC/gdtoa/gdtoa.inf b/StdLib/LibC/gdtoa/gdtoa.inf +index 9d975bb..44af305 100644 +--- a/StdLib/LibC/gdtoa/gdtoa.inf ++++ b/StdLib/LibC/gdtoa/gdtoa.inf +@@ -61,6 +61,9 @@ + sum.c + ulp.c + ++ _strtof.c ++ _strtold.c ++ + [Packages] + StdLib/StdLib.dec + StdLibPrivateInternalFiles/DoNotUse.dec diff --git a/src/lobby/uefi_client.cpp b/src/lobby/uefi_client.cpp index 68307c07..31726cdf 100644 --- a/src/lobby/uefi_client.cpp +++ b/src/lobby/uefi_client.cpp @@ -433,6 +433,10 @@ static EFI_STATUS FindNetworkController(OUT EFI_HANDLE* Controller) { EFI_HANDLE* Handles = NULL; UINTN HandleCount = 0; + if(!gBS){ + return EFI_NOT_READY; + } + EFI_STATUS Status = gBS->LocateHandleBuffer( ByProtocol, &gEfiManagedNetworkServiceBindingProtocolGuid, NULL, &HandleCount, &Handles ); From c854c5ccfc5ab804ea0f71f78cbeaced4aaeffe7 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 11 Aug 2026 01:09:17 +0200 Subject: [PATCH 105/112] feat: some final script fixes for uefi - fix some edk2 cpp related things - link the final efi file to the output, that meson expects --- platforms/build-uefi.sh | 1 + platforms/uefi/compile-final.sh | 20 ++++++++++++---- .../helper_files_support_cpp_include.diff | 23 +++++++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 platforms/uefi/helper_files_support_cpp_include.diff diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index b3438c35..1810c35e 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -131,6 +131,7 @@ if ! [ -e "$EDK2_PATCH_FILE" ]; then git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/cxx_compiler.diff" git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/ssl_lib.diff" git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/ssl_lib_compile_with_libc.diff" + git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/helper_files_support_cpp_include.diff" touch "$EDK2_PATCH_FILE" fi diff --git a/platforms/uefi/compile-final.sh b/platforms/uefi/compile-final.sh index a0c69bc2..a14a9899 100755 --- a/platforms/uefi/compile-final.sh +++ b/platforms/uefi/compile-final.sh @@ -25,6 +25,7 @@ EDK2_BUILD_COMMAND="$(jq -M -r -c '.["build"]' "$UEFI_INFO_FILE")" EDK2_TARGET_PROPERTIES_ARCH="$(jq -M -r -c '.["arch"]' "$UEFI_INFO_FILE")" WORKSPACE="$(jq -M -r -c '.["workspace"]' "$UEFI_INFO_FILE")" EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM="$(jq -M -r -c '.["platform"]' "$UEFI_INFO_FILE")" +EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM_NAME="$(jq -M -r -c '.["platform_name"]' "$UEFI_INFO_FILE")" EDK2_TARGET_PROPERTIES_BUILDTYPE="$(jq -M -r -c '.["buildtype"]' "$UEFI_INFO_FILE")" EDK2_TARGET_PROPERTIES_TOOLCHAIN="$(jq -M -r -c '.["toolchain"]' "$UEFI_INFO_FILE")" @@ -56,9 +57,20 @@ fi -t "$EDK2_TARGET_PROPERTIES_TOOLCHAIN" \ -w # -v # verbose -OUTPUT_FILE="TODO" +##TODO: un-hardcode this +##NOTE: this is just hardcoded +PACKAGE_NAME="OOPetrisApplication" -# link the output .efi to the correct location +if [ "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM_NAME" == "MdeModulePkg/MdeModulePkg.dsc" ]; then + MODULE_NAME="MdeModule" +else + echo "MODULE_NAME mapping not supported for platform: $EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM_NAME" >&2 + exit 2 +fi -echo "TODO" -exit 45 +OUTPUT_FILE="$WORKSPACE/Build/$MODULE_NAME/${EDK2_TARGET_PROPERTIES_BUILDTYPE}_${EDK2_TARGET_PROPERTIES_TOOLCHAIN}/${EDK2_TARGET_PROPERTIES_ARCH}/$PACKAGE_NAME.efi" + +# link the output .efi to the correct location +if ! [ -e "$DEST_FILE" ]; then + link_files_checked "$OUTPUT_FILE" "$DEST_FILE" +fi diff --git a/platforms/uefi/helper_files_support_cpp_include.diff b/platforms/uefi/helper_files_support_cpp_include.diff new file mode 100644 index 00000000..c9d0c354 --- /dev/null +++ b/platforms/uefi/helper_files_support_cpp_include.diff @@ -0,0 +1,23 @@ +diff --git a/MdePkg/Include/Library/DebugLib.h b/MdePkg/Include/Library/DebugLib.h +index 30cfcc77f9..449b11d9f1 100644 +--- a/MdePkg/Include/Library/DebugLib.h ++++ b/MdePkg/Include/Library/DebugLib.h +@@ -131,6 +131,10 @@ SPDX-License-Identifier: BSD-2-Clause-Patent + based on the format string specified by Format. + + **/ ++#if defined(__cplusplus) ++extern "C" { ++#endif ++ + VOID + EFIAPI + DebugPrint ( +@@ -669,3 +673,7 @@ UnitTestDebugAssert ( + NULL : \ + BASE_CR (Record, TYPE, Field) + #endif ++ ++#if defined(__cplusplus) ++ } ++#endif From 8a21cf66c1dcfd4da929b39d86fbefc7c1ba89e4 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 11 Aug 2026 01:36:33 +0200 Subject: [PATCH 106/112] feat: add meson runtime target to run qemu for the .efi file --- platforms/uefi/create-fat-folder.sh | 33 +++++++++ src/executables/platforms/uefi/meson.build | 84 ++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100755 platforms/uefi/create-fat-folder.sh diff --git a/platforms/uefi/create-fat-folder.sh b/platforms/uefi/create-fat-folder.sh new file mode 100755 index 00000000..18637603 --- /dev/null +++ b/platforms/uefi/create-fat-folder.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +# Exit immediately if a command exits with a non-zero status. +set -e +## Treat undefined variables as an error +set -u +# fails if any part of a pipeline (|) fails +set -o pipefail + +SCRIPT_DIR="$(realpath "$(dirname -- "${BASH_SOURCE[0]}")")" + +# shellcheck source=./platforms/helper.sh +source "$SCRIPT_DIR/../helper.sh" + +if [ "$#" -eq 3 ]; then + FAT_FOLDER_LOC="$(realpath "$1")" + EFI_FILE="$(realpath "$2")" + PSEUDO_OUTPUT="$(realpath "$3")" +else + echo "Too many arguments given, expected 3" >&2 + exit 1 +fi + +mkdir -p "$FAT_FOLDER_LOC" + +DEST_FILE="$FAT_FOLDER_LOC/$(basename "$EFI_FILE")" + +# copy the output .efi to the correct location +if ! [ -e "$DEST_FILE" ]; then + cp -p -f "$EFI_FILE" "$DEST_FILE" +fi + +touch "$PSEUDO_OUTPUT" diff --git a/src/executables/platforms/uefi/meson.build b/src/executables/platforms/uefi/meson.build index 76fc68a8..91d4a7e6 100644 --- a/src/executables/platforms/uefi/meson.build +++ b/src/executables/platforms/uefi/meson.build @@ -49,3 +49,87 @@ oopetris_efi = custom_target( output: [_uefi_exe_name + '.efi'], build_by_default: true, ) +_qemu_system_exe = find_program( + 'qemu-system-x86_64', + required: false, +) + + +if _qemu_system_exe.found() + cat = find_program('cat') + + os_release_info = run_command( + cat, + '/etc/os-release', + check: true, + ).stdout().strip().split('\n') + + linux_distro = '' + + foreach line : os_release_info + line_detail = line.split('=') + + if line_detail[0] == 'ID' + linux_distro = line_detail[1] + endif + + endforeach + + if linux_distro == '' + warning('Couldn\'t detect the linux distro') + OVMF_CODE_fd_path = '/usr/share/OVMF/OVMF_CODE.fd' + OVMF_VARS_fd_path = '/usr/share/OVMF/OVMF_VARS.fd' + elif linux_distro == 'ubuntu' + OVMF_CODE_fd_path = '/usr/share/OVMF/OVMF_CODE_4M.fd' + OVMF_VARS_fd_path = '/usr/share/OVMF/OVMF_VARS_4M.fd' + else + OVMF_CODE_fd_path = '/usr/share/OVMF/OVMF_CODE.fd' + OVMF_VARS_fd_path = '/usr/share/OVMF/OVMF_VARS.fd' + endif + + fs = import('fs') + + + if fs.exists(OVMF_CODE_fd_path) and fs.exists(OVMF_VARS_fd_path) + + _uefi_create_fat_folder_exe = find_program( + 'create-fat-folder.sh', + dirs: [meson.project_source_root() / 'platforms' / 'uefi'], + required: true, + ) + + fat_folder_loc = fs.parent(oopetris_efi.full_path()) / 'FAT_FOLDER' + + fat_folder = custom_target( + 'fat_folder', + command: [_uefi_create_fat_folder_exe, fat_folder_loc, '@INPUT@', '@OUTPUT@'], + depends: [oopetris_efi], + input: [oopetris_efi], + output: ['FAT_FOLDER_CREATED.meta'], + build_by_default: false, + ) + + + run_target( + 'emulate_efi', + command: [ + _qemu_system_exe, + '-cpu', + 'qemu64', + '-drive', + 'if=pflash,format=raw,unit=0,file=' + OVMF_CODE_fd_path + ',readonly=on', + '-drive', + 'if=pflash,format=raw,unit=1,file=' + OVMF_VARS_fd_path, + '-drive', + 'format=raw,file=fat:rw:' + fat_folder_loc, + '-net', + 'none', + ], + depends: [oopetris_efi, fat_folder], + ) + else + warning('OVMF files couldn\'t be found: target for running efi not created') + endif +else + warning('qemu couldn\'t be found: target for running efi not created') +endif From 988eea4f36c35840e7f9385db92e7dc2c1818add Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 11 Aug 2026 01:48:15 +0200 Subject: [PATCH 107/112] feat: add debug output to qemu for efi simulation --- platforms/uefi/create-fat-folder.sh | 8 ++++-- src/executables/platforms/uefi/meson.build | 31 +++++++++++++--------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/platforms/uefi/create-fat-folder.sh b/platforms/uefi/create-fat-folder.sh index 18637603..ba58cdc0 100755 --- a/platforms/uefi/create-fat-folder.sh +++ b/platforms/uefi/create-fat-folder.sh @@ -21,9 +21,13 @@ else exit 1 fi -mkdir -p "$FAT_FOLDER_LOC" +rm -rf "$FAT_FOLDER_LOC" -DEST_FILE="$FAT_FOLDER_LOC/$(basename "$EFI_FILE")" +BOOT_FOLDER_LOC="$FAT_FOLDER_LOC/EFI/BOOT" + +mkdir -p "$BOOT_FOLDER_LOC" + +DEST_FILE="$BOOT_FOLDER_LOC/BOOTX64.EFI" # copy the output .efi to the correct location if ! [ -e "$DEST_FILE" ]; then diff --git a/src/executables/platforms/uefi/meson.build b/src/executables/platforms/uefi/meson.build index 91d4a7e6..278fae8a 100644 --- a/src/executables/platforms/uefi/meson.build +++ b/src/executables/platforms/uefi/meson.build @@ -109,22 +109,27 @@ if _qemu_system_exe.found() build_by_default: false, ) + emulate_command = [ + _qemu_system_exe, + '-cpu', + 'qemu64', + '-drive', + 'if=pflash,format=raw,unit=0,file=' + OVMF_CODE_fd_path + ',readonly=on', + '-drive', + 'if=pflash,format=raw,unit=1,file=' + OVMF_VARS_fd_path, + '-drive', + 'format=raw,file=fat:rw:' + fat_folder_loc, + '-net', + 'none', + ] + + if get_option('buildtype') != 'release' + emulate_command += ['-debugcon', 'stdio', '-global', 'isa-debugcon.iobase=0x402'] + endif run_target( 'emulate_efi', - command: [ - _qemu_system_exe, - '-cpu', - 'qemu64', - '-drive', - 'if=pflash,format=raw,unit=0,file=' + OVMF_CODE_fd_path + ',readonly=on', - '-drive', - 'if=pflash,format=raw,unit=1,file=' + OVMF_VARS_fd_path, - '-drive', - 'format=raw,file=fat:rw:' + fat_folder_loc, - '-net', - 'none', - ], + command: emulate_command, depends: [oopetris_efi, fat_folder], ) else From 5e151ad2b42872009d517ae4573c0c9242e75fc4 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 11 Aug 2026 02:03:08 +0200 Subject: [PATCH 108/112] feat: fix debug print usage for uefi --- platforms/build-uefi.sh | 1 - .../helper_files_support_cpp_include.diff | 23 ------------------- src/helper/uefi_utils.cpp | 8 +++---- src/helper/uefi_utils.hpp | 5 ++-- src/libs/core/helper/meson.build | 1 + src/libs/core/helper/uefi_debug.h | 19 +++++++++++++++ src/libs/core/helper/utils.hpp | 12 +++++----- .../utfcpp-4.0.8_no_exceptions.diff | 2 +- 8 files changed, 33 insertions(+), 38 deletions(-) delete mode 100644 platforms/uefi/helper_files_support_cpp_include.diff create mode 100644 src/libs/core/helper/uefi_debug.h diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 1810c35e..b3438c35 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -131,7 +131,6 @@ if ! [ -e "$EDK2_PATCH_FILE" ]; then git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/cxx_compiler.diff" git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/ssl_lib.diff" git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/ssl_lib_compile_with_libc.diff" - git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/helper_files_support_cpp_include.diff" touch "$EDK2_PATCH_FILE" fi diff --git a/platforms/uefi/helper_files_support_cpp_include.diff b/platforms/uefi/helper_files_support_cpp_include.diff deleted file mode 100644 index c9d0c354..00000000 --- a/platforms/uefi/helper_files_support_cpp_include.diff +++ /dev/null @@ -1,23 +0,0 @@ -diff --git a/MdePkg/Include/Library/DebugLib.h b/MdePkg/Include/Library/DebugLib.h -index 30cfcc77f9..449b11d9f1 100644 ---- a/MdePkg/Include/Library/DebugLib.h -+++ b/MdePkg/Include/Library/DebugLib.h -@@ -131,6 +131,10 @@ SPDX-License-Identifier: BSD-2-Clause-Patent - based on the format string specified by Format. - - **/ -+#if defined(__cplusplus) -+extern "C" { -+#endif -+ - VOID - EFIAPI - DebugPrint ( -@@ -669,3 +673,7 @@ UnitTestDebugAssert ( - NULL : \ - BASE_CR (Record, TYPE, Field) - #endif -+ -+#if defined(__cplusplus) -+ } -+#endif diff --git a/src/helper/uefi_utils.cpp b/src/helper/uefi_utils.cpp index fa1c3057..099a4d2a 100644 --- a/src/helper/uefi_utils.cpp +++ b/src/helper/uefi_utils.cpp @@ -19,17 +19,17 @@ std::shared_ptr uefi::get_debug_sink() { return; case spdlog::level::trace: case spdlog::level::debug: - DebugPrint(DEBUG_VERBOSE, "%s", message); + EFI_DEBUG((DEBUG_VERBOSE, "%s", message)); break; case spdlog::level::info: - DebugPrint(DEBUG_INFO, "%s", message); + EFI_DEBUG((DEBUG_INFO, "%s", message)); break; case spdlog::level::warn: - DebugPrint(DEBUG_WARN, "%s", message); + EFI_DEBUG((DEBUG_WARN, "%s", message)); break; case spdlog::level::err: case spdlog::level::critical: - DebugPrint(DEBUG_ERROR, "%s", message); + EFI_DEBUG((DEBUG_ERROR, "%s", message)); break; default: return; diff --git a/src/helper/uefi_utils.hpp b/src/helper/uefi_utils.hpp index 6d5971ca..6cc27e37 100644 --- a/src/helper/uefi_utils.hpp +++ b/src/helper/uefi_utils.hpp @@ -16,12 +16,11 @@ #include -#include +#include -namespace uefi { +namespace uefi { [[nodiscard]] std::shared_ptr get_debug_sink(); - }; // namespace uefi diff --git a/src/libs/core/helper/meson.build b/src/libs/core/helper/meson.build index c440546a..027e23ca 100644 --- a/src/libs/core/helper/meson.build +++ b/src/libs/core/helper/meson.build @@ -29,6 +29,7 @@ _header_files = files( 'string_manipulation.hpp', 'timer.hpp', 'types.hpp', + 'uefi_debug.h', 'utils.hpp', 'versions.hpp', ) diff --git a/src/libs/core/helper/uefi_debug.h b/src/libs/core/helper/uefi_debug.h new file mode 100644 index 00000000..075a99d8 --- /dev/null +++ b/src/libs/core/helper/uefi_debug.h @@ -0,0 +1,19 @@ + +#pragma once + +#if defined(NDEBUG) +#define MDEPKG_NDEBUG 1 +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +#include + +#if defined(__cplusplus) +} +#endif + + +#define EFI_DEBUG DEBUG diff --git a/src/libs/core/helper/utils.hpp b/src/libs/core/helper/utils.hpp index 6b783b81..730f5686 100644 --- a/src/libs/core/helper/utils.hpp +++ b/src/libs/core/helper/utils.hpp @@ -16,7 +16,7 @@ #include #if defined(__UEFI__) -#include +#include "./uefi_debug.h" #endif namespace helper { @@ -132,7 +132,7 @@ namespace utils { [[noreturn]] inline void throw_(E&& exc) { //NOLINT(readability-identifier-naming) #if defined(__OOPETRIS_NO_EXCEPTIONS) #if defined(__UEFI__) - DebugPrint(DEBUG_ERROR, "Exception: %s", exc.what()); + EFI_DEBUG((DEBUG_ERROR, "Exception: %s", exc.what())); #else std::cerr << "Exception: " << exc.what() << "\n"; #endif @@ -156,10 +156,10 @@ namespace utils { #if !defined(NDEBUG) #if defined(__UEFI__) -#define UNREACHABLE() /* NOLINT(cppcoreguidelines-macro-usage)*/ \ - do { /* NOLINT(cppcoreguidelines-avoid-do-while)*/ \ - DebugPrint(DEBUG_ERROR, "UNREACHABLE %s:%d - %s\n", __FILE__, __LINE__, __FUNCTION__); \ - utils::unreachable(); \ +#define UNREACHABLE() /* NOLINT(cppcoreguidelines-macro-usage)*/ \ + do { /* NOLINT(cppcoreguidelines-avoid-do-while)*/ \ + EFI_DEBUG((DEBUG_ERROR, "UNREACHABLE %s:%d - %s\n", __FILE__, __LINE__, __FUNCTION__)); \ + utils::unreachable(); \ } while (false) #else #define UNREACHABLE() /* NOLINT(cppcoreguidelines-macro-usage)*/ \ diff --git a/subprojects/packagefiles/utfcpp-4.0.8_no_exceptions.diff b/subprojects/packagefiles/utfcpp-4.0.8_no_exceptions.diff index bd8958a1..ba05c746 100644 --- a/subprojects/packagefiles/utfcpp-4.0.8_no_exceptions.diff +++ b/subprojects/packagefiles/utfcpp-4.0.8_no_exceptions.diff @@ -917,7 +917,7 @@ index 064f838..0dd1d99 100644 +#if defined(__UEFI__) +#define UTFCPP_THROW(exc) \ + do { \ -+ DebugPrint(DEBUG_ERROR, "THROW %s:%d - %s: %s\n", __FILE__, __LINE__, __FUNCTION__, exc.what()); \ ++ DEBUG((DEBUG_ERROR, "THROW %s:%d - %s: %s\n", __FILE__, __LINE__, __FUNCTION__, exc.what())); \ + abort(); \ + } while (false) +#else From 9e3af7a546f196fcc743b6c286f612bd8611a625 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 11 Aug 2026 11:48:53 +0200 Subject: [PATCH 109/112] fix: fix more uefi related issues --- src/helper/uefi_utils.hpp | 2 +- .../SDL2_image_2.6.3_define_fix.diff | 19 +++++++++++++++++++ subprojects/sdl2_image.wrap | 2 +- 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 subprojects/packagefiles/SDL2_image_2.6.3_define_fix.diff diff --git a/src/helper/uefi_utils.hpp b/src/helper/uefi_utils.hpp index 6cc27e37..8b72ea46 100644 --- a/src/helper/uefi_utils.hpp +++ b/src/helper/uefi_utils.hpp @@ -16,7 +16,7 @@ #include -#include +#include namespace uefi { diff --git a/subprojects/packagefiles/SDL2_image_2.6.3_define_fix.diff b/subprojects/packagefiles/SDL2_image_2.6.3_define_fix.diff new file mode 100644 index 00000000..09e5758b --- /dev/null +++ b/subprojects/packagefiles/SDL2_image_2.6.3_define_fix.diff @@ -0,0 +1,19 @@ +diff --git a/IMG_gif.c b/IMG_gif.c +index 5611dec..43498b2 100644 +--- a/IMG_gif.c ++++ b/IMG_gif.c +@@ -63,8 +63,14 @@ + + #define MAXCOLORMAPSIZE 256 + ++#ifndef TRUE + #define TRUE 1 ++#endif ++ ++#ifndef FALSE + #define FALSE 0 ++#endif ++ + + #define CM_RED 0 + #define CM_GREEN 1 diff --git a/subprojects/sdl2_image.wrap b/subprojects/sdl2_image.wrap index 2206ad11..205c5d17 100644 --- a/subprojects/sdl2_image.wrap +++ b/subprojects/sdl2_image.wrap @@ -8,6 +8,6 @@ patch_url = https://wrapdb.mesonbuild.com/v2/sdl2_image_2.6.3-3/get_patch patch_hash = 4c7132ec24d277c54491c3faad75c4a5d0c5ce15cb9fadbd72b232d7abf35d7e source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/sdl2_image_2.6.3-3/SDL2_image-2.6.3.tar.gz wrapdb_version = 2.6.3-3 - +diff_files = SDL2_image_2.6.3_define_fix.diff [provide] sdl2_image = sdl2_image_dep From 76c92a0aaa2cc301751d3e8dbdad3cce46366624 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 11 Aug 2026 12:32:42 +0200 Subject: [PATCH 110/112] feat: more uefi fixes --- platforms/build-android.sh | 2 +- platforms/build-uefi.sh | 15 ++++++++++----- platforms/uefi/extract-definitions.sh | 22 ++++++++++++++++++---- platforms/uefi/g++-wrapper.sh | 2 +- platforms/uefi/gcc-wrapper.sh | 2 +- tools/dependencies/meson.build | 2 +- 6 files changed, 32 insertions(+), 13 deletions(-) diff --git a/platforms/build-android.sh b/platforms/build-android.sh index c9ccda5f..98831149 100755 --- a/platforms/build-android.sh +++ b/platforms/build-android.sh @@ -473,7 +473,7 @@ EOF done -# TODO only copy the supported music ones (atm we need both for i686 flac is needed!) +# TODO only copy the supported music ones (atm we need both, for i686 flac is needed!) cp -r ./assets/ platforms/android/app/src/main diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index b3438c35..9c0fa8e4 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -61,8 +61,10 @@ if [ "$RUNTIME_TARGET" == "emulator" ]; then : # noop elif [ "$RUNTIME_TARGET" == "hardware" ]; then : # noop +elif [ "$RUNTIME_TARGET" == "ovmf" ]; then + : # noop else - echo "Invalid RUNTIME_TARGET, expected: 'emulator' or 'hardware'" >&2 + echo "Invalid RUNTIME_TARGET, expected: 'emulator' 'hardware' or 'ovmf'" >&2 exit 1 fi @@ -166,6 +168,8 @@ if [ "$RUNTIME_TARGET" == "emulator" ]; then EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM="EmulatorPkg/EmulatorPkg.dsc" elif [ "$RUNTIME_TARGET" == "hardware" ]; then EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM="MdeModulePkg/MdeModulePkg.dsc" +elif [ "$RUNTIME_TARGET" == "ovmf" ]; then + EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM="OvmfPkg/OvmfPkgX64.dsc" else echo "Invalid RUNTIME_TARGET, expected: 'emulator' or 'hardware'" >&2 exit 1 @@ -265,8 +269,8 @@ export CXX="$SCRIPT_DIR/uefi/g++-wrapper.sh" export AR="$SCRIPT_DIR/uefi/ar-wrapper.sh" export RANLIB="" -export STRIP="" -export NM="" +export STRIP="false" +export NM="nm" export PKG_CONFIG_EXEC="$SCRIPT_DIR/uefi/pkg-config-wrapper.sh" @@ -389,8 +393,9 @@ if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "$BUILD_DIR" ]; then -Dtests=false \ --force-fallback-for="fmt,nlohmann_json,magic_enum,utf8cpp,sdl2_ttf,freetype2,spdlog,argparse,sdl2_image" \ --wrap-mode=nofallback \ - "-Drun_in_ci=$RUN_IN_CI" #TODO: enable \ - #--fatal-meson-warnings + "-Drun_in_ci=$RUN_IN_CI" \ + -Dstrip=false \ + --fatal-meson-warnings if ! [ -L "$WORKSPACE/GeneratedPackages" ]; then diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index d2ef93d8..0526cf30 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -294,6 +294,7 @@ if [ "$MESON_TARGETS_INFO_LIB_LANGUAGE" == "cpp" ]; then for CPP_LIBRARY in "${CPP_LIBRARIES[@]}"; do DEP_CLASSES+=("$CPP_LIBRARY") done + DEP_PACKAGES+=("LLVM/LLVMPkg.dec") elif [ "$MESON_TARGETS_INFO_LIB_LANGUAGE" == "c" ]; then FLAGS_TARGET="CC" else @@ -352,10 +353,11 @@ done # TODO: what should i do here, archives alias static_libraries don't specify argument, but executables and shared libraries hae -Wl -l or similar arguments if [ "$MESON_TARGETS_INFO_LIB_TYPE" == "static library" ]; then - echo "TODO" + #TODO: maybe do something based on the json information we have? + : elif [ "$MESON_TARGETS_INFO_LIB_TYPE" == "executable" ] || [ "$MESON_TARGETS_INFO_LIB_TYPE" == "shared library" ]; then - echo "TODO" - # exit 34 + #TODO: maybe do something based on the json information we have? + : else echo "Error: invalid meson target type for '$SOURCE_FILE_ENTRY_MESON_NAME': $MESON_TARGETS_INFO_LIB_TYPE" >&2 exit 2 @@ -394,14 +396,22 @@ if [ "$MAPPING_TYPE" == "application" ]; then $(expand_array_inf "${DEP_SOURCES[@]}") [Packages] +# basic deps MdePkg/MdePkg.dec StdLib/StdLib.dec + LLVM/LLVMPkg.dec +# dynamic deps $(expand_array_inf "${DEP_PACKAGES[@]}") [LibraryClasses] +# MdePkg UefiApplicationEntryPoint UefiLib +# C Libs $(expand_array_inf "${C_LIBRARIES[@]}") +# CPP Libs +$(expand_array_inf "${CPP_LIBRARIES[@]}") +# Dep Classes $(expand_array_inf "${DEP_CLASSES[@]}") [Guids] @@ -464,14 +474,18 @@ elif [ "$MAPPING_TYPE" == "library" ]; then $(expand_array_inf "${DEP_SOURCES[@]}") [Packages] +# basic deps MdePkg/MdePkg.dec StdLib/StdLib.dec +# dynamic deps $(expand_array_inf "${DEP_PACKAGES[@]}") [LibraryClasses] +# MdePkg UefiLib +# C Libs $(expand_array_inf "${C_LIBRARIES[@]}") -$(expand_array_inf "${CPP_LIBRARIES[@]}") +# Dep Classes $(expand_array_inf "${DEP_CLASSES[@]}") [BuildOptions] diff --git a/platforms/uefi/g++-wrapper.sh b/platforms/uefi/g++-wrapper.sh index e88adbb8..a7abb083 100755 --- a/platforms/uefi/g++-wrapper.sh +++ b/platforms/uefi/g++-wrapper.sh @@ -47,7 +47,7 @@ for ARG in "${ARGS[@]}"; do change_mode "link" LINK_ARG="${ARG:4}" case "$LINK_ARG" in - --as-needed | --no-undefined | --whole-archive | --no-whole-archive | -O* | -soname,* | -rpath,*) + --as-needed | --no-undefined | --fatal-warnings | --whole-archive | --no-whole-archive | -O* | -soname,* | -rpath,*) # ignore, valid arguments ;; --start-group) diff --git a/platforms/uefi/gcc-wrapper.sh b/platforms/uefi/gcc-wrapper.sh index 5a285f96..61954a27 100755 --- a/platforms/uefi/gcc-wrapper.sh +++ b/platforms/uefi/gcc-wrapper.sh @@ -45,7 +45,7 @@ for ARG in "${ARGS[@]}"; do change_mode "link" LINK_ARG="${ARG:4}" case "$LINK_ARG" in - --as-needed | --no-undefined | --whole-archive | --no-whole-archive | -O* | -soname,* | -rpath,*) + --as-needed | --no-undefined | --fatal-warnings | --whole-archive | --no-whole-archive | -O* | -soname,* | -rpath,*) # ignore, valid arguments ;; --start-group) diff --git a/tools/dependencies/meson.build b/tools/dependencies/meson.build index a753b2c7..fc098827 100644 --- a/tools/dependencies/meson.build +++ b/tools/dependencies/meson.build @@ -134,7 +134,7 @@ if meson.is_cross_build() } elif host_machine.system() == 'uefi' - warning('TODO: implement') + # nothing special to do for uefi else error('Unhandled cross built system: ' + host_machine.system()) endif From 47313b7e1064cda863cb1451aaa94beb992d0ed8 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 11 Aug 2026 14:21:24 +0200 Subject: [PATCH 111/112] fix: fix library ordering --- platforms/uefi/extract-definitions.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 0526cf30..8e40e8d8 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -398,8 +398,8 @@ $(expand_array_inf "${DEP_SOURCES[@]}") [Packages] # basic deps MdePkg/MdePkg.dec - StdLib/StdLib.dec LLVM/LLVMPkg.dec + StdLib/StdLib.dec # dynamic deps $(expand_array_inf "${DEP_PACKAGES[@]}") @@ -476,9 +476,10 @@ $(expand_array_inf "${DEP_SOURCES[@]}") [Packages] # basic deps MdePkg/MdePkg.dec - StdLib/StdLib.dec # dynamic deps $(expand_array_inf "${DEP_PACKAGES[@]}") +# stdlib + StdLib/StdLib.dec [LibraryClasses] # MdePkg From a8d20cf71bb1fe09d05e2a33d229bbece55e7c32 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Wed, 12 Aug 2026 14:19:05 +0200 Subject: [PATCH 112/112] fix: fix some uefi edk2 issues - use newer edk2 version - use correct llvm port for uefi - use ports for sdl2 from github --- platforms/build-uefi.sh | 14 ++++++-------- platforms/uefi/g++-wrapper.sh | 2 -- platforms/versions.sh | 6 +++--- src/executables/platforms/uefi/meson.build | 18 ++++++++++++++++-- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 9c0fa8e4..eaa34c6d 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -95,7 +95,7 @@ else git -C "$EDK2_ROOT" fetch fi -git -C "$EDK2_ROOT" checkout "$EDK2_RELEASE_TAG" +git -C "$EDK2_ROOT" checkout "$EDK2_COMMIT_HASH" git -C "$EDK2_ROOT" submodule update --init export EDK2_LIBC_ROOT="$TOOLCHAIN_DIR/edk2-libc" @@ -112,13 +112,13 @@ export EDK2_LLVM_ROOT="$TOOLCHAIN_DIR/llvm-project" if [ ! -d "$EDK2_LLVM_ROOT" ]; then - git clone --filter=blob:none --sparse https://github.com/llvm/llvm-project.git "$EDK2_LLVM_ROOT" - git -C "$EDK2_LLVM_ROOT" sparse-checkout set libcxx libc libcxxabi + git clone --filter=blob:none --sparse https://github.com/Totto16/llvm-project.git "$EDK2_LLVM_ROOT" + git -C "$EDK2_LLVM_ROOT" sparse-checkout set libcxx libc libcxxabi libunwind else git -C "$EDK2_LLVM_ROOT" fetch fi -git -C "$EDK2_LLVM_ROOT" checkout "$EDK2_LLVM_RELEASE_TAG" +git -C "$EDK2_LLVM_ROOT" checkout "$EDK2_LLVM_PORT_BRANCH" export EDK_TOOLS_PATH="$EDK2_ROOT/BaseTools" export PACKAGES_PATH="$EDK2_ROOT" @@ -245,9 +245,6 @@ for EDK2_PORT_KEY in "${!EDK2_PORT_NAMES[@]}"; do EDK2_PORT_ROOT="$TOOLCHAIN_DIR/$EDK2_PORT_NAME" - #TODO: use after sdl2 packages are ported - continue - if [ ! -d "$EDK2_PORT_ROOT" ]; then git clone "$EDK2_PORT_URL" "$EDK2_PORT_ROOT" else @@ -365,7 +362,8 @@ export EDK2_INFO_FILE="./platforms/crossbuild/uefi_info.json" validate_parent_dir "$EDK2_INFO_FILE" -export EDK2_GENERATED_PACKAGES="$(pwd)/$BUILD_DIR/GeneratedPackages" +EDK2_GENERATED_PACKAGES="$(pwd)/$BUILD_DIR/GeneratedPackages" +export EDK2_GENERATED_PACKAGES cat <"$EDK2_INFO_FILE" { diff --git a/platforms/uefi/g++-wrapper.sh b/platforms/uefi/g++-wrapper.sh index a7abb083..ed2cc67e 100755 --- a/platforms/uefi/g++-wrapper.sh +++ b/platforms/uefi/g++-wrapper.sh @@ -18,8 +18,6 @@ TOOL="G++" # shellcheck source=./platforms/uefi/base.sh source "$SCRIPT_DIR/base.sh" -COMPILED=() - # Capture all args ARGS=("$@") diff --git a/platforms/versions.sh b/platforms/versions.sh index 225d9dbd..f5eb584b 100755 --- a/platforms/versions.sh +++ b/platforms/versions.sh @@ -33,8 +33,8 @@ export EMSDK_EXECUTE_NODE_VERSION="24.7.0" # edk2 section -export EDK2_RELEASE_TAG="edk2-stable202605" +export EDK2_COMMIT_HASH="2970e5699ba6267f3384ffab20f96647578aebc8" -export EDK2_LIBC_COMMIT_HASH="c8313c11c2dc43647aa4c9f73baf3b323c68ecba" +export EDK2_LIBC_COMMIT_HASH="e6985d1dd786f89be3c908ec7b19e3e6da463578" -export EDK2_LLVM_RELEASE_TAG="llvmorg-22.1.8" +export EDK2_LLVM_PORT_BRANCH="uefi_port" diff --git a/src/executables/platforms/uefi/meson.build b/src/executables/platforms/uefi/meson.build index 278fae8a..0e98a3f7 100644 --- a/src/executables/platforms/uefi/meson.build +++ b/src/executables/platforms/uefi/meson.build @@ -109,6 +109,11 @@ if _qemu_system_exe.found() build_by_default: false, ) + user_vars_fd = fs.copyfile( + OVMF_VARS_fd_path, + 'OVMF_VARS.fd', + ) + emulate_command = [ _qemu_system_exe, '-cpu', @@ -116,7 +121,7 @@ if _qemu_system_exe.found() '-drive', 'if=pflash,format=raw,unit=0,file=' + OVMF_CODE_fd_path + ',readonly=on', '-drive', - 'if=pflash,format=raw,unit=1,file=' + OVMF_VARS_fd_path, + 'if=pflash,format=raw,unit=1,file=' + user_vars_fd.full_path(), '-drive', 'format=raw,file=fat:rw:' + fat_folder_loc, '-net', @@ -124,9 +129,18 @@ if _qemu_system_exe.found() ] if get_option('buildtype') != 'release' - emulate_command += ['-debugcon', 'stdio', '-global', 'isa-debugcon.iobase=0x402'] + emulate_command += [ + '-debugcon', + 'stdio', + '-global', + 'isa-debugcon.iobase=0x402', + '-s', + '-S', + ] endif + + run_target( 'emulate_efi', command: emulate_command,