From 8606b3d42fcee43bb3636829b8436e7b5fae81ae Mon Sep 17 00:00:00 2001 From: Totto16 Date: Mon, 13 Oct 2025 19:54:52 +0200 Subject: [PATCH 001/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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/143] 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, From 8e631ba9068c1ce8b79229ed0c055671655924a6 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Mon, 17 Aug 2026 21:26:04 +0200 Subject: [PATCH 113/143] feat: change some uefi related things - use custom platform for building the application --- platforms/build-uefi.sh | 98 +++++---- platforms/uefi/OOPetrisPlatform.template.dsc | 202 +++++++++++++++++++ platforms/uefi/compile-final.sh | 6 +- platforms/uefi/use_arch_x86_64_v1.diff | 131 ++++++++++++ platforms/versions.sh | 2 +- src/executables/platforms/uefi/meson.build | 195 ++++++++++-------- 6 files changed, 501 insertions(+), 133 deletions(-) create mode 100644 platforms/uefi/OOPetrisPlatform.template.dsc create mode 100644 platforms/uefi/use_arch_x86_64_v1.diff diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index eaa34c6d..134da51b 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="hardware" +export RUNTIME_TARGET="emulator" if [ "$#" -eq 0 ]; then # nothing @@ -61,10 +61,8 @@ 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' 'hardware' or 'ovmf'" >&2 + echo "Invalid RUNTIME_TARGET, expected: 'emulator' or 'hardware'" >&2 exit 1 fi @@ -95,7 +93,7 @@ else git -C "$EDK2_ROOT" fetch fi -git -C "$EDK2_ROOT" checkout "$EDK2_COMMIT_HASH" +git -C "$EDK2_ROOT" checkout "$EDK2_RELEASE_TAG" git -C "$EDK2_ROOT" submodule update --init export EDK2_LIBC_ROOT="$TOOLCHAIN_DIR/edk2-libc" @@ -123,16 +121,21 @@ git -C "$EDK2_LLVM_ROOT" checkout "$EDK2_LLVM_PORT_BRANCH" export EDK_TOOLS_PATH="$EDK2_ROOT/BaseTools" export PACKAGES_PATH="$EDK2_ROOT" -PATCH_DIR="platforms/uefi" +PLATFORMS_DIR="$(pwd)/platforms/uefi" + +PATCH_DIR="$PLATFORMS_DIR" EDK2_PATCH_FILE="$EDK2_ROOT/.patched_manually.meta" if ! [ -e "$EDK2_PATCH_FILE" ]; then ##TODO: upstream those patches + #TODO: use loop for this patches + 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/use_arch_x86_64_v1.diff" touch "$EDK2_PATCH_FILE" fi @@ -162,45 +165,14 @@ 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" -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 -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 - -# add llvm to active platform - -LLVM_PACKAGE_INCLUDE="!include LLVM/LLVMPkg.inc" - -if grep -q "$LLVM_PACKAGE_INCLUDE" "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM"; then - : # found already, do nothing -else - echo -e "$LLVM_PACKAGE_INCLUDE\n" >>"$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" -fi +EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM_NAME="Platforms/OOPetrisPlatform.dsc" 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") +declare -A EDK2_TARGET_PROPERTIES=(["ACTIVE_PLATFORM"]="$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM_NAME" ["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]}" @@ -277,7 +249,7 @@ export ENDIANESS="little" export ROMFS="platforms/romfs" -export COMMON_FLAGS="'-m64', '-maccumulate-outgoing-args', '-mno-red-zone', '-mcmodel=small'" +export COMMON_FLAGS="'-m64', '-march=x86-64', '-maccumulate-outgoing-args', '-mno-red-zone', '-mcmodel=small'" export SYS_ROOT="$WORKSPACE" @@ -294,6 +266,8 @@ export CROSS_FILE="./platforms/crossbuild/uefi.ini" validate_parent_dir "$CROSS_FILE" +## note: UEFI_USE_GDB can be set via environment variables, to use gdb + cat <"$CROSS_FILE" [host_machine] system = 'uefi' @@ -338,6 +312,8 @@ sys_root = '${SYS_ROOT}' needs_exe_wrapper = true APP_ROMFS='$ROMFS/assets/' +RUNTIME_TARGET='$RUNTIME_TARGET' +USE_GDB='${UEFI_USE_GDB:-false}' [cmake] @@ -365,21 +341,54 @@ validate_parent_dir "$EDK2_INFO_FILE" EDK2_GENERATED_PACKAGES="$(pwd)/$BUILD_DIR/GeneratedPackages" export EDK2_GENERATED_PACKAGES +export EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM="$WORKSPACE/$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM_NAME" + cat <"$EDK2_INFO_FILE" { "build": "$EDK2_BUILD_COMMAND", "arch": "$EDK2_TARGET_PROPERTIES_ARCH", "workspace": "$WORKSPACE", - "platform": "$WORKSPACE/$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM", - "platform_name": "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM", + "platform": "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM", + "platform_name": "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM_NAME", "buildtype": "$EDK2_TARGET_PROPERTIES_BUILDTYPE", "toolchain": "$EDK2_TARGET_PROPERTIES_TOOLCHAIN", - "generated_packages": "$EDK2_GENERATED_PACKAGES" + "generated_packages": "$EDK2_GENERATED_PACKAGES", + "runtime_target": "$RUNTIME_TARGET" } EOF -if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "$BUILD_DIR" ]; then +if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "${EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM:?}" ]; then + rm -f "${EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM:?}" + + # copy template for oopetris platform + + mkdir -p "$(dirname "${EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM:?}")" + + cp "$PLATFORMS_DIR/OOPetrisPlatform.template.dsc" "${EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM:?}" + + # 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 + + # add llvm to active platform + + LLVM_PACKAGE_INCLUDE="!include LLVM/LLVMPkg.inc" + + if grep -q "$LLVM_PACKAGE_INCLUDE" "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM"; then + : # found already, do nothing + else + echo -e "$LLVM_PACKAGE_INCLUDE\n" >>"$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" + fi + +fi +if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "$BUILD_DIR" ]; then rm -rf "$WORKSPACE/Build/" meson setup "$BUILD_DIR" \ @@ -400,6 +409,7 @@ if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "$BUILD_DIR" ]; then echo "mkdir: $EDK2_GENERATED_PACKAGES" mkdir -p "$EDK2_GENERATED_PACKAGES" link_files_checked "$EDK2_GENERATED_PACKAGES" "$WORKSPACE/GeneratedPackages" + fi fi diff --git a/platforms/uefi/OOPetrisPlatform.template.dsc b/platforms/uefi/OOPetrisPlatform.template.dsc new file mode 100644 index 00000000..b7e01854 --- /dev/null +++ b/platforms/uefi/OOPetrisPlatform.template.dsc @@ -0,0 +1,202 @@ +[Defines] + PLATFORM_NAME = OOPetrisModule + PLATFORM_GUID = 6e7aa053-beda-40a8-b729-375bd9c71e2c + PLATFORM_VERSION = 1.0 + DSC_SPECIFICATION = 0x0001001B + OUTPUT_DIRECTORY = Build/OOPetrisModule + SUPPORTED_ARCHITECTURES = X64 + BUILD_TARGETS = DEBUG|RELEASE + SKUID_IDENTIFIER = DEFAULT + + +!ifndef OOPETRIS_RUNTIME_TARGET + !error "OOPETRIS_RUNTIME_TARGET must be set" +!endif + + # + # RUNTIME TARGET related defintions + # + +!if $(OOPETRIS_RUNTIME_TARGET) == "hardware" + DEFINE PLAT_QEMU = FALSE + DEFINE QEMU_PV_VARS = FALSE + DEFINE DEBUG_ON_SERIAL_PORT = FALSE +!elseif $(OOPETRIS_RUNTIME_TARGET) == "emulator" + DEFINE PLAT_QEMU = TRUE + DEFINE QEMU_PV_VARS = FALSE + DEFINE DEBUG_ON_SERIAL_PORT = TRUE +!else + !error "OOPETRIS_RUNTIME_TARGET has invalid value" +!endif + + # + # Default definitions + # + + DEFINE TTY_TERMINAL = FALSE + DEFINE DEBUG_TO_MEM = FALSE + + # + # Network definition + # + DEFINE NETWORK_SNP_ENABLE = FALSE + DEFINE NETWORK_IP6_ENABLE = TRUE + DEFINE NETWORK_TLS_ENABLE = TRUE + DEFINE NETWORK_HTTP_BOOT_ENABLE = FALSE + DEFINE NETWORK_ALLOW_HTTP_CONNECTIONS = TRUE + DEFINE NETWORK_HTTP_ENABLE = TRUE + DEFINE NETWORK_ISCSI_ENABLE = FALSE + DEFINE SECURE_BOOT_ENABLE = FALSE + DEFINE NETWORK_PXE_BOOT_ENABLE = FALSE + + # + # Other defintions + # + + DEFINE CUSTOM_STACK_CHECK_LIB = "STATIC" + + + + # + # Redfish definition + # + DEFINE REDFISH_ENABLE = FALSE + + !include MdePkg/MdeLibs.dsc.inc + +[Packages] + MdePkg/MdePkg.dec + + + +[LibraryClasses] + # + # Entry point (only application supported) + # + UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf + + # + # Basic + # + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf + PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf + PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf + PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf + CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf + PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + SortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf + + # + # UEFI & PI + # + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf + UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf + + # + # Generic Modules + # + UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf + UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf + SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf + TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf + +!if $(OOPETRIS_RUNTIME_TARGET) == "hardware" + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf +!else + MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogLibNull.inf + DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf +!endif + + CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf + FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf + + # + # Misc + # + ## see above: DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf + ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf + PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf + DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf + PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf + ResetSystemLib|MdeModulePkg/Library/BaseResetSystemLibNull/BaseResetSystemLibNull.inf + SmbusLib|MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf + S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf + CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf + PlatformBootManagerLib|MdeModulePkg/Library/PlatformBootManagerLibNull/PlatformBootManagerLibNull.inf + PciHostBridgeLib|MdeModulePkg/Library/PciHostBridgeLibNull/PciHostBridgeLibNull.inf + TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf + TdxMeasurementLib|MdeModulePkg/Library/TdxMeasurementLibNull/TdxMeasurementLibNull.inf + AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf + VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf + FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf + NonDiscoverableDeviceRegistrationLib|MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.inf + ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf + + FmpAuthenticationLib|MdeModulePkg/Library/FmpAuthenticationLibNull/FmpAuthenticationLibNull.inf + BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf + SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf + DisplayUpdateProgressLib|MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.inf + VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf + MmUnblockMemoryLib|MdePkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLibNull.inf + VariableFlashInfoLib|MdeModulePkg/Library/BaseVariableFlashInfoLib/BaseVariableFlashInfoLib.inf + IpmiCommandLib|MdeModulePkg/Library/BaseIpmiCommandLibNull/BaseIpmiCommandLibNull.inf + SpiHcPlatformLib|MdeModulePkg/Library/BaseSpiHcPlatformLibNull/BaseSpiHcPlatformLibNull.inf + + + ###TODO: +### +### + ### RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf + ### StackCheckLib|MdePkg/Library/StackCheckLib/StackCheckLib.inf + ### StackCheckFailureHookLib|MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf + ### PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf + ### PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf +### +### + +[LibraryClasses.common.UEFI_APPLICATION] + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + #see above: DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf + FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf + +[PcdsFixedAtBuild] +!if $(OOPETRIS_RUNTIME_TARGET) == "hardware" +# nothing +!else +#define DEBUG_WARN 0x00000002 // Warnings +#define DEBUG_INFO 0x00000040 // Informational debug messages +#define DEBUG_VERBOSE 0x00400000 // Detailed debug messages that may +#define DEBUG_ERROR 0x80000000 // Error +gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80400042 + +## This flag is used to control the destination port for PlatformDebugLibIoPort +# this is the same address as QEMU uses + gUefiOvmfPkgTokenSpaceGuid.PcdDebugIoPort|0x402|UINT16|4 + +#define DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED 0x01 +#define DEBUG_PROPERTY_DEBUG_PRINT_ENABLED 0x02 +#define DEBUG_PROPERTY_DEBUG_CODE_ENABLED 0x04 +#define DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED 0x08 +#define DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED 0x10 +#define DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED 0x20 + + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F +!endif + +# inserted components after that diff --git a/platforms/uefi/compile-final.sh b/platforms/uefi/compile-final.sh index a14a9899..73a30c33 100755 --- a/platforms/uefi/compile-final.sh +++ b/platforms/uefi/compile-final.sh @@ -28,6 +28,7 @@ EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM="$(jq -M -r -c '.["platform"]' "$UEFI_INF 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")" +EDK2_TARGET_PROPERTIES_RUNTIME_TARGET="$(jq -M -r -c '.["runtime_target"]' "$UEFI_INFO_FILE")" BUILD_NAME=$(basename -- $"$BUILD_INF") @@ -55,14 +56,15 @@ fi -m "$BUILD_FILE_TARGET" \ -b "$EDK2_TARGET_PROPERTIES_BUILDTYPE" \ -t "$EDK2_TARGET_PROPERTIES_TOOLCHAIN" \ + -D "OOPETRIS_RUNTIME_TARGET=$EDK2_TARGET_PROPERTIES_RUNTIME_TARGET" \ -w # -v # verbose ##TODO: un-hardcode this ##NOTE: this is just hardcoded PACKAGE_NAME="OOPetrisApplication" -if [ "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM_NAME" == "MdeModulePkg/MdeModulePkg.dsc" ]; then - MODULE_NAME="MdeModule" +if [ "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM_NAME" == "Platforms/OOPetrisPlatform.dsc" ]; then + MODULE_NAME="OOPetrisModule" else echo "MODULE_NAME mapping not supported for platform: $EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM_NAME" >&2 exit 2 diff --git a/platforms/uefi/use_arch_x86_64_v1.diff b/platforms/uefi/use_arch_x86_64_v1.diff new file mode 100644 index 00000000..1a761bce --- /dev/null +++ b/platforms/uefi/use_arch_x86_64_v1.diff @@ -0,0 +1,131 @@ +diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template +index eca4cb82d0..f5f3f1c447 100644 +--- a/BaseTools/Conf/tools_def.template ++++ b/BaseTools/Conf/tools_def.template +@@ -956,7 +956,7 @@ DEFINE GCC_DEPS_FLAGS = -MMD -MF $@.deps + DEFINE GCC_ALL_CC_FLAGS = DEF(GCC_ALL_CC_COMMON) -ffunction-sections -fdata-sections -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings + + DEFINE GCCNOLTO_IA32_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) DEF(GCC_IA32_X64_CC_FLAGS) -m32 -march=i586 -malign-double -D EFI32 -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer -fno-pic -fno-pie +-DEFINE GCCNOLTO_X64_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) DEF(GCC_IA32_X64_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer ++DEFINE GCCNOLTO_X64_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) DEF(GCC_IA32_X64_CC_FLAGS) -m64 -march=x86-64 "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer + DEFINE GCCNOLTO_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections -z common-page-size=0x40 + DEFINE GCCNOLTO_IA32_X64_ASLDLINK_FLAGS = DEF(GCCNOLTO_IA32_X64_DLINK_COMMON) -Wl,--defsym=PECOFF_HEADER_SIZE=0 DEF(GCC_DLINK2_FLAGS_COMMON) -Wl,--entry,ReferenceAcpiTable -u ReferenceAcpiTable + DEFINE GCCNOLTO_IA32_X64_DLINK_FLAGS = DEF(GCCNOLTO_IA32_X64_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map,--whole-archive +@@ -1076,9 +1076,9 @@ RELEASE_GCCNOLTO_IA32_CC_FLAGS = DEF(GCCNOLTO_IA32_CC_FLAGS) + *_GCCNOLTO_X64_ASLPP_PATH = DEF(GCCNOLTO_X64_PREFIX)gcc + *_GCCNOLTO_X64_RC_PATH = DEF(GCCNOLTO_X64_PREFIX)objcopy + +-*_GCCNOLTO_X64_ASLCC_FLAGS = DEF(GCCNOLTO_ASLCC_FLAGS) -m64 ++*_GCCNOLTO_X64_ASLCC_FLAGS = DEF(GCCNOLTO_ASLCC_FLAGS) -m64 -march=x86-64 + *_GCCNOLTO_X64_ASLDLINK_FLAGS = DEF(GCCNOLTO_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_x86_64 +-*_GCCNOLTO_X64_ASM_FLAGS = DEF(GCCNOLTO_ASM_FLAGS) -m64 ++*_GCCNOLTO_X64_ASM_FLAGS = DEF(GCCNOLTO_ASM_FLAGS) -m64 -march=x86-64 + *_GCCNOLTO_X64_DLINK_FLAGS = DEF(GCCNOLTO_X64_DLINK_FLAGS) + *_GCCNOLTO_X64_DLINK2_FLAGS = DEF(GCCNOLTO_X64_DLINK2_FLAGS) + *_GCCNOLTO_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS) +@@ -1194,9 +1194,9 @@ RELEASE_GCC_IA32_DLINK_FLAGS = DEF(GCC_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,-m + *_GCC_X64_ASLPP_PATH = DEF(GCC_X64_PREFIX)gcc + *_GCC_X64_RC_PATH = DEF(GCC_X64_PREFIX)objcopy + +-*_GCC_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m64 ++*_GCC_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m64 -march=x86-64 + *_GCC_X64_ASLDLINK_FLAGS = DEF(GCC_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_x86_64 +-*_GCC_X64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -m64 ++*_GCC_X64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -m64 -march=x86-64 + *_GCC_X64_DLINK2_FLAGS = DEF(GCC_X64_DLINK2_FLAGS) + *_GCC_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS) + *_GCC_X64_OBJCOPY_FLAGS = +@@ -1394,8 +1394,8 @@ NOOPT_CLANGPDB_IA32_DLINK2_FLAGS = + *_CLANGPDB_X64_ASLPP_PATH = DEF(CLANGPDB_X64_PREFIX)clang + *_CLANGPDB_X64_RC_PATH = DEF(CLANGPDB_IA32_PREFIX)llvm-rc + +-*_CLANGPDB_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_COMMON) -m64 -fno-lto DEF(CLANGPDB_X64_TARGET) +-*_CLANGPDB_X64_ASM_FLAGS = DEF(GCC_ASM_COMMON) -m64 DEF(CLANGPDB_X64_TARGET) ++*_CLANGPDB_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_COMMON) -m64 -march=x86-64 -fno-lto DEF(CLANGPDB_X64_TARGET) ++*_CLANGPDB_X64_ASM_FLAGS = DEF(GCC_ASM_COMMON) -m64 -march=x86-64 DEF(CLANGPDB_X64_TARGET) + *_CLANGPDB_X64_OBJCOPY_FLAGS = + + DEBUG_CLANGPDB_X64_NASM_FLAGS = -Ox -f win64 -g +@@ -1406,17 +1406,17 @@ NOOPT_CLANGPDB_X64_NASM_FLAGS = -O0 -f win64 -g + *_CLANGPDB_X64_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS) DEF(CLANGPDB_X64_TARGET) + *_CLANGPDB_X64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGPDB_X64_TARGET) + +-DEBUG_CLANGPDB_X64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -Oz -flto DEF(CLANGPDB_X64_TARGET) -gcodeview -funwind-tables ++DEBUG_CLANGPDB_X64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 -march=x86-64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -Oz -flto DEF(CLANGPDB_X64_TARGET) -gcodeview -funwind-tables + DEBUG_CLANGPDB_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /ALIGN:4096 /DRIVER /FILEALIGN:32 /Machine:X64 /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap + DEBUG_CLANGPDB_X64_DLINK2_FLAGS = + DEBUG_CLANGPDB_X64_GENFW_FLAGS = --keepexceptiontable + +-RELEASE_CLANGPDB_X64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -Oz -flto DEF(CLANGPDB_X64_TARGET) -fno-unwind-tables ++RELEASE_CLANGPDB_X64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 -march=x86-64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -Oz -flto DEF(CLANGPDB_X64_TARGET) -fno-unwind-tables + RELEASE_CLANGPDB_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /ALIGN:4096 /DRIVER /FILEALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /MERGE:.rdata=.data /MLLVM:-exception-model=wineh /lldmap + RELEASE_CLANGPDB_X64_DLINK2_FLAGS = + RELEASE_CLANGPDB_X64_GENFW_FLAGS = + +-NOOPT_CLANGPDB_X64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -O0 DEF(CLANGPDB_X64_TARGET) -gcodeview -funwind-tables ++NOOPT_CLANGPDB_X64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 -march=x86-64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -O0 DEF(CLANGPDB_X64_TARGET) -gcodeview -funwind-tables + NOOPT_CLANGPDB_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /ALIGN:32 /DRIVER /FILEALIGN:32 /Machine:X64 /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap + NOOPT_CLANGPDB_X64_DLINK2_FLAGS = + NOOPT_CLANGPDB_X64_GENFW_FLAGS = --keepexceptiontable +@@ -1437,8 +1437,8 @@ NOOPT_CLANGPDB_X64_GENFW_FLAGS = --keepexceptiontable + *_CLANGPDB_AARCH64_ASLPP_PATH = DEF(CLANGPDB_AARCH64_PREFIX)clang + *_CLANGPDB_AARCH64_RC_PATH = DEF(CLANGPDB_AARCH64_PREFIX)llvm-rc + +-*_CLANGPDB_AARCH64_ASLCC_FLAGS = DEF(GCC_ASLCC_COMMON) -m64 -fno-lto DEF(CLANGPDB_AARCH64_TARGET) +-*_CLANGPDB_AARCH64_ASM_FLAGS = DEF(GCC_ASM_COMMON) -m64 DEF(CLANGPDB_AARCH64_TARGET) ++*_CLANGPDB_AARCH64_ASLCC_FLAGS = DEF(GCC_ASLCC_COMMON) -m64 -march=x86-64-fno-lto DEF(CLANGPDB_AARCH64_TARGET) ++*_CLANGPDB_AARCH64_ASM_FLAGS = DEF(GCC_ASM_COMMON) -m64 -march=x86-64 DEF(CLANGPDB_AARCH64_TARGET) + *_CLANGPDB_AARCH64_OBJCOPY_FLAGS = + *_CLANGPDB_AARCH64_NASM_FLAGS = -f win64 + *_CLANGPDB_AARCH64_PP_FLAGS = DEF(GCC_PP_FLAGS) DEF(CLANGPDB_AARCH64_TARGET) +@@ -1446,16 +1446,16 @@ NOOPT_CLANGPDB_X64_GENFW_FLAGS = --keepexceptiontable + *_CLANGPDB_AARCH64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGPDB_AARCH64_TARGET) + *_CLANGPDB_AARCH64_CC_XIPFLAGS = -mstrict-align + +-DEBUG_CLANGPDB_AARCH64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 -mcmodel=small -Oz -flto DEF(CLANGPDB_AARCH64_TARGET) -gcodeview -funwind-tables -Wno-deprecated-non-prototype -Wno-constant-conversion -Werror ++DEBUG_CLANGPDB_AARCH64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 -march=x86-64 -mcmodel=small -Oz -flto DEF(CLANGPDB_AARCH64_TARGET) -gcodeview -funwind-tables -Wno-deprecated-non-prototype -Wno-constant-conversion -Werror + DEBUG_CLANGPDB_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /WX /OPT:REF /OPT:ICF=10 /ALIGN:4096 /Machine:ARM64 /DLL /DRIVER /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap + DEBUG_CLANGPDB_AARCH64_DLINK2_FLAGS = + DEBUG_CLANGPDB_AARCH64_GENFW_FLAGS = --keepexceptiontable + +-RELEASE_CLANGPDB_AARCH64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 -mcmodel=small -Oz -flto DEF(CLANGPDB_AARCH64_TARGET) -fno-unwind-tables -Wno-deprecated-non-prototype -Wno-constant-conversion -Werror ++RELEASE_CLANGPDB_AARCH64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 -march=x86-64 -mcmodel=small -Oz -flto DEF(CLANGPDB_AARCH64_TARGET) -fno-unwind-tables -Wno-deprecated-non-prototype -Wno-constant-conversion -Werror + RELEASE_CLANGPDB_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /WX /OPT:REF /OPT:ICF=10 /ALIGN:4096 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:ARM64 /DLL /DRIVER /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /MERGE:.rdata=.data /MLLVM:-exception-model=wineh /lldmap + RELEASE_CLANGPDB_AARCH64_DLINK2_FLAGS = + +-NOOPT_CLANGPDB_AARCH64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 -mcmodel=small -O0 DEF(CLANGPDB_AARCH64_TARGET) -gcodeview -funwind-tables -Wno-deprecated-non-prototype -Wno-constant-conversion -Werror ++NOOPT_CLANGPDB_AARCH64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 -march=x86-64 -mcmodel=small -O0 DEF(CLANGPDB_AARCH64_TARGET) -gcodeview -funwind-tables -Wno-deprecated-non-prototype -Wno-constant-conversion -Werror + NOOPT_CLANGPDB_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /WX /OPT:REF /OPT:ICF=10 /ALIGN:4096 /Machine:ARM64 /DLL /DRIVER /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap + NOOPT_CLANGPDB_AARCH64_DLINK2_FLAGS = + NOOPT_CLANGPDB_AARCH64_GENFW_FLAGS = --keepexceptiontable +@@ -1569,9 +1569,9 @@ NOOPT_CLANGDWARF_IA32_DLINK2_FLAGS = DEF(CLANGDWARF_IA32_DLINK2_FLAGS) -O0 - + *_CLANGDWARF_X64_ASLPP_PATH = DEF(CLANGDWARF_X64_PREFIX)clang + *_CLANGDWARF_X64_RC_PATH = DEF(CLANGDWARF_X64_PREFIX)llvm-objcopy + +-*_CLANGDWARF_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_COMMON) -m64 -fno-lto DEF(CLANGDWARF_X64_TARGET) ++*_CLANGDWARF_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_COMMON) -m64 -march=x86-64 -fno-lto DEF(CLANGDWARF_X64_TARGET) + *_CLANGDWARF_X64_ASLDLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_x86_64 -fuse-ld=lld +-*_CLANGDWARF_X64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -m64 DEF(CLANGDWARF_X64_TARGET) ++*_CLANGDWARF_X64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -m64 -march=x86-64 DEF(CLANGDWARF_X64_TARGET) + *_CLANGDWARF_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS) + *_CLANGDWARF_X64_OBJCOPY_FLAGS = + +@@ -1583,15 +1583,15 @@ NOOPT_CLANGDWARF_X64_NASM_FLAGS = -O0 -f elf64 -g + *_CLANGDWARF_X64_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS) DEF(CLANGDWARF_X64_TARGET) + *_CLANGDWARF_X64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGDWARF_X64_TARGET) + +-DEBUG_CLANGDWARF_X64_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -fpie -fdirect-access-external-data -Oz -flto DEF(CLANGDWARF_X64_TARGET) -g -funwind-tables ++DEBUG_CLANGDWARF_X64_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -m64 -march=x86-64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -fpie -fdirect-access-external-data -Oz -flto DEF(CLANGDWARF_X64_TARGET) -g -funwind-tables + DEBUG_CLANGDWARF_X64_DLINK_FLAGS = DEF(CLANGDWARF_X64_TARGET) DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -flto -Wl,-O3 -Wl,-melf_x86_64 -Wl,--oformat,elf64-x86-64 -Wl,-pie -mcmodel=small -Wl,--apply-dynamic-relocs -z common-page-size=0x1000 + DEBUG_CLANGDWARF_X64_DLINK2_FLAGS = DEF(CLANGDWARF_X64_DLINK2_FLAGS) -O3 -fuse-ld=lld + +-RELEASE_CLANGDWARF_X64_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -fpie -fdirect-access-external-data -Oz -flto DEF(CLANGDWARF_X64_TARGET) ++RELEASE_CLANGDWARF_X64_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -m64 -march=x86-64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -fpie -fdirect-access-external-data -Oz -flto DEF(CLANGDWARF_X64_TARGET) + RELEASE_CLANGDWARF_X64_DLINK_FLAGS = DEF(CLANGDWARF_X64_TARGET) DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -flto -Wl,-O3 -Wl,-melf_x86_64 -Wl,--oformat,elf64-x86-64 -Wl,-pie -mcmodel=small -Wl,--apply-dynamic-relocs -z common-page-size=0x1000 + RELEASE_CLANGDWARF_X64_DLINK2_FLAGS = DEF(CLANGDWARF_X64_DLINK2_FLAGS) -O3 -fuse-ld=lld + +-NOOPT_CLANGDWARF_X64_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -fpie -fdirect-access-external-data -O0 DEF(CLANGDWARF_X64_TARGET) -g -funwind-tables ++NOOPT_CLANGDWARF_X64_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -m64 -march=x86-64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -fpie -fdirect-access-external-data -O0 DEF(CLANGDWARF_X64_TARGET) -g -funwind-tables + NOOPT_CLANGDWARF_X64_DLINK_FLAGS = DEF(CLANGDWARF_X64_TARGET) DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -Wl,-O0 -Wl,-melf_x86_64 -Wl,--oformat,elf64-x86-64 -Wl,-pie -mcmodel=small -Wl,--apply-dynamic-relocs -z common-page-size=0x1000 + NOOPT_CLANGDWARF_X64_DLINK2_FLAGS = DEF(CLANGDWARF_X64_DLINK2_FLAGS) -O0 -fuse-ld=lld + diff --git a/platforms/versions.sh b/platforms/versions.sh index f5eb584b..aaba68c1 100755 --- a/platforms/versions.sh +++ b/platforms/versions.sh @@ -33,7 +33,7 @@ export EMSDK_EXECUTE_NODE_VERSION="24.7.0" # edk2 section -export EDK2_COMMIT_HASH="2970e5699ba6267f3384ffab20f96647578aebc8" +export EDK2_RELEASE_TAG="edk2-stable202605" export EDK2_LIBC_COMMIT_HASH="e6985d1dd786f89be3c908ec7b19e3e6da463578" diff --git a/src/executables/platforms/uefi/meson.build b/src/executables/platforms/uefi/meson.build index 0e98a3f7..9657703b 100644 --- a/src/executables/platforms/uefi/meson.build +++ b/src/executables/platforms/uefi/meson.build @@ -49,106 +49,129 @@ oopetris_efi = custom_target( output: [_uefi_exe_name + '.efi'], build_by_default: true, ) -_qemu_system_exe = find_program( - 'qemu-system-x86_64', - required: false, -) +RUNTIME_TARGET = meson.get_external_property('RUNTIME_TARGET', '') -if _qemu_system_exe.found() - cat = find_program('cat') +if RUNTIME_TARGET == 'hardware' + # nothing to do +elif RUNTIME_TARGET == 'emulator' + # add some qemu related targets + _qemu_system_exe = find_program( + 'qemu-system-x86_64', + required: false, + ) - os_release_info = run_command( - cat, - '/etc/os-release', - check: true, - ).stdout().strip().split('\n') - linux_distro = '' + if _qemu_system_exe.found() + cat = find_program('cat') - foreach line : os_release_info - line_detail = line.split('=') + os_release_info = run_command( + cat, + '/etc/os-release', + check: true, + ).stdout().strip().split('\n') - if line_detail[0] == 'ID' - linux_distro = line_detail[1] - endif + linux_distro = '' - endforeach + foreach line : os_release_info + line_detail = line.split('=') - 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 + if line_detail[0] == 'ID' + linux_distro = line_detail[1] + 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, - ) - - user_vars_fd = fs.copyfile( - OVMF_VARS_fd_path, - 'OVMF_VARS.fd', - ) - - 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=' + user_vars_fd.full_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', - '-s', - '-S', - ] + 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, + ) + + user_vars_fd = fs.copyfile( + OVMF_VARS_fd_path, + 'OVMF_VARS.fd', + ) + + emulate_command = [ + _qemu_system_exe, + # see https://www.qemu.org/docs/master/system/qemu-cpu-models.html#id1 + # this cpu has x86-64 v1 (baseline) support + '-cpu', + 'qemu64-v1', + '-drive', + 'if=pflash,format=raw,unit=0,file=' + OVMF_CODE_fd_path + ',readonly=on', + '-drive', + 'if=pflash,format=raw,unit=1,file=' + user_vars_fd.full_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', + ] + + + use_gdb = ['true', 'True', '1', true].contains( + meson.get_external_property('USE_GDB', '') + ) + + if use_gdb + emulate_command += [ + '-s', + '-S', + ] + endif + endif - run_target( - 'emulate_efi', - command: emulate_command, - depends: [oopetris_efi, fat_folder], - ) + + + run_target( + 'emulate_efi', + command: emulate_command, + depends: [oopetris_efi, fat_folder], + ) + else + warning('OVMF files couldn\'t be found: target for running efi not created') + endif else - warning('OVMF files couldn\'t be found: target for running efi not created') + warning('qemu couldn\'t be found: target for running efi not created') endif else - warning('qemu couldn\'t be found: target for running efi not created') + error('RUNTIME_TARGET has invalid value: \'' + RUNTIME_TARGET + '\'') endif From 914f7e62c5b027edf110fe24b2fb7a0cd7c5d074 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Mon, 17 Aug 2026 21:45:47 +0200 Subject: [PATCH 114/143] feat: fix missing libraries for the uefi libraries and the custom oopetris platform --- platforms/uefi/OOPetrisPlatform.template.dsc | 46 +++++++++++++------- platforms/uefi/extract-definitions.sh | 2 + 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/platforms/uefi/OOPetrisPlatform.template.dsc b/platforms/uefi/OOPetrisPlatform.template.dsc index b7e01854..6a7b96f3 100644 --- a/platforms/uefi/OOPetrisPlatform.template.dsc +++ b/platforms/uefi/OOPetrisPlatform.template.dsc @@ -15,7 +15,7 @@ # # RUNTIME TARGET related defintions - # + # !if $(OOPETRIS_RUNTIME_TARGET) == "hardware" DEFINE PLAT_QEMU = FALSE @@ -49,9 +49,9 @@ DEFINE SECURE_BOOT_ENABLE = FALSE DEFINE NETWORK_PXE_BOOT_ENABLE = FALSE - # + # # Other defintions - # + # DEFINE CUSTOM_STACK_CHECK_LIB = "STATIC" @@ -62,7 +62,7 @@ # DEFINE REDFISH_ENABLE = FALSE - !include MdePkg/MdeLibs.dsc.inc +!include MdePkg/MdeLibs.dsc.inc [Packages] MdePkg/MdePkg.dec @@ -71,8 +71,12 @@ [LibraryClasses] # - # Entry point (only application supported) + # Entry point # + PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf + PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf + DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf # @@ -98,6 +102,8 @@ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf + HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf @@ -157,17 +163,24 @@ IpmiCommandLib|MdeModulePkg/Library/BaseIpmiCommandLibNull/BaseIpmiCommandLibNull.inf SpiHcPlatformLib|MdeModulePkg/Library/BaseSpiHcPlatformLibNull/BaseSpiHcPlatformLibNull.inf +[LibraryClasses.common.DXE_CORE] + HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf + MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf + ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf + +[LibraryClasses.common.DXE_DRIVER] + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf + CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf + +[LibraryClasses.common.UEFI_DRIVER] + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf + LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf - ###TODO: -### -### - ### RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf - ### StackCheckLib|MdePkg/Library/StackCheckLib/StackCheckLib.inf - ### StackCheckFailureHookLib|MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf - ### PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf - ### PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf -### -### [LibraryClasses.common.UEFI_APPLICATION] HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf @@ -199,4 +212,5 @@ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80400042 gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F !endif -# inserted components after that +# inserted components / includes after that + diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 8e40e8d8..214dded7 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -398,6 +398,7 @@ $(expand_array_inf "${DEP_SOURCES[@]}") [Packages] # basic deps MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec LLVM/LLVMPkg.dec StdLib/StdLib.dec # dynamic deps @@ -407,6 +408,7 @@ $(expand_array_inf "${DEP_PACKAGES[@]}") # MdePkg UefiApplicationEntryPoint UefiLib + DebugLib # C Libs $(expand_array_inf "${C_LIBRARIES[@]}") # CPP Libs From 61e4c982a2f4f09d0c97d6d0864d41de809aeb5a Mon Sep 17 00:00:00 2001 From: Totto16 Date: Thu, 20 Aug 2026 18:46:06 +0200 Subject: [PATCH 115/143] feat: refactor the whole UEFI build process - apply a few fixes, that where discovered in another project i tested things in - don't link all folders to the edk2/ root,, us the PACKAGES_PATH feature, as it helps discovering the pkgs in another folder --- platforms/build-uefi.sh | 81 +++++++++---------- platforms/uefi/OOPetrisPlatform.template.dsc | 9 ++- platforms/uefi/compile-final.sh | 5 +- ...x_compiler.diff => edk2_cxx_compiler.diff} | 0 ....diff => edk2_libc_cpp_compatibility.diff} | 0 .../uefi/edk2_libc_ctype_lib_name_fix.diff | 62 ++++++++++++++ .../uefi/{ssl_lib.diff => edk2_ssl_lib.diff} | 0 ...ff => edk2_ssl_lib_compile_with_libc.diff} | 0 ...4_v1.diff => edk2_use_arch_x86_64_v1.diff} | 0 platforms/uefi/extract-definitions.sh | 2 +- platforms/uefi/pkg-config-wrapper.sh | 4 +- src/executables/platforms/uefi/meson.build | 3 + src/libs/core/helper/sleep.cpp | 23 +----- 13 files changed, 118 insertions(+), 71 deletions(-) rename platforms/uefi/{cxx_compiler.diff => edk2_cxx_compiler.diff} (100%) rename platforms/uefi/{libc_cpp_compatibility.diff => edk2_libc_cpp_compatibility.diff} (100%) create mode 100644 platforms/uefi/edk2_libc_ctype_lib_name_fix.diff rename platforms/uefi/{ssl_lib.diff => edk2_ssl_lib.diff} (100%) rename platforms/uefi/{ssl_lib_compile_with_libc.diff => edk2_ssl_lib_compile_with_libc.diff} (100%) rename platforms/uefi/{use_arch_x86_64_v1.diff => edk2_use_arch_x86_64_v1.diff} (100%) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 134da51b..2c77bd04 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -66,10 +66,6 @@ else exit 1 fi -if [ ! -d "toolchains" ]; then - mkdir -p toolchains -fi - # source dependency version information SCRIPT_DIR="$(realpath "$(dirname -- "${BASH_SOURCE[0]}")")" @@ -83,9 +79,23 @@ source "$SCRIPT_DIR/helper.sh" TOOLCHAIN_DIR="$(pwd)/toolchains" export TOOLCHAIN_DIR -export EDK2_ROOT="$TOOLCHAIN_DIR/edk2" +if [ ! -d "$TOOLCHAIN_DIR" ]; then + mkdir -p "$TOOLCHAIN_DIR" +fi + +export EDK2_TOOLS_DIR="$TOOLCHAIN_DIR/EDK2_TOOLS" + +if [ ! -d "$EDK2_TOOLS_DIR" ]; then + mkdir -p "$EDK2_TOOLS_DIR" +fi + +export EDK2_ROOT="$EDK2_TOOLS_DIR/edk2" -export WORKSPACE="$EDK2_ROOT" +export WORKSPACE="$EDK2_TOOLS_DIR/workspace" + +if [ ! -d "$WORKSPACE" ]; then + mkdir -p "$WORKSPACE" +fi if [ ! -d "$EDK2_ROOT" ]; then git clone https://github.com/tianocore/edk2 "$EDK2_ROOT" @@ -96,7 +106,7 @@ fi git -C "$EDK2_ROOT" checkout "$EDK2_RELEASE_TAG" git -C "$EDK2_ROOT" submodule update --init -export EDK2_LIBC_ROOT="$TOOLCHAIN_DIR/edk2-libc" +export EDK2_LIBC_ROOT="$EDK2_TOOLS_DIR/edk2-libc" if [ ! -d "$EDK2_LIBC_ROOT" ]; then git clone https://github.com/tianocore/edk2-libc "$EDK2_LIBC_ROOT" @@ -106,7 +116,7 @@ fi git -C "$EDK2_LIBC_ROOT" checkout "$EDK2_LIBC_COMMIT_HASH" -export EDK2_LLVM_ROOT="$TOOLCHAIN_DIR/llvm-project" +export EDK2_LLVM_ROOT="$EDK2_TOOLS_DIR/llvm-project" if [ ! -d "$EDK2_LLVM_ROOT" ]; then @@ -119,7 +129,7 @@ fi git -C "$EDK2_LLVM_ROOT" checkout "$EDK2_LLVM_PORT_BRANCH" export EDK_TOOLS_PATH="$EDK2_ROOT/BaseTools" -export PACKAGES_PATH="$EDK2_ROOT" +export PACKAGES_PATH="$EDK2_ROOT;$EDK2_LIBC_ROOT;$EDK2_LLVM_ROOT;$EDK2_TOOLS_DIR/GeneratedPackages;$EDK2_TOOLS_DIR/LibraryPkg" PLATFORMS_DIR="$(pwd)/platforms/uefi" @@ -132,10 +142,10 @@ if ! [ -e "$EDK2_PATCH_FILE" ]; then #TODO: use loop for this patches - 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/use_arch_x86_64_v1.diff" + git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/edk2_cxx_compiler.diff" + git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/edk2_ssl_lib.diff" + git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/edk2_ssl_lib_compile_with_libc.diff" + git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/edk2_use_arch_x86_64_v1.diff" touch "$EDK2_PATCH_FILE" fi @@ -145,7 +155,8 @@ 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" + git apply --unsafe-paths -p1 --directory="$EDK2_LIBC_ROOT" "$PATCH_DIR/edk2_libc_cpp_compatibility.diff" + git apply --unsafe-paths -p1 --directory="$EDK2_LIBC_ROOT" "$PATCH_DIR/edk2_libc_ctype_lib_name_fix.diff" touch "$EDK2_LIBC_PATCH_FILE" fi @@ -165,7 +176,7 @@ set -u export EDK2_CONF_TARGET="$EDK2_ROOT/Conf/target.txt" -EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM_NAME="Platforms/OOPetrisPlatform.dsc" +EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM_NAME="GeneratedPackages/Platforms/OOPetrisPlatform.dsc" EDK2_TARGET_PROPERTIES_BUILDTYPE="$(echo "$BUILDTYPE" | tr "[:lower:]" "[:upper:]")" @@ -187,27 +198,13 @@ export EDK2_BUILD_COMMAND="$EDK2_POSIX_BIN_PATH/build" # add links to needed packages -EDK2_LIB_PACKAGES=("AppPkg" "StdLib" "StdLibPrivateInternalFiles") - -for EDK2_LIB_PACKAGE in "${EDK2_LIB_PACKAGES[@]}"; do - - if ! [ -e "$WORKSPACE/$EDK2_LIB_PACKAGE" ]; then - link_files_checked "$EDK2_LIBC_ROOT/$EDK2_LIB_PACKAGE" "$WORKSPACE/$EDK2_LIB_PACKAGE" - fi - -done - -if ! [ -e "$WORKSPACE/LLVM" ]; then - link_files_checked "$EDK2_LLVM_ROOT" "$WORKSPACE/LLVM" -fi - -LIBRARY_PKG_ROOT="$WORKSPACE/LibraryPkg" +LIBRARY_PKG_ROOT="$EDK2_TOOLS_DIR/LibraryPkg" mkdir -p "$LIBRARY_PKG_ROOT" -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") +EDK2_PORT_NAMES=("SDL2Pkg" "SDL2MixerPkg" "SupportLib") +EDK2_PORT_URLS=("https://github.com/Totto16/SDL2_UEFI" "https://github.com/Totto16/SDL2_mixer_UEFI" "https://github.com/Totto16/UefiEdk2SupportLib.git ") +EDK2_PORT_TAGS=("uefi_port" "uefi_port" "main") for EDK2_PORT_KEY in "${!EDK2_PORT_NAMES[@]}"; do @@ -215,7 +212,7 @@ for EDK2_PORT_KEY in "${!EDK2_PORT_NAMES[@]}"; do 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" + EDK2_PORT_ROOT="$LIBRARY_PKG_ROOT/$EDK2_PORT_NAME" if [ ! -d "$EDK2_PORT_ROOT" ]; then git clone "$EDK2_PORT_URL" "$EDK2_PORT_ROOT" @@ -225,10 +222,6 @@ for EDK2_PORT_KEY in "${!EDK2_PORT_NAMES[@]}"; do 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 @@ -258,9 +251,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', '-I$WORKSPACE/MdePkg/Include', '-I$WORKSPACE/MdePkg/Include/$EDK2_TARGET_PROPERTIES_ARCH'" +export CC_COMPILE_FLAGS="'-nostdinc', '-I$EDK2_LIBC_ROOT/StdLib/Include', '-I$EDK2_LIBC_ROOT/StdLib/Include/$EDK2_TARGET_PROPERTIES_ARCH', '-I$EDK2_ROOT/MdePkg/Include', '-I$EDK2_ROOT/MdePkg/Include/$EDK2_TARGET_PROPERTIES_ARCH'" -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 CXX_COMPILE_FLAGS="'-fno-exceptions', '-fno-threadsafe-statics', '-fno-use-cxa-atexit', '-fno-unwind-tables', '-fno-asynchronous-unwind-tables', '-nostdinc++', '-nodefaultlibs', '-I$EDK2_LLVM_ROOT/LLVM/libcxx/include', $CC_COMPILE_FLAGS" export CROSS_FILE="./platforms/crossbuild/uefi.ini" @@ -348,6 +341,10 @@ cat <"$EDK2_INFO_FILE" "build": "$EDK2_BUILD_COMMAND", "arch": "$EDK2_TARGET_PROPERTIES_ARCH", "workspace": "$WORKSPACE", + "edk2_tools_dir": "$EDK2_TOOLS_DIR", + "edk2_root": "$EDK2_ROOT", + "edk2_libc_root": "$EDK2_LIBC_ROOT", + "edk2_llvm_root": "$EDK2_LLVM_ROOT", "platform": "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM", "platform_name": "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM_NAME", "buildtype": "$EDK2_TARGET_PROPERTIES_BUILDTYPE", @@ -404,11 +401,11 @@ if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "$BUILD_DIR" ]; then -Dstrip=false \ --fatal-meson-warnings - if ! [ -L "$WORKSPACE/GeneratedPackages" ]; then + if ! [ -L "$EDK2_TOOLS_DIR/GeneratedPackages" ]; then echo "mkdir: $EDK2_GENERATED_PACKAGES" mkdir -p "$EDK2_GENERATED_PACKAGES" - link_files_checked "$EDK2_GENERATED_PACKAGES" "$WORKSPACE/GeneratedPackages" + link_files_checked "$EDK2_GENERATED_PACKAGES" "$EDK2_TOOLS_DIR/GeneratedPackages" fi diff --git a/platforms/uefi/OOPetrisPlatform.template.dsc b/platforms/uefi/OOPetrisPlatform.template.dsc index 6a7b96f3..c780d8e2 100644 --- a/platforms/uefi/OOPetrisPlatform.template.dsc +++ b/platforms/uefi/OOPetrisPlatform.template.dsc @@ -178,7 +178,7 @@ [LibraryClasses.common.UEFI_DRIVER] HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf - DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf + #see above: DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf @@ -209,8 +209,13 @@ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80400042 #define DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED 0x10 #define DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED 0x20 - gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x3F + !endif + # disable auto initialize, initialize manually, and if it fails, use backup non shell code backup + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE + + # inserted components / includes after that diff --git a/platforms/uefi/compile-final.sh b/platforms/uefi/compile-final.sh index 73a30c33..a20d91cc 100755 --- a/platforms/uefi/compile-final.sh +++ b/platforms/uefi/compile-final.sh @@ -24,6 +24,7 @@ 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_TOOLS_DIR="$(jq -M -r -c '.["edk2_tools_dir"]' "$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")" @@ -34,10 +35,10 @@ BUILD_NAME=$(basename -- $"$BUILD_INF") BUILD_FILE_TARGET="GeneratedPackages/$BUILD_NAME" -BUILD_FILE_TARGET_ABS="$WORKSPACE/$BUILD_FILE_TARGET" +BUILD_FILE_TARGET_ABS="$EDK2_TOOLS_DIR/$BUILD_FILE_TARGET" if ! [ -e "$BUILD_FILE_TARGET_ABS" ]; then - echo "Build file is not in the workspace: $BUILD_FILE_TARGET" >&2 + echo "Build file is not in the expected place: $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 diff --git a/platforms/uefi/cxx_compiler.diff b/platforms/uefi/edk2_cxx_compiler.diff similarity index 100% rename from platforms/uefi/cxx_compiler.diff rename to platforms/uefi/edk2_cxx_compiler.diff diff --git a/platforms/uefi/libc_cpp_compatibility.diff b/platforms/uefi/edk2_libc_cpp_compatibility.diff similarity index 100% rename from platforms/uefi/libc_cpp_compatibility.diff rename to platforms/uefi/edk2_libc_cpp_compatibility.diff diff --git a/platforms/uefi/edk2_libc_ctype_lib_name_fix.diff b/platforms/uefi/edk2_libc_ctype_lib_name_fix.diff new file mode 100644 index 00000000..621e89a8 --- /dev/null +++ b/platforms/uefi/edk2_libc_ctype_lib_name_fix.diff @@ -0,0 +1,62 @@ +diff --git a/StdLib/LibC/Locale/Locale.inf b/StdLib/LibC/Locale/Locale.inf +index 1bbb611..1c81272 100644 +--- a/StdLib/LibC/Locale/Locale.inf ++++ b/StdLib/LibC/Locale/Locale.inf +@@ -61,4 +61,4 @@ + + [LibraryClasses] + LibC +- LibCType ++ LibCtype +diff --git a/StdLib/LibC/StdLib/StdLib.inf b/StdLib/LibC/StdLib/StdLib.inf +index e7bdf5a..968e6a7 100644 +--- a/StdLib/LibC/StdLib/StdLib.inf ++++ b/StdLib/LibC/StdLib/StdLib.inf +@@ -53,7 +53,7 @@ + MemoryAllocationLib + ShellLib + LibC +- LibCType ++ LibCtype + LibSignal + + ################################################################ +diff --git a/StdLib/LibC/Stdio/Stdio.inf b/StdLib/LibC/Stdio/Stdio.inf +index fe87242..daffb34 100644 +--- a/StdLib/LibC/Stdio/Stdio.inf ++++ b/StdLib/LibC/Stdio/Stdio.inf +@@ -128,7 +128,7 @@ + + [LibraryClasses] + LibC +- LibCType ++ LibCtype + LibGdtoa + LibLocale + LibStdLib +diff --git a/StdLib/LibC/String/String.inf b/StdLib/LibC/String/String.inf +index c8b4d88..4bd06da 100644 +--- a/StdLib/LibC/String/String.inf ++++ b/StdLib/LibC/String/String.inf +@@ -48,7 +48,7 @@ + PrintLib # Used for strerror() + PcdLib + LibC +- LibCType ++ LibCtype + LibStdLib + + ################################################################ +diff --git a/StdLib/StdLib.inc b/StdLib/StdLib.inc +index 8083e2b..4d08302 100644 +--- a/StdLib/StdLib.inc ++++ b/StdLib/StdLib.inc +@@ -29,7 +29,7 @@ + # C Standard Libraries + # + LibC|StdLib/LibC/LibC.inf +- LibCType|StdLib/LibC/Ctype/Ctype.inf ++ LibCtype|StdLib/LibC/Ctype/Ctype.inf + LibLocale|StdLib/LibC/Locale/Locale.inf + LibMath|StdLib/LibC/Math/Math.inf + LibSignal|StdLib/LibC/Signal/Signal.inf diff --git a/platforms/uefi/ssl_lib.diff b/platforms/uefi/edk2_ssl_lib.diff similarity index 100% rename from platforms/uefi/ssl_lib.diff rename to platforms/uefi/edk2_ssl_lib.diff diff --git a/platforms/uefi/ssl_lib_compile_with_libc.diff b/platforms/uefi/edk2_ssl_lib_compile_with_libc.diff similarity index 100% rename from platforms/uefi/ssl_lib_compile_with_libc.diff rename to platforms/uefi/edk2_ssl_lib_compile_with_libc.diff diff --git a/platforms/uefi/use_arch_x86_64_v1.diff b/platforms/uefi/edk2_use_arch_x86_64_v1.diff similarity index 100% rename from platforms/uefi/use_arch_x86_64_v1.diff rename to platforms/uefi/edk2_use_arch_x86_64_v1.diff diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 214dded7..afe124fc 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" "LibGdtoa") +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")" diff --git a/platforms/uefi/pkg-config-wrapper.sh b/platforms/uefi/pkg-config-wrapper.sh index cf0e1300..1b5c4dd1 100755 --- a/platforms/uefi/pkg-config-wrapper.sh +++ b/platforms/uefi/pkg-config-wrapper.sh @@ -38,7 +38,7 @@ 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")" +EDK2_TOOLS_DIR="$(jq -M -r -c '.["edk2_tools_dir"]' "$UEFI_INFO_FILE")" link_uefi_libray() { local LIB_NAME_INF="$1" @@ -138,7 +138,7 @@ elif [[ "$MODE" == "get" ]]; then 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" + PACKAGE_DESC_FILE="$EDK2_TOOLS_DIR/LibraryPkg/$PACKAGE_NAME_DEC" if ! [ -e "$PACKAGE_DESC_FILE" ]; then exit 1 diff --git a/src/executables/platforms/uefi/meson.build b/src/executables/platforms/uefi/meson.build index 9657703b..1e0a595f 100644 --- a/src/executables/platforms/uefi/meson.build +++ b/src/executables/platforms/uefi/meson.build @@ -123,6 +123,9 @@ elif RUNTIME_TARGET == 'emulator' emulate_command = [ _qemu_system_exe, + # this machine supports the tcd timer frequency ACPI getter call + '-machine', + 'q35', # see https://www.qemu.org/docs/master/system/qemu-cpu-models.html#id1 # this cpu has x86-64 v1 (baseline) support '-cpu', diff --git a/src/libs/core/helper/sleep.cpp b/src/libs/core/helper/sleep.cpp index a6a4ab7e..480364b2 100644 --- a/src/libs/core/helper/sleep.cpp +++ b/src/libs/core/helper/sleep.cpp @@ -23,28 +23,7 @@ using namespace std::chrono_literals; #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; -} +#include #endif From ea29f8a4a8cadaf0705bb8edbcad540c7bf644b1 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Thu, 20 Aug 2026 21:36:12 +0200 Subject: [PATCH 116/143] feat: more fixes for the uefi refactor --- platforms/build-uefi.sh | 49 ++--- platforms/uefi/OOPetrisPlatform.template.dsc | 42 ++++- platforms/uefi/compile-final.sh | 2 +- .../uefi/edk2_ssl_lib_compile_with_libc.diff | 168 +++++++++--------- platforms/uefi/extract-definitions.sh | 24 +-- platforms/uefi/pkg-config-wrapper.sh | 7 +- src/executables/game/main.cpp | 23 +-- src/executables/platforms/uefi/libraries.json | 6 +- .../sdl2_ttf-2.20.1_sdl_uefi_sse_fix.diff | 13 ++ subprojects/sdl2_ttf.wrap | 1 + 10 files changed, 193 insertions(+), 142 deletions(-) create mode 100644 subprojects/packagefiles/sdl2_ttf-2.20.1_sdl_uefi_sse_fix.diff diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 2c77bd04..d7185797 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -97,6 +97,9 @@ if [ ! -d "$WORKSPACE" ]; then mkdir -p "$WORKSPACE" fi +# needed by the setup script +mkdir -p "$WORKSPACE/Conf/" + if [ ! -d "$EDK2_ROOT" ]; then git clone https://github.com/tianocore/edk2 "$EDK2_ROOT" else @@ -116,20 +119,12 @@ fi git -C "$EDK2_LIBC_ROOT" checkout "$EDK2_LIBC_COMMIT_HASH" -export EDK2_LLVM_ROOT="$EDK2_TOOLS_DIR/llvm-project" +export EDK2_GENERATED_PACKAGES_ROOT="$EDK2_TOOLS_DIR/GeneratedPackages" -if [ ! -d "$EDK2_LLVM_ROOT" ]; then - - 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_PORT_BRANCH" +export LIBRARY_PKG_ROOT="$EDK2_TOOLS_DIR/LibraryPkg" export EDK_TOOLS_PATH="$EDK2_ROOT/BaseTools" -export PACKAGES_PATH="$EDK2_ROOT;$EDK2_LIBC_ROOT;$EDK2_LLVM_ROOT;$EDK2_TOOLS_DIR/GeneratedPackages;$EDK2_TOOLS_DIR/LibraryPkg" +export PACKAGES_PATH="$EDK2_ROOT:$EDK2_LIBC_ROOT:$EDK2_GENERATED_PACKAGES_ROOT:$LIBRARY_PKG_ROOT" PLATFORMS_DIR="$(pwd)/platforms/uefi" @@ -174,9 +169,9 @@ source "$EDK2_ROOT/edksetup.sh" "--reconfig" set -u -export EDK2_CONF_TARGET="$EDK2_ROOT/Conf/target.txt" +export EDK2_CONF_TARGET="$WORKSPACE/Conf/target.txt" -EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM_NAME="GeneratedPackages/Platforms/OOPetrisPlatform.dsc" +EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM_NAME="Platforms/OOPetrisPlatform.dsc" EDK2_TARGET_PROPERTIES_BUILDTYPE="$(echo "$BUILDTYPE" | tr "[:lower:]" "[:upper:]")" @@ -198,12 +193,10 @@ export EDK2_BUILD_COMMAND="$EDK2_POSIX_BIN_PATH/build" # add links to needed packages -LIBRARY_PKG_ROOT="$EDK2_TOOLS_DIR/LibraryPkg" - mkdir -p "$LIBRARY_PKG_ROOT" EDK2_PORT_NAMES=("SDL2Pkg" "SDL2MixerPkg" "SupportLib") -EDK2_PORT_URLS=("https://github.com/Totto16/SDL2_UEFI" "https://github.com/Totto16/SDL2_mixer_UEFI" "https://github.com/Totto16/UefiEdk2SupportLib.git ") +EDK2_PORT_URLS=("https://github.com/Totto16/SDL2_UEFI" "https://github.com/Totto16/SDL2_mixer_UEFI" "https://github.com/Totto16/UefiEdk2SupportLib.git") EDK2_PORT_TAGS=("uefi_port" "uefi_port" "main") for EDK2_PORT_KEY in "${!EDK2_PORT_NAMES[@]}"; do @@ -224,8 +217,22 @@ for EDK2_PORT_KEY in "${!EDK2_PORT_NAMES[@]}"; do done +export EDK2_LLVM_ROOT="$LIBRARY_PKG_ROOT/LLVM" + +if [ ! -d "$EDK2_LLVM_ROOT" ]; then + + 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_PORT_BRANCH" + + popd + export CC="$SCRIPT_DIR/uefi/gcc-wrapper.sh" export CXX="$SCRIPT_DIR/uefi/g++-wrapper.sh" @@ -253,7 +260,7 @@ export COMPILE_FLAGS="$COMMON_FLAGS ,'--sysroot=${SYS_ROOT}', '-D__UEFI__', '-DE export CC_COMPILE_FLAGS="'-nostdinc', '-I$EDK2_LIBC_ROOT/StdLib/Include', '-I$EDK2_LIBC_ROOT/StdLib/Include/$EDK2_TARGET_PROPERTIES_ARCH', '-I$EDK2_ROOT/MdePkg/Include', '-I$EDK2_ROOT/MdePkg/Include/$EDK2_TARGET_PROPERTIES_ARCH'" -export CXX_COMPILE_FLAGS="'-fno-exceptions', '-fno-threadsafe-statics', '-fno-use-cxa-atexit', '-fno-unwind-tables', '-fno-asynchronous-unwind-tables', '-nostdinc++', '-nodefaultlibs', '-I$EDK2_LLVM_ROOT/LLVM/libcxx/include', $CC_COMPILE_FLAGS" +export CXX_COMPILE_FLAGS="'-fno-exceptions', '-fno-threadsafe-statics', '-fno-use-cxa-atexit', '-fno-unwind-tables', '-fno-asynchronous-unwind-tables', '-nostdinc++', '-nodefaultlibs', '-I$EDK2_LLVM_ROOT/libcxx/include', $CC_COMPILE_FLAGS" export CROSS_FILE="./platforms/crossbuild/uefi.ini" @@ -334,7 +341,7 @@ validate_parent_dir "$EDK2_INFO_FILE" EDK2_GENERATED_PACKAGES="$(pwd)/$BUILD_DIR/GeneratedPackages" export EDK2_GENERATED_PACKAGES -export EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM="$WORKSPACE/$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM_NAME" +export EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM="$LIBRARY_PKG_ROOT/$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM_NAME" cat <"$EDK2_INFO_FILE" { @@ -354,6 +361,7 @@ cat <"$EDK2_INFO_FILE" } EOF + if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "${EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM:?}" ]; then rm -f "${EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM:?}" @@ -401,11 +409,10 @@ if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "$BUILD_DIR" ]; then -Dstrip=false \ --fatal-meson-warnings - if ! [ -L "$EDK2_TOOLS_DIR/GeneratedPackages" ]; then + if ! [ -L "$EDK2_GENERATED_PACKAGES_ROOT" ]; then - echo "mkdir: $EDK2_GENERATED_PACKAGES" mkdir -p "$EDK2_GENERATED_PACKAGES" - link_files_checked "$EDK2_GENERATED_PACKAGES" "$EDK2_TOOLS_DIR/GeneratedPackages" + link_files_checked "$EDK2_GENERATED_PACKAGES" "$EDK2_GENERATED_PACKAGES_ROOT" fi diff --git a/platforms/uefi/OOPetrisPlatform.template.dsc b/platforms/uefi/OOPetrisPlatform.template.dsc index c780d8e2..12d04c1b 100644 --- a/platforms/uefi/OOPetrisPlatform.template.dsc +++ b/platforms/uefi/OOPetrisPlatform.template.dsc @@ -66,8 +66,7 @@ [Packages] MdePkg/MdePkg.dec - - + UefiCpuPkg/UefiCpuPkg.dec [LibraryClasses] # @@ -115,15 +114,48 @@ UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf - TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf + ## see below: TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf !if $(OOPETRIS_RUNTIME_TARGET) == "hardware" + # DebugLib DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + + # Support and TimerLib + #TODO: doesn't work on qemu, but maybe on CPU?? + TimerLib|UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf + LibUEfiSupportNanosleep|SupportLib/Library/Default/SupportLibDefaultNanosleep.inf + LibUEfiSupportClock|SupportLib/Library/TimerLib/SupportLibTimerClock.inf !else - MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogLibNull.inf + # DebugLib DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf + MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogLibNull.inf + + # Support and TimerLib + LibUEfiSupportNanosleep|SupportLib/Library/Default/SupportLibDefaultNanosleep.inf + LibUEfiSupportClock|SupportLib/Library/TimerLib/SupportLibTimerClock.inf + #LibUEfiSupportClock|LibraryPkg/SupportLib/Library/Default/SupportLibDefaultClock.inf + #LibUEfiSupportClock|LibraryPkg/SupportLib/Library/Null/SupportLibNullClock.inf + + ## doesn't work on qemu, setup (cpuid leaf 0x15) error + ## TimerLib|UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf + + ## not supported for DXE or UEFI_APPLICATION: + ## TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf + + ## NOT WORKING on some machines, works with q35, but not the default (pc?), + ## the reason is Pmba reading is incorrect in the timerlib Constructor :( + ## TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf + + ## not working: need special emulator? + ## TimerLib|EmulatorPkg/Library/DxeTimerLib/DxeTimerLib.inf + + TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf + !endif + ShellCEntryLibDynamical|SupportLib/Library/UefiShellCEntryLibDynamical/UefiShellCEntryLibDynamical.inf + + CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf @@ -200,7 +232,7 @@ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80400042 ## This flag is used to control the destination port for PlatformDebugLibIoPort # this is the same address as QEMU uses - gUefiOvmfPkgTokenSpaceGuid.PcdDebugIoPort|0x402|UINT16|4 + gUefiOvmfPkgTokenSpaceGuid.PcdDebugIoPort|0x402 #define DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED 0x01 #define DEBUG_PROPERTY_DEBUG_PRINT_ENABLED 0x02 diff --git a/platforms/uefi/compile-final.sh b/platforms/uefi/compile-final.sh index a20d91cc..f244b2f1 100755 --- a/platforms/uefi/compile-final.sh +++ b/platforms/uefi/compile-final.sh @@ -54,7 +54,7 @@ fi "$EDK2_BUILD_COMMAND" -a "$EDK2_TARGET_PROPERTIES_ARCH" \ -p "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" \ - -m "$BUILD_FILE_TARGET" \ + -m "$BUILD_NAME" \ -b "$EDK2_TARGET_PROPERTIES_BUILDTYPE" \ -t "$EDK2_TARGET_PROPERTIES_TOOLCHAIN" \ -D "OOPETRIS_RUNTIME_TARGET=$EDK2_TARGET_PROPERTIES_RUNTIME_TARGET" \ diff --git a/platforms/uefi/edk2_ssl_lib_compile_with_libc.diff b/platforms/uefi/edk2_ssl_lib_compile_with_libc.diff index 4c9b224b..2fcbb2a5 100644 --- a/platforms/uefi/edk2_ssl_lib_compile_with_libc.diff +++ b/platforms/uefi/edk2_ssl_lib_compile_with_libc.diff @@ -1,25 +1,25 @@ -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 @@ +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 ++ *_*_*_CC_FLAGS = -I$(EDK2_LIBC_ROOT) ++ *_*_*_CC_FLAGS = -I$(EDK2_ROOT)/CryptoPkg/Library/Include ++ *_*_*_CC_FLAGS = -I$(EDK2_LIBC_ROOT)/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 ( ++ *_*_*_CC_FLAGS = -I$(EDK2_LIBC_ROOT)/StdLib/Include/X64 ++ *_*_*_CC_FLAGS = -I$(EDK2_ROOT)/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) { @@ -29,7 +29,7 @@ index 34e81246ed..8b260495a1 100644 } EVP_PKEY_CTX_free (pHkdfCtx); -@@ -153,7 +154,8 @@ HkdfMdExtract ( +@@ -153,7 +154,8 @@ HkdfMdExtract ( } if (Result) { @@ -39,7 +39,7 @@ index 34e81246ed..8b260495a1 100644 } EVP_PKEY_CTX_free (pHkdfCtx); -@@ -220,7 +222,8 @@ HkdfMdExpand ( +@@ -220,7 +222,8 @@ HkdfMdExpand ( } if (Result) { @@ -49,11 +49,11 @@ index 34e81246ed..8b260495a1 100644 } 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 ( +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. // @@ -63,7 +63,7 @@ index 7634ab1f6f..e0c12dc264 100644 // // Fail to determine output buffer size. // -@@ -187,7 +188,8 @@ InternalPkcs1v2Encrypt ( +@@ -187,7 +188,8 @@ InternalPkcs1v2Encrypt ( // // Encrypt Data. // @@ -73,7 +73,7 @@ index 7634ab1f6f..e0c12dc264 100644 // // Fail to encrypt data, need to free the output buffer. // -@@ -514,7 +516,8 @@ InternalPkcs1v2Decrypt ( +@@ -514,7 +516,8 @@ InternalPkcs1v2Decrypt ( // // Determine the required buffer length for malloc'ing. // @@ -83,7 +83,7 @@ index 7634ab1f6f..e0c12dc264 100644 if (ReturnCode <= 0) { // // Fail to determine output buffer size. -@@ -537,7 +540,8 @@ InternalPkcs1v2Decrypt ( +@@ -537,7 +540,8 @@ InternalPkcs1v2Decrypt ( // // Decrypt Data. // @@ -93,11 +93,11 @@ index 7634ab1f6f..e0c12dc264 100644 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 ( +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) { @@ -107,7 +107,7 @@ index 4835f81168..cefa40b440 100644 } _Exit: -@@ -284,10 +285,11 @@ RsaPssSignDigest ( +@@ -284,10 +285,11 @@ RsaPssSignDigest ( } if (Result) { @@ -120,11 +120,11 @@ index 4835f81168..cefa40b440 100644 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 +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 **/ @@ -139,17 +139,17 @@ index b7bed15c18..b1271166a5 100644 // // Extra header to record the memory buffer size from malloc routine. // -@@ -120,3 +125,5 @@ free ( +@@ -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 +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 @@ -158,7 +158,7 @@ index 8a8fdfefc7..0b9541267f 100644 int errno = 0; FILE *stderr = NULL; -@@ -22,6 +24,7 @@ int +@@ -22,6 +24,7 @@ int IN VOID *Buffer2 ); @@ -166,17 +166,17 @@ index 8a8fdfefc7..0b9541267f 100644 // // Duplicated from EDKII BaseSortLib for qsort() wrapper // -@@ -651,3 +654,5 @@ printf ( +@@ -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 +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 @@ -186,17 +186,17 @@ index 894aeb016f..eca712b348 100644 // // -- Time Management Routines -- // -@@ -249,3 +252,5 @@ gettimeofday ( +@@ -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 +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. // @@ -231,7 +231,7 @@ index dc5a357d8f..6c4a32186f 100644 // // 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 +@@ -58,6 +78,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define va_start VA_START #define va_end VA_END @@ -240,17 +240,17 @@ index dc5a357d8f..6c4a32186f 100644 // // Definitions for global constants used by CRT library routines // -@@ -492,3 +514,5 @@ memcpy ( +@@ -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 ( +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 @@ -259,27 +259,27 @@ index 5e346728c5..666ecc61d1 100644 /* Copies bytes between buffers */ void * memcpy ( -@@ -47,3 +49,5 @@ 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 @@ +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; +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 @@ -288,26 +288,26 @@ index 9b091f1901..faedee2d9e 100644 /* 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 ( +@@ -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 @@ +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 ++ *_*_*_CC_FLAGS = -I$(EDK2_LIBC_ROOT) ++ *_*_*_CC_FLAGS = -I$(EDK2_ROOT)/CryptoPkg/Library/Include ++ *_*_*_CC_FLAGS = -I$(EDK2_LIBC_ROOT)/StdLib/Include + +[BuildOptions.X64] -+ *_*_*_CC_FLAGS = -I$(WORKSPACE)/StdLib/Include/X64 -+ *_*_*_CC_FLAGS = -I$(WORKSPACE)/MdePkg/Include/X64 ++ *_*_*_CC_FLAGS = -I$(EDK2_LIBC_ROOT)/StdLib/Include/X64 ++ *_*_*_CC_FLAGS = -I$(EDK2_ROOT)/MdePkg/Include/X64 diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index afe124fc..4a85b8e8 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -103,7 +103,7 @@ EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM="$(jq -M -r -c '.["platform"]' "$UEFI_INF add_component_to_platform() { local PACKAGE_NAME="$1" - local FINAL_PKG_NAME="GeneratedPackages/$PACKAGE_NAME" + local FINAL_PKG_NAME="$PACKAGE_NAME" if grep -q "$FINAL_PKG_NAME" "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM"; then : # found already, do nothing @@ -121,7 +121,7 @@ EOF add_include_to_platform() { local PACKAGE_NAME="$1" - local FINAL_PKG_INC_NAME="GeneratedPackages/$PACKAGE_NAME" + local FINAL_PKG_INC_NAME="$PACKAGE_NAME" if grep -q "$FINAL_PKG_INC_NAME" "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM"; then : # found already, do nothing @@ -219,7 +219,7 @@ for FILE_DEPENDENCY in "${FILE_DEPENDENCIES[@]}"; do exit 2 fi - PACKAGE_NAME="GeneratedPackages/Lib/$MAPPING_ENTRY_DEP_NAME.dec" + PACKAGE_NAME="GenPkg/$MAPPING_ENTRY_DEP_NAME.dec" DEP_OUTPUT_FILE="$DEST_FILE_DIR/$MAPPING_ENTRY_DEP_NAME.inf" @@ -295,6 +295,7 @@ if [ "$MESON_TARGETS_INFO_LIB_LANGUAGE" == "cpp" ]; then DEP_CLASSES+=("$CPP_LIBRARY") done DEP_PACKAGES+=("LLVM/LLVMPkg.dec") + DEP_PACKAGES+=("SupportLib/SupportLib.dec") # needed by LLVM elif [ "$MESON_TARGETS_INFO_LIB_LANGUAGE" == "c" ]; then FLAGS_TARGET="CC" else @@ -318,7 +319,7 @@ for MESON_TARGETS_INFO_LIB_PARAMATER in "${MESON_TARGETS_INFO_LIB_PARAMATERS[@]} ;; -t:use-lib:pkg=*) DEP_PACKAGE_NAME="${MESON_TARGETS_INFO_LIB_PARAMATER:15}" - DEP_PACKAGES+=("LibraryPkg/$DEP_PACKAGE_NAME/$DEP_PACKAGE_NAME.dec") + DEP_PACKAGES+=("$DEP_PACKAGE_NAME/$DEP_PACKAGE_NAME.dec") ;; -t:use-pkg:pkg=*) DEP_PACKAGE_NAME="${MESON_TARGETS_INFO_LIB_PARAMATER:15}" @@ -390,7 +391,7 @@ if [ "$MAPPING_TYPE" == "application" ]; then FILE_GUID = $MAPPING_GUID MODULE_TYPE = UEFI_APPLICATION VERSION_STRING = $MAPPING_VERSION - ENTRY_POINT = UefiMain + ENTRY_POINT = ShellCEntryLibDynamical [Sources] $(expand_array_inf "${DEP_SOURCES[@]}") @@ -401,6 +402,7 @@ $(expand_array_inf "${DEP_SOURCES[@]}") OvmfPkg/OvmfPkg.dec LLVM/LLVMPkg.dec StdLib/StdLib.dec + SupportLib/SupportLib.dec # dynamic deps $(expand_array_inf "${DEP_PACKAGES[@]}") @@ -409,6 +411,8 @@ $(expand_array_inf "${DEP_PACKAGES[@]}") UefiApplicationEntryPoint UefiLib DebugLib +# shell libs + ShellCEntryLibDynamical # C Libs $(expand_array_inf "${C_LIBRARIES[@]}") # CPP Libs @@ -457,7 +461,7 @@ elif [ "$MAPPING_TYPE" == "library" ]; then MAPPING_LIB_NAME="$(echo "$MAPPING_ENTRY" | jq -M -r -c ".[\"lib\"]")" - LIB_DEST_DIR="$DEST_FILE_DIR/Lib" + LIB_DEST_DIR="$DEST_FILE_DIR/GenPkg" validate_parent_dir "$LIB_DEST_DIR/dummy" @@ -498,7 +502,7 @@ $(expand_array_inf "${DEP_CLASSES[@]}") $(expand_array_inf "${DEP_BUILD_OPTIONS[@]}") EOF - link_package "Lib/$DEST_FILE_STEM.inf" "$LIB_DEST_FILE_INF" + link_package "GenPkg/$DEST_FILE_STEM.inf" "$LIB_DEST_FILE_INF" LIB_DEST_FILE_DEC="$LIB_DEST_DIR/$DEST_FILE_STEM.dec" @@ -516,16 +520,16 @@ $(expand_array_inf "${DEP_INCLUDES[@]}") # None # TODO, also add dsc? with ,.inf mappings EOF - link_package "Lib/$DEST_FILE_STEM.dec" "$LIB_DEST_FILE_DEC" + link_package "GenPkg/$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 + $MAPPING_LIB_NAME|GenPkg/$DEST_FILE_STEM.inf EOF - link_package "Lib/$DEST_FILE_STEM.inc" "$LIB_DEST_FILE_INC" + link_package "GenPkg/$DEST_FILE_STEM.inc" "$LIB_DEST_FILE_INC" else echo "Error: invalid mapping type: $MAPPING_TYPE" >&2 diff --git a/platforms/uefi/pkg-config-wrapper.sh b/platforms/uefi/pkg-config-wrapper.sh index 1b5c4dd1..1e48d7e1 100755 --- a/platforms/uefi/pkg-config-wrapper.sh +++ b/platforms/uefi/pkg-config-wrapper.sh @@ -70,9 +70,9 @@ EOF link_built_libray() { local PACKAGE_NAME_PKG="$1" - local FINAL_PKG_NAME="LibraryPkg/$PACKAGE_NAME_PKG/$PACKAGE_NAME_PKG.inf" + local FINAL_PKG_NAME="$PACKAGE_NAME_PKG/$PACKAGE_NAME_PKG.inf" - local FINAL_PKG_INC_NAME="LibraryPkg/$PACKAGE_NAME_PKG/$PACKAGE_NAME_PKG.inc" + local FINAL_PKG_INC_NAME="$PACKAGE_NAME_PKG/$PACKAGE_NAME_PKG.inc" link_uefi_libray "$FINAL_PKG_NAME" "$FINAL_PKG_INC_NAME" @@ -136,9 +136,10 @@ elif [[ "$MODE" == "get" ]]; then 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\"]")" + TOOL_PREFIX_UEFI="$(echo "$LIBRARY_ENTRY_UEFI" | jq -M -r -c ".[\"tool_prefix\"]")" PACKAGE_NAME_DEC="$PACKAGE_NAME_UEFI.dec" - PACKAGE_DESC_FILE="$EDK2_TOOLS_DIR/LibraryPkg/$PACKAGE_NAME_DEC" + PACKAGE_DESC_FILE="$EDK2_TOOLS_DIR/$TOOL_PREFIX_UEFI/$PACKAGE_NAME_DEC" if ! [ -e "$PACKAGE_DESC_FILE" ]; then exit 1 diff --git a/src/executables/game/main.cpp b/src/executables/game/main.cpp index 4d4acaae..fe413113 100644 --- a/src/executables/game/main.cpp +++ b/src/executables/game/main.cpp @@ -185,29 +185,20 @@ namespace { } // 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); +// link it as C function, the rest is done by the StdLib Wrapper, but argc might be 0 and argv NULL - return result == 0 ? EFI_SUCCESS : RETURN_LOAD_ERROR; +int main(int argc, char** argv) { + return main_no_sdl_replace(argc, argv); } } +#else +int main(int argc, char** argv) { + return main_no_sdl_replace(argc, argv); +} #endif diff --git a/src/executables/platforms/uefi/libraries.json b/src/executables/platforms/uefi/libraries.json index 281899bb..1abf92a4 100644 --- a/src/executables/platforms/uefi/libraries.json +++ b/src/executables/platforms/uefi/libraries.json @@ -16,13 +16,15 @@ "pkg": "NetworkPkg/NetworkPkg", "lib": "HttpIoLib", "inf": "NetworkPkg/Library/DxeHttpIoLib/DxeHttpIoLib.inf", - "inc": "NetworkPkg/Network.dsc.inc" + "inc": "NetworkPkg/Network.dsc.inc", + "tool_prefix": "edk2" }, "BaseCryptLib": { "pkg": "CryptoPkg/CryptoPkg", "lib": "BaseCryptLib", "inf": "CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf", - "inc": "CryptoPkg/CryptoPkgCustom.dsc.inc" + "inc": "CryptoPkg/CryptoPkgCustom.dsc.inc", + "tool_prefix": "edk2" } } } diff --git a/subprojects/packagefiles/sdl2_ttf-2.20.1_sdl_uefi_sse_fix.diff b/subprojects/packagefiles/sdl2_ttf-2.20.1_sdl_uefi_sse_fix.diff new file mode 100644 index 00000000..8733c57f --- /dev/null +++ b/subprojects/packagefiles/sdl2_ttf-2.20.1_sdl_uefi_sse_fix.diff @@ -0,0 +1,13 @@ +diff --git a/SDL_ttf.c b/SDL_ttf.c +index 404e00b..35cfa4b 100644 +--- a/SDL_ttf.c ++++ b/SDL_ttf.c +@@ -114,7 +114,7 @@ int TTF_SetScript(int script) /* hb_script_t */ + } + + /* Round glyph to 16 bytes width and use SSE2 instructions */ +-#if defined(__SSE2__) ++#if defined(__SSE2__) && !defined(SDL_DISABLE_SSE2_INTRINSICS) + # define HAVE_SSE2_INTRINSICS 1 + #endif + diff --git a/subprojects/sdl2_ttf.wrap b/subprojects/sdl2_ttf.wrap index 4fd78ddb..235f525f 100644 --- a/subprojects/sdl2_ttf.wrap +++ b/subprojects/sdl2_ttf.wrap @@ -8,6 +8,7 @@ patch_url = https://wrapdb.mesonbuild.com/v2/sdl2_ttf_2.20.1-4/get_patch patch_hash = 44311aba31c9d5a3366101e5afd439a1d95e64d2079e9d5487e4d0790b6858f1 source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/sdl2_ttf_2.20.1-4/SDL2_ttf-2.20.1.tar.gz wrapdb_version = 2.20.1-4 +diff_files = sdl2_ttf-2.20.1_sdl_uefi_sse_fix.diff [provide] sdl2_ttf = sdl2_ttf_dep From 9fc076350e663b56aff5b59cdc4048f5c7890003 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 25 Aug 2026 17:18:40 +0200 Subject: [PATCH 117/143] feat: fix some things - use %a instead of %s in UEFI debug, as these are char8_t* strings and %s is char16_t* strings - fix some other things --- edk2_libc_constructor_support_v2.diff | 106 ++++++++++ platforms/build-uefi.sh | 6 +- .../0001-feat-make-LibC-support-C.patch} | 20 ++ ...-fix-naming-of-LibCType-to-LibCtype.patch} | 20 +- .../0003-feat-add-c-and-c-constructors.patch | 189 ++++++++++++++++++ src/executables/game/main.cpp | 8 +- src/helper/uefi_utils.cpp | 8 +- src/libs/core/helper/utils.hpp | 4 +- .../utfcpp-4.0.8_no_exceptions.diff | 2 +- 9 files changed, 346 insertions(+), 17 deletions(-) create mode 100644 edk2_libc_constructor_support_v2.diff rename platforms/uefi/{edk2_libc_cpp_compatibility.diff => libc/0001-feat-make-LibC-support-C.patch} (85%) rename platforms/uefi/{edk2_libc_ctype_lib_name_fix.diff => libc/0002-fix-fix-naming-of-LibCType-to-LibCtype.patch} (74%) create mode 100644 platforms/uefi/libc/0003-feat-add-c-and-c-constructors.patch diff --git a/edk2_libc_constructor_support_v2.diff b/edk2_libc_constructor_support_v2.diff new file mode 100644 index 00000000..42c58ce2 --- /dev/null +++ b/edk2_libc_constructor_support_v2.diff @@ -0,0 +1,106 @@ +diff --git a/StdLib/Include/libc/main.h b/StdLib/Include/libc/main.h +new file mode 100644 +index 0000000..caae7c1 +--- /dev/null ++++ b/StdLib/Include/libc/main.h +@@ -0,0 +1,20 @@ ++ ++#pragma once ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#define EDK2_LIBC_ENTRY_NAME edk2_libc_main ++ ++extern int EDK2_LIBC_ENTRY_NAME(int, char**); ++ ++#ifdef __cplusplus ++} ++ ++#define EDK2_LIBCXX_ENTRY_NAME edk2_libcxx_main ++ ++extern int EDK2_LIBCXX_ENTRY_NAME(int, char**); ++ ++ ++#endif +diff --git a/StdLib/LibC/Main/Main.c b/StdLib/LibC/Main/Main.c +index b203d15..d98e1a0 100644 +--- a/StdLib/LibC/Main/Main.c ++++ b/StdLib/LibC/Main/Main.c +@@ -31,15 +31,51 @@ + #include + #include + +-extern int main( int, char**); ++#include ++ + extern int __sse2_available; + + struct __MainData *gMD; + +-/* Worker function to keep GCC happy. */ +-void __main() +-{ +- ; ++// these symbols are provided by the linker from the extions .init_array and .fini_array ++typedef void (*init_func_t)(void); ++ ++extern init_func_t __init_array_start[] __attribute__ ((section(".init_array"), aligned(sizeof(init_func_t)))) ; ++extern init_func_t __init_array_end[] __attribute__ ((section(".init_array"), aligned(sizeof(init_func_t)))) ; ++ ++extern init_func_t __fini_array_start[] __attribute__ ((section(".fini_array"), aligned(sizeof(init_func_t)))) ; ++extern init_func_t __fini_array_end[]; __attribute__ ((section(".fini_array"), aligned(sizeof(init_func_t)))) ++ ++static void run_init_array(void) { ++ size_t size = __init_array_end - __init_array_start; ++ for (size_t i = 0; i < size; ++i) { ++ init_func_t* func = __init_array_start + i ; ++ if (*func != NULL) { ++ (*func)(); ++ } ++ } ++} ++ ++static void run_fini_array(void) { ++ // iterate reversed ++ size_t size = __fini_array_end - __fini_array_start; ++ for (size_t i = size; i != 0; --i) { ++ init_func_t* func = __fini_array_start + (i - 1); ++ if (*func != NULL) { ++ (*func)(); ++ } ++ } ++} ++ ++ ++//TODO: this can be c or c++ constructors, so these shoul only be run, after libc or libc AND libcxx is intilized, before we call EDK2_LIBC_ENTRY_NAME or EDK2_LIBCXX_ENTRY_NAME, but how to know if the final entry point is c++ or c? as c++ also uses the c entry point too ++ ++void edk2_libc_call_constructors(void) { ++ run_init_array(); ++} ++ ++void edk2_libc_call_destructors(void) { ++ run_fini_array(); + } + + /** Clean up data as required by the exit() function. +@@ -67,6 +103,8 @@ exitCleanup(INTN ExitVal) + CleanUp(); + } + } ++ ++ edk2_libc_call_destructors(); + } + + /* Create mbcs versions of the Argv strings. */ +@@ -179,7 +217,8 @@ ShellAppMain ( + else { + if( setjmp(gMD->MainExit) == 0) { + errno = 0; // Clean up any "scratch" values from startup. +- ExitVal = (INTN)main( (int)Argc, gMD->NArgV); ++ edk2_libc_call_constructors(); ++ ExitVal = (INTN)EDK2_LIBC_ENTRY_NAME( (int)Argc, gMD->NArgV); + exitCleanup(ExitVal); + } + /* You reach here if: diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index d7185797..8b981538 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -141,6 +141,7 @@ if ! [ -e "$EDK2_PATCH_FILE" ]; then git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/edk2_ssl_lib.diff" git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/edk2_ssl_lib_compile_with_libc.diff" git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/edk2_use_arch_x86_64_v1.diff" + #TODO: GENFW and linker script for constructors touch "$EDK2_PATCH_FILE" fi @@ -150,8 +151,7 @@ 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/edk2_libc_cpp_compatibility.diff" - git apply --unsafe-paths -p1 --directory="$EDK2_LIBC_ROOT" "$PATCH_DIR/edk2_libc_ctype_lib_name_fix.diff" + git am --directory="$EDK2_ROOT" "$PATCH_DIR/libc/*.patch" touch "$EDK2_LIBC_PATCH_FILE" fi @@ -256,7 +256,7 @@ 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 COMPILE_FLAGS="$COMMON_FLAGS ,'--sysroot=${SYS_ROOT}', '-D__UEFI__', '-DEFIAPI=__attribute__((ms_abi))', '-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$EDK2_LIBC_ROOT/StdLib/Include', '-I$EDK2_LIBC_ROOT/StdLib/Include/$EDK2_TARGET_PROPERTIES_ARCH', '-I$EDK2_ROOT/MdePkg/Include', '-I$EDK2_ROOT/MdePkg/Include/$EDK2_TARGET_PROPERTIES_ARCH'" diff --git a/platforms/uefi/edk2_libc_cpp_compatibility.diff b/platforms/uefi/libc/0001-feat-make-LibC-support-C.patch similarity index 85% rename from platforms/uefi/edk2_libc_cpp_compatibility.diff rename to platforms/uefi/libc/0001-feat-make-LibC-support-C.patch index 7d18690b..0c247458 100644 --- a/platforms/uefi/edk2_libc_cpp_compatibility.diff +++ b/platforms/uefi/libc/0001-feat-make-LibC-support-C.patch @@ -1,3 +1,20 @@ +From 5a3072b1d25e1b78290ba1bbed6370e5c2be9df2 Mon Sep 17 00:00:00 2001 +From: Totto16 +Date: Fri, 21 Aug 2026 18:28:16 +0200 +Subject: [PATCH 1/3] feat: make LibC support C++ - make the includes support + c++ - fix some other small libc related things + +--- + StdLib/Include/assert.h | 7 +++++++ + StdLib/Include/math.h | 8 ++++++++ + StdLib/Include/time.h | 3 ++- + StdLib/Include/wchar.h | 3 +++ + StdLib/LibC/Math/s_ceil.c | 4 ++++ + StdLib/LibC/Stdio/Stdio.inf | 1 + + StdLib/LibC/Stdio/vasprintf.c | 9 +++------ + StdLib/LibC/gdtoa/gdtoa.inf | 3 +++ + 8 files changed, 31 insertions(+), 7 deletions(-) + diff --git a/StdLib/Include/assert.h b/StdLib/Include/assert.h index 26c7037..5296e9a 100644 --- a/StdLib/Include/assert.h @@ -144,3 +161,6 @@ index 9d975bb..44af305 100644 [Packages] StdLib/StdLib.dec StdLibPrivateInternalFiles/DoNotUse.dec +-- +2.55.0 + diff --git a/platforms/uefi/edk2_libc_ctype_lib_name_fix.diff b/platforms/uefi/libc/0002-fix-fix-naming-of-LibCType-to-LibCtype.patch similarity index 74% rename from platforms/uefi/edk2_libc_ctype_lib_name_fix.diff rename to platforms/uefi/libc/0002-fix-fix-naming-of-LibCType-to-LibCtype.patch index 621e89a8..795f13e1 100644 --- a/platforms/uefi/edk2_libc_ctype_lib_name_fix.diff +++ b/platforms/uefi/libc/0002-fix-fix-naming-of-LibCType-to-LibCtype.patch @@ -1,3 +1,16 @@ +From c100be98fc907b9573612503e784618b082f5997 Mon Sep 17 00:00:00 2001 +From: Totto16 +Date: Fri, 21 Aug 2026 18:28:44 +0200 +Subject: [PATCH 2/3] fix: fix naming of LibCType to LibCtype + +--- + StdLib/LibC/Locale/Locale.inf | 2 +- + StdLib/LibC/StdLib/StdLib.inf | 2 +- + StdLib/LibC/Stdio/Stdio.inf | 2 +- + StdLib/LibC/String/String.inf | 2 +- + StdLib/StdLib.inc | 2 +- + 5 files changed, 5 insertions(+), 5 deletions(-) + diff --git a/StdLib/LibC/Locale/Locale.inf b/StdLib/LibC/Locale/Locale.inf index 1bbb611..1c81272 100644 --- a/StdLib/LibC/Locale/Locale.inf @@ -22,10 +35,10 @@ index e7bdf5a..968e6a7 100644 ################################################################ diff --git a/StdLib/LibC/Stdio/Stdio.inf b/StdLib/LibC/Stdio/Stdio.inf -index fe87242..daffb34 100644 +index df122fa..c6e6071 100644 --- a/StdLib/LibC/Stdio/Stdio.inf +++ b/StdLib/LibC/Stdio/Stdio.inf -@@ -128,7 +128,7 @@ +@@ -129,7 +129,7 @@ [LibraryClasses] LibC @@ -60,3 +73,6 @@ index 8083e2b..4d08302 100644 LibLocale|StdLib/LibC/Locale/Locale.inf LibMath|StdLib/LibC/Math/Math.inf LibSignal|StdLib/LibC/Signal/Signal.inf +-- +2.55.0 + diff --git a/platforms/uefi/libc/0003-feat-add-c-and-c-constructors.patch b/platforms/uefi/libc/0003-feat-add-c-and-c-constructors.patch new file mode 100644 index 00000000..5a36e294 --- /dev/null +++ b/platforms/uefi/libc/0003-feat-add-c-and-c-constructors.patch @@ -0,0 +1,189 @@ +From 02a3651a93980bb62b3e463fe091ba5b9bedaea0 Mon Sep 17 00:00:00 2001 +From: Totto16 +Date: Tue, 25 Aug 2026 17:06:59 +0200 +Subject: [PATCH 3/3] feat: add c and c++ constructors - add libcxx and libc + interlaving constructors and destructors, that are invoked before .init_array + and .fini_array - use better option to run libc initializer, use the same + mechanism as the init_array and fini_array one, but with other section names, + so that irt can be run before any init array (note we have .preinit_array but + no destructor counterpart) + +--- + StdLib/Include/libc/main.h | 18 ++++++++ + StdLib/LibC/LibC.inf | 1 + + StdLib/LibC/Main/Main.c | 94 +++++++++++++++++++++++++++++++++++--- + StdLib/StdLib.inc | 2 + + 4 files changed, 109 insertions(+), 6 deletions(-) + create mode 100644 StdLib/Include/libc/main.h + +diff --git a/StdLib/Include/libc/main.h b/StdLib/Include/libc/main.h +new file mode 100644 +index 0000000..65bd539 +--- /dev/null ++++ b/StdLib/Include/libc/main.h +@@ -0,0 +1,18 @@ ++ ++#pragma once ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#define EDK2_LIBC_ENTRY_NAME edk2_libc_main ++ ++extern int EDK2_LIBC_ENTRY_NAME(int, char**); ++ ++#ifdef __cplusplus ++} ++ ++#define EDK2_LIBCXX_ENTRY_NAME edk2_libcxx_main ++ ++extern int EDK2_LIBCXX_ENTRY_NAME(int, char**); ++#endif +diff --git a/StdLib/LibC/LibC.inf b/StdLib/LibC/LibC.inf +index 40b2222..4130326 100644 +--- a/StdLib/LibC/LibC.inf ++++ b/StdLib/LibC/LibC.inf +@@ -118,3 +118,4 @@ + GCC:*_*_IA32_CC_FLAGS = -fno-lto + GCC:*_*_ARM_CC_FLAGS = -fno-lto + GCC:*_*_LOONGARCH64_CC_FLAGS = -fno-lto ++ GCC:*_*_*_CC_FLAGS = -Wprio-ctor-dtor +diff --git a/StdLib/LibC/Main/Main.c b/StdLib/LibC/Main/Main.c +index b203d15..69204cd 100644 +--- a/StdLib/LibC/Main/Main.c ++++ b/StdLib/LibC/Main/Main.c +@@ -31,17 +31,95 @@ + #include + #include + +-extern int main( int, char**); ++#include ++ + extern int __sse2_available; + + struct __MainData *gMD; + +-/* Worker function to keep GCC happy. */ +-void __main() +-{ +- ; ++// these symbols are provided by the linker from the extions .init_array and .fini_array ++typedef void (*init_func_t)(void); ++ ++extern init_func_t __init_array_start[] __attribute__((section(".init_array"), aligned(sizeof(init_func_t)))); ++extern init_func_t __init_array_end[] __attribute__((section(".init_array"), aligned(sizeof(init_func_t)))); ++ ++extern init_func_t __fini_array_start[] __attribute__((section(".fini_array"), aligned(sizeof(init_func_t)))); ++extern init_func_t __fini_array_end[] __attribute__((section(".fini_array"), aligned(sizeof(init_func_t)))); ++ ++extern init_func_t __libc_init_array_start[] __attribute__((section(".init_array"), aligned(sizeof(init_func_t)))); ++extern init_func_t __libc_init_array_end[] __attribute__((section(".init_array"), aligned(sizeof(init_func_t)))); ++ ++extern init_func_t __libc_fini_array_start[] __attribute__((section(".fini_array"), aligned(sizeof(init_func_t)))); ++extern init_func_t __libc_fini_array_end[] __attribute__((section(".fini_array"), aligned(sizeof(init_func_t)))); ++ ++ ++ ++// see: https://gcc.gnu.org/onlinedocs/gccint/Initialization.html ++// for more information on how gcc handles initialization ++ ++static void run_init_array(void) { ++ size_t size = __init_array_end - __init_array_start; ++ for (size_t i = 0; i < size; ++i) { ++ init_func_t func = __init_array_start[i]; ++ if (*func != NULL) { ++ (*func)(); ++ } ++ } ++} ++ ++static void run_fini_array(void) { ++ // iterate reversed ++ size_t size = __fini_array_end - __fini_array_start; ++ for (size_t i = size; i != 0; --i) { ++ init_func_t func = __fini_array_start[i - 1]; ++ if (*func != NULL) { ++ (*func)(); ++ } ++ } ++} ++ ++// see eg. here for some information: ++// https://maskray.me/blog/2021-11-07-init-ctors-init-array ++ ++static void edk2_libc_call_constructors(void) { ++ run_init_array(); ++} ++ ++static void edk2_libc_call_destructors(void) { ++ run_fini_array(); ++} ++ ++static void __c_uefi_init_libc(void) { ++ size_t size = __libc_init_array_end - __libc_init_array_start; ++ for (size_t i = 0; i < size; ++i) { ++ init_func_t func = __libc_init_array_start[i]; ++ if (*func != NULL) { ++ (*func)(); ++ } ++ } ++} ++ ++ ++init_func_t __libc_init_ref_edk2_libc_call_constructors __attribute__((retain, used, section(".__libc_init.prio_99.libc_constructors"), aligned(sizeof(init_func_t)))) = ++edk2_libc_call_constructors; ++ ++ ++static void __c_uefi_deinit_libc(void) { ++ // iterate reversed ++ size_t size = __libc_fini_array_end - __libc_fini_array_start; ++ for (size_t i = size; i != 0; --i) { ++ init_func_t func = __libc_fini_array_start[i - 1]; ++ if (*func != NULL) { ++ (*func)(); ++ } ++ } + } + ++ ++init_func_t __libc_init_ref_edk2_libc_call_destructors __attribute__((retain, used, section(".__libc_fini.prio_99.libc_destructors"), aligned(sizeof(init_func_t)))) = ++edk2_libc_call_destructors; ++ ++ + /** Clean up data as required by the exit() function. + + **/ +@@ -67,6 +145,9 @@ exitCleanup(INTN ExitVal) + CleanUp(); + } + } ++ ++ // this is needed, if we use a c++ standard library, we need to clean up that before we clean up the libc and after custom cleanup and atexit calls ++ __c_uefi_deinit_libc(); + } + + /* Create mbcs versions of the Argv strings. */ +@@ -179,7 +260,8 @@ ShellAppMain ( + else { + if( setjmp(gMD->MainExit) == 0) { + errno = 0; // Clean up any "scratch" values from startup. +- ExitVal = (INTN)main( (int)Argc, gMD->NArgV); ++ __c_uefi_init_libc(); ++ ExitVal = (INTN)EDK2_LIBC_ENTRY_NAME( (int)Argc, gMD->NArgV); + exitCleanup(ExitVal); + } + /* You reach here if: +diff --git a/StdLib/StdLib.inc b/StdLib/StdLib.inc +index 4d08302..d6f2b73 100644 +--- a/StdLib/StdLib.inc ++++ b/StdLib/StdLib.inc +@@ -138,3 +138,5 @@ + MSFT:*_VS2015x86xASL_*_CC_FLAGS = /Wv:11 + MSFT:*_VS2017_*_CC_FLAGS = /Wv:11 + MSFT:*_VS2019_*_CC_FLAGS = /Wv:11 ++ ++ GCC:*_*_*_CC_FLAGS = -Wprio-ctor-dtor +-- +2.55.0 + diff --git a/src/executables/game/main.cpp b/src/executables/game/main.cpp index fe413113..9e47ec0e 100644 --- a/src/executables/game/main.cpp +++ b/src/executables/game/main.cpp @@ -187,14 +187,12 @@ namespace { #if defined(__UEFI__) -extern "C" { +#include -// link it as C function, the rest is done by the StdLib Wrapper, but argc might be 0 and argv NULL - -int main(int argc, char** argv) { +int EDK2_LIBCXX_ENTRY_NAME(int argc, char** argv) { return main_no_sdl_replace(argc, argv); } -} + #else int main(int argc, char** argv) { diff --git a/src/helper/uefi_utils.cpp b/src/helper/uefi_utils.cpp index 099a4d2a..04149c77 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: - EFI_DEBUG((DEBUG_VERBOSE, "%s", message)); + EFI_DEBUG((DEBUG_VERBOSE, "%a", message)); break; case spdlog::level::info: - EFI_DEBUG((DEBUG_INFO, "%s", message)); + EFI_DEBUG((DEBUG_INFO, "%a", message)); break; case spdlog::level::warn: - EFI_DEBUG((DEBUG_WARN, "%s", message)); + EFI_DEBUG((DEBUG_WARN, "%a", message)); break; case spdlog::level::err: case spdlog::level::critical: - EFI_DEBUG((DEBUG_ERROR, "%s", message)); + EFI_DEBUG((DEBUG_ERROR, "%a", message)); break; default: return; diff --git a/src/libs/core/helper/utils.hpp b/src/libs/core/helper/utils.hpp index 730f5686..b72150d5 100644 --- a/src/libs/core/helper/utils.hpp +++ b/src/libs/core/helper/utils.hpp @@ -132,7 +132,7 @@ namespace utils { [[noreturn]] inline void throw_(E&& exc) { //NOLINT(readability-identifier-naming) #if defined(__OOPETRIS_NO_EXCEPTIONS) #if defined(__UEFI__) - EFI_DEBUG((DEBUG_ERROR, "Exception: %s", exc.what())); + EFI_DEBUG((DEBUG_ERROR, "Exception: %a", exc.what())); #else std::cerr << "Exception: " << exc.what() << "\n"; #endif @@ -158,7 +158,7 @@ namespace utils { #if defined(__UEFI__) #define UNREACHABLE() /* NOLINT(cppcoreguidelines-macro-usage)*/ \ do { /* NOLINT(cppcoreguidelines-avoid-do-while)*/ \ - EFI_DEBUG((DEBUG_ERROR, "UNREACHABLE %s:%d - %s\n", __FILE__, __LINE__, __FUNCTION__)); \ + EFI_DEBUG((DEBUG_ERROR, "UNREACHABLE %a:%d - %a\n", __FILE__, __LINE__, __FUNCTION__)); \ utils::unreachable(); \ } while (false) #else diff --git a/subprojects/packagefiles/utfcpp-4.0.8_no_exceptions.diff b/subprojects/packagefiles/utfcpp-4.0.8_no_exceptions.diff index ba05c746..0dffd828 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 { \ -+ DEBUG((DEBUG_ERROR, "THROW %s:%d - %s: %s\n", __FILE__, __LINE__, __FUNCTION__, exc.what())); \ ++ DEBUG((DEBUG_ERROR, "THROW %a:%d - %a: %a\n", __FILE__, __LINE__, __FUNCTION__, exc.what())); \ + abort(); \ + } while (false) +#else From 1049b7fd8061bc0b93c6662318b8a2cfe2eca93a Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 25 Aug 2026 17:41:22 +0200 Subject: [PATCH 118/143] feat: use git patches instead of custom diffs --- platforms/build-uefi.sh | 13 +- .../0001-feat-make-LibC-support-C.patch | 0 ...x-fix-naming-of-LibCType-to-LibCtype.patch | 0 .../0003-feat-add-c-and-c-constructors.patch | 0 .../0001-feat-correct-cxx-support.patch} | 24 +- ...-use-x86_64-v1-for-the-architecture.patch} | 90 ++++++-- ...-for-C-and-C-constructors-and-destru.patch | 208 ++++++++++++++++++ ...l-lib-include-for-the-package-I-use.patch} | 19 +- ...ompiling-crypto-library-with-stdlib.patch} | 173 ++++++++------- 9 files changed, 418 insertions(+), 109 deletions(-) rename platforms/uefi/{libc => edk2-libc}/0001-feat-make-LibC-support-C.patch (100%) rename platforms/uefi/{libc => edk2-libc}/0002-fix-fix-naming-of-LibCType-to-LibCtype.patch (100%) rename platforms/uefi/{libc => edk2-libc}/0003-feat-add-c-and-c-constructors.patch (100%) rename platforms/uefi/{edk2_cxx_compiler.diff => edk2/0001-feat-correct-cxx-support.patch} (79%) rename platforms/uefi/{edk2_use_arch_x86_64_v1.diff => edk2/0002-feat-use-x86_64-v1-for-the-architecture.patch} (68%) create mode 100644 platforms/uefi/edk2/0003-feat-add-support-for-C-and-C-constructors-and-destru.patch rename platforms/uefi/{edk2_ssl_lib.diff => edk2/0004-feat-add-ssl-lib-include-for-the-package-I-use.patch} (80%) rename platforms/uefi/{edk2_ssl_lib_compile_with_libc.diff => edk2/0005-feat-support-compiling-crypto-library-with-stdlib.patch} (88%) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 8b981538..1588fc2e 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -135,13 +135,7 @@ EDK2_PATCH_FILE="$EDK2_ROOT/.patched_manually.meta" if ! [ -e "$EDK2_PATCH_FILE" ]; then ##TODO: upstream those patches - #TODO: use loop for this patches - - git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/edk2_cxx_compiler.diff" - git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/edk2_ssl_lib.diff" - git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/edk2_ssl_lib_compile_with_libc.diff" - git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_DIR/edk2_use_arch_x86_64_v1.diff" - #TODO: GENFW and linker script for constructors + git am --directory="$EDK2_ROOT" "$PATCH_DIR/edk2/*.patch" touch "$EDK2_PATCH_FILE" fi @@ -151,7 +145,7 @@ EDK2_LIBC_PATCH_FILE="$EDK2_LIBC_ROOT/.patched_manually.meta" if ! [ -e "$EDK2_LIBC_PATCH_FILE" ]; then ##TODO: upstream those patches - git am --directory="$EDK2_ROOT" "$PATCH_DIR/libc/*.patch" + git am --directory="$EDK2_ROOT" "$PATCH_DIR/edk2-libc/*.patch" touch "$EDK2_LIBC_PATCH_FILE" fi @@ -229,10 +223,8 @@ fi git -C "$EDK2_LLVM_ROOT" checkout "$EDK2_LLVM_PORT_BRANCH" - popd - export CC="$SCRIPT_DIR/uefi/gcc-wrapper.sh" export CXX="$SCRIPT_DIR/uefi/g++-wrapper.sh" @@ -361,7 +353,6 @@ cat <"$EDK2_INFO_FILE" } EOF - if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "${EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM:?}" ]; then rm -f "${EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM:?}" diff --git a/platforms/uefi/libc/0001-feat-make-LibC-support-C.patch b/platforms/uefi/edk2-libc/0001-feat-make-LibC-support-C.patch similarity index 100% rename from platforms/uefi/libc/0001-feat-make-LibC-support-C.patch rename to platforms/uefi/edk2-libc/0001-feat-make-LibC-support-C.patch diff --git a/platforms/uefi/libc/0002-fix-fix-naming-of-LibCType-to-LibCtype.patch b/platforms/uefi/edk2-libc/0002-fix-fix-naming-of-LibCType-to-LibCtype.patch similarity index 100% rename from platforms/uefi/libc/0002-fix-fix-naming-of-LibCType-to-LibCtype.patch rename to platforms/uefi/edk2-libc/0002-fix-fix-naming-of-LibCType-to-LibCtype.patch diff --git a/platforms/uefi/libc/0003-feat-add-c-and-c-constructors.patch b/platforms/uefi/edk2-libc/0003-feat-add-c-and-c-constructors.patch similarity index 100% rename from platforms/uefi/libc/0003-feat-add-c-and-c-constructors.patch rename to platforms/uefi/edk2-libc/0003-feat-add-c-and-c-constructors.patch diff --git a/platforms/uefi/edk2_cxx_compiler.diff b/platforms/uefi/edk2/0001-feat-correct-cxx-support.patch similarity index 79% rename from platforms/uefi/edk2_cxx_compiler.diff rename to platforms/uefi/edk2/0001-feat-correct-cxx-support.patch index 222930d1..e0f31325 100644 --- a/platforms/uefi/edk2_cxx_compiler.diff +++ b/platforms/uefi/edk2/0001-feat-correct-cxx-support.patch @@ -1,8 +1,17 @@ -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 @@ +From 449c60fbe87e7517f2820ca3c2a2e951a377bbfe Mon Sep 17 00:00:00 2001 +From: Totto16 +Date: Tue, 25 Aug 2026 17:33:06 +0200 +Subject: [PATCH 1/5] feat: correct cxx support - make C++ correctly supported + +--- + BaseTools/Conf/build_rule.template | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/BaseTools/Conf/build_rule.template b/BaseTools/Conf/build_rule.template +index a89866d700..e804a1c965 100755 +--- a/BaseTools/Conf/build_rule.template ++++ b/BaseTools/Conf/build_rule.template +@@ -121,13 +121,13 @@ $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj @@ -19,7 +28,7 @@ index 0c454ee3d5..9e13b638f8 100755 [Cxx-Code-File] -@@ -144,13 +144,13 @@ +@@ -144,13 +144,13 @@ $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj @@ -36,3 +45,6 @@ index 0c454ee3d5..9e13b638f8 100755 [C-Code-File.BASE.AARCH64,C-Code-File.SEC.AARCH64,C-Code-File.PEI_CORE.AARCH64,C-Code-File.PEIM.AARCH64] +-- +2.55.0 + diff --git a/platforms/uefi/edk2_use_arch_x86_64_v1.diff b/platforms/uefi/edk2/0002-feat-use-x86_64-v1-for-the-architecture.patch similarity index 68% rename from platforms/uefi/edk2_use_arch_x86_64_v1.diff rename to platforms/uefi/edk2/0002-feat-use-x86_64-v1-for-the-architecture.patch index 1a761bce..42b512d9 100644 --- a/platforms/uefi/edk2_use_arch_x86_64_v1.diff +++ b/platforms/uefi/edk2/0002-feat-use-x86_64-v1-for-the-architecture.patch @@ -1,8 +1,17 @@ +From 858623f599d6ed659f2d33d55d1e1104be3d0981 Mon Sep 17 00:00:00 2001 +From: Totto16 +Date: Tue, 25 Aug 2026 17:34:06 +0200 +Subject: [PATCH 2/5] feat: use x86_64 v1 for the architecture + +--- + BaseTools/Conf/tools_def.template | 64 +++++++++++++++---------------- + 1 file changed, 32 insertions(+), 32 deletions(-) + diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template -index eca4cb82d0..f5f3f1c447 100644 +index 72ca0dfa21..f437d0b9da 100644 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template -@@ -956,7 +956,7 @@ DEFINE GCC_DEPS_FLAGS = -MMD -MF $@.deps +@@ -618,7 +618,7 @@ DEFINE GCC_DEPS_FLAGS = -MMD -MF $@.deps DEFINE GCC_ALL_CC_FLAGS = DEF(GCC_ALL_CC_COMMON) -ffunction-sections -fdata-sections -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings DEFINE GCCNOLTO_IA32_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) DEF(GCC_IA32_X64_CC_FLAGS) -m32 -march=i586 -malign-double -D EFI32 -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer -fno-pic -fno-pie @@ -11,7 +20,7 @@ index eca4cb82d0..f5f3f1c447 100644 DEFINE GCCNOLTO_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections -z common-page-size=0x40 DEFINE GCCNOLTO_IA32_X64_ASLDLINK_FLAGS = DEF(GCCNOLTO_IA32_X64_DLINK_COMMON) -Wl,--defsym=PECOFF_HEADER_SIZE=0 DEF(GCC_DLINK2_FLAGS_COMMON) -Wl,--entry,ReferenceAcpiTable -u ReferenceAcpiTable DEFINE GCCNOLTO_IA32_X64_DLINK_FLAGS = DEF(GCCNOLTO_IA32_X64_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map,--whole-archive -@@ -1076,9 +1076,9 @@ RELEASE_GCCNOLTO_IA32_CC_FLAGS = DEF(GCCNOLTO_IA32_CC_FLAGS) +@@ -738,9 +738,9 @@ RELEASE_GCCNOLTO_IA32_CC_FLAGS = DEF(GCCNOLTO_IA32_CC_FLAGS) *_GCCNOLTO_X64_ASLPP_PATH = DEF(GCCNOLTO_X64_PREFIX)gcc *_GCCNOLTO_X64_RC_PATH = DEF(GCCNOLTO_X64_PREFIX)objcopy @@ -23,7 +32,23 @@ index eca4cb82d0..f5f3f1c447 100644 *_GCCNOLTO_X64_DLINK_FLAGS = DEF(GCCNOLTO_X64_DLINK_FLAGS) *_GCCNOLTO_X64_DLINK2_FLAGS = DEF(GCCNOLTO_X64_DLINK2_FLAGS) *_GCCNOLTO_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS) -@@ -1194,9 +1194,9 @@ RELEASE_GCC_IA32_DLINK_FLAGS = DEF(GCC_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,-m +@@ -832,11 +832,11 @@ RELEASE_GCCNOLTO_AARCH64_DLINK_FLAGS = DEF(GCCNOLTO_AARCH64_DLINK_FLAGS) + *_GCC_IA32_OBJCOPY_FLAGS = + *_GCC_IA32_NASM_FLAGS = -f elf32 + +- DEBUG_GCC_IA32_CC_FLAGS = DEF(GCC_IA32_CC_FLAGS) -flto +- DEBUG_GCC_IA32_DLINK_FLAGS = DEF(GCC_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,-m,elf_i386,--oformat=elf32-i386 -z common-page-size=0x40 ++ DEBUG_GCC_IA32_CC_FLAGS = DEF(GCC_IA32_CC_FLAGS) -flto=auto ++ DEBUG_GCC_IA32_DLINK_FLAGS = DEF(GCC_IA32_X64_DLINK_FLAGS) -flto=auto -Os -Wl,-m,elf_i386,--oformat=elf32-i386 -z common-page-size=0x40 + +-RELEASE_GCC_IA32_CC_FLAGS = DEF(GCC_IA32_CC_FLAGS) -flto +-RELEASE_GCC_IA32_DLINK_FLAGS = DEF(GCC_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,-m,elf_i386,--oformat=elf32-i386 -z common-page-size=0x40 ++RELEASE_GCC_IA32_CC_FLAGS = DEF(GCC_IA32_CC_FLAGS) -flto=auto ++RELEASE_GCC_IA32_DLINK_FLAGS = DEF(GCC_IA32_X64_DLINK_FLAGS) -flto=auto -Os -Wl,-m,elf_i386,--oformat=elf32-i386 -z common-page-size=0x40 + + NOOPT_GCC_IA32_CC_FLAGS = DEF(GCC_IA32_CC_FLAGS) -O0 + NOOPT_GCC_IA32_DLINK_FLAGS = DEF(GCC_IA32_X64_DLINK_FLAGS) -Wl,-m,elf_i386,--oformat=elf32-i386 -O0 -z common-page-size=0x40 +@@ -856,19 +856,19 @@ RELEASE_GCC_IA32_DLINK_FLAGS = DEF(GCC_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,-m *_GCC_X64_ASLPP_PATH = DEF(GCC_X64_PREFIX)gcc *_GCC_X64_RC_PATH = DEF(GCC_X64_PREFIX)objcopy @@ -35,7 +60,37 @@ index eca4cb82d0..f5f3f1c447 100644 *_GCC_X64_DLINK2_FLAGS = DEF(GCC_X64_DLINK2_FLAGS) *_GCC_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS) *_GCC_X64_OBJCOPY_FLAGS = -@@ -1394,8 +1394,8 @@ NOOPT_CLANGPDB_IA32_DLINK2_FLAGS = + *_GCC_X64_NASM_FLAGS = -f elf64 + +- DEBUG_GCC_X64_CC_FLAGS = DEF(GCC_X64_CC_FLAGS) -flto -DUSING_LTO +- DEBUG_GCC_X64_DLINK_FLAGS = DEF(GCC_X64_DLINK_FLAGS) -flto -Os -z common-page-size=0x1000 ++ DEBUG_GCC_X64_CC_FLAGS = DEF(GCC_X64_CC_FLAGS) -flto=auto -DUSING_LTO ++ DEBUG_GCC_X64_DLINK_FLAGS = DEF(GCC_X64_DLINK_FLAGS) -flto=auto -Os -z common-page-size=0x1000 + +-RELEASE_GCC_X64_CC_FLAGS = DEF(GCC_X64_CC_FLAGS) -flto -DUSING_LTO +-RELEASE_GCC_X64_DLINK_FLAGS = DEF(GCC_X64_DLINK_FLAGS) -flto -Os -z common-page-size=0x1000 ++RELEASE_GCC_X64_CC_FLAGS = DEF(GCC_X64_CC_FLAGS) -flto=auto -DUSING_LTO ++RELEASE_GCC_X64_DLINK_FLAGS = DEF(GCC_X64_DLINK_FLAGS) -flto=auto -Os -z common-page-size=0x1000 + + NOOPT_GCC_X64_CC_FLAGS = DEF(GCC_X64_CC_FLAGS) -O0 + NOOPT_GCC_X64_DLINK_FLAGS = DEF(GCC_X64_DLINK_FLAGS) -O0 -z common-page-size=0x1000 +@@ -900,11 +900,11 @@ RELEASE_GCC_X64_DLINK_FLAGS = DEF(GCC_X64_DLINK_FLAGS) -flto -Os -z common-p + *_GCC_AARCH64_VFRPP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS) + *_GCC_AARCH64_CC_XIPFLAGS = DEF(GCC_AARCH64_CC_XIPFLAGS) + +- DEBUG_GCC_AARCH64_CC_FLAGS = DEF(GCC_AARCH64_CC_FLAGS) -flto +- DEBUG_GCC_AARCH64_DLINK_FLAGS = DEF(GCC_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch -z common-page-size=0x1000 ++ DEBUG_GCC_AARCH64_CC_FLAGS = DEF(GCC_AARCH64_CC_FLAGS) -flto=auto ++ DEBUG_GCC_AARCH64_DLINK_FLAGS = DEF(GCC_AARCH64_DLINK_FLAGS) -flto=auto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch -z common-page-size=0x1000 + +-RELEASE_GCC_AARCH64_CC_FLAGS = DEF(GCC_AARCH64_CC_FLAGS) -flto +-RELEASE_GCC_AARCH64_DLINK_FLAGS = DEF(GCC_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch -z common-page-size=0x1000 ++RELEASE_GCC_AARCH64_CC_FLAGS = DEF(GCC_AARCH64_CC_FLAGS) -flto=auto ++RELEASE_GCC_AARCH64_DLINK_FLAGS = DEF(GCC_AARCH64_DLINK_FLAGS) -flto=auto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch -z common-page-size=0x1000 + + NOOPT_GCC_AARCH64_CC_FLAGS = DEF(GCC_AARCH64_CC_FLAGS) -O0 + NOOPT_GCC_AARCH64_DLINK_FLAGS = DEF(GCC_AARCH64_DLINK_FLAGS) -O0 -z common-page-size=0x1000 +@@ -1056,8 +1056,8 @@ NOOPT_CLANGPDB_IA32_DLINK2_FLAGS = *_CLANGPDB_X64_ASLPP_PATH = DEF(CLANGPDB_X64_PREFIX)clang *_CLANGPDB_X64_RC_PATH = DEF(CLANGPDB_IA32_PREFIX)llvm-rc @@ -46,12 +101,12 @@ index eca4cb82d0..f5f3f1c447 100644 *_CLANGPDB_X64_OBJCOPY_FLAGS = DEBUG_CLANGPDB_X64_NASM_FLAGS = -Ox -f win64 -g -@@ -1406,17 +1406,17 @@ NOOPT_CLANGPDB_X64_NASM_FLAGS = -O0 -f win64 -g +@@ -1068,17 +1068,17 @@ NOOPT_CLANGPDB_X64_NASM_FLAGS = -O0 -f win64 -g *_CLANGPDB_X64_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS) DEF(CLANGPDB_X64_TARGET) *_CLANGPDB_X64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGPDB_X64_TARGET) -DEBUG_CLANGPDB_X64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -Oz -flto DEF(CLANGPDB_X64_TARGET) -gcodeview -funwind-tables -+DEBUG_CLANGPDB_X64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 -march=x86-64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -Oz -flto DEF(CLANGPDB_X64_TARGET) -gcodeview -funwind-tables ++DEBUG_CLANGPDB_X64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 -march=x86-64"-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -Oz -flto DEF(CLANGPDB_X64_TARGET) -gcodeview -funwind-tables DEBUG_CLANGPDB_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /ALIGN:4096 /DRIVER /FILEALIGN:32 /Machine:X64 /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap DEBUG_CLANGPDB_X64_DLINK2_FLAGS = DEBUG_CLANGPDB_X64_GENFW_FLAGS = --keepexceptiontable @@ -63,42 +118,42 @@ index eca4cb82d0..f5f3f1c447 100644 RELEASE_CLANGPDB_X64_GENFW_FLAGS = -NOOPT_CLANGPDB_X64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -O0 DEF(CLANGPDB_X64_TARGET) -gcodeview -funwind-tables -+NOOPT_CLANGPDB_X64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 -march=x86-64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -O0 DEF(CLANGPDB_X64_TARGET) -gcodeview -funwind-tables ++NOOPT_CLANGPDB_X64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 -march=x86-64"-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -O0 DEF(CLANGPDB_X64_TARGET) -gcodeview -funwind-tables NOOPT_CLANGPDB_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /ALIGN:32 /DRIVER /FILEALIGN:32 /Machine:X64 /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap NOOPT_CLANGPDB_X64_DLINK2_FLAGS = NOOPT_CLANGPDB_X64_GENFW_FLAGS = --keepexceptiontable -@@ -1437,8 +1437,8 @@ NOOPT_CLANGPDB_X64_GENFW_FLAGS = --keepexceptiontable +@@ -1099,8 +1099,8 @@ NOOPT_CLANGPDB_X64_GENFW_FLAGS = --keepexceptiontable *_CLANGPDB_AARCH64_ASLPP_PATH = DEF(CLANGPDB_AARCH64_PREFIX)clang *_CLANGPDB_AARCH64_RC_PATH = DEF(CLANGPDB_AARCH64_PREFIX)llvm-rc -*_CLANGPDB_AARCH64_ASLCC_FLAGS = DEF(GCC_ASLCC_COMMON) -m64 -fno-lto DEF(CLANGPDB_AARCH64_TARGET) -*_CLANGPDB_AARCH64_ASM_FLAGS = DEF(GCC_ASM_COMMON) -m64 DEF(CLANGPDB_AARCH64_TARGET) -+*_CLANGPDB_AARCH64_ASLCC_FLAGS = DEF(GCC_ASLCC_COMMON) -m64 -march=x86-64-fno-lto DEF(CLANGPDB_AARCH64_TARGET) ++*_CLANGPDB_AARCH64_ASLCC_FLAGS = DEF(GCC_ASLCC_COMMON) -m64 -march=x86-64 -fno-lto DEF(CLANGPDB_AARCH64_TARGET) +*_CLANGPDB_AARCH64_ASM_FLAGS = DEF(GCC_ASM_COMMON) -m64 -march=x86-64 DEF(CLANGPDB_AARCH64_TARGET) *_CLANGPDB_AARCH64_OBJCOPY_FLAGS = *_CLANGPDB_AARCH64_NASM_FLAGS = -f win64 *_CLANGPDB_AARCH64_PP_FLAGS = DEF(GCC_PP_FLAGS) DEF(CLANGPDB_AARCH64_TARGET) -@@ -1446,16 +1446,16 @@ NOOPT_CLANGPDB_X64_GENFW_FLAGS = --keepexceptiontable +@@ -1108,16 +1108,16 @@ NOOPT_CLANGPDB_X64_GENFW_FLAGS = --keepexceptiontable *_CLANGPDB_AARCH64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGPDB_AARCH64_TARGET) *_CLANGPDB_AARCH64_CC_XIPFLAGS = -mstrict-align -DEBUG_CLANGPDB_AARCH64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 -mcmodel=small -Oz -flto DEF(CLANGPDB_AARCH64_TARGET) -gcodeview -funwind-tables -Wno-deprecated-non-prototype -Wno-constant-conversion -Werror -+DEBUG_CLANGPDB_AARCH64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 -march=x86-64 -mcmodel=small -Oz -flto DEF(CLANGPDB_AARCH64_TARGET) -gcodeview -funwind-tables -Wno-deprecated-non-prototype -Wno-constant-conversion -Werror ++DEBUG_CLANGPDB_AARCH64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 -march=x86-64-mcmodel=small -Oz -flto DEF(CLANGPDB_AARCH64_TARGET) -gcodeview -funwind-tables -Wno-deprecated-non-prototype -Wno-constant-conversion -Werror DEBUG_CLANGPDB_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /WX /OPT:REF /OPT:ICF=10 /ALIGN:4096 /Machine:ARM64 /DLL /DRIVER /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap DEBUG_CLANGPDB_AARCH64_DLINK2_FLAGS = DEBUG_CLANGPDB_AARCH64_GENFW_FLAGS = --keepexceptiontable -RELEASE_CLANGPDB_AARCH64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 -mcmodel=small -Oz -flto DEF(CLANGPDB_AARCH64_TARGET) -fno-unwind-tables -Wno-deprecated-non-prototype -Wno-constant-conversion -Werror -+RELEASE_CLANGPDB_AARCH64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 -march=x86-64 -mcmodel=small -Oz -flto DEF(CLANGPDB_AARCH64_TARGET) -fno-unwind-tables -Wno-deprecated-non-prototype -Wno-constant-conversion -Werror ++RELEASE_CLANGPDB_AARCH64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 -march=x86-64-mcmodel=small -Oz -flto DEF(CLANGPDB_AARCH64_TARGET) -fno-unwind-tables -Wno-deprecated-non-prototype -Wno-constant-conversion -Werror RELEASE_CLANGPDB_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /WX /OPT:REF /OPT:ICF=10 /ALIGN:4096 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:ARM64 /DLL /DRIVER /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /MERGE:.rdata=.data /MLLVM:-exception-model=wineh /lldmap RELEASE_CLANGPDB_AARCH64_DLINK2_FLAGS = -NOOPT_CLANGPDB_AARCH64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 -mcmodel=small -O0 DEF(CLANGPDB_AARCH64_TARGET) -gcodeview -funwind-tables -Wno-deprecated-non-prototype -Wno-constant-conversion -Werror -+NOOPT_CLANGPDB_AARCH64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 -march=x86-64 -mcmodel=small -O0 DEF(CLANGPDB_AARCH64_TARGET) -gcodeview -funwind-tables -Wno-deprecated-non-prototype -Wno-constant-conversion -Werror ++NOOPT_CLANGPDB_AARCH64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 -march=x86-64-mcmodel=small -O0 DEF(CLANGPDB_AARCH64_TARGET) -gcodeview -funwind-tables -Wno-deprecated-non-prototype -Wno-constant-conversion -Werror NOOPT_CLANGPDB_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /WX /OPT:REF /OPT:ICF=10 /ALIGN:4096 /Machine:ARM64 /DLL /DRIVER /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap NOOPT_CLANGPDB_AARCH64_DLINK2_FLAGS = NOOPT_CLANGPDB_AARCH64_GENFW_FLAGS = --keepexceptiontable -@@ -1569,9 +1569,9 @@ NOOPT_CLANGDWARF_IA32_DLINK2_FLAGS = DEF(CLANGDWARF_IA32_DLINK2_FLAGS) -O0 - +@@ -1234,9 +1234,9 @@ NOOPT_CLANGDWARF_IA32_DLINK2_FLAGS = DEF(CLANGDWARF_IA32_DLINK2_FLAGS) -O0 - *_CLANGDWARF_X64_ASLPP_PATH = DEF(CLANGDWARF_X64_PREFIX)clang *_CLANGDWARF_X64_RC_PATH = DEF(CLANGDWARF_X64_PREFIX)llvm-objcopy @@ -110,7 +165,7 @@ index eca4cb82d0..f5f3f1c447 100644 *_CLANGDWARF_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS) *_CLANGDWARF_X64_OBJCOPY_FLAGS = -@@ -1583,15 +1583,15 @@ NOOPT_CLANGDWARF_X64_NASM_FLAGS = -O0 -f elf64 -g +@@ -1248,15 +1248,15 @@ NOOPT_CLANGDWARF_X64_NASM_FLAGS = -O0 -f elf64 -g *_CLANGDWARF_X64_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS) DEF(CLANGDWARF_X64_TARGET) *_CLANGDWARF_X64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGDWARF_X64_TARGET) @@ -129,3 +184,6 @@ index eca4cb82d0..f5f3f1c447 100644 NOOPT_CLANGDWARF_X64_DLINK_FLAGS = DEF(CLANGDWARF_X64_TARGET) DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -Wl,-O0 -Wl,-melf_x86_64 -Wl,--oformat,elf64-x86-64 -Wl,-pie -mcmodel=small -Wl,--apply-dynamic-relocs -z common-page-size=0x1000 NOOPT_CLANGDWARF_X64_DLINK2_FLAGS = DEF(CLANGDWARF_X64_DLINK2_FLAGS) -O0 -fuse-ld=lld +-- +2.55.0 + diff --git a/platforms/uefi/edk2/0003-feat-add-support-for-C-and-C-constructors-and-destru.patch b/platforms/uefi/edk2/0003-feat-add-support-for-C-and-C-constructors-and-destru.patch new file mode 100644 index 00000000..9434cc30 --- /dev/null +++ b/platforms/uefi/edk2/0003-feat-add-support-for-C-and-C-constructors-and-destru.patch @@ -0,0 +1,208 @@ +From 520e261faf9e4afb436f63143f4a0401ad74d251 Mon Sep 17 00:00:00 2001 +From: Totto16 +Date: Tue, 25 Aug 2026 17:35:20 +0200 +Subject: [PATCH 3/5] feat: add support for C and C++ constructors and + destructors - this requires as linker script change and GenFW modifications - + this can 5than be used by edk2-libc and libcxx for uefi + +--- + BaseTools/Scripts/GccBase.lds | 61 +++++++++++++++++++++++++ + BaseTools/Source/C/GenFw/Elf32Convert.c | 35 ++++++++++++++ + BaseTools/Source/C/GenFw/Elf64Convert.c | 35 ++++++++++++++ + 3 files changed, 131 insertions(+) + +diff --git a/BaseTools/Scripts/GccBase.lds b/BaseTools/Scripts/GccBase.lds +index 3d2a97ddeb..32b54385fc 100644 +--- a/BaseTools/Scripts/GccBase.lds ++++ b/BaseTools/Scripts/GccBase.lds +@@ -85,6 +85,67 @@ SECTIONS { + */ + .build-id (INFO) : { *(.note.gnu.build-id) } + ++ /* ++ * Retain the GCC static / global constructor / initializer and destructors / finalizer ++ */ ++ .init_array : { ++ PROVIDE_HIDDEN(__init_array_start = .); ++ ++ KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*))) ++ KEEP(*(.init_array)) ++ ++ PROVIDE_HIDDEN(__init_array_end = .); ++ ++ PROVIDE_HIDDEN(__libc_init_array_start = .); ++ ++ KEEP(*(SORT_BY_NAME(.__libc_init.*))) ++ ++ PROVIDE_HIDDEN(__libc_init_array_end = .); ++ } ++ ++ .fini_array : { ++ PROVIDE_HIDDEN(__fini_array_start = .); ++ ++ KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*))) ++ KEEP(*(.fini_array)) ++ ++ PROVIDE_HIDDEN(__fini_array_end = .); ++ ++ PROVIDE_HIDDEN(__libc_fini_array_start = .); ++ ++ KEEP(*(SORT_BY_NAME(.__libc_fini.*))) ++ ++ PROVIDE_HIDDEN(__libc_fini_array_end = .); ++ } ++ ++ /* ++ * Error on unsupported (or not yet implemented) sections for construction / destruction ++ */ ++ .preinit_array : { ++ *(.preinit_array) ++ } ++ ASSERT(SIZEOF(.preinit_array) == 0, "error: .preinit_array is not supported (yet)") ++ ++ .init : { ++ *(.init) ++ } ++ ASSERT(SIZEOF(.init) == 0, "error: .init is deprecated (System V uses it, and GCC uses other mechanisms)") ++ ++ .fini : { ++ *(.fini) ++ } ++ ASSERT(SIZEOF(.fini) == 0, "error: .fini is deprecated (System V uses it, and GCC uses other mechanisms)") ++ ++ .ctors : { ++ *(.ctors) ++ } ++ ASSERT(SIZEOF(.ctors) == 0, "error: .ctors is not implemented yet (C++ uses that)") ++ ++ .dtors : { ++ *(.dtors) ++ } ++ ASSERT(SIZEOF(.dtors) == 0, "error: .dtors is not implemented yet (C++ uses that)") ++ + /DISCARD/ : { + *(.note.GNU-stack) + *(.gnu_debuglink) +diff --git a/BaseTools/Source/C/GenFw/Elf32Convert.c b/BaseTools/Source/C/GenFw/Elf32Convert.c +index 7b4fb4410a..45d5965228 100644 +--- a/BaseTools/Source/C/GenFw/Elf32Convert.c ++++ b/BaseTools/Source/C/GenFw/Elf32Convert.c +@@ -239,6 +239,26 @@ IsHiiRsrcShdr ( + return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + Shdr->sh_name, ELF_HII_SECTION_NAME) == 0); + } + ++#define ELF_INIT_ARRAY_SECTION_NAME ".init_array" ++#define ELF_FINI_ARRAY_SECTION_NAME ".fini_array" ++ ++STATIC ++BOOLEAN ++IsInitFiniArrayShdr ( ++ Elf_Shdr *Shdr ++ ) ++{ ++ Elf_Shdr *Namedr = GetShdrByIndex(mEhdr->e_shstrndx); ++ const CHAR8 *Name = (const CHAR8 *)mEhdr + ++ Namedr->sh_offset + ++ Shdr->sh_name; ++ ++ return (BOOLEAN)( ++ strcmp(Name, ELF_INIT_ARRAY_SECTION_NAME) == 0 || ++ strcmp(Name, ELF_FINI_ARRAY_SECTION_NAME) == 0 ++ ); ++} ++ + STATIC + BOOLEAN + IsDataShdr ( +@@ -248,6 +268,9 @@ IsDataShdr ( + if (IsHiiRsrcShdr(Shdr)) { + return FALSE; + } ++ if (IsInitFiniArrayShdr (Shdr)) { ++ return TRUE; ++ } + return (BOOLEAN) (Shdr->sh_flags & (SHF_EXECINSTR | SHF_WRITE | SHF_ALLOC)) == (SHF_ALLOC | SHF_WRITE); + } + +@@ -662,6 +685,18 @@ WriteSections32 ( + memset(mCoffFile + mCoffSectionsOffset[Idx], 0, Shdr->sh_size); + break; + ++ case SHT_INIT_ARRAY: ++ case SHT_FINI_ARRAY: ++ //NOTE: do the same as the SHT_PROGBITS section (we SHOULd have already determined them as data sections, so there should be space) ++ /* Copy. */ ++ if (Shdr->sh_offset + Shdr->sh_size > mFileBufferSize) { ++ return FALSE; ++ } ++ memcpy(mCoffFile + mCoffSectionsOffset[Idx], ++ (UINT8*)mEhdr + Shdr->sh_offset, ++ (size_t) Shdr->sh_size); ++ break; ++ + default: + // + // Ignore for unknown section type. +diff --git a/BaseTools/Source/C/GenFw/Elf64Convert.c b/BaseTools/Source/C/GenFw/Elf64Convert.c +index 1208137bca..c1a01de706 100644 +--- a/BaseTools/Source/C/GenFw/Elf64Convert.c ++++ b/BaseTools/Source/C/GenFw/Elf64Convert.c +@@ -323,6 +323,26 @@ IsSymbolShdr ( + return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namehdr->sh_offset + Shdr->sh_name, ELF_SYMBOL_SECTION_NAME) == 0); + } + ++#define ELF_INIT_ARRAY_SECTION_NAME ".init_array" ++#define ELF_FINI_ARRAY_SECTION_NAME ".fini_array" ++ ++STATIC ++BOOLEAN ++IsInitFiniArrayShdr ( ++ Elf_Shdr *Shdr ++ ) ++{ ++ Elf_Shdr *Namedr = GetShdrByIndex(mEhdr->e_shstrndx); ++ const CHAR8 *Name = (const CHAR8 *)mEhdr + ++ Namedr->sh_offset + ++ Shdr->sh_name; ++ ++ return (BOOLEAN)( ++ strcmp(Name, ELF_INIT_ARRAY_SECTION_NAME) == 0 || ++ strcmp(Name, ELF_FINI_ARRAY_SECTION_NAME) == 0 ++ ); ++} ++ + STATIC + BOOLEAN + IsDataShdr ( +@@ -332,6 +352,9 @@ IsDataShdr ( + if (IsHiiRsrcShdr(Shdr)) { + return FALSE; + } ++ if (IsInitFiniArrayShdr (Shdr)) { ++ return TRUE; ++ } + return (BOOLEAN) (Shdr->sh_flags & (SHF_EXECINSTR | SHF_WRITE | SHF_ALLOC)) == (SHF_ALLOC | SHF_WRITE); + } + +@@ -1388,6 +1411,18 @@ WriteSections64 ( + memset(mCoffFile + mCoffSectionsOffset[Idx], 0, (size_t) Shdr->sh_size); + break; + ++ case SHT_INIT_ARRAY: ++ case SHT_FINI_ARRAY: ++ //NOTE: do the same as the SHT_PROGBITS section (we SHOULd have already determined them as data sections, so there should be space) ++ /* Copy. */ ++ if (Shdr->sh_offset + Shdr->sh_size > mFileBufferSize) { ++ return FALSE; ++ } ++ memcpy(mCoffFile + mCoffSectionsOffset[Idx], ++ (UINT8*)mEhdr + Shdr->sh_offset, ++ (size_t) Shdr->sh_size); ++ break; ++ + default: + // + // Ignore for unknown section type. +-- +2.55.0 + diff --git a/platforms/uefi/edk2_ssl_lib.diff b/platforms/uefi/edk2/0004-feat-add-ssl-lib-include-for-the-package-I-use.patch similarity index 80% rename from platforms/uefi/edk2_ssl_lib.diff rename to platforms/uefi/edk2/0004-feat-add-ssl-lib-include-for-the-package-I-use.patch index 28de1150..4e0c6518 100644 --- a/platforms/uefi/edk2_ssl_lib.diff +++ b/platforms/uefi/edk2/0004-feat-add-ssl-lib-include-for-the-package-I-use.patch @@ -1,3 +1,15 @@ +From 3cb0101fe1c8a0f2e5390897475bb9ed74b43438 Mon Sep 17 00:00:00 2001 +From: Totto16 +Date: Tue, 25 Aug 2026 17:36:28 +0200 +Subject: [PATCH 4/5] feat: add ssl lib include for the package I use - this is + just for oopetris, so that it doesn't have to be in git that tree + +--- + CryptoPkg/CryptoPkgCustom.dsc.inc | 25 +++++++++++++++++++++ + CryptoPkg/Library/OpensslLib/OpensslLib.inf | 1 + + 2 files changed, 26 insertions(+) + create mode 100644 CryptoPkg/CryptoPkgCustom.dsc.inc + diff --git a/CryptoPkg/CryptoPkgCustom.dsc.inc b/CryptoPkg/CryptoPkgCustom.dsc.inc new file mode 100644 index 0000000000..b9279e9ce8 @@ -30,10 +42,10 @@ index 0000000000..b9279e9ce8 + 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 +index 1456be7320..629ceec139 100644 --- a/CryptoPkg/Library/OpensslLib/OpensslLib.inf +++ b/CryptoPkg/Library/OpensslLib/OpensslLib.inf -@@ -775,6 +775,7 @@ +@@ -795,6 +795,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 @@ -41,3 +53,6 @@ index 094d4439b1..aa36664108 100644 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 +-- +2.55.0 + diff --git a/platforms/uefi/edk2_ssl_lib_compile_with_libc.diff b/platforms/uefi/edk2/0005-feat-support-compiling-crypto-library-with-stdlib.patch similarity index 88% rename from platforms/uefi/edk2_ssl_lib_compile_with_libc.diff rename to platforms/uefi/edk2/0005-feat-support-compiling-crypto-library-with-stdlib.patch index 2fcbb2a5..927db7eb 100644 --- a/platforms/uefi/edk2_ssl_lib_compile_with_libc.diff +++ b/platforms/uefi/edk2/0005-feat-support-compiling-crypto-library-with-stdlib.patch @@ -1,8 +1,30 @@ -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 @@ +From 9f530a8bdad4b3cb5bbddbce5b6c02f5490b8a5f Mon Sep 17 00:00:00 2001 +From: Totto16 +Date: Tue, 25 Aug 2026 17:38:22 +0200 +Subject: [PATCH 5/5] feat: support compiling crypto library with stdlib - + don't use compatibility layer for crypto library as that creates link errors, + when using edk2-libc too + +--- + .../Library/BaseCryptLib/BaseCryptLib.inf | 9 +++++++ + .../Library/BaseCryptLib/Kdf/CryptHkdf.c | 9 ++++--- + .../Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c | 12 ++++++---- + .../Library/BaseCryptLib/Pk/CryptRsaPssSign.c | 6 +++-- + .../BaseCryptLib/SysCall/BaseMemAllocation.c | 7 ++++++ + .../Library/BaseCryptLib/SysCall/CrtWrapper.c | 5 ++++ + .../BaseCryptLib/SysCall/TimerWrapper.c | 5 ++++ + CryptoPkg/Library/Include/CrtLibSupport.h | 24 +++++++++++++++++++ + CryptoPkg/Library/IntrinsicLib/CopyMem.c | 4 ++++ + .../Library/IntrinsicLib/IntrinsicLib.inf | 2 ++ + .../Library/IntrinsicLib/MemoryIntrinsics.c | 3 +++ + CryptoPkg/Library/OpensslLib/OpensslLib.inf | 10 ++++++++ + 12 files changed, 87 insertions(+), 9 deletions(-) + +diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf +index bf8f1f86af..8f50a77911 100644 +--- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf ++++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf +@@ -116,3 +116,12 @@ GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99 -Wno-error=incompatible-pointer-types XCODE:*_*_*_CC_FLAGS = -std=c99 @@ -15,11 +37,11 @@ index 8190968a53..83d474e95a 100644 +[BuildOptions.X64] + *_*_*_CC_FLAGS = -I$(EDK2_LIBC_ROOT)/StdLib/Include/X64 + *_*_*_CC_FLAGS = -I$(EDK2_ROOT)/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 ( +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) { @@ -29,7 +51,7 @@ index 34e81246ed..8b260495a1 100644 } EVP_PKEY_CTX_free (pHkdfCtx); -@@ -153,7 +154,8 @@ HkdfMdExtract ( +@@ -153,7 +154,8 @@ HkdfMdExtract ( } if (Result) { @@ -39,7 +61,7 @@ index 34e81246ed..8b260495a1 100644 } EVP_PKEY_CTX_free (pHkdfCtx); -@@ -220,7 +222,8 @@ HkdfMdExpand ( +@@ -220,7 +222,8 @@ HkdfMdExpand ( } if (Result) { @@ -49,11 +71,11 @@ index 34e81246ed..8b260495a1 100644 } 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 ( +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. // @@ -63,7 +85,7 @@ index 7634ab1f6f..e0c12dc264 100644 // // Fail to determine output buffer size. // -@@ -187,7 +188,8 @@ InternalPkcs1v2Encrypt ( +@@ -187,7 +188,8 @@ InternalPkcs1v2Encrypt ( // // Encrypt Data. // @@ -73,7 +95,7 @@ index 7634ab1f6f..e0c12dc264 100644 // // Fail to encrypt data, need to free the output buffer. // -@@ -514,7 +516,8 @@ InternalPkcs1v2Decrypt ( +@@ -514,7 +516,8 @@ InternalPkcs1v2Decrypt ( // // Determine the required buffer length for malloc'ing. // @@ -83,7 +105,7 @@ index 7634ab1f6f..e0c12dc264 100644 if (ReturnCode <= 0) { // // Fail to determine output buffer size. -@@ -537,7 +540,8 @@ InternalPkcs1v2Decrypt ( +@@ -537,7 +540,8 @@ InternalPkcs1v2Decrypt ( // // Decrypt Data. // @@ -93,11 +115,11 @@ index 7634ab1f6f..e0c12dc264 100644 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 ( +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) { @@ -107,7 +129,7 @@ index 4835f81168..cefa40b440 100644 } _Exit: -@@ -284,10 +285,11 @@ RsaPssSignDigest ( +@@ -284,10 +285,11 @@ RsaPssSignDigest ( } if (Result) { @@ -120,11 +142,11 @@ index 4835f81168..cefa40b440 100644 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 +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 **/ @@ -139,17 +161,17 @@ index b7bed15c18..b1271166a5 100644 // // Extra header to record the memory buffer size from malloc routine. // -@@ -120,3 +125,5 @@ free ( +@@ -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 +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 @@ -158,7 +180,7 @@ index 8a8fdfefc7..0b9541267f 100644 int errno = 0; FILE *stderr = NULL; -@@ -22,6 +24,7 @@ int +@@ -22,6 +24,7 @@ int IN VOID *Buffer2 ); @@ -166,17 +188,17 @@ index 8a8fdfefc7..0b9541267f 100644 // // Duplicated from EDKII BaseSortLib for qsort() wrapper // -@@ -651,3 +654,5 @@ printf ( +@@ -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 +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 @@ -186,17 +208,17 @@ index 894aeb016f..eca712b348 100644 // // -- Time Management Routines -- // -@@ -249,3 +252,5 @@ gettimeofday ( +@@ -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 +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. // @@ -231,7 +253,7 @@ index dc5a357d8f..6c4a32186f 100644 // // 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 +@@ -58,6 +78,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define va_start VA_START #define va_end VA_END @@ -240,17 +262,17 @@ index dc5a357d8f..6c4a32186f 100644 // // Definitions for global constants used by CRT library routines // -@@ -492,3 +514,5 @@ memcpy ( +@@ -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 ( +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 @@ -259,27 +281,27 @@ index 5e346728c5..666ecc61d1 100644 /* Copies bytes between buffers */ void * memcpy ( -@@ -47,3 +49,5 @@ 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 @@ +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; +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 @@ -288,16 +310,16 @@ index 9b091f1901..faedee2d9e 100644 /* 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 ( +@@ -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 @@ +diff --git a/CryptoPkg/Library/OpensslLib/OpensslLib.inf b/CryptoPkg/Library/OpensslLib/OpensslLib.inf +index 629ceec139..1aaf224333 100644 +--- a/CryptoPkg/Library/OpensslLib/OpensslLib.inf ++++ b/CryptoPkg/Library/OpensslLib/OpensslLib.inf +@@ -836,3 +836,13 @@ # use floating point types, so clear the flags here. # GCC:*_*_AARCH64_CC_XIPFLAGS == @@ -311,3 +333,6 @@ index 094d4439b1..f9ddaa4d26 100644 +[BuildOptions.X64] + *_*_*_CC_FLAGS = -I$(EDK2_LIBC_ROOT)/StdLib/Include/X64 + *_*_*_CC_FLAGS = -I$(EDK2_ROOT)/MdePkg/Include/X64 +-- +2.55.0 + From 19fde22b6ac46d28f7f397b18ffbdeadff226071 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 25 Aug 2026 18:38:51 +0200 Subject: [PATCH 119/143] fix: fix patching of edk2 and edk2-libc --- platforms/build-uefi.sh | 12 ++++++++++-- platforms/versions.sh | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 1588fc2e..983ae728 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -135,7 +135,11 @@ EDK2_PATCH_FILE="$EDK2_ROOT/.patched_manually.meta" if ! [ -e "$EDK2_PATCH_FILE" ]; then ##TODO: upstream those patches - git am --directory="$EDK2_ROOT" "$PATCH_DIR/edk2/*.patch" + mapfile -d "" -t PATCH_FILES < <(find "$PATCH_DIR/edk2" -name "*.patch" -print0 | sort -z) + + for PATCH_FILE in "${PATCH_FILES[@]}"; do + git apply --unsafe-paths -p1 --directory="$EDK2_ROOT" "$PATCH_FILE" + done touch "$EDK2_PATCH_FILE" fi @@ -145,7 +149,11 @@ EDK2_LIBC_PATCH_FILE="$EDK2_LIBC_ROOT/.patched_manually.meta" if ! [ -e "$EDK2_LIBC_PATCH_FILE" ]; then ##TODO: upstream those patches - git am --directory="$EDK2_ROOT" "$PATCH_DIR/edk2-libc/*.patch" + mapfile -d "" -t PATCH_FILES < <(find "$PATCH_DIR/edk2-libc" -name "*.patch" -print0 | sort -z) + + for PATCH_FILE in "${PATCH_FILES[@]}"; do + git apply --unsafe-paths -p1 --directory="$EDK2_LIBC_ROOT" "$PATCH_FILE" + done touch "$EDK2_LIBC_PATCH_FILE" fi diff --git a/platforms/versions.sh b/platforms/versions.sh index aaba68c1..c46f2952 100755 --- a/platforms/versions.sh +++ b/platforms/versions.sh @@ -33,7 +33,7 @@ export EMSDK_EXECUTE_NODE_VERSION="24.7.0" # edk2 section -export EDK2_RELEASE_TAG="edk2-stable202605" +export EDK2_RELEASE_TAG="edk2-stable202608" export EDK2_LIBC_COMMIT_HASH="e6985d1dd786f89be3c908ec7b19e3e6da463578" From ab704e0da58f9b931d207e3253738be2a27ca799 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 25 Aug 2026 18:55:11 +0200 Subject: [PATCH 120/143] feat: fix edk2 crypto lib patches --- .../edk2/0001-feat-correct-cxx-support.patch | 2 +- ...t-use-x86_64-v1-for-the-architecture.patch | 2 +- ...-for-C-and-C-constructors-and-destru.patch | 2 +- ...sl-lib-include-for-the-package-I-use.patch | 2 +- ...compiling-crypto-library-with-stdlib.patch | 79 ++++++++++++++++++- 5 files changed, 81 insertions(+), 6 deletions(-) diff --git a/platforms/uefi/edk2/0001-feat-correct-cxx-support.patch b/platforms/uefi/edk2/0001-feat-correct-cxx-support.patch index e0f31325..5122d8ed 100644 --- a/platforms/uefi/edk2/0001-feat-correct-cxx-support.patch +++ b/platforms/uefi/edk2/0001-feat-correct-cxx-support.patch @@ -1,4 +1,4 @@ -From 449c60fbe87e7517f2820ca3c2a2e951a377bbfe Mon Sep 17 00:00:00 2001 +From 588d56df90b1ff3ef3543f904ead16987507d67e Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 25 Aug 2026 17:33:06 +0200 Subject: [PATCH 1/5] feat: correct cxx support - make C++ correctly supported diff --git a/platforms/uefi/edk2/0002-feat-use-x86_64-v1-for-the-architecture.patch b/platforms/uefi/edk2/0002-feat-use-x86_64-v1-for-the-architecture.patch index 42b512d9..9deac2e2 100644 --- a/platforms/uefi/edk2/0002-feat-use-x86_64-v1-for-the-architecture.patch +++ b/platforms/uefi/edk2/0002-feat-use-x86_64-v1-for-the-architecture.patch @@ -1,4 +1,4 @@ -From 858623f599d6ed659f2d33d55d1e1104be3d0981 Mon Sep 17 00:00:00 2001 +From 18bc84f196e6689834f6c13c6d0aeb41bc5b6e9f Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 25 Aug 2026 17:34:06 +0200 Subject: [PATCH 2/5] feat: use x86_64 v1 for the architecture diff --git a/platforms/uefi/edk2/0003-feat-add-support-for-C-and-C-constructors-and-destru.patch b/platforms/uefi/edk2/0003-feat-add-support-for-C-and-C-constructors-and-destru.patch index 9434cc30..c33754aa 100644 --- a/platforms/uefi/edk2/0003-feat-add-support-for-C-and-C-constructors-and-destru.patch +++ b/platforms/uefi/edk2/0003-feat-add-support-for-C-and-C-constructors-and-destru.patch @@ -1,4 +1,4 @@ -From 520e261faf9e4afb436f63143f4a0401ad74d251 Mon Sep 17 00:00:00 2001 +From 4a7b560f9b4e960a2a3046bcbf84716eea63035d Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 25 Aug 2026 17:35:20 +0200 Subject: [PATCH 3/5] feat: add support for C and C++ constructors and diff --git a/platforms/uefi/edk2/0004-feat-add-ssl-lib-include-for-the-package-I-use.patch b/platforms/uefi/edk2/0004-feat-add-ssl-lib-include-for-the-package-I-use.patch index 4e0c6518..8864668a 100644 --- a/platforms/uefi/edk2/0004-feat-add-ssl-lib-include-for-the-package-I-use.patch +++ b/platforms/uefi/edk2/0004-feat-add-ssl-lib-include-for-the-package-I-use.patch @@ -1,4 +1,4 @@ -From 3cb0101fe1c8a0f2e5390897475bb9ed74b43438 Mon Sep 17 00:00:00 2001 +From 4cdbcf203d7d39ce52630df5cd4a4a57f76af5a9 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 25 Aug 2026 17:36:28 +0200 Subject: [PATCH 4/5] feat: add ssl lib include for the package I use - this is diff --git a/platforms/uefi/edk2/0005-feat-support-compiling-crypto-library-with-stdlib.patch b/platforms/uefi/edk2/0005-feat-support-compiling-crypto-library-with-stdlib.patch index 927db7eb..aa224cfa 100644 --- a/platforms/uefi/edk2/0005-feat-support-compiling-crypto-library-with-stdlib.patch +++ b/platforms/uefi/edk2/0005-feat-support-compiling-crypto-library-with-stdlib.patch @@ -1,4 +1,4 @@ -From 9f530a8bdad4b3cb5bbddbce5b6c02f5490b8a5f Mon Sep 17 00:00:00 2001 +From ad98f39ff45efb2ee7ef034caea724bc3ab29d32 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 25 Aug 2026 17:38:22 +0200 Subject: [PATCH 5/5] feat: support compiling crypto library with stdlib - @@ -8,8 +8,11 @@ Subject: [PATCH 5/5] feat: support compiling crypto library with stdlib - --- .../Library/BaseCryptLib/BaseCryptLib.inf | 9 +++++++ .../Library/BaseCryptLib/Kdf/CryptHkdf.c | 9 ++++--- + .../Library/BaseCryptLib/Pk/CryptEdDsa.c | 6 +++-- + .../Library/BaseCryptLib/Pk/CryptMlDsa.c | 6 +++-- .../Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c | 12 ++++++---- .../Library/BaseCryptLib/Pk/CryptRsaPssSign.c | 6 +++-- + .../Library/BaseCryptLib/Pk/CryptSlhDsa.c | 6 +++-- .../BaseCryptLib/SysCall/BaseMemAllocation.c | 7 ++++++ .../Library/BaseCryptLib/SysCall/CrtWrapper.c | 5 ++++ .../BaseCryptLib/SysCall/TimerWrapper.c | 5 ++++ @@ -18,7 +21,7 @@ Subject: [PATCH 5/5] feat: support compiling crypto library with stdlib - .../Library/IntrinsicLib/IntrinsicLib.inf | 2 ++ .../Library/IntrinsicLib/MemoryIntrinsics.c | 3 +++ CryptoPkg/Library/OpensslLib/OpensslLib.inf | 10 ++++++++ - 12 files changed, 87 insertions(+), 9 deletions(-) + 15 files changed, 99 insertions(+), 15 deletions(-) diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf index bf8f1f86af..8f50a77911 100644 @@ -71,6 +74,54 @@ index 34e81246ed..8b260495a1 100644 } EVP_PKEY_CTX_free (pHkdfCtx); +diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptEdDsa.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptEdDsa.c +index 0b75f9542a..1ee91ebf20 100644 +--- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptEdDsa.c ++++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptEdDsa.c +@@ -378,7 +378,8 @@ EdDsaGetPubKey ( + + *PublicKeySize = FinalPublicKeySize; + +- Result = EVP_PKEY_get_raw_public_key (Ctx->EvpPkey, PublicKey, PublicKeySize); ++ _Static_assert(sizeof(UINTN) == sizeof(size_t)); ++ Result = EVP_PKEY_get_raw_public_key (Ctx->EvpPkey, PublicKey, (size_t*)PublicKeySize); + if (Result != 1) { + return FALSE; + } +@@ -498,7 +499,8 @@ EdDsaSign ( + return FALSE; + } + +- if (EVP_DigestSign (SignCtx, Signature, SigSize, Message, MessageSize) != 1) { ++ _Static_assert(sizeof(UINTN) == sizeof(size_t)); ++ if (EVP_DigestSign (SignCtx, Signature, (size_t*)SigSize, Message, MessageSize) != 1) { + EVP_MD_CTX_free (SignCtx); + return FALSE; + } +diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptMlDsa.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptMlDsa.c +index d17459daf9..b869bb6b73 100644 +--- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptMlDsa.c ++++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptMlDsa.c +@@ -471,7 +471,8 @@ MlDsaGetPubKey ( + + *PublicKeySize = FinalPublicKeySize; + +- Result = EVP_PKEY_get_raw_public_key (Ctx->EvpPkey, PublicKey, PublicKeySize); ++ _Static_assert(sizeof(UINTN) == sizeof(size_t)); ++ Result = EVP_PKEY_get_raw_public_key (Ctx->EvpPkey, PublicKey, (size_t*)PublicKeySize); + if (Result != 1) { + return FALSE; + } +@@ -580,7 +581,8 @@ MlDsaSign ( + return FALSE; + } + +- Result = EVP_DigestSign (SignCtx, Signature, SigSize, Message, MessageSize); ++ _Static_assert(sizeof(UINTN) == sizeof(size_t)); ++ Result = EVP_DigestSign (SignCtx, Signature, (size_t*)SigSize, Message, MessageSize); + if (Result != 1) { + EVP_MD_CTX_free (SignCtx); + return FALSE; 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 @@ -142,6 +193,30 @@ index 4835f81168..cefa40b440 100644 Digest, (UINT32)DigestSize ) > 0; +diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptSlhDsa.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptSlhDsa.c +index dc974fde12..3235a43412 100644 +--- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptSlhDsa.c ++++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptSlhDsa.c +@@ -471,7 +471,8 @@ SlhDsaGetPubKey ( + + *PublicKeySize = FinalPublicKeySize; + +- Result = EVP_PKEY_get_raw_public_key (Ctx->EvpPkey, PublicKey, PublicKeySize); ++ _Static_assert(sizeof(UINTN) == sizeof(size_t)); ++ Result = EVP_PKEY_get_raw_public_key (Ctx->EvpPkey, PublicKey, (size_t*)PublicKeySize); + if (Result != 1) { + return FALSE; + } +@@ -580,7 +581,8 @@ SlhDsaSign ( + return FALSE; + } + +- Result = EVP_DigestSign (SignCtx, Signature, SigSize, Message, MessageSize); ++ _Static_assert(sizeof(UINTN) == sizeof(size_t)); ++ Result = EVP_DigestSign (SignCtx, Signature, (size_t*)SigSize, Message, MessageSize); + if (Result != 1) { + EVP_MD_CTX_free (SignCtx); + return FALSE; 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 From 5b2bab600ef9331c83a1dc04b3ac051c8c341c76 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 25 Aug 2026 21:01:19 +0200 Subject: [PATCH 121/143] feat: fix crypto libraries using wrong debug lib --- platforms/uefi/OOPetrisPlatform.template.dsc | 30 +++++++++- .../edk2/0001-feat-correct-cxx-support.patch | 2 +- ...t-use-x86_64-v1-for-the-architecture.patch | 2 +- ...-for-C-and-C-constructors-and-destru.patch | 2 +- ...sl-lib-include-for-the-package-I-use.patch | 58 ------------------- ...ompiling-crypto-library-with-stdlib.patch} | 22 ++++--- src/executables/platforms/uefi/meson.build | 4 ++ 7 files changed, 49 insertions(+), 71 deletions(-) delete mode 100644 platforms/uefi/edk2/0004-feat-add-ssl-lib-include-for-the-package-I-use.patch rename platforms/uefi/edk2/{0005-feat-support-compiling-crypto-library-with-stdlib.patch => 0004-feat-support-compiling-crypto-library-with-stdlib.patch} (91%) diff --git a/platforms/uefi/OOPetrisPlatform.template.dsc b/platforms/uefi/OOPetrisPlatform.template.dsc index 12d04c1b..0c6852b6 100644 --- a/platforms/uefi/OOPetrisPlatform.template.dsc +++ b/platforms/uefi/OOPetrisPlatform.template.dsc @@ -118,9 +118,10 @@ !if $(OOPETRIS_RUNTIME_TARGET) == "hardware" # DebugLib - DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf-TODO-not-implemented-and-checked-yet - # Support and TimerLib + TODO|not implemented and checked yet + # SupportLib and TimerLib #TODO: doesn't work on qemu, but maybe on CPU?? TimerLib|UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf LibUEfiSupportNanosleep|SupportLib/Library/Default/SupportLibDefaultNanosleep.inf @@ -220,6 +221,29 @@ #see above: DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf +#start crypto related libs +[LibraryClasses] + ## TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf + RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.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 + +#end crypto related libs + + + [PcdsFixedAtBuild] !if $(OOPETRIS_RUNTIME_TARGET) == "hardware" # nothing @@ -228,7 +252,7 @@ #define DEBUG_INFO 0x00000040 // Informational debug messages #define DEBUG_VERBOSE 0x00400000 // Detailed debug messages that may #define DEBUG_ERROR 0x80000000 // Error -gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80400042 + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80400042 ## This flag is used to control the destination port for PlatformDebugLibIoPort # this is the same address as QEMU uses diff --git a/platforms/uefi/edk2/0001-feat-correct-cxx-support.patch b/platforms/uefi/edk2/0001-feat-correct-cxx-support.patch index 5122d8ed..8533da67 100644 --- a/platforms/uefi/edk2/0001-feat-correct-cxx-support.patch +++ b/platforms/uefi/edk2/0001-feat-correct-cxx-support.patch @@ -1,7 +1,7 @@ From 588d56df90b1ff3ef3543f904ead16987507d67e Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 25 Aug 2026 17:33:06 +0200 -Subject: [PATCH 1/5] feat: correct cxx support - make C++ correctly supported +Subject: [PATCH 1/4] feat: correct cxx support - make C++ correctly supported --- BaseTools/Conf/build_rule.template | 12 ++++++------ diff --git a/platforms/uefi/edk2/0002-feat-use-x86_64-v1-for-the-architecture.patch b/platforms/uefi/edk2/0002-feat-use-x86_64-v1-for-the-architecture.patch index 9deac2e2..c72193c1 100644 --- a/platforms/uefi/edk2/0002-feat-use-x86_64-v1-for-the-architecture.patch +++ b/platforms/uefi/edk2/0002-feat-use-x86_64-v1-for-the-architecture.patch @@ -1,7 +1,7 @@ From 18bc84f196e6689834f6c13c6d0aeb41bc5b6e9f Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 25 Aug 2026 17:34:06 +0200 -Subject: [PATCH 2/5] feat: use x86_64 v1 for the architecture +Subject: [PATCH 2/4] feat: use x86_64 v1 for the architecture --- BaseTools/Conf/tools_def.template | 64 +++++++++++++++---------------- diff --git a/platforms/uefi/edk2/0003-feat-add-support-for-C-and-C-constructors-and-destru.patch b/platforms/uefi/edk2/0003-feat-add-support-for-C-and-C-constructors-and-destru.patch index c33754aa..1aa60884 100644 --- a/platforms/uefi/edk2/0003-feat-add-support-for-C-and-C-constructors-and-destru.patch +++ b/platforms/uefi/edk2/0003-feat-add-support-for-C-and-C-constructors-and-destru.patch @@ -1,7 +1,7 @@ From 4a7b560f9b4e960a2a3046bcbf84716eea63035d Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 25 Aug 2026 17:35:20 +0200 -Subject: [PATCH 3/5] feat: add support for C and C++ constructors and +Subject: [PATCH 3/4] feat: add support for C and C++ constructors and destructors - this requires as linker script change and GenFW modifications - this can 5than be used by edk2-libc and libcxx for uefi diff --git a/platforms/uefi/edk2/0004-feat-add-ssl-lib-include-for-the-package-I-use.patch b/platforms/uefi/edk2/0004-feat-add-ssl-lib-include-for-the-package-I-use.patch deleted file mode 100644 index 8864668a..00000000 --- a/platforms/uefi/edk2/0004-feat-add-ssl-lib-include-for-the-package-I-use.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 4cdbcf203d7d39ce52630df5cd4a4a57f76af5a9 Mon Sep 17 00:00:00 2001 -From: Totto16 -Date: Tue, 25 Aug 2026 17:36:28 +0200 -Subject: [PATCH 4/5] feat: add ssl lib include for the package I use - this is - just for oopetris, so that it doesn't have to be in git that tree - ---- - CryptoPkg/CryptoPkgCustom.dsc.inc | 25 +++++++++++++++++++++ - CryptoPkg/Library/OpensslLib/OpensslLib.inf | 1 + - 2 files changed, 26 insertions(+) - create mode 100644 CryptoPkg/CryptoPkgCustom.dsc.inc - -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 1456be7320..629ceec139 100644 ---- a/CryptoPkg/Library/OpensslLib/OpensslLib.inf -+++ b/CryptoPkg/Library/OpensslLib/OpensslLib.inf -@@ -795,6 +795,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 --- -2.55.0 - diff --git a/platforms/uefi/edk2/0005-feat-support-compiling-crypto-library-with-stdlib.patch b/platforms/uefi/edk2/0004-feat-support-compiling-crypto-library-with-stdlib.patch similarity index 91% rename from platforms/uefi/edk2/0005-feat-support-compiling-crypto-library-with-stdlib.patch rename to platforms/uefi/edk2/0004-feat-support-compiling-crypto-library-with-stdlib.patch index aa224cfa..8471feb8 100644 --- a/platforms/uefi/edk2/0005-feat-support-compiling-crypto-library-with-stdlib.patch +++ b/platforms/uefi/edk2/0004-feat-support-compiling-crypto-library-with-stdlib.patch @@ -1,7 +1,7 @@ -From ad98f39ff45efb2ee7ef034caea724bc3ab29d32 Mon Sep 17 00:00:00 2001 +From c79476b209aa2b390894c1e367f9efea1e7ed2da Mon Sep 17 00:00:00 2001 From: Totto16 -Date: Tue, 25 Aug 2026 17:38:22 +0200 -Subject: [PATCH 5/5] feat: support compiling crypto library with stdlib - +Date: Tue, 25 Aug 2026 17:36:28 +0200 +Subject: [PATCH 4/4] feat: support compiling crypto library with stdlib - don't use compatibility layer for crypto library as that creates link errors, when using edk2-libc too @@ -20,8 +20,8 @@ Subject: [PATCH 5/5] feat: support compiling crypto library with stdlib - CryptoPkg/Library/IntrinsicLib/CopyMem.c | 4 ++++ .../Library/IntrinsicLib/IntrinsicLib.inf | 2 ++ .../Library/IntrinsicLib/MemoryIntrinsics.c | 3 +++ - CryptoPkg/Library/OpensslLib/OpensslLib.inf | 10 ++++++++ - 15 files changed, 99 insertions(+), 15 deletions(-) + CryptoPkg/Library/OpensslLib/OpensslLib.inf | 11 +++++++++ + 15 files changed, 100 insertions(+), 15 deletions(-) diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf index bf8f1f86af..8f50a77911 100644 @@ -391,10 +391,18 @@ index 9b091f1901..faedee2d9e 100644 } +#endif diff --git a/CryptoPkg/Library/OpensslLib/OpensslLib.inf b/CryptoPkg/Library/OpensslLib/OpensslLib.inf -index 629ceec139..1aaf224333 100644 +index 1456be7320..1aaf224333 100644 --- a/CryptoPkg/Library/OpensslLib/OpensslLib.inf +++ b/CryptoPkg/Library/OpensslLib/OpensslLib.inf -@@ -836,3 +836,13 @@ +@@ -795,6 +795,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 +@@ -835,3 +836,13 @@ # use floating point types, so clear the flags here. # GCC:*_*_AARCH64_CC_XIPFLAGS == diff --git a/src/executables/platforms/uefi/meson.build b/src/executables/platforms/uefi/meson.build index 1e0a595f..9e8a9324 100644 --- a/src/executables/platforms/uefi/meson.build +++ b/src/executables/platforms/uefi/meson.build @@ -107,6 +107,8 @@ elif RUNTIME_TARGET == 'emulator' fat_folder_loc = fs.parent(oopetris_efi.full_path()) / 'FAT_FOLDER' + serial_debug_file = fs.parent(oopetris_efi.full_path()) / 'serial_debug.log' + fat_folder = custom_target( 'fat_folder', command: [_uefi_create_fat_folder_exe, fat_folder_loc, '@INPUT@', '@OUTPUT@'], @@ -146,6 +148,8 @@ elif RUNTIME_TARGET == 'emulator' 'stdio', '-global', 'isa-debugcon.iobase=0x402', + '-serial', + 'file:' + serial_debug_file, ] From 1c39854462aae6dcb0377b7e1acdef8d5b1a6ce8 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 25 Aug 2026 21:11:54 +0200 Subject: [PATCH 122/143] fix: don't include inc, when none is needed (for the crypto lib) --- platforms/uefi/extract-definitions.sh | 2 +- platforms/uefi/pkg-config-wrapper.sh | 13 ++++++++----- src/executables/platforms/uefi/libraries.json | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 4a85b8e8..4cac4050 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -127,7 +127,7 @@ add_include_to_platform() { : # found already, do nothing else cat <>"$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" -!include $FINAL_PKG_INC_NAME +!include $FINAL_PKG_INC_NAME #from extract-defintions EOF diff --git a/platforms/uefi/pkg-config-wrapper.sh b/platforms/uefi/pkg-config-wrapper.sh index 1e48d7e1..1af461f2 100755 --- a/platforms/uefi/pkg-config-wrapper.sh +++ b/platforms/uefi/pkg-config-wrapper.sh @@ -55,14 +55,17 @@ EOF fi - if grep -q "$PACKAGE_NAME_INC" "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM"; then - : # found already, do nothing - else - cat <>"$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" -!include $PACKAGE_NAME_INC + if [ "$PACKAGE_NAME_INC" != "null" ]; 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 $PACKAGE_NAME_INC # from pkg-config EOF + fi fi } diff --git a/src/executables/platforms/uefi/libraries.json b/src/executables/platforms/uefi/libraries.json index 1abf92a4..a40e1ac7 100644 --- a/src/executables/platforms/uefi/libraries.json +++ b/src/executables/platforms/uefi/libraries.json @@ -23,7 +23,7 @@ "pkg": "CryptoPkg/CryptoPkg", "lib": "BaseCryptLib", "inf": "CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf", - "inc": "CryptoPkg/CryptoPkgCustom.dsc.inc", + "inc": null, "tool_prefix": "edk2" } } From a643c0349e790a7882d10f38c3c9ab5f50266901 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 25 Aug 2026 21:59:07 +0200 Subject: [PATCH 123/143] feat: fix some uefi related cpp issues - fix %a, it needs a cstr not a std::string as argument, but the DEBUG macro isn't checked as it is not a standard fprint implementation - fix some defines --- src/executables/game/main.cpp | 4 +++- src/graphics/renderer.cpp | 2 +- src/helper/uefi_utils.cpp | 11 ++++++----- src/libs/core/helper/utils.hpp | 2 +- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/executables/game/main.cpp b/src/executables/game/main.cpp index 9e47ec0e..c39e1be7 100644 --- a/src/executables/game/main.cpp +++ b/src/executables/game/main.cpp @@ -59,6 +59,8 @@ namespace { sinks.push_back(std::make_shared()); #elif defined(__UEFI__) sinks.push_back(uefi::get_debug_sink()); + // is outputted to serial, handled by edk2-libc + sinks.push_back(std::make_shared(spdlog::color_mode::never)); #elif defined(__EMSCRIPTEN__) sinks.push_back(web::get_console_sink()); #else @@ -66,7 +68,7 @@ namespace { #endif -#if !(defined(__EMSCRIPTEN__)) +#if !(defined(__EMSCRIPTEN__) || defined(__UEFI__)) const auto logs_path = utils::get_root_folder() / "logs"; diff --git a/src/graphics/renderer.cpp b/src/graphics/renderer.cpp index cc767cf7..3aa983da 100644 --- a/src/graphics/renderer.cpp +++ b/src/graphics/renderer.cpp @@ -10,7 +10,7 @@ Renderer::Renderer(const Window& window, const VSync v_sync) window.get_sdl_window(), -1, (v_sync == VSync::Enabled ? SDL_RENDERER_PRESENTVSYNC : 0) | SDL_RENDERER_TARGETTEXTURE -#if defined(__3DS__) || defined(__SERENITY__) +#if defined(__3DS__) || defined(__SERENITY__) || defined(__UEFI__) | SDL_RENDERER_SOFTWARE #else | SDL_RENDERER_ACCELERATED diff --git a/src/helper/uefi_utils.cpp b/src/helper/uefi_utils.cpp index 04149c77..acf7fe76 100644 --- a/src/helper/uefi_utils.cpp +++ b/src/helper/uefi_utils.cpp @@ -12,24 +12,25 @@ 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() }; + const std::string 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: - EFI_DEBUG((DEBUG_VERBOSE, "%a", message)); + EFI_DEBUG((DEBUG_VERBOSE, "%a\n", message.c_str())); break; case spdlog::level::info: - EFI_DEBUG((DEBUG_INFO, "%a", message)); + EFI_DEBUG((DEBUG_INFO, "%a\n", message.c_str())); break; case spdlog::level::warn: - EFI_DEBUG((DEBUG_WARN, "%a", message)); + EFI_DEBUG((DEBUG_WARN, "%a\n", message.c_str())); break; case spdlog::level::err: case spdlog::level::critical: - EFI_DEBUG((DEBUG_ERROR, "%a", message)); + EFI_DEBUG((DEBUG_ERROR, "%a\n", message.c_str())); break; default: return; diff --git a/src/libs/core/helper/utils.hpp b/src/libs/core/helper/utils.hpp index b72150d5..d3919a1b 100644 --- a/src/libs/core/helper/utils.hpp +++ b/src/libs/core/helper/utils.hpp @@ -132,7 +132,7 @@ namespace utils { [[noreturn]] inline void throw_(E&& exc) { //NOLINT(readability-identifier-naming) #if defined(__OOPETRIS_NO_EXCEPTIONS) #if defined(__UEFI__) - EFI_DEBUG((DEBUG_ERROR, "Exception: %a", exc.what())); + EFI_DEBUG((DEBUG_ERROR, "Exception: %a\n", exc.what())); #else std::cerr << "Exception: " << exc.what() << "\n"; #endif From c883227f51d37535f448fd37caa79bbd6563eef7 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 28 Aug 2026 01:39:29 +0200 Subject: [PATCH 124/143] feat: add async wrapper helper for uefi --- src/executables/game/application.cpp | 19 +- src/executables/game/application.hpp | 39 ++- src/executables/platforms/uefi/meson.build | 2 + src/helper/meson.build | 20 +- src/helper/uefi_futures.cpp | 251 +++++++++++++++++++ src/helper/uefi_futures.hpp | 265 +++++++++++++++++++++ src/helper/web_utils.cpp | 4 - src/lobby/api.cpp | 11 + tools/dependencies/meson.build | 8 +- 9 files changed, 597 insertions(+), 22 deletions(-) create mode 100644 src/helper/uefi_futures.cpp create mode 100644 src/helper/uefi_futures.hpp diff --git a/src/executables/game/application.cpp b/src/executables/game/application.cpp index e357bca4..6ac8f6bf 100644 --- a/src/executables/game/application.cpp +++ b/src/executables/game/application.cpp @@ -71,14 +71,14 @@ helper::TimeInfo::TimeInfo( helper::LoadingInfo::LoadingInfo( std::chrono::nanoseconds sleep_time, Uint64 start_time, - std::future&& load_everything_thread, + oopetris::future&& load_everything_future, std::chrono::steady_clock::time_point start_execution_time, bool finished_loading, scenes::LoadingScreen&& loading_screen ) : m_sleep_time{ sleep_time }, m_start_time{ start_time }, - m_load_everything_thread{ std::move(load_everything_thread) }, + m_load_everything_future{ std::move(load_everything_future) }, m_start_execution_time{ start_execution_time }, m_finished_loading{ finished_loading }, m_loading_screen{ std::move(loading_screen) } { } @@ -92,8 +92,8 @@ helper::LoadingInfo::LoadingInfo( } -[[nodiscard]] const std::future& helper::LoadingInfo::load_everything_thread() const { - return m_load_everything_thread; +[[nodiscard]] const oopetris::future& helper::LoadingInfo::load_everything_future() const { + return m_load_everything_future; } Application::Application(std::shared_ptr&& window, CommandLineArguments&& arguments) @@ -308,9 +308,10 @@ void Application::load_loop() { // end waiting // wait until is faster, since it just compares two time_points instead of getting now() and than adding the wait-for argument - m_loading_info->m_finished_loading = - m_loading_info->load_everything_thread().wait_until(std::chrono::system_clock::time_point::min()) - == std::future_status::ready; + auto loading_status = + m_loading_info->load_everything_future().wait_until(std::chrono::system_clock::time_point::min()); + ASSERT(loading_status == oopetris::future_status::ready || loading_status == oopetris::future_status::timeout); + m_loading_info->m_finished_loading = loading_status == oopetris::future_status::ready; } @@ -475,7 +476,7 @@ void Application::initialize() { const auto start_time = SDL_GetTicks64(); - std::future load_everything_thread = std::async(std::launch::async, [this] { + oopetris::future load_everything_future = OOPETRIS_ASYNC(OOPETRIS_ASYNC_LAUNCH_ARG, [this]() -> void { this->m_settings_manager = std::make_unique(this); this->m_settings_manager->add_callback([this](const auto& settings) { this->reload_api(settings); }); @@ -520,7 +521,7 @@ void Application::initialize() { auto start_execution_time_arg = std::chrono::steady_clock::now(); m_loading_info = std::make_unique( - sleep_time, start_time, std::move(load_everything_thread), start_execution_time_arg, false, + sleep_time, start_time, std::move(load_everything_future), start_execution_time_arg, false, std::move(loading_screen_arg) ); diff --git a/src/executables/game/application.hpp b/src/executables/game/application.hpp index feef60df..fdbd2ca5 100644 --- a/src/executables/game/application.hpp +++ b/src/executables/game/application.hpp @@ -17,10 +17,41 @@ #include "ui/components/label.hpp" #include -#include #include #include +#if !defined(__OOPETRIS_HAVE_NO_THREADS) +#include + +#define OOPETRIS_ASYNC std::async +#define OOPETRIS_ASYNC_LAUNCH_ARG std::launch::async + +namespace oopetris { + template + using future = std::future; + using future_status = std::future_status; +} // namespace oopetris + +#else +#if defined(__UEFI__) + + +#include "helper/uefi_futures.hpp" + +#define OOPETRIS_ASYNC uefi::helper::async +#define OOPETRIS_ASYNC_LAUNCH_ARG (std::monostate{}) + +namespace oopetris { + template + using future = uefi::helper::future; + using future_status = uefi::helper::future_status; +} // namespace oopetris +#else +#error "We need threads in this environment" +#endif + +#endif + #if defined(__EMSCRIPTEN__) #include "helper/web_utils.hpp" @@ -61,7 +92,7 @@ namespace helper { std::chrono::nanoseconds m_sleep_time; Uint64 m_start_time; - std::future m_load_everything_thread; + oopetris::future m_load_everything_future; public: std::chrono::steady_clock::time_point m_start_execution_time; @@ -71,7 +102,7 @@ namespace helper { LoadingInfo( std::chrono::nanoseconds sleep_time, Uint64 start_time, - std::future&& load_everything_thread, + oopetris::future&& m_load_everything_future, std::chrono::steady_clock::time_point start_execution_time, bool finished_loading, scenes::LoadingScreen&& loading_screen @@ -81,7 +112,7 @@ namespace helper { [[nodiscard]] Uint64 start_time() const; - [[nodiscard]] const std::future& load_everything_thread() const; + [[nodiscard]] const oopetris::future& load_everything_future() const; }; } // namespace helper diff --git a/src/executables/platforms/uefi/meson.build b/src/executables/platforms/uefi/meson.build index 9e8a9324..b6eeff7c 100644 --- a/src/executables/platforms/uefi/meson.build +++ b/src/executables/platforms/uefi/meson.build @@ -132,6 +132,8 @@ elif RUNTIME_TARGET == 'emulator' # this cpu has x86-64 v1 (baseline) support '-cpu', 'qemu64-v1', + '-smp', + 'sockets=1,cores=4,threads=1', '-drive', 'if=pflash,format=raw,unit=0,file=' + OVMF_CODE_fd_path + ',readonly=on', '-drive', diff --git a/src/helper/meson.build b/src/helper/meson.build index 3a47c129..2779a879 100644 --- a/src/helper/meson.build +++ b/src/helper/meson.build @@ -14,12 +14,24 @@ graphics_src_files += files( 'platform.cpp', 'platform.hpp', 'spdlog_wrapper.hpp', - 'uefi_utils.cpp', - 'uefi_utils.hpp', - 'web_utils.cpp', - 'web_utils.hpp', ) +if meson.is_cross_build() and host_machine.system() == 'uefi' + graphics_src_files += files( + 'uefi_futures.cpp', + 'uefi_futures.hpp', + 'uefi_utils.cpp', + 'uefi_utils.hpp', + ) +elif meson.is_cross_build() and host_machine.system() == 'emscripten' + graphics_src_files += files( + 'web_utils.cpp', + 'web_utils.hpp', + ) +endif + + + if have_file_dialogs graphics_src_files += files('nfd.cpp', 'nfd_include.hpp') endif diff --git a/src/helper/uefi_futures.cpp b/src/helper/uefi_futures.cpp new file mode 100644 index 00000000..fbeea98b --- /dev/null +++ b/src/helper/uefi_futures.cpp @@ -0,0 +1,251 @@ +#include "./uefi_futures.hpp" + + +extern "C" { +#include +} + +details::MainCPUState* details::__cpu_state = nullptr; + + +static UINTN my_cpu_id_impl(EFI_MP_SERVICES_PROTOCOL* Mp) { + + ASSERT(Mp); + + UINTN BspNumber; + + EFI_STATUS Status = Mp->WhoAmI(Mp, &BspNumber); + + if (EFI_ERROR(Status)) { + EFI_DEBUG((DEBUG_ERROR, "ERROR: couldn't execute WhoAmI: %r\n", Status)); + abort(); + } + + return BspNumber; +} + + +UINTN details::my_cpu_id() { + ASSERT(__cpu_state != nullptr); + return my_cpu_id_impl(__cpu_state->Mp); +} + + +void details::init_cpu_state() { + if (__cpu_state != nullptr) { + return; + } + + __cpu_state = new details::MainCPUState(nullptr, 0, 0, {}); + + + if (!gBS) { + EFI_DEBUG((DEBUG_ERROR, "ERROR: gBS is NULL\n")); + abort(); + } + + + EFI_STATUS Status = gBS->LocateProtocol(&gEfiMpServiceProtocolGuid, NULL, (VOID**) &(__cpu_state->Mp)); + + if (EFI_ERROR(Status)) { + EFI_DEBUG((DEBUG_ERROR, "ERROR: couldn't get the EfiMpServiceProtocolGuid: %r\n", Status)); + abort(); + } + + UINTN NumberOfEnabledProcessors; + + Status = __cpu_state->Mp->GetNumberOfProcessors( + __cpu_state->Mp, &(__cpu_state->NumberOfProcessors), &NumberOfEnabledProcessors + ); + + if (EFI_ERROR(Status)) { + EFI_DEBUG((DEBUG_ERROR, "ERROR: couldn't get the Number Of Processors: %r\n", Status)); + abort(); + } + + __cpu_state->BspId = my_cpu_id_impl(__cpu_state->Mp); + + __cpu_state->cpus = std::vector{}; + __cpu_state->cpus.reserve(__cpu_state->NumberOfProcessors - 1); + + for (size_t i = 0; i < __cpu_state->NumberOfProcessors; ++i) { + + EFI_PROCESSOR_INFORMATION info; + + Status = __cpu_state->Mp->GetProcessorInfo(__cpu_state->Mp, (UINTN) i, &info); + + if (EFI_ERROR(Status)) { + EFI_DEBUG((DEBUG_ERROR, "ERROR: couldn't Get Processor Info: %r\n", Status)); + abort(); + } + + if ((info.StatusFlag & PROCESSOR_AS_BSP_BIT) != 0) { + continue; + } + + __cpu_state->cpus.emplace_back(info.ProcessorId, (UINTN) i, info.StatusFlag, false); + } +} + + +static __attribute__((destructor)) void deinit_cpu_state(void) { + if (details::__cpu_state == nullptr) { + return; + } + + delete details::__cpu_state; +} + + +details::SecondaryCPUState* find_cpu_for_new_thread_impl(details::MainCPUState* const state) { + + ASSERT(state); + + for (size_t i = 0; i < state->cpus.size(); i++) { + details::SecondaryCPUState* cpu = &(state->cpus.data()[i]); + + if (cpu->IsBusy) { + continue; + } + + if ((cpu->StatusFlags & PROCESSOR_ENABLED_BIT) == 0) { + continue; + } + + if ((cpu->StatusFlags & PROCESSOR_HEALTH_STATUS_BIT) == 0) { + continue; + } + + return cpu; + } + + return nullptr; +} + + +details::SecondaryCPUState* details::find_cpu_for_new_thread(void) { + + ASSERT(__cpu_state != nullptr); + return find_cpu_for_new_thread_impl(__cpu_state); +} + +static void EFIAPI __impl_uefi_new_thread_function(IN OUT VOID* private_data) { + details::ThreadInfo* ptr = static_cast(private_data); + + ptr->info.fn(); +} + + +struct details::DetachedThreadStateImpl { + // inout state + EFI_EVENT DoneEvent; + BOOLEAN finished; + //output state + bool terminated; + + // mutex to protect state, that can be used by the AP (when writing the result) and the BSP (when using poll) + details::helper::ThreadMutex data_mutex; + + DetachedThreadStateImpl() : DoneEvent{}, finished{ FALSE }, terminated{ false }, data_mutex{} { + // + } + + void terminate(void) { + const std::lock_guard scope_lock(this->data_mutex); + + this->terminated = true; + } + + details::thread_state poll(void) { + const std::lock_guard scope_lock(this->data_mutex); + + // likely for long running async + if (!this->terminated) [[likely]] { + return details::thread_state::running; + } + + // unlikely, as we don't set a timeout + if (!this->finished) [[unlikely]] { + return details::thread_state::aborted; + } + + return details::thread_state::finished; + } + + ~DetachedThreadStateImpl() noexcept { + gBS->CloseEvent(DoneEvent); + } +}; + +details::DetachedThreadStatePublic::DetachedThreadStatePublic(DetachedThreadState* state_impl) + : m_state_impl{ state_impl } { + // +} + +details::DetachedThreadStatePublic::~DetachedThreadStatePublic() { + if (m_state_impl != nullptr) { + delete m_state_impl; + m_state_impl = nullptr; + } +} + +details::thread_state details::DetachedThreadStatePublic::poll() { + ASSERT(m_state_impl != nullptr); + return m_state_impl->poll(); +} + + +static VOID EFIAPI __impl_uefi_thread_done_function(IN EFI_EVENT Event, IN VOID* Context) { + details::DetachedThreadStateImpl* state = static_cast(Context); + + state->terminate(); +} + + +std::shared_ptr start_detached_thread_impl( + EFI_MP_SERVICES_PROTOCOL* Mp, + const details::SecondaryCPUState* const cpu_to_execute_on, + const std::shared_ptr& info +) { + + ASSERT(Mp != nullptr); + ASSERT(cpu_to_execute_on != nullptr); + + details::DetachedThreadStateImpl* state = new details::DetachedThreadStateImpl(); + + EFI_STATUS Status = gBS->CreateEvent( + EVT_NOTIFY_SIGNAL, TPL_CALLBACK, __impl_uefi_thread_done_function, state, &(state->DoneEvent) + ); + + if (EFI_ERROR(Status)) { + EFI_DEBUG((DEBUG_ERROR, "ERROR: couldn't execute CreateEvent: %r\n", Status)); + abort(); + } + + + Status = Mp->StartupThisAP( + Mp, __impl_uefi_new_thread_function, cpu_to_execute_on->Id, state->DoneEvent, 0, info.get(), + &(state->finished) + ); + + + if (EFI_ERROR(Status)) { + EFI_DEBUG((DEBUG_ERROR, "ERROR: couldn't execute StartupThisAP: %r\n", Status)); + abort(); + } + + std::shared_ptr public_state = + std::make_shared(state); + + return public_state; +} + + +std::shared_ptr details::start_detached_thread( + const details::SecondaryCPUState* const cpu_to_execute_on, + const std::shared_ptr& info +) { + + ASSERT(__cpu_state != nullptr); + return start_detached_thread_impl(__cpu_state->Mp, cpu_to_execute_on, info); +} diff --git a/src/helper/uefi_futures.hpp b/src/helper/uefi_futures.hpp new file mode 100644 index 00000000..e777b0df --- /dev/null +++ b/src/helper/uefi_futures.hpp @@ -0,0 +1,265 @@ + + +#pragma once + + +#if !defined(__UEFI__) +#error "this header is for uefi only" +#endif + + +#include + +extern "C" { +#include + +#include + +#include +} + +#include +#include +#include +#include +#include +#include + + +//COPY from oopetris, to make this header more independent +namespace helper::uefi::future { + + template + struct Overloaded : Ts... { + using Ts::operator()...; + }; + template + Overloaded(Ts...) -> Overloaded; +} // namespace helper::uefi::future + + +namespace details { + + struct SecondaryCPUState { + UINT64 UniqueProcessorId; + UINTN Id; + UINT32 StatusFlags; + bool IsBusy; + }; + + struct MainCPUState { + EFI_MP_SERVICES_PROTOCOL* Mp; + UINTN NumberOfProcessors; + UINTN BspId; + std::vector cpus; + }; + + extern MainCPUState* __cpu_state; + + void init_cpu_state(); + + [[nodiscard]] UINTN my_cpu_id(); + + + [[nodiscard]] SecondaryCPUState* find_cpu_for_new_thread(); + + struct RunningFunctionInfo { + //TODO: use generic fn pointer; + std::function fn; + //TODO: support arguments + // void args; + }; + + struct ThreadInfo { + RunningFunctionInfo info; + }; + + enum class thread_state { aborted, running, finished }; + + typedef struct DetachedThreadStateImpl DetachedThreadState; + + + struct DetachedThreadStatePublic { + private: + DetachedThreadState* m_state_impl; + + public: + DetachedThreadStatePublic(DetachedThreadState* state_impl); + + ~DetachedThreadStatePublic(); + + [[nodiscard]] thread_state poll(); + }; + + std::shared_ptr + start_detached_thread(const SecondaryCPUState* const cpu_to_execute_on, const std::shared_ptr& info); + + namespace helper { + + + struct ThreadMutex { + + ThreadMutex() noexcept; + + ThreadMutex(const ThreadMutex& other) = delete; + ThreadMutex& operator=(const ThreadMutex& other) = delete; + + ThreadMutex(ThreadMutex&& other) noexcept; + ThreadMutex& operator=(ThreadMutex&& other) noexcept; + + ~ThreadMutex() noexcept; + + void lock(); + void unlock(); + }; + + } // namespace helper + + +} // namespace details + + +namespace uefi::helper { + + enum class future_status { ready, timeout, error }; + + template + //TODO: only allow void! + class future { + private: + struct ErrorState { + std::string error; + }; + + struct FinishedState { + std::conditional_t, std::monostate, T> value; + }; + + struct RunningState { + details::SecondaryCPUState* const cpu; + std::shared_ptr info; + std::shared_ptr thread; + }; + + std::variant m_state; + // + + void __internal_poll(void) { + + + auto new_value = std::visit( + ::helper::uefi::future::Overloaded{ + [this](const RunningState& state) + -> std::optional> { + auto thread_st = state.poll(); + + switch (thread_st) { + case details::thread_state::running: + return std::nullopt; + + case details::thread_state::finished: { + //TODO: how to get the value + return FinishedState{}; + } + case details::thread_state::aborted: + default: { + //TODO: get the error from somewhere + return ErrorState{ "TODO" }; + } + } + }, + [this](const ErrorState& state) + -> std::optional> { + return std::nullopt; + }, + [this](const FinishedState& state) + -> std::optional> { + return std::nullopt; + }, + + }, + this->m_state + ); + + if (new_value.has_value()) { + this->m_state = new_value.value(); + } + } + + public: + future(details::SecondaryCPUState* const cpu, + std::shared_ptr&& info, + std::shared_ptr&& thread) + : m_state{ + RunningState{ cpu, std::move(info), std::move(thread) } + } { + // + } + + template + [[nodiscard]] future_status wait_until(const std::chrono::time_point<_Clock, _Duration>& __abs_time) const { + + //TODO: implement other wait too, but we only use this atm + if (__abs_time != std::chrono::system_clock::time_point::min()) { + spdlog::error("Invalid abs_time for wait_until: {}", __abs_time); + abort(); + } + + this->__internal_poll(); + + + return std::visit( + ::helper::uefi::future::Overloaded{ + [this](const RunningState& state) -> future_status { return future_status::timeout; }, + [this](const ErrorState& state) -> future_status { return future_status::error; }, + [this](const FinishedState& state) -> future_status { return future_status::ready; }, + + }, + this->m_state + ); + } + }; + + using async_launch_type = std::monostate; + + + //NOTE: that all calls in this thread are NOT THREAD SAFE, but it should be fine(tm), as we don't use many services at a time anyway + template + [[nodiscard]] future, std::decay_t...>> + async(async_launch_type launch_type, F&& f, Args&&... args) { + + // NOTE: atm only implemented for this, so we don't have to pass arguments ore set the result value + static_assert(sizeof...(Args) == 0, "the function inside async() doesn't support arguments yet"); + + static_assert( + std::is_void_v, std::decay_t...>>, + "the function inside async() doesn't support a non void return type" + ); + + details::init_cpu_state(); + + ASSERT(details::__cpu_state != nullptr); + auto my_id = details::my_cpu_id(); + if (details::__cpu_state->BspId != my_id) { + spdlog::error("Invalid start of async in non main CPU: {} != {}", details::__cpu_state->BspId, my_id); + abort(); + } + + // need no lock, as only the bsp can do that, and it is single threaded + details::SecondaryCPUState* const cpu_to_execute_on = details::find_cpu_for_new_thread(); + + if (cpu_to_execute_on == nullptr) { + spdlog::error("Can't find CPU to start thread on", details::__cpu_state->BspId, my_id); + abort(); + } + + details::RunningFunctionInfo fn_info = { f }; + + std::shared_ptr info = std::make_shared(fn_info); + + auto thread = details::start_detached_thread(cpu_to_execute_on, info); + + return future, std::decay_t...>>{ cpu_to_execute_on, std::move(info), + std::move(thread) }; + } +}; // namespace uefi::helper diff --git a/src/helper/web_utils.cpp b/src/helper/web_utils.cpp index 29deaa7c..3984693b 100644 --- a/src/helper/web_utils.cpp +++ b/src/helper/web_utils.cpp @@ -1,7 +1,5 @@ -#if defined(__EMSCRIPTEN__) - #include #include "./web_utils.hpp" @@ -190,5 +188,3 @@ void web::WebContext::do_processing() { [[nodiscard]] const web::LocalStorage& web::WebContext::local_storage() const { return m_local_storage; } - -#endif diff --git a/src/lobby/api.cpp b/src/lobby/api.cpp index 481ff56c..3d824015 100644 --- a/src/lobby/api.cpp +++ b/src/lobby/api.cpp @@ -3,7 +3,10 @@ #include "api.hpp" #include "helper/spdlog_wrapper.hpp" + +#if !defined(__OOPETRIS_HAVE_NO_THREADS) #include +#endif #if !defined(_OOPETRIS_ONLINE_SYSTEM) #error "_OOPETRIS_ONLINE_SYSTEM has to be defined" @@ -132,11 +135,19 @@ void lobby::API::check_url( ) { //TODO(Totto): is this done correctly + +#if !defined(__OOPETRIS_HAVE_NO_THREADS) + std::ignore = std::async(std::launch::async, [url, callback = std::move(callback), service_provider] { auto result = lobby::API::get_api(service_provider, url); callback(result.has_value()); }); +#else + auto result = lobby::API::get_api(service_provider, url); + + callback(result.has_value()); +#endif } diff --git a/tools/dependencies/meson.build b/tools/dependencies/meson.build index fc098827..a693552e 100644 --- a/tools/dependencies/meson.build +++ b/tools/dependencies/meson.build @@ -134,7 +134,13 @@ if meson.is_cross_build() } elif host_machine.system() == 'uefi' - # nothing special to do for uefi + temp = core_lib.get('compile_args') + temp += '-D__OOPETRIS_HAVE_NO_THREADS' + + core_lib += { + 'compile_args': temp, + } + temp = 0 else error('Unhandled cross built system: ' + host_machine.system()) endif From c5ed8deaa15c13d9957c6127cfecc89e33ce9f98 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 28 Aug 2026 01:52:57 +0200 Subject: [PATCH 125/143] feat: add pseudo mutex for uefi threads --- src/helper/uefi_futures.cpp | 50 +++++++++++++++++++++++++++++++++++++ src/helper/uefi_futures.hpp | 5 +++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/helper/uefi_futures.cpp b/src/helper/uefi_futures.cpp index fbeea98b..0c74535d 100644 --- a/src/helper/uefi_futures.cpp +++ b/src/helper/uefi_futures.cpp @@ -2,6 +2,8 @@ extern "C" { +#include +#include #include } @@ -249,3 +251,51 @@ std::shared_ptr details::start_detached_thre ASSERT(__cpu_state != nullptr); return start_detached_thread_impl(__cpu_state->Mp, cpu_to_execute_on, info); } + + +details::helper::ThreadMutex::ThreadMutex() noexcept : locked{ 0 } { + // +} + +details::helper::ThreadMutex::ThreadMutex(ThreadMutex&& other) noexcept : locked{ 0 } { + ASSERT(!other.locked); + + other.locked = 0; +} + +details::helper::ThreadMutex& details::helper::ThreadMutex::operator=(ThreadMutex&& other) noexcept { + ASSERT(!other.locked); + + this->locked = other.locked; + other.locked = 0; + + return *this; +} + +details::helper::ThreadMutex::~ThreadMutex() noexcept { + ASSERT(!this->locked); +} + + +void details::helper::ThreadMutex::lock() { + while (InterlockedCompareExchange32( + &(this->locked), + 0, // Compare: unlocked + 1 // Exchange: locked + ) + != 0) { + // + // Someone else owns it. + // + CpuPause(); + } +} + +void details::helper::ThreadMutex::unlock() { + + InterlockedCompareExchange32( + &(this->locked), + 1, // Compare: locked + 0 // Exchange: unlocked + ); +} diff --git a/src/helper/uefi_futures.hpp b/src/helper/uefi_futures.hpp index e777b0df..3bd6e0b2 100644 --- a/src/helper/uefi_futures.hpp +++ b/src/helper/uefi_futures.hpp @@ -96,9 +96,12 @@ namespace details { namespace helper { - + //TODO: we could use a c++ wrapper of the SPIN_LOCK from "SynchronizationLib.h" instead struct ThreadMutex { + private: + volatile UINT32 locked; + public: ThreadMutex() noexcept; ThreadMutex(const ThreadMutex& other) = delete; From 7cc93b2d0fb3d604e4a3a1fcc713800a512b0009 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 28 Aug 2026 02:04:56 +0200 Subject: [PATCH 126/143] fix: fix som e uefi future errors --- src/helper/uefi_futures.hpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/helper/uefi_futures.hpp b/src/helper/uefi_futures.hpp index 3bd6e0b2..4f3ea787 100644 --- a/src/helper/uefi_futures.hpp +++ b/src/helper/uefi_futures.hpp @@ -139,22 +139,20 @@ namespace uefi::helper { }; struct RunningState { - details::SecondaryCPUState* const cpu; + details::SecondaryCPUState* cpu; std::shared_ptr info; std::shared_ptr thread; }; - std::variant m_state; + mutable std::variant m_state; // - void __internal_poll(void) { - - - auto new_value = std::visit( + void __internal_poll(void) const { + std::optional> new_value = std::visit( ::helper::uefi::future::Overloaded{ [this](const RunningState& state) -> std::optional> { - auto thread_st = state.poll(); + auto thread_st = state.thread->poll(); switch (thread_st) { case details::thread_state::running: @@ -185,7 +183,7 @@ namespace uefi::helper { ); if (new_value.has_value()) { - this->m_state = new_value.value(); + this->m_state = std::move(new_value.value()); } } From 798682640306ec94c1e59bcf947a5d4365bc45c3 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 28 Aug 2026 15:47:55 +0200 Subject: [PATCH 127/143] feat: fix some link errors --- src/lobby/uefi_client.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lobby/uefi_client.cpp b/src/lobby/uefi_client.cpp index 31726cdf..207b0c13 100644 --- a/src/lobby/uefi_client.cpp +++ b/src/lobby/uefi_client.cpp @@ -4,9 +4,11 @@ #include #include +extern "C" { #include #include #include +} #include @@ -433,7 +435,7 @@ static EFI_STATUS FindNetworkController(OUT EFI_HANDLE* Controller) { EFI_HANDLE* Handles = NULL; UINTN HandleCount = 0; - if(!gBS){ + if (!gBS) { return EFI_NOT_READY; } From 4e08ddc7364853a35175bb3918efe2853e842a18 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 28 Aug 2026 22:32:52 +0200 Subject: [PATCH 128/143] fix: remove unused file --- edk2_libc_constructor_support_v2.diff | 106 -------------------------- 1 file changed, 106 deletions(-) delete mode 100644 edk2_libc_constructor_support_v2.diff diff --git a/edk2_libc_constructor_support_v2.diff b/edk2_libc_constructor_support_v2.diff deleted file mode 100644 index 42c58ce2..00000000 --- a/edk2_libc_constructor_support_v2.diff +++ /dev/null @@ -1,106 +0,0 @@ -diff --git a/StdLib/Include/libc/main.h b/StdLib/Include/libc/main.h -new file mode 100644 -index 0000000..caae7c1 ---- /dev/null -+++ b/StdLib/Include/libc/main.h -@@ -0,0 +1,20 @@ -+ -+#pragma once -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#define EDK2_LIBC_ENTRY_NAME edk2_libc_main -+ -+extern int EDK2_LIBC_ENTRY_NAME(int, char**); -+ -+#ifdef __cplusplus -+} -+ -+#define EDK2_LIBCXX_ENTRY_NAME edk2_libcxx_main -+ -+extern int EDK2_LIBCXX_ENTRY_NAME(int, char**); -+ -+ -+#endif -diff --git a/StdLib/LibC/Main/Main.c b/StdLib/LibC/Main/Main.c -index b203d15..d98e1a0 100644 ---- a/StdLib/LibC/Main/Main.c -+++ b/StdLib/LibC/Main/Main.c -@@ -31,15 +31,51 @@ - #include - #include - --extern int main( int, char**); -+#include -+ - extern int __sse2_available; - - struct __MainData *gMD; - --/* Worker function to keep GCC happy. */ --void __main() --{ -- ; -+// these symbols are provided by the linker from the extions .init_array and .fini_array -+typedef void (*init_func_t)(void); -+ -+extern init_func_t __init_array_start[] __attribute__ ((section(".init_array"), aligned(sizeof(init_func_t)))) ; -+extern init_func_t __init_array_end[] __attribute__ ((section(".init_array"), aligned(sizeof(init_func_t)))) ; -+ -+extern init_func_t __fini_array_start[] __attribute__ ((section(".fini_array"), aligned(sizeof(init_func_t)))) ; -+extern init_func_t __fini_array_end[]; __attribute__ ((section(".fini_array"), aligned(sizeof(init_func_t)))) -+ -+static void run_init_array(void) { -+ size_t size = __init_array_end - __init_array_start; -+ for (size_t i = 0; i < size; ++i) { -+ init_func_t* func = __init_array_start + i ; -+ if (*func != NULL) { -+ (*func)(); -+ } -+ } -+} -+ -+static void run_fini_array(void) { -+ // iterate reversed -+ size_t size = __fini_array_end - __fini_array_start; -+ for (size_t i = size; i != 0; --i) { -+ init_func_t* func = __fini_array_start + (i - 1); -+ if (*func != NULL) { -+ (*func)(); -+ } -+ } -+} -+ -+ -+//TODO: this can be c or c++ constructors, so these shoul only be run, after libc or libc AND libcxx is intilized, before we call EDK2_LIBC_ENTRY_NAME or EDK2_LIBCXX_ENTRY_NAME, but how to know if the final entry point is c++ or c? as c++ also uses the c entry point too -+ -+void edk2_libc_call_constructors(void) { -+ run_init_array(); -+} -+ -+void edk2_libc_call_destructors(void) { -+ run_fini_array(); - } - - /** Clean up data as required by the exit() function. -@@ -67,6 +103,8 @@ exitCleanup(INTN ExitVal) - CleanUp(); - } - } -+ -+ edk2_libc_call_destructors(); - } - - /* Create mbcs versions of the Argv strings. */ -@@ -179,7 +217,8 @@ ShellAppMain ( - else { - if( setjmp(gMD->MainExit) == 0) { - errno = 0; // Clean up any "scratch" values from startup. -- ExitVal = (INTN)main( (int)Argc, gMD->NArgV); -+ edk2_libc_call_constructors(); -+ ExitVal = (INTN)EDK2_LIBC_ENTRY_NAME( (int)Argc, gMD->NArgV); - exitCleanup(ExitVal); - } - /* You reach here if: From 538ed1cc9893ba55a234a66f8fdbf6ccf69b19b3 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 29 Aug 2026 02:02:06 +0200 Subject: [PATCH 129/143] fix: fix some linking issues --- .../0001-feat-make-LibC-support-C.patch | 44 ++++++++++++++----- ...x-fix-naming-of-LibCType-to-LibCtype.patch | 4 +- .../0003-feat-add-c-and-c-constructors.patch | 14 +++--- platforms/uefi/extract-definitions.sh | 2 + src/executables/platforms/uefi/libraries.json | 7 +++ tools/dependencies/meson.build | 10 ++++- 6 files changed, 59 insertions(+), 22 deletions(-) diff --git a/platforms/uefi/edk2-libc/0001-feat-make-LibC-support-C.patch b/platforms/uefi/edk2-libc/0001-feat-make-LibC-support-C.patch index 0c247458..12837fbe 100644 --- a/platforms/uefi/edk2-libc/0001-feat-make-LibC-support-C.patch +++ b/platforms/uefi/edk2-libc/0001-feat-make-LibC-support-C.patch @@ -1,19 +1,20 @@ -From 5a3072b1d25e1b78290ba1bbed6370e5c2be9df2 Mon Sep 17 00:00:00 2001 +From f7003762ba238197634d4769c49e2d7c98757552 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 21 Aug 2026 18:28:16 +0200 Subject: [PATCH 1/3] feat: make LibC support C++ - make the includes support c++ - fix some other small libc related things --- - StdLib/Include/assert.h | 7 +++++++ - StdLib/Include/math.h | 8 ++++++++ - StdLib/Include/time.h | 3 ++- - StdLib/Include/wchar.h | 3 +++ - StdLib/LibC/Math/s_ceil.c | 4 ++++ - StdLib/LibC/Stdio/Stdio.inf | 1 + - StdLib/LibC/Stdio/vasprintf.c | 9 +++------ - StdLib/LibC/gdtoa/gdtoa.inf | 3 +++ - 8 files changed, 31 insertions(+), 7 deletions(-) + StdLib/Include/assert.h | 7 +++++++ + StdLib/Include/math.h | 8 ++++++++ + StdLib/Include/time.h | 3 ++- + StdLib/Include/wchar.h | 3 +++ + StdLib/LibC/Math/s_ceil.c | 4 ++++ + StdLib/LibC/Stdio/Stdio.inf | 1 + + StdLib/LibC/Stdio/ftello.c | 13 +++++++++++++ + StdLib/LibC/Stdio/vasprintf.c | 9 +++------ + StdLib/LibC/gdtoa/gdtoa.inf | 3 +++ + 9 files changed, 44 insertions(+), 7 deletions(-) diff --git a/StdLib/Include/assert.h b/StdLib/Include/assert.h index 26c7037..5296e9a 100644 @@ -127,6 +128,27 @@ index fe87242..df122fa 100644 vfwscanf.c # vswprintf.c # vswscanf.c # +diff --git a/StdLib/LibC/Stdio/ftello.c b/StdLib/LibC/Stdio/ftello.c +index 0677d1a..a9c1031 100644 +--- a/StdLib/LibC/Stdio/ftello.c ++++ b/StdLib/LibC/Stdio/ftello.c +@@ -98,3 +98,16 @@ ftello(FILE *fp) + FUNLOCKFILE(fp); + return (pos); + } ++ ++ ++// instead of using weak symbol, define an alias ++ ++#ifdef ftello ++#undef ftello ++#endif ++ ++off_t ++ftello(FILE *fp) ++{ ++ return _ftello(fp); ++} diff --git a/StdLib/LibC/Stdio/vasprintf.c b/StdLib/LibC/Stdio/vasprintf.c index 3a36468..e8ba589 100644 --- a/StdLib/LibC/Stdio/vasprintf.c @@ -162,5 +184,5 @@ index 9d975bb..44af305 100644 StdLib/StdLib.dec StdLibPrivateInternalFiles/DoNotUse.dec -- -2.55.0 +2.53.0 diff --git a/platforms/uefi/edk2-libc/0002-fix-fix-naming-of-LibCType-to-LibCtype.patch b/platforms/uefi/edk2-libc/0002-fix-fix-naming-of-LibCType-to-LibCtype.patch index 795f13e1..e49efa98 100644 --- a/platforms/uefi/edk2-libc/0002-fix-fix-naming-of-LibCType-to-LibCtype.patch +++ b/platforms/uefi/edk2-libc/0002-fix-fix-naming-of-LibCType-to-LibCtype.patch @@ -1,4 +1,4 @@ -From c100be98fc907b9573612503e784618b082f5997 Mon Sep 17 00:00:00 2001 +From 064d91037d5661b0520c1620f1de61310bd3eae4 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 21 Aug 2026 18:28:44 +0200 Subject: [PATCH 2/3] fix: fix naming of LibCType to LibCtype @@ -74,5 +74,5 @@ index 8083e2b..4d08302 100644 LibMath|StdLib/LibC/Math/Math.inf LibSignal|StdLib/LibC/Signal/Signal.inf -- -2.55.0 +2.53.0 diff --git a/platforms/uefi/edk2-libc/0003-feat-add-c-and-c-constructors.patch b/platforms/uefi/edk2-libc/0003-feat-add-c-and-c-constructors.patch index 5a36e294..e5665d6d 100644 --- a/platforms/uefi/edk2-libc/0003-feat-add-c-and-c-constructors.patch +++ b/platforms/uefi/edk2-libc/0003-feat-add-c-and-c-constructors.patch @@ -1,12 +1,12 @@ -From 02a3651a93980bb62b3e463fe091ba5b9bedaea0 Mon Sep 17 00:00:00 2001 +From 7ea2fb646693a14f43ae8e85d861b67dc7e4ae43 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 25 Aug 2026 17:06:59 +0200 Subject: [PATCH 3/3] feat: add c and c++ constructors - add libcxx and libc - interlaving constructors and destructors, that are invoked before .init_array - and .fini_array - use better option to run libc initializer, use the same - mechanism as the init_array and fini_array one, but with other section names, - so that irt can be run before any init array (note we have .preinit_array but - no destructor counterpart) + interlaving constructors and destructors, that are invoked before + .init_array and .fini_array - use better option to run libc initializer, use + the same mechanism as the init_array and fini_array one, but with other + section names, so that it can be run before any init array (note we have + .preinit_array but no destructor counterpart) --- StdLib/Include/libc/main.h | 18 ++++++++ @@ -185,5 +185,5 @@ index 4d08302..d6f2b73 100644 + + GCC:*_*_*_CC_FLAGS = -Wprio-ctor-dtor -- -2.55.0 +2.53.0 diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 4cac4050..867cc71f 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -425,6 +425,8 @@ $(expand_array_inf "${DEP_CLASSES[@]}") [Ppis] [Protocols] + gEfiHttpProtocolGuid ## CONSUMES + gEfiHttpServiceBindingProtocolGuid ## CONSUMES [FeaturePcd] diff --git a/src/executables/platforms/uefi/libraries.json b/src/executables/platforms/uefi/libraries.json index a40e1ac7..20b185ed 100644 --- a/src/executables/platforms/uefi/libraries.json +++ b/src/executables/platforms/uefi/libraries.json @@ -19,6 +19,13 @@ "inc": "NetworkPkg/Network.dsc.inc", "tool_prefix": "edk2" }, + "HttpLib": { + "pkg": "NetworkPkg/NetworkPkg", + "lib": "HttpLib", + "inf": "NetworkPkg/Library/DxeHttpLib/DxeHttpLib.inf", + "inc": "NetworkPkg/Network.dsc.inc", + "tool_prefix": "edk2" + }, "BaseCryptLib": { "pkg": "CryptoPkg/CryptoPkg", "lib": "BaseCryptLib", diff --git a/tools/dependencies/meson.build b/tools/dependencies/meson.build index a693552e..24d73ea9 100644 --- a/tools/dependencies/meson.build +++ b/tools/dependencies/meson.build @@ -477,11 +477,17 @@ 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_http_lib_dep = dependency('uefi:HttpLib') + uefi_http_io_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], + 'deps': [ + graphics_lib.get('deps'), + uefi_http_lib_dep, + uefi_http_io_lib_dep, + uefi_crypto_lib_dep, + ], 'compile_args': [graphics_lib.get('compile_args'), '-D_OOPETRIS_ONLINE_SYSTEM=3'], } From 1bbb3b4c524bef72564230a9f5a69c841164de74 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 29 Aug 2026 20:20:17 +0200 Subject: [PATCH 130/143] feat: add c-embed romlib for uefi - still WIP --- platforms/build-uefi.sh | 9 +- platforms/uefi/c-embed-wrapper.sh | 55 ++++++ platforms/uefi/extract-definitions.sh | 186 ++++++++++-------- src/executables/platforms/uefi/mappings.json | 11 ++ src/executables/platforms/uefi/meson.build | 60 ++++++ src/helper/uefi_utils.cpp | 2 +- subprojects/c-embed.wrap | 9 + subprojects/packagefiles/c-embed/meson.build | 39 ++++ subprojects/packagefiles/keyutils/meson.build | 2 +- tools/dependencies/meson.build | 23 ++- 10 files changed, 299 insertions(+), 97 deletions(-) create mode 100755 platforms/uefi/c-embed-wrapper.sh create mode 100644 subprojects/c-embed.wrap create mode 100644 subprojects/packagefiles/c-embed/meson.build diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 983ae728..8fdfc26a 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -311,7 +311,7 @@ pkg_config_libdir = '$PKG_CONFIG_PATH' sys_root = '${SYS_ROOT}' needs_exe_wrapper = true -APP_ROMFS='$ROMFS/assets/' +APP_ROMFS='$ROMFS' RUNTIME_TARGET='$RUNTIME_TARGET' USE_GDB='${UEFI_USE_GDB:-false}' @@ -330,7 +330,10 @@ if [ ! -d "$ROMFS" ]; then mkdir -p "$ROMFS" - cp -r assets "$ROMFS/" + cp -r "./assets" "$ROMFS/" + + # no need for music + rm -rf "$ROMFS/assets/music/" fi @@ -402,7 +405,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" \ + --force-fallback-for="fmt,nlohmann_json,magic_enum,utf8cpp,sdl2_ttf,freetype2,spdlog,argparse,sdl2_image,c-embed" \ --wrap-mode=nofallback \ "-Drun_in_ci=$RUN_IN_CI" \ -Dstrip=false \ diff --git a/platforms/uefi/c-embed-wrapper.sh b/platforms/uefi/c-embed-wrapper.sh new file mode 100755 index 00000000..bd5898f7 --- /dev/null +++ b/platforms/uefi/c-embed-wrapper.sh @@ -0,0 +1,55 @@ +#!/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="C-EMBED" +# Capture all args +ARGS=("$@") + +# shellcheck source=./platforms/uefi/base.sh +source "$SCRIPT_DIR/base.sh" + +if [ "$#" -eq 3 ]; then + C_EMBED_EXE="$(realpath "$1")" + INPUT_FOLDER="$(realpath "$2")" + OUTPUT_FILE="$(realpath "$3")" +else + echo "Too many arguments given, expected 3" >&2 + exit 1 +fi + +"$C_EMBED_EXE" "$INPUT_FOLDER" + +PARENT_DIR="$(dirname "$OUTPUT_FILE")" + +if [[ ! -d "$PARENT_DIR" ]]; then + mkdir -p "$PARENT_DIR" +fi + +REAL_O_FILE="$PARENT_DIR/c-embed_compiled.o" + +mv "./c-embed.o" "$REAL_O_FILE" + +# create a "extern_object" json description for the automatic inf creation process to generate the inf for this file, as if it was compiled via the edk2 toolchain, but it wasn't +cat <"$OUTPUT_FILE" +{ + "cwd": "$(pwd)", + "args": $(to_json_array), + "language": "c", + "type": "extern_object", + "dependencies": { + "output": "$OUTPUT_FILE", + "extern": $(to_json_array "$REAL_O_FILE") + } +} +EOF diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index 867cc71f..f19f12ae 100755 --- a/platforms/uefi/extract-definitions.sh +++ b/platforms/uefi/extract-definitions.sh @@ -87,7 +87,7 @@ fi SOURCE_FILE_TYPE="$(jq -M -r -c '.["type"]' "$SOURCE_FILE")" -if [ "$SOURCE_FILE_TYPE" == "link" ] || [ "$SOURCE_FILE_TYPE" == "archive" ]; then +if [ "$SOURCE_FILE_TYPE" == "link" ] || [ "$SOURCE_FILE_TYPE" == "extern_object" ] || [ "$SOURCE_FILE_TYPE" == "archive" ]; then : else echo "Error: invalid source file type: $SOURCE_FILE_TYPE" >&2 @@ -176,8 +176,8 @@ for FILE_DEPENDENCY in "${FILE_DEPENDENCIES[@]}"; do if [ "$FILE_DEPENDENCY_TYPE" == "compile" ]; then mapfile -t FILE_DEPENDENCY_SRC < <(jq -e '.["dependencies"]["src"][]' -M -r -c "$FILE_DEPENDENCY") - for FILE_DEPENDENCY_SRC in "${FILE_DEPENDENCY_SRC[@]}"; do - DEP_SOURCES+=("$FILE_DEPENDENCY_SRC") + for FILE_DEPENDENCY_SRC_ENTRY in "${FILE_DEPENDENCY_SRC[@]}"; do + DEP_SOURCES+=("$FILE_DEPENDENCY_SRC_ENTRY") done elif [ "$FILE_DEPENDENCY_TYPE" == "archive" ] || [ "$FILE_DEPENDENCY_TYPE" == "link" ]; then @@ -229,8 +229,14 @@ for FILE_DEPENDENCY in "${FILE_DEPENDENCIES[@]}"; do DEP_PACKAGES+=("$PACKAGE_NAME") DEP_CLASSES+=("$MAPPING_ENTRY_DEP_LIB") + elif [ "$FILE_DEPENDENCY_TYPE" == "extern_object" ]; then + mapfile -t FILE_DEPENDENCY_EXTERN < <(jq -e '.["dependencies"]["extern"][]' -M -r -c "$FILE_DEPENDENCY") + + for FILE_DEPENDENCY_EXTERN_ENTRY in "${FILE_DEPENDENCY_EXTERN[@]}"; do + DEP_SOURCES+=("$FILE_DEPENDENCY_EXTERN_ENTRY") + done else - echo "Error: invalid source file type: $FILE_DEPENDENCY_TYPE" >&2 + echo "Error: invalid file dependency type: $FILE_DEPENDENCY_TYPE" >&2 exit 2 fi @@ -268,99 +274,111 @@ 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 +if [ "$MESON_TARGETS_INFO_LIB" = "null" ] || [ "$MESON_TARGETS_INFO_LIB" = "" ]; 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 [ "$SOURCE_FILE_TYPE" == "link" ] || [ "$SOURCE_FILE_TYPE" == "archive" ]; then -mapfile -t MESON_TARGETS_INFO_LIB_COMPILER_TARGETS < <(echo "$MESON_TARGETS_INFO_LIB" | jq '.["target_sources"][] | select( has("compiler") )' -M -r -c) + MESON_TARGETS_INFO_LIB_TYPE="$(echo "$MESON_TARGETS_INFO_LIB" | jq -M -r -c ".[\"type\"]")" -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 + mapfile -t MESON_TARGETS_INFO_LIB_COMPILER_TARGETS < <(echo "$MESON_TARGETS_INFO_LIB" | jq '.["target_sources"][] | select( has("compiler") )' -M -r -c) -MESON_TARGETS_INFO_LIB_COMPILER_TARGET="${MESON_TARGETS_INFO_LIB_COMPILER_TARGETS[0]}" + if [ "${#MESON_TARGETS_INFO_LIB_COMPILER_TARGETS[@]}" -ne 1 ]; then + #this is fine, as some libraries consist of only extern_objects + : + else -MESON_TARGETS_INFO_LIB_LANGUAGE="$(echo "$MESON_TARGETS_INFO_LIB_COMPILER_TARGET" | jq -M -r -c ".[\"language\"]")" + MESON_TARGETS_INFO_LIB_COMPILER_TARGET="${MESON_TARGETS_INFO_LIB_COMPILER_TARGETS[0]}" -FLAGS_TARGET="CC" + MESON_TARGETS_INFO_LIB_LANGUAGE="$(echo "$MESON_TARGETS_INFO_LIB_COMPILER_TARGET" | jq -M -r -c ".[\"language\"]")" -if [ "$MESON_TARGETS_INFO_LIB_LANGUAGE" == "cpp" ]; then - FLAGS_TARGET="CXX" - for CPP_LIBRARY in "${CPP_LIBRARIES[@]}"; do - DEP_CLASSES+=("$CPP_LIBRARY") - done - DEP_PACKAGES+=("LLVM/LLVMPkg.dec") - DEP_PACKAGES+=("SupportLib/SupportLib.dec") # needed by LLVM -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 + FLAGS_TARGET="CC" -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*) - DEP_INCLUDES+=("${MESON_TARGETS_INFO_LIB_PARAMATER:2}") - ;; - -W*) - # TODO: include warnings - ;; - -nostdinc | -nostdinc++ | -nodefaultlibs | -D* | --sysroot=* | -isystem*) - DEP_BUILD_OPTIONS+=("*_*_*_${FLAGS_TARGET}_FLAGS = \"${MESON_TARGETS_INFO_LIB_PARAMATER}\"") - ;; - -t:use-lib:pkg=*) - DEP_PACKAGE_NAME="${MESON_TARGETS_INFO_LIB_PARAMATER:15}" - DEP_PACKAGES+=("$DEP_PACKAGE_NAME/$DEP_PACKAGE_NAME.dec") - ;; - -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 - ;; - -f* | -m*) - DEP_BUILD_OPTIONS+=("*_*_*_${FLAGS_TARGET}_FLAGS = \"${MESON_TARGETS_INFO_LIB_PARAMATER}\"") - ;; - -g | -std=* | -O*) - #ignore - ;; - *) - echo "Invalid argument detected for compiling '$SOURCE_FILE_ENTRY_MESON_NAME': '$MESON_TARGETS_INFO_LIB_PARAMATER'" >&2 - exit 6 - ;; - esac -done + if [ "$MESON_TARGETS_INFO_LIB_LANGUAGE" == "cpp" ]; then + FLAGS_TARGET="CXX" + for CPP_LIBRARY in "${CPP_LIBRARIES[@]}"; do + DEP_CLASSES+=("$CPP_LIBRARY") + done + DEP_PACKAGES+=("LLVM/LLVMPkg.dec") + DEP_PACKAGES+=("SupportLib/SupportLib.dec") # needed by LLVM + 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 -# 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 - #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 - #TODO: maybe do something based on the json information we have? + 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*) + DEP_INCLUDES+=("${MESON_TARGETS_INFO_LIB_PARAMATER:2}") + ;; + -W*) + # TODO: include warnings + ;; + -nostdinc | -nostdinc++ | -nodefaultlibs | -D* | --sysroot=* | -isystem*) + DEP_BUILD_OPTIONS+=("*_*_*_${FLAGS_TARGET}_FLAGS = \"${MESON_TARGETS_INFO_LIB_PARAMATER}\"") + ;; + -t:use-lib:pkg=*) + DEP_PACKAGE_NAME="${MESON_TARGETS_INFO_LIB_PARAMATER:15}" + DEP_PACKAGES+=("$DEP_PACKAGE_NAME/$DEP_PACKAGE_NAME.dec") + ;; + -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 + ;; + -f* | -m*) + DEP_BUILD_OPTIONS+=("*_*_*_${FLAGS_TARGET}_FLAGS = \"${MESON_TARGETS_INFO_LIB_PARAMATER}\"") + ;; + -g | -std=* | -O*) + #ignore + ;; + *) + echo "Invalid argument detected for compiling '$SOURCE_FILE_ENTRY_MESON_NAME': '$MESON_TARGETS_INFO_LIB_PARAMATER'" >&2 + exit 6 + ;; + esac + done + + fi + + # 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 + #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 + #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 + fi + +elif [ "$SOURCE_FILE_TYPE" == "extern_object" ]; then : + echo "TODO: not implemented yet" >&2 + exit 35 else - echo "Error: invalid meson target type for '$SOURCE_FILE_ENTRY_MESON_NAME': $MESON_TARGETS_INFO_LIB_TYPE" >&2 + echo "Error: invalid source file type: $SOURCE_FILE_TYPE" >&2 exit 2 fi @@ -425,8 +443,10 @@ $(expand_array_inf "${DEP_CLASSES[@]}") [Ppis] [Protocols] + gEfiHiiPackageListProtocolGuid ## CONSUMES gEfiHttpProtocolGuid ## CONSUMES gEfiHttpServiceBindingProtocolGuid ## CONSUMES + gEfiManagedNetworkServiceBindingProtocolGuid ## CONSUMES [FeaturePcd] diff --git a/src/executables/platforms/uefi/mappings.json b/src/executables/platforms/uefi/mappings.json index 47a9a7ac..e3096915 100644 --- a/src/executables/platforms/uefi/mappings.json +++ b/src/executables/platforms/uefi/mappings.json @@ -48,6 +48,13 @@ "guid": "cc61c805-2419-4b68-b806-495d11be162c", "version": "zlib" }, + "UEFIROMPkg": { + "type": "library", + "name": "UEFIROMLib", + "lib": "LibUEFIROM", + "guid": "a917a2c0-7ff6-4da8-a2b2-f1f28077c8c0", + "version": "c-embed" + }, "SpdlogPkg": { "type": "library", "name": "SpdlogLib", @@ -108,6 +115,10 @@ "libsdl2image": { "name": "SDL2ImagePkg", "meson": "sdl2image" + }, + "libuefi_rom": { + "name": "UEFIROMPkg", + "meson": "uefi_rom" } } } diff --git a/src/executables/platforms/uefi/meson.build b/src/executables/platforms/uefi/meson.build index b6eeff7c..568ea9e4 100644 --- a/src/executables/platforms/uefi/meson.build +++ b/src/executables/platforms/uefi/meson.build @@ -4,6 +4,66 @@ _uefi_exe_name = _uefi_options[0] _uefi_src_files = _uefi_options[1] _uefi_deps = _uefi_options[2] + +APP_ROMFS = meson.get_external_property('APP_ROMFS', '') + +if APP_ROMFS != '' + # create uefi_rom.o and add it as dependency + + fs = import('fs') + + if not fs.is_absolute(APP_ROMFS) + APP_ROMFS = meson.project_source_root() / APP_ROMFS + endif + + if not fs.exists(APP_ROMFS) + error('APP_ROMFS should exist, but doesn\'t: \'' + APP_ROMFS + '\'') + endif + + if not APP_ROMFS.endswith('/') + APP_ROMFS = APP_ROMFS + '/' + endif + + __uefi_c_embed_exe = find_program( + 'c-embed', + required: true, + native: true, + ) + + _uefi_c_embed_wrapper_exe = find_program( + 'c-embed-wrapper.sh', + dirs: [meson.project_source_root() / 'platforms' / 'uefi'], + required: true, + ) + + _uefi_rom_o = custom_target( + 'uefi_rom.o', + command: [ + _uefi_c_embed_wrapper_exe, + __uefi_c_embed_exe, + APP_ROMFS, + '@OUTPUT@', + ], + output: ['uefi_rom.o'], + build_by_default: false, + ) + + _uefi_rom_lib = library( + 'uefi_rom', + sources: _uefi_rom_o, + link_language: 'c', + ) + + _uefi_rom_dep = declare_dependency( + link_with: _uefi_rom_lib + ) + + _uefi_deps += _uefi_rom_dep + + +endif + + ## compilation _uefi_final_description = executable( diff --git a/src/helper/uefi_utils.cpp b/src/helper/uefi_utils.cpp index acf7fe76..375e347d 100644 --- a/src/helper/uefi_utils.cpp +++ b/src/helper/uefi_utils.cpp @@ -30,7 +30,7 @@ std::shared_ptr uefi::get_debug_sink() { break; case spdlog::level::err: case spdlog::level::critical: - EFI_DEBUG((DEBUG_ERROR, "%a\n", message.c_str())); + EFI_DEBUG((DEBUG_ERROR, "HHEERREE %a\n", message.c_str())); break; default: return; diff --git a/subprojects/c-embed.wrap b/subprojects/c-embed.wrap new file mode 100644 index 00000000..70f84373 --- /dev/null +++ b/subprojects/c-embed.wrap @@ -0,0 +1,9 @@ +[wrap-git] +url = https://github.com/weigert/c-embed.git +revision = main +depth = 1 +patch_directory = c-embed + +[provide] +dependency_names = c-embed +program_names = c-embed diff --git a/subprojects/packagefiles/c-embed/meson.build b/subprojects/packagefiles/c-embed/meson.build new file mode 100644 index 00000000..300d40c5 --- /dev/null +++ b/subprojects/packagefiles/c-embed/meson.build @@ -0,0 +1,39 @@ +project( + 'c-embed', + 'c', + meson_version: '>=1.12.0', + version: '0.0.1', + license: 'MIT', + default_options: { + 'optimization': '3', + 'warning_level': '2', + 'werror': false, + 'c_std': ['c11'], + 'b_ndebug': 'if-release', + }, +) + +inc_dirs = include_directories('.') + + + +c_embed_exe = executable( + 'c-embed', + files('c-embed.c'), + include_directories: inc_dirs, + native: true, +) + +meson.override_find_program( + 'c-embed', + c_embed_exe, + native: true, +) + + +c_embed_dep = declare_dependency( + include_directories: inc_dirs, + version: meson.project_version(), +) + +meson.override_dependency('c-embed', c_embed_dep) diff --git a/subprojects/packagefiles/keyutils/meson.build b/subprojects/packagefiles/keyutils/meson.build index e2e0e04d..79e95be2 100644 --- a/subprojects/packagefiles/keyutils/meson.build +++ b/subprojects/packagefiles/keyutils/meson.build @@ -9,7 +9,7 @@ project( 'warning_level': '2', 'werror': true, 'strip': true, - 'cpp_std': ['c++23', 'c++latest', 'vc++latest', 'c++20'], + 'c_std': ['c11'], 'b_ndebug': 'if-release', }, ) diff --git a/tools/dependencies/meson.build b/tools/dependencies/meson.build index 24d73ea9..10fcf8de 100644 --- a/tools/dependencies/meson.build +++ b/tools/dependencies/meson.build @@ -321,16 +321,21 @@ if build_application endif ## the switch sdl2 packages are not findable with '--fatal-meson-warnings' and cmake, so prefind it and than override the dependency - if (meson.is_cross_build() and host_machine.system() == 'switch') - sdl2_ttf_switch_dep = dependency( - 'sdl2_ttf', - 'SDL2_ttf', - method: 'pkg-config', - allow_fallback: not only_allow_native_libs, - required: true, - ) + if meson.is_cross_build() + if host_machine.system() == 'switch' + sdl2_ttf_switch_dep = dependency( + 'sdl2_ttf', + 'SDL2_ttf', + method: 'pkg-config', + allow_fallback: not only_allow_native_libs, + required: true, + ) - meson.override_dependency('sdl2_ttf', sdl2_ttf_switch_dep) + meson.override_dependency('sdl2_ttf', sdl2_ttf_switch_dep) + elif host_machine.system() == 'uefi' + c_embed_dep = dependency('c-embed') + graphic_application_deps += c_embed_dep + endif endif From 9d79317553c7d6a4bafd96cc0ef24eabaf981e33 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 29 Aug 2026 23:14:16 +0200 Subject: [PATCH 131/143] feat: add startup calls for using the c-embed romfs as "romfs:" with edk2-libc --- platforms/build-uefi.sh | 2 +- src/graphics/sdl_context.cpp | 6 + src/helper/console_helpers.cpp | 7 +- src/helper/console_helpers.hpp | 7 +- src/helper/meson.build | 11 +- src/helper/uefi_utils.cpp | 404 ++++++++++++++++++++++++++++++++- src/helper/uefi_utils.hpp | 8 +- src/lobby/uefi_client.cpp | 95 +------- tools/dependencies/meson.build | 5 +- 9 files changed, 439 insertions(+), 106 deletions(-) diff --git a/platforms/build-uefi.sh b/platforms/build-uefi.sh index 8fdfc26a..9a5f6b37 100755 --- a/platforms/build-uefi.sh +++ b/platforms/build-uefi.sh @@ -258,7 +258,7 @@ 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))', '-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$EDK2_LIBC_ROOT/StdLib/Include', '-I$EDK2_LIBC_ROOT/StdLib/Include/$EDK2_TARGET_PROPERTIES_ARCH', '-I$EDK2_ROOT/MdePkg/Include', '-I$EDK2_ROOT/MdePkg/Include/$EDK2_TARGET_PROPERTIES_ARCH'" +export CC_COMPILE_FLAGS="'-nostdinc', '-I$EDK2_LIBC_ROOT/StdLib/Include', '-I$EDK2_LIBC_ROOT/StdLib/Include/$EDK2_TARGET_PROPERTIES_ARCH', '-I$EDK2_ROOT/MdePkg/Include', '-I$EDK2_ROOT/MdePkg/Include/$EDK2_TARGET_PROPERTIES_ARCH','-I$EDK2_LIBC_ROOT'" export CXX_COMPILE_FLAGS="'-fno-exceptions', '-fno-threadsafe-statics', '-fno-use-cxa-atexit', '-fno-unwind-tables', '-fno-asynchronous-unwind-tables', '-nostdinc++', '-nodefaultlibs', '-I$EDK2_LLVM_ROOT/libcxx/include', $CC_COMPILE_FLAGS" diff --git a/src/graphics/sdl_context.cpp b/src/graphics/sdl_context.cpp index b68ef926..3a4d8b39 100644 --- a/src/graphics/sdl_context.cpp +++ b/src/graphics/sdl_context.cpp @@ -9,6 +9,8 @@ #if defined(__CONSOLE__) #include "helper/console_helpers.hpp" +#elif defined(__UEFI__) +#include "helper/uefi_utils.hpp" #endif #if defined(_HAVE_FILE_DIALOGS) @@ -28,6 +30,8 @@ SdlContext::SdlContext() { #if defined(__CONSOLE__) console::platform_init(); +#elif defined(__UEFI__) + uefi::platform_init(); #endif #if defined(_HAVE_FILE_DIALOGS) @@ -49,6 +53,8 @@ SdlContext::~SdlContext() { #if defined(__CONSOLE__) console::platform_exit(); +#elif defined(__UEFI__) + uefi::platform_exit(); #endif TTF_Quit(); diff --git a/src/helper/console_helpers.cpp b/src/helper/console_helpers.cpp index c804a0ac..48e96ea9 100644 --- a/src/helper/console_helpers.cpp +++ b/src/helper/console_helpers.cpp @@ -1,7 +1,9 @@ #include -#if defined(__NINTENDO_CONSOLE__) +#if !defined(__NINTENDO_CONSOLE__) +#error "only supported on consoles" +#endif #include "console_helpers.hpp" @@ -84,6 +86,3 @@ bool console::inMainLoop() { #error "not implemented" #endif } - - -#endif diff --git a/src/helper/console_helpers.hpp b/src/helper/console_helpers.hpp index 96e53d64..511a33d9 100644 --- a/src/helper/console_helpers.hpp +++ b/src/helper/console_helpers.hpp @@ -2,7 +2,9 @@ #pragma once -#if defined(__CONSOLE__) +#if !defined(__CONSOLE__) +#error "Only supported on consoles" +#endif #include @@ -65,6 +67,3 @@ namespace console { } // namespace console - - -#endif diff --git a/src/helper/meson.build b/src/helper/meson.build index 2779a879..5a0bdc4f 100644 --- a/src/helper/meson.build +++ b/src/helper/meson.build @@ -1,8 +1,6 @@ graphics_src_files += files( 'clock_source.cpp', 'clock_source.hpp', - 'console_helpers.cpp', - 'console_helpers.hpp', 'constants.hpp', 'export_symbols.hpp', 'git_helper.hpp', @@ -28,6 +26,15 @@ elif meson.is_cross_build() and host_machine.system() == 'emscripten' 'web_utils.cpp', 'web_utils.hpp', ) +elif meson.is_cross_build() and ( + host_machine.system() == '3ds' + or host_machine.system() == 'switch' +) + graphics_src_files += files( + 'console_helpers.cpp', + 'console_helpers.hpp', + ) + endif diff --git a/src/helper/uefi_utils.cpp b/src/helper/uefi_utils.cpp index 375e347d..47ef757a 100644 --- a/src/helper/uefi_utils.cpp +++ b/src/helper/uefi_utils.cpp @@ -1,6 +1,8 @@ -#if defined(__UEFI__) +#if !defined(__UEFI__) +#error "Only supported on UEFI" +#endif #include @@ -38,4 +40,402 @@ std::shared_ptr uefi::get_debug_sink() { }); } -#endif + +[[nodiscard]] std::string uefi::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 ""; + } +} + +extern "C" { + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-compare" + +#define rewind erewind +#include +#undef rewind + +#pragma GCC diagnostic pop + +// use stdlib internals, to register a new rom device under romfs: +#include +#include +} + +#define ROM_COOKIE 0x464d4f52 ///< 'RomF' + + +/** EFI specific operations for close(). + + @param[in] Fp Pointer to a file descriptor structure. + + @retval 0 Successful completion. + @retval -1 Operation failed. Further information is specified by errno. +**/ +static int EFIAPI _f_romfs_Close(IN struct __filedes* Fp) { + eclose((EFILE*) (&Fp->devdata)); + return 0; +} + +/** EFI specific operations for deleting a file or directory. + + @param[in] filp Pointer to a file descriptor structure. + + @retval 0 Successful completion. + @retval -1 Operation failed. Further information is specified by errno. +**/ +static int EFIAPI _f_romfs_Delete(struct __filedes* filp) { + errno = ENOTSUP; + return -1; +} + +/** EFI specific operations for setting the position within a file. + + @param[in] filp Pointer to a file descriptor structure. + @param[in] offset Relative position to move to. + @param[in] whence Specifies the location offset is relative to: Beginning, Current, End. + + @return Returns the new file position or EOF if the seek failed. +**/ +static off_t EFIAPI _f_romfs_Seek(struct __filedes* filp, off_t offset, int whence) { + EFILE* file = (EFILE*) (&filp->devdata); + + //NOTE: eseek works differently than the expected seek, so map the behavior + + int result = eseek(file, offset, whence); + if (result != 0) { + errno = eerno; + return EOF; + } + + //NOTE: etell cannot fail + return etell(file); +} + +/** The directory path is created with the access permissions specified by + perms. + + The directory is closed after it is created. + + @param[in] path The directory to be created. + @param[in] perms Access permissions for the new directory. + + @retval 0 The directory was created successfully. + @retval -1 An error occurred and an error code is stored in errno. +**/ +static int EFIAPI _f_romfs_Mkdir(const char* path, __mode_t perms) { + errno = ENOTSUP; + return -1; +} + +/** EFI specific operations for reading from a file. + + @param[in] filp Pointer to a file descriptor structure. + @param[in] offset Offset into the file to begin reading at, or NULL. + @param[in] BufferSize Number of bytes in Buffer. Max number of bytes to read. + @param[in] Buffer Pointer to a buffer to receive the read data. + + @return Returns the number of bytes successfully read, + or -1 if the operation failed. Further information is specified by errno. +**/ +static ssize_t EFIAPI +_f_romfs_Read(IN OUT struct __filedes* filp, IN OUT off_t* offset, IN size_t BufferSize, OUT VOID* Buffer) { + + EFILE* stream = (EFILE*) (&filp->devdata); + + if (offset != NULL) { + //TODO: support + errno = ENOTSUP; + return -1; + } + // NOTE: eread cannot fail, it doesn't return negative values + + return (ssize_t) eread(Buffer, BufferSize, 1, stream); +} + +/** EFI specific operations for writing to a file. + + @param[in] filp Pointer to a file descriptor structure. + @param[in] offset Offset into the file to begin writing at, or NULL. + @param[in] BufferSize Number of bytes in Buffer. Max number of bytes to write. + @param[in] Buffer Pointer to a buffer containing the data to be written. + + @return Returns the number of bytes successfully written, + or -1 if the operation failed. Further information is specified by errno. +**/ +static ssize_t EFIAPI +_f_romfs_Write(IN struct __filedes* filp, IN off_t* offset, IN size_t BufferSize, IN const void* Buffer) { + errno = ENOTSUP; + return -1; +} + +/** EFI specific operations for getting information about an open file. + + @param[in] filp Pointer to a file descriptor structure. + @param[out] statbuf Buffer in which to store the file status. + @param[in] Something This parameter is not used by this device. + + @retval 0 Successful completion. + @retval -1 Operation failed. Further information is specified by errno. +**/ +static int EFIAPI _f_romfs_Stat(struct __filedes* filp, struct stat* statbuf, void* Something) { + errno = ENOTSUP; + return -1; +} + +/** EFI specific operations for low-level control of a file or device. + + @param[in] filp Pointer to a file descriptor structure. + @param[in] cmd The command this ioctl is to perform. + @param[in,out] argp Zero or more arguments as needed by the command. + + @retval 0 Successful completion. + @retval -1 Operation failed. Further information is specified by errno. +**/ +static int EFIAPI _f_romfs_Ioctl(struct __filedes* filp, ULONGN cmd, va_list argp) { + errno = ENOTSUP; + return -1; +} + +/** EFI specific operations for opening a file. + + @param[in] DevNode Pointer to the Device control structure for this stream. + @param[in] filp Pointer to the new file control structure for this stream. + @param[in] DevInstance Not used by this device. + @param[in] Path File-system path to the file or directory. + @param[in] MPath Not used by this device. + + @retval 0 This console stream has been successfully opened. + @retval -1 The DevNode or filp pointer is NULL. + @retval -1 DevNode does not point to a valid console stream device. +**/ +int EFIAPI _f_romfs_Open( + DeviceNode* DevNode, + struct __filedes* filp, + int DevInstance, /* Not used by romfs */ + wchar_t* Path, + wchar_t* MPath +) { + if (filp->Oflags != O_RDONLY) { + errno = EINVAL; + return -1; + } + + + // Call the EFI's Open function + EFILE* file = eopen(Path, "r"); + if (file == NULL) { + filp->f_iflags = 0; // Release our reservation on this FD + // Set errno based upon Status + errno = eerrno; + return -1; + } + + + // Successfully got a regular File (note c-embed doesnÄt support to open directories) + filp->f_iflags |= S_IFREG; + + // Update the info in the fd + filp->devdata = (void*) file; + + Gip = (GenericInstance*) DevNode->InstanceList; + filp->f_offset = 0; + filp->f_ops = &Gip->Abstraction; + + return 0; +} + +/** Returns a bit mask describing which operations could be completed immediately. + + For now, assume the file system, via the shell, is always ready. + + (POLLIN | POLLRDNORM) The file system is ready to be read. + (POLLOUT) The file system is ready for output. + + @param[in] filp Pointer to a file descriptor structure. + @param[in] events Bit mask describing which operations to check. + + @return The returned value is a bit mask describing which operations + could be completed immediately, without blocking. +**/ +static short EFIAPI _f_romfs_Poll(struct __filedes* filp, short events) { + errno = ENOTSUP; + return -1; +} + +/** EFI specific operations for renaming a file. + + @param[in] from Name of the file to be renamed. + @param[in] to New name for the file. + + @retval 0 Successful completion. + @retval -1 Operation failed. Further information is specified by errno. +**/ +static int EFIAPI _f_romfs_Rename(const char* from, const char* to) { + errno = ENOTSUP; + return -1; +} + +/** EFI specific operations for deleting directories. + + @param[in] filp Pointer to a file descriptor structure. + + @retval 0 Successful completion. + @retval -1 Operation failed. Further information is specified by errno. +**/ +static int EFIAPI _f_romfs_Rmdir(struct __filedes* filp) { + errno = ENOTSUP; + return -1; +} + + +#define ROMFS_NAME ((const CHAR16*) L"romfs:") + +RETURN_STATUS +EFIAPI +__ctor_rom_fs(void) { + GenericInstance* Stream = (GenericInstance*) AllocateZeroPool(sizeof(GenericInstance)); + if (Stream == NULL) { + return RETURN_OUT_OF_RESOURCES; + } + + Stream->Cookie = ROM_COOKIE; + Stream->InstanceNum = 1; + Stream->Dev = NULL; + Stream->Abstraction.fo_close = &_f_romfs_Close; + Stream->Abstraction.fo_read = &_f_romfs_Read; + Stream->Abstraction.fo_write = &_f_romfs_Write; + Stream->Abstraction.fo_fcntl = &fnullop_fcntl; + Stream->Abstraction.fo_poll = &_f_romfs_Poll; + Stream->Abstraction.fo_flush = &fnullop_flush; + Stream->Abstraction.fo_stat = &_f_romfs_Stat; + Stream->Abstraction.fo_ioctl = &_f_romfs_Ioctl; + Stream->Abstraction.fo_delete = &_f_romfs_Delete; + Stream->Abstraction.fo_rmdir = &_f_romfs_Rmdir; + Stream->Abstraction.fo_mkdir = &_f_romfs_Mkdir; + Stream->Abstraction.fo_rename = &_f_romfs_Rename; + Stream->Abstraction.fo_lseek = &_f_romfs_Seek; + + DeviceNode* Node = __DevRegister(ROMFS_NAME, NULL, &_f_romfs_Open, Stream, 1, sizeof(GenericInstance), O_RDONLY); + RETURN_STATUS Status = EFIerrno; + Stream->Parent = Node; + + return Status; +} + + +RETURN_STATUS +EFIAPI +__dtor__rom_fs(void) { + if (daDefaultDevice != NULL) { + if (daDefaultDevice->InstanceList != NULL) { + FreePool(daDefaultDevice->InstanceList); + } + FreePool(daDefaultDevice); + } + return RETURN_SUCCESS; +} + + +void uefi::platform_init() { + auto status = __ctor_rom_fs(); + if (EFI_ERROR(status)) { + utils::throw_( + std::runtime_error{ fmt::format("can't initialize ROM fs: {}", map_efi_status_to_string(status)) } + ); + } +} + +void uefi::platform_exit() { + auto status = __dtor__rom_fs(); + if (EFI_ERROR(status)) { + utils::throw_( + std::runtime_error{ fmt::format("can't deinitialize ROM fs: {}", map_efi_status_to_string(status)) } + ); + } +} diff --git a/src/helper/uefi_utils.hpp b/src/helper/uefi_utils.hpp index 8b72ea46..ec910ea5 100644 --- a/src/helper/uefi_utils.hpp +++ b/src/helper/uefi_utils.hpp @@ -21,6 +21,12 @@ namespace uefi { - [[nodiscard]] std::shared_ptr get_debug_sink(); + [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::shared_ptr get_debug_sink(); + + [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::string map_efi_status_to_string(EFI_STATUS status); + + OOPETRIS_GRAPHICS_EXPORTED void platform_init(); + + OOPETRIS_GRAPHICS_EXPORTED void platform_exit(); }; // namespace uefi diff --git a/src/lobby/uefi_client.cpp b/src/lobby/uefi_client.cpp index 207b0c13..e27a7d08 100644 --- a/src/lobby/uefi_client.cpp +++ b/src/lobby/uefi_client.cpp @@ -1,9 +1,11 @@ #include "./uefi_client.hpp" +#include "helper/uefi_utils.hpp" #include #include + extern "C" { #include #include @@ -112,95 +114,6 @@ namespace { } } - [[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 @@ -259,7 +172,7 @@ oopetris::http::implementation::ActualResult::ActualResult(ActualResult&& other) if (m_response.Status != EFI_SUCCESS) { - return fmt::format("Invalid EFI status: {}", map_efi_status_to_string(m_response.Status)); + return fmt::format("Invalid EFI status: {}", uefi::map_efi_status_to_string(m_response.Status)); } return std::nullopt; @@ -470,7 +383,7 @@ oopetris::http::implementation::ActualClient::construct(const std::string& api_u if (EFI_ERROR(status)) { utils::throw_( std::runtime_error{ - fmt::format("couldn't get network controller: {}", map_efi_status_to_string(status)) } + fmt::format("couldn't get network controller: {}", uefi::map_efi_status_to_string(status)) } ); } diff --git a/tools/dependencies/meson.build b/tools/dependencies/meson.build index 10fcf8de..2be0d3b2 100644 --- a/tools/dependencies/meson.build +++ b/tools/dependencies/meson.build @@ -334,7 +334,10 @@ if build_application meson.override_dependency('sdl2_ttf', sdl2_ttf_switch_dep) elif host_machine.system() == 'uefi' c_embed_dep = dependency('c-embed') - graphic_application_deps += c_embed_dep + + graphics_lib += { + 'deps': [graphics_lib.get('deps'), c_embed_dep], + } endif endif From f8430fd53fff324508cfd4b07374cd78c7344c85 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 29 Aug 2026 23:30:14 +0200 Subject: [PATCH 132/143] fix: fix romfs compilation errors --- src/helper/uefi_utils.cpp | 56 +++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/src/helper/uefi_utils.cpp b/src/helper/uefi_utils.cpp index 47ef757a..39468637 100644 --- a/src/helper/uefi_utils.cpp +++ b/src/helper/uefi_utils.cpp @@ -142,8 +142,13 @@ extern "C" { #pragma GCC diagnostic pop +#include +#include +#include + // use stdlib internals, to register a new rom device under romfs: #include + #include } @@ -189,7 +194,7 @@ static off_t EFIAPI _f_romfs_Seek(struct __filedes* filp, off_t offset, int when int result = eseek(file, offset, whence); if (result != 0) { - errno = eerno; + errno = eerrno; return EOF; } @@ -254,6 +259,12 @@ _f_romfs_Write(IN struct __filedes* filp, IN off_t* offset, IN size_t BufferSize return -1; } + +static int EFIAPI _f_romfs_Fcntl(struct __filedes* filp, UINT32 Cmd, void* p3, void* p4) { + errno = ENOTSUP; + return -1; +} + /** EFI specific operations for getting information about an open file. @param[in] filp Pointer to a file descriptor structure. @@ -306,16 +317,31 @@ int EFIAPI _f_romfs_Open( return -1; } + char* strPath = (char*) AllocateZeroPool(PATH_MAX); + if (strPath == NULL) { + errno = ENOMEM; + return -1; + } + + size_t convert_result = wcstombs(strPath, Path, PATH_MAX); + + if (convert_result == ((size_t) -1) || convert_result > PATH_MAX) { + errno = EINVAL; + return -1; + } // Call the EFI's Open function - EFILE* file = eopen(Path, "r"); + EFILE* file = eopen(strPath, "r"); if (file == NULL) { filp->f_iflags = 0; // Release our reservation on this FD // Set errno based upon Status errno = eerrno; + + FreePool(strPath); return -1; } + FreePool(strPath); // Successfully got a regular File (note c-embed doesnÄt support to open directories) filp->f_iflags |= S_IFREG; @@ -323,7 +349,7 @@ int EFIAPI _f_romfs_Open( // Update the info in the fd filp->devdata = (void*) file; - Gip = (GenericInstance*) DevNode->InstanceList; + GenericInstance* Gip = (GenericInstance*) DevNode->InstanceList; filp->f_offset = 0; filp->f_ops = &Gip->Abstraction; @@ -348,6 +374,12 @@ static short EFIAPI _f_romfs_Poll(struct __filedes* filp, short events) { return -1; } +static int EFIAPI _f_romfs_Flush(struct __filedes* filp) { + errno = ENOTSUP; + return -1; +} + + /** EFI specific operations for renaming a file. @param[in] from Name of the file to be renamed. @@ -376,6 +408,8 @@ static int EFIAPI _f_romfs_Rmdir(struct __filedes* filp) { #define ROMFS_NAME ((const CHAR16*) L"romfs:") +GenericInstance* _g_stream_instance = NULL; + RETURN_STATUS EFIAPI __ctor_rom_fs(void) { @@ -385,14 +419,15 @@ __ctor_rom_fs(void) { } Stream->Cookie = ROM_COOKIE; - Stream->InstanceNum = 1; + Stream->InstanceNum = 1; // not used by this Stream->Dev = NULL; + Stream->Abstraction.fo_close = &_f_romfs_Close; Stream->Abstraction.fo_read = &_f_romfs_Read; Stream->Abstraction.fo_write = &_f_romfs_Write; - Stream->Abstraction.fo_fcntl = &fnullop_fcntl; + Stream->Abstraction.fo_fcntl = &_f_romfs_Fcntl; Stream->Abstraction.fo_poll = &_f_romfs_Poll; - Stream->Abstraction.fo_flush = &fnullop_flush; + Stream->Abstraction.fo_flush = &_f_romfs_Flush; Stream->Abstraction.fo_stat = &_f_romfs_Stat; Stream->Abstraction.fo_ioctl = &_f_romfs_Ioctl; Stream->Abstraction.fo_delete = &_f_romfs_Delete; @@ -405,6 +440,8 @@ __ctor_rom_fs(void) { RETURN_STATUS Status = EFIerrno; Stream->Parent = Node; + _g_stream_instance = Stream; + return Status; } @@ -412,11 +449,8 @@ __ctor_rom_fs(void) { RETURN_STATUS EFIAPI __dtor__rom_fs(void) { - if (daDefaultDevice != NULL) { - if (daDefaultDevice->InstanceList != NULL) { - FreePool(daDefaultDevice->InstanceList); - } - FreePool(daDefaultDevice); + if (_g_stream_instance != NULL) { + FreePool(_g_stream_instance); } return RETURN_SUCCESS; } From 94416e8fb190060ddaed313f1024defe73172c32 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sat, 29 Aug 2026 23:51:39 +0200 Subject: [PATCH 133/143] fix: fix some uefi related errors --- src/helper/graphic_utils.cpp | 9 ++++++++- src/helper/uefi_utils.cpp | 26 +++++++++++++------------- src/manager/music_manager.cpp | 6 ++++++ 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/helper/graphic_utils.cpp b/src/helper/graphic_utils.cpp index d3b33a6a..a0a0ba31 100644 --- a/src/helper/graphic_utils.cpp +++ b/src/helper/graphic_utils.cpp @@ -42,6 +42,10 @@ std::vector utils::supported_features() { return std::filesystem::path{ std::string{ pref_path } }; #elif defined(__EMSCRIPTEN__) return std::filesystem::path{ "/" }; +#elif defined(__UEFI__) + //TODO: can i have writable file systems in uefi? + //NOTE: UEFI has no writable filesystems, so just use "." and than open calls fail + return std::filesystem::path{ "." }; #elif defined(__CONSOLE__) // this is in the sdcard of the switch / 3ds , since internal storage is read-only for applications! return std::filesystem::path{ "." }; @@ -103,8 +107,11 @@ std::vector utils::supported_features() { #if defined(__ANDROID__) return std::filesystem::path{ "" }; #elif defined(__EMSCRIPTEN__) - // emscripten mounts a memfs in the / location, we package assest into this dir, see: https://emscripten.org/docs/porting/files/packaging_files.html#packaging-using-emcc + // emscripten mounts a memfs in the / location, we package assets into this dir, see: https://emscripten.org/docs/porting/files/packaging_files.html#packaging-using-emcc return std::filesystem::path{ "/assets" }; +#elif defined(__UEFI__) + // this is a embedded read only file system, created by c-embed and mounted by edk2-libc and our layer above that (fuse like) + return std::filesystem::path{ "romfs:/assets" }; #elif defined(__CONSOLE__) // this is in the internal storage of the nintendo switch, it is mounted by libnx (runtime switch support library) and filled at compile time with assets (its called ROMFS there) return std::filesystem::path{ "romfs:/assets" }; diff --git a/src/helper/uefi_utils.cpp b/src/helper/uefi_utils.cpp index 39468637..5d937721 100644 --- a/src/helper/uefi_utils.cpp +++ b/src/helper/uefi_utils.cpp @@ -32,7 +32,7 @@ std::shared_ptr uefi::get_debug_sink() { break; case spdlog::level::err: case spdlog::level::critical: - EFI_DEBUG((DEBUG_ERROR, "HHEERREE %a\n", message.c_str())); + EFI_DEBUG((DEBUG_ERROR, "%a\n", message.c_str())); break; default: return; @@ -457,19 +457,19 @@ __dtor__rom_fs(void) { void uefi::platform_init() { - auto status = __ctor_rom_fs(); - if (EFI_ERROR(status)) { - utils::throw_( - std::runtime_error{ fmt::format("can't initialize ROM fs: {}", map_efi_status_to_string(status)) } - ); - } + // auto status = __ctor_rom_fs(); + // if (EFI_ERROR(status)) { + // utils::throw_( + // std::runtime_error{ fmt::format("can't initialize ROM fs: {}", map_efi_status_to_string(status)) } + // ); + // } } void uefi::platform_exit() { - auto status = __dtor__rom_fs(); - if (EFI_ERROR(status)) { - utils::throw_( - std::runtime_error{ fmt::format("can't deinitialize ROM fs: {}", map_efi_status_to_string(status)) } - ); - } + // auto status = __dtor__rom_fs(); + // if (EFI_ERROR(status)) { + // utils::throw_( + // std::runtime_error{ fmt::format("can't deinitialize ROM fs: {}", map_efi_status_to_string(status)) } + // ); + // } } diff --git a/src/manager/music_manager.cpp b/src/manager/music_manager.cpp index e8966c4c..e8be670f 100644 --- a/src/manager/music_manager.cpp +++ b/src/manager/music_manager.cpp @@ -28,6 +28,10 @@ MusicManager::MusicManager(ServiceProvider* service_provider, u8 channel_size) return; } +#if defined(__UEFI__) + SDL_SetHint(SDL_HINT_AUDIODRIVER, "dummy"); +#endif + const auto result = SDL_InitSubSystem(SDL_INIT_AUDIO); if (result != 0) { utils::throw_( @@ -65,6 +69,8 @@ MusicManager::MusicManager(ServiceProvider* service_provider, u8 channel_size) #if defined(__EMSCRIPTEN__) //TODO: do we need this, first do this: // https://github.com/libsdl-org/SDL/issues/6385 +#elif defined(__UEFI__) +// do nothing #else const auto audio_channels = 2; From 06fca96e2d1139517af8ca3b4c0dc73f84acc702 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Sun, 30 Aug 2026 01:00:22 +0200 Subject: [PATCH 134/143] fix: fix some uefi related stuff --- src/helper/uefi_utils.cpp | 18 ++++++++++++-- subprojects/c-embed.wrap | 2 ++ .../packagefiles/c-embed-system-checked.diff | 24 +++++++++++++++++++ subprojects/packagefiles/c-embed/meson.build | 2 +- 4 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 subprojects/packagefiles/c-embed-system-checked.diff diff --git a/src/helper/uefi_utils.cpp b/src/helper/uefi_utils.cpp index 5d937721..77c46991 100644 --- a/src/helper/uefi_utils.cpp +++ b/src/helper/uefi_utils.cpp @@ -275,8 +275,22 @@ static int EFIAPI _f_romfs_Fcntl(struct __filedes* filp, UINT32 Cmd, void* p3, v @retval -1 Operation failed. Further information is specified by errno. **/ static int EFIAPI _f_romfs_Stat(struct __filedes* filp, struct stat* statbuf, void* Something) { - errno = ENOTSUP; - return -1; + EFILE* file = (EFILE*) (&filp->devdata); + + + // Got the info, now populate statbuf with it + statbuf->st_size = file->size; + statbuf->st_physsize = 0; + statbuf->st_curpos = 0; + + statbuf->st_birthtime = 0; + statbuf->st_atime = 0; + statbuf->st_mtime = 0; + + statbuf->st_mode = filp->f_iflags; + statbuf->st_blksize = S_BLKSIZE; + + return 0; } /** EFI specific operations for low-level control of a file or device. diff --git a/subprojects/c-embed.wrap b/subprojects/c-embed.wrap index 70f84373..204f9b25 100644 --- a/subprojects/c-embed.wrap +++ b/subprojects/c-embed.wrap @@ -3,6 +3,8 @@ url = https://github.com/weigert/c-embed.git revision = main depth = 1 patch_directory = c-embed +diff_files = c-embed-system-checked.diff + [provide] dependency_names = c-embed diff --git a/subprojects/packagefiles/c-embed-system-checked.diff b/subprojects/packagefiles/c-embed-system-checked.diff new file mode 100644 index 00000000..52e3e0cb --- /dev/null +++ b/subprojects/packagefiles/c-embed-system-checked.diff @@ -0,0 +1,24 @@ +diff --git a/c-embed.c b/c-embed.c +index bdcec8d..e233d4a 100644 +--- a/c-embed.c ++++ b/c-embed.c +@@ -106,6 +106,19 @@ void iterdir(char* d){ + + } + ++void system_checked(const char *command){ ++ ++ int result = system(command); ++ ++ if(result != 0){ ++ fprintf(stderr, "system() failed with %d: %s\n", result, command); ++ exit(1); ++ } ++ ++} ++ ++#define system system_checked ++ + int main(int argc, char* argv[]){ + + char fmt[CEMBED_MAXPATH]; diff --git a/subprojects/packagefiles/c-embed/meson.build b/subprojects/packagefiles/c-embed/meson.build index 300d40c5..0633c253 100644 --- a/subprojects/packagefiles/c-embed/meson.build +++ b/subprojects/packagefiles/c-embed/meson.build @@ -7,7 +7,7 @@ project( default_options: { 'optimization': '3', 'warning_level': '2', - 'werror': false, + 'werror': true, 'c_std': ['c11'], 'b_ndebug': 'if-release', }, From 02f83bb09d96904e4faf6b27c656fc2177bd5a1f Mon Sep 17 00:00:00 2001 From: Totto16 Date: Thu, 3 Sep 2026 17:10:31 +0200 Subject: [PATCH 135/143] feat: add abort support for uefi async threads --- src/helper/uefi_futures.cpp | 179 +++++++++++++++++++++++++++++++----- src/helper/uefi_futures.hpp | 70 ++++++++------ 2 files changed, 201 insertions(+), 48 deletions(-) diff --git a/src/helper/uefi_futures.cpp b/src/helper/uefi_futures.cpp index 0c74535d..0f173ed0 100644 --- a/src/helper/uefi_futures.cpp +++ b/src/helper/uefi_futures.cpp @@ -32,13 +32,79 @@ UINTN details::my_cpu_id() { return my_cpu_id_impl(__cpu_state->Mp); } +static details::SecondaryCPUState* __impl_get_cpu_state_by_id(UINTN cpu_id) { + + // likely this is 1 indexed into the cpu array, if it is not, than search the whole array + + if (cpu_id == 0) { + goto search_cpu_in_array; + } + + if ((cpu_id - 1) < details::__cpu_state->cpus.size()) { + details::SecondaryCPUState* state = &(details::__cpu_state->cpus.data()[cpu_id - 1]); + if (state->Id == cpu_id) { + return state; + } + goto search_cpu_in_array; + } + +search_cpu_in_array: + + for (size_t i = 0; i < details::__cpu_state->cpus.size(); ++i) { + details::SecondaryCPUState* state = &(details::__cpu_state->cpus.data()[i]); + if (state->Id == cpu_id) { + return state; + } + } + + return nullptr; +} + +#define UEFI_THREAD_ABORT_SIGNAL_HANDLER __impl_uefi_thread_abort_signal_handler + +static void __impl_uefi_thread_abort_signal_handler(int actual_signal) { + //TODO: assert actual_signal == SIGABRT + + const std::lock_guard scope_lock(details::__cpu_state->signal_state.mutex); + + + UINTN cpu_id = details::my_cpu_id(); + + if (cpu_id == details::__cpu_state->BspId) { + // don't intercept that on the bsp thread + return; + } + + + // if this thread is an AP that has a signal_state, don't return, but longjmp to the saved function, where we handle that error + + details::SecondaryCPUState* const state = __impl_get_cpu_state_by_id(cpu_id); + + if (state == nullptr) { + // nothing found, just abort it + return; + } + + if (state->jump_state.has_value()) { + auto& jump_state = state->jump_state.value().jump_state; + + longjmp(jump_state, 0x42); // Get out of here. longjmp can't return 0. Use 0x42 for a non-zero value. + + __builtin_unreachable(); + } + + // no signal state for that thread, so continue + return; +} + void details::init_cpu_state() { if (__cpu_state != nullptr) { return; } - __cpu_state = new details::MainCPUState(nullptr, 0, 0, {}); + __cpu_state = + new details::MainCPUState(nullptr, 0, 0, std::vector{}, GlobalSignalState{ nullptr }); if (!gBS) { @@ -67,6 +133,14 @@ void details::init_cpu_state() { __cpu_state->BspId = my_cpu_id_impl(__cpu_state->Mp); + //TODO: this is global, so just reset it once, so when old_sig_handler == __impl_sigabrt_handler, don't add it, have one global old handler + __sighandler_t* old_sig_handler = signal(SIGABRT, UEFI_THREAD_ABORT_SIGNAL_HANDLER); + + //TODO: inline this in start_detached_thread + + + __cpu_state->signal_state = GlobalSignalState{ old_sig_handler, {} }; + __cpu_state->cpus = std::vector{}; __cpu_state->cpus.reserve(__cpu_state->NumberOfProcessors - 1); @@ -85,16 +159,23 @@ void details::init_cpu_state() { continue; } - __cpu_state->cpus.emplace_back(info.ProcessorId, (UINTN) i, info.StatusFlag, false); + __cpu_state->cpus.emplace_back(info.ProcessorId, (UINTN) i, info.StatusFlag, false, std::nullopt); } } +static void __destroy_cpu_state_impl() { + __sighandler_t* old_sig_handler = signal(SIGABRT, details::__cpu_state->signal_state.old_sig_handler); + ASSERT(old_sig_handler == UEFI_THREAD_ABORT_SIGNAL_HANDLER); +} + static __attribute__((destructor)) void deinit_cpu_state(void) { if (details::__cpu_state == nullptr) { return; } + __destroy_cpu_state_impl(); + delete details::__cpu_state; } @@ -131,54 +212,106 @@ details::SecondaryCPUState* details::find_cpu_for_new_thread(void) { return find_cpu_for_new_thread_impl(__cpu_state); } -static void EFIAPI __impl_uefi_new_thread_function(IN OUT VOID* private_data) { - details::ThreadInfo* ptr = static_cast(private_data); +struct ThreadLocalState { + + ThreadLocalState() { + //TODO, add some constructores + } + + ThreadLocalState(const ThreadLocalState& other) = delete; + ThreadLocalState& operator=(const ThreadLocalState& other) = delete; + + ThreadLocalState(ThreadLocalState&& other) noexcept; + ThreadLocalState& operator=(ThreadLocalState&& other) noexcept; - ptr->info.fn(); -} + ~ThreadLocalState() { + //TODO: add some destructors + } +}; struct details::DetachedThreadStateImpl { - // inout state + // input state EFI_EVENT DoneEvent; BOOLEAN finished; //output state - bool terminated; + std::pair> run_state; + // thread info state, not owned + ThreadInfo* info_ref; + details::SecondaryCPUState* cpu_to_execute_on_ref; // mutex to protect state, that can be used by the AP (when writing the result) and the BSP (when using poll) details::helper::ThreadMutex data_mutex; - DetachedThreadStateImpl() : DoneEvent{}, finished{ FALSE }, terminated{ false }, data_mutex{} { + DetachedThreadStateImpl(ThreadInfo* info_ref, details::SecondaryCPUState* cpu_to_execute_on_ref) + : DoneEvent{}, + finished{ FALSE }, + run_state{ false, std::nullopt }, + info_ref{ info_ref }, + cpu_to_execute_on_ref{ cpu_to_execute_on_ref }, + data_mutex{} { // } - void terminate(void) { + void terminate(std::optional error) { const std::lock_guard scope_lock(this->data_mutex); - this->terminated = true; + this->run_state = { true, error }; + } + + void terminate_done_cb() { + this->run_state = { true, this->finished ? std::optional{ std::nullopt } + : std::optional{ "Not finished" } }; } details::thread_state poll(void) { const std::lock_guard scope_lock(this->data_mutex); - // likely for long running async - if (!this->terminated) [[likely]] { + if (this->run_state.first) { return details::thread_state::running; } - // unlikely, as we don't set a timeout - if (!this->finished) [[unlikely]] { + if (this->run_state.second.has_value()) { return details::thread_state::aborted; } return details::thread_state::finished; } + std::string state() const { + return this->run_state.second.has_value() ? this->run_state.second.value() : ""; + } + ~DetachedThreadStateImpl() noexcept { gBS->CloseEvent(DoneEvent); } }; +static void EFIAPI __impl_uefi_new_thread_function(IN OUT VOID* private_data) { + + ThreadLocalState constructors{}; + + details::DetachedThreadStateImpl* state = static_cast(private_data); + + { + + state->cpu_to_execute_on_ref->jump_state = details::CpuJumpState{}; + auto& setjmp_state = state->cpu_to_execute_on_ref->jump_state.value().jump_state; + + if (setjmp(setjmp_state) == 0) { + // we are executing it the first time + state->info_ref->info.fn(); + } else { + // we aborted + state->terminate("Thread aborted"); + } + + // in both cases destroy the state + state->cpu_to_execute_on_ref->jump_state = std::nullopt; + } +} + + details::DetachedThreadStatePublic::DetachedThreadStatePublic(DetachedThreadState* state_impl) : m_state_impl{ state_impl } { // @@ -196,24 +329,29 @@ details::thread_state details::DetachedThreadStatePublic::poll() { return m_state_impl->poll(); } +std::string details::DetachedThreadStatePublic::state() const { + ASSERT(m_state_impl != nullptr); + return m_state_impl->state(); +} + static VOID EFIAPI __impl_uefi_thread_done_function(IN EFI_EVENT Event, IN VOID* Context) { details::DetachedThreadStateImpl* state = static_cast(Context); - state->terminate(); + state->terminate_done_cb(); } std::shared_ptr start_detached_thread_impl( EFI_MP_SERVICES_PROTOCOL* Mp, - const details::SecondaryCPUState* const cpu_to_execute_on, + details::SecondaryCPUState* const cpu_to_execute_on, const std::shared_ptr& info ) { ASSERT(Mp != nullptr); ASSERT(cpu_to_execute_on != nullptr); - details::DetachedThreadStateImpl* state = new details::DetachedThreadStateImpl(); + details::DetachedThreadStateImpl* state = new details::DetachedThreadStateImpl(info.get(), cpu_to_execute_on); EFI_STATUS Status = gBS->CreateEvent( EVT_NOTIFY_SIGNAL, TPL_CALLBACK, __impl_uefi_thread_done_function, state, &(state->DoneEvent) @@ -226,8 +364,7 @@ std::shared_ptr start_detached_thread_impl( Status = Mp->StartupThisAP( - Mp, __impl_uefi_new_thread_function, cpu_to_execute_on->Id, state->DoneEvent, 0, info.get(), - &(state->finished) + Mp, __impl_uefi_new_thread_function, cpu_to_execute_on->Id, state->DoneEvent, 0, state, &(state->finished) ); @@ -244,7 +381,7 @@ std::shared_ptr start_detached_thread_impl( std::shared_ptr details::start_detached_thread( - const details::SecondaryCPUState* const cpu_to_execute_on, + details::SecondaryCPUState* const cpu_to_execute_on, const std::shared_ptr& info ) { diff --git a/src/helper/uefi_futures.hpp b/src/helper/uefi_futures.hpp index 4f3ea787..2565782d 100644 --- a/src/helper/uefi_futures.hpp +++ b/src/helper/uefi_futures.hpp @@ -16,6 +16,9 @@ extern "C" { #include #include + +#include +#include } #include @@ -40,11 +43,46 @@ namespace helper::uefi::future { namespace details { + + namespace helper { + + //TODO: we could use a c++ wrapper of the SPIN_LOCK from "SynchronizationLib.h" instead + struct ThreadMutex { + private: + volatile UINT32 locked; + + public: + ThreadMutex() noexcept; + + ThreadMutex(const ThreadMutex& other) = delete; + ThreadMutex& operator=(const ThreadMutex& other) = delete; + + ThreadMutex(ThreadMutex&& other) noexcept; + ThreadMutex& operator=(ThreadMutex&& other) noexcept; + + ~ThreadMutex() noexcept; + + void lock(); + void unlock(); + }; + + } // namespace helper + + struct CpuJumpState { + jmp_buf jump_state; + }; + struct SecondaryCPUState { UINT64 UniqueProcessorId; UINTN Id; UINT32 StatusFlags; bool IsBusy; + std::optional jump_state; + }; + + struct GlobalSignalState { + __sighandler_t* old_sig_handler; + helper::ThreadMutex mutex; }; struct MainCPUState { @@ -52,6 +90,7 @@ namespace details { UINTN NumberOfProcessors; UINTN BspId; std::vector cpus; + GlobalSignalState signal_state; }; extern MainCPUState* __cpu_state; @@ -89,34 +128,12 @@ namespace details { ~DetachedThreadStatePublic(); [[nodiscard]] thread_state poll(); + + [[nodiscard]] std::string state() const; }; std::shared_ptr - start_detached_thread(const SecondaryCPUState* const cpu_to_execute_on, const std::shared_ptr& info); - - namespace helper { - - //TODO: we could use a c++ wrapper of the SPIN_LOCK from "SynchronizationLib.h" instead - struct ThreadMutex { - private: - volatile UINT32 locked; - - public: - ThreadMutex() noexcept; - - ThreadMutex(const ThreadMutex& other) = delete; - ThreadMutex& operator=(const ThreadMutex& other) = delete; - - ThreadMutex(ThreadMutex&& other) noexcept; - ThreadMutex& operator=(ThreadMutex&& other) noexcept; - - ~ThreadMutex() noexcept; - - void lock(); - void unlock(); - }; - - } // namespace helper + start_detached_thread(SecondaryCPUState* const cpu_to_execute_on, const std::shared_ptr& info); } // namespace details @@ -164,8 +181,7 @@ namespace uefi::helper { } case details::thread_state::aborted: default: { - //TODO: get the error from somewhere - return ErrorState{ "TODO" }; + return ErrorState{ state.thread.state() }; } } }, From 1b3be9f424e0b419d5578a7e3eb473f380bcc1a9 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 4 Sep 2026 00:02:04 +0200 Subject: [PATCH 136/143] feat: use mutexes for spdlog in the uefi case --- src/executables/game/main.cpp | 2 +- src/helper/meson.build | 1 + src/helper/uefi_futures.cpp | 57 ++--------------------- src/helper/uefi_futures.hpp | 31 ++----------- src/helper/uefi_utils.cpp | 66 +++++++++++++++++++++++++-- src/helper/uefi_utils.hpp | 45 +++++++++++++++++- src/helper/uefi_utils_spdlog_sink.cpp | 21 +++++++++ 7 files changed, 137 insertions(+), 86 deletions(-) create mode 100644 src/helper/uefi_utils_spdlog_sink.cpp diff --git a/src/executables/game/main.cpp b/src/executables/game/main.cpp index c39e1be7..db1bfa40 100644 --- a/src/executables/game/main.cpp +++ b/src/executables/game/main.cpp @@ -60,7 +60,7 @@ namespace { #elif defined(__UEFI__) sinks.push_back(uefi::get_debug_sink()); // is outputted to serial, handled by edk2-libc - sinks.push_back(std::make_shared(spdlog::color_mode::never)); + sinks.push_back(std::make_shared(spdlog::color_mode::never)); #elif defined(__EMSCRIPTEN__) sinks.push_back(web::get_console_sink()); #else diff --git a/src/helper/meson.build b/src/helper/meson.build index 5a0bdc4f..d279b7c6 100644 --- a/src/helper/meson.build +++ b/src/helper/meson.build @@ -20,6 +20,7 @@ if meson.is_cross_build() and host_machine.system() == 'uefi' 'uefi_futures.hpp', 'uefi_utils.cpp', 'uefi_utils.hpp', + 'uefi_utils_spdlog_sink.cpp', ) elif meson.is_cross_build() and host_machine.system() == 'emscripten' graphics_src_files += files( diff --git a/src/helper/uefi_futures.cpp b/src/helper/uefi_futures.cpp index 0f173ed0..3bea9aae 100644 --- a/src/helper/uefi_futures.cpp +++ b/src/helper/uefi_futures.cpp @@ -3,7 +3,6 @@ extern "C" { #include -#include #include } @@ -65,7 +64,7 @@ static details::SecondaryCPUState* __impl_get_cpu_state_by_id(UINTN cpu_id) { static void __impl_uefi_thread_abort_signal_handler(int actual_signal) { //TODO: assert actual_signal == SIGABRT - const std::lock_guard scope_lock(details::__cpu_state->signal_state.mutex); + const std::lock_guard scope_lock(details::__cpu_state->signal_state.mutex); UINTN cpu_id = details::my_cpu_id(); @@ -241,7 +240,7 @@ struct details::DetachedThreadStateImpl { details::SecondaryCPUState* cpu_to_execute_on_ref; // mutex to protect state, that can be used by the AP (when writing the result) and the BSP (when using poll) - details::helper::ThreadMutex data_mutex; + uefi::helper::ThreadMutex data_mutex; DetachedThreadStateImpl(ThreadInfo* info_ref, details::SecondaryCPUState* cpu_to_execute_on_ref) : DoneEvent{}, @@ -254,7 +253,7 @@ struct details::DetachedThreadStateImpl { } void terminate(std::optional error) { - const std::lock_guard scope_lock(this->data_mutex); + const std::lock_guard scope_lock(this->data_mutex); this->run_state = { true, error }; } @@ -265,7 +264,7 @@ struct details::DetachedThreadStateImpl { } details::thread_state poll(void) { - const std::lock_guard scope_lock(this->data_mutex); + const std::lock_guard scope_lock(this->data_mutex); if (this->run_state.first) { return details::thread_state::running; @@ -388,51 +387,3 @@ std::shared_ptr details::start_detached_thre ASSERT(__cpu_state != nullptr); return start_detached_thread_impl(__cpu_state->Mp, cpu_to_execute_on, info); } - - -details::helper::ThreadMutex::ThreadMutex() noexcept : locked{ 0 } { - // -} - -details::helper::ThreadMutex::ThreadMutex(ThreadMutex&& other) noexcept : locked{ 0 } { - ASSERT(!other.locked); - - other.locked = 0; -} - -details::helper::ThreadMutex& details::helper::ThreadMutex::operator=(ThreadMutex&& other) noexcept { - ASSERT(!other.locked); - - this->locked = other.locked; - other.locked = 0; - - return *this; -} - -details::helper::ThreadMutex::~ThreadMutex() noexcept { - ASSERT(!this->locked); -} - - -void details::helper::ThreadMutex::lock() { - while (InterlockedCompareExchange32( - &(this->locked), - 0, // Compare: unlocked - 1 // Exchange: locked - ) - != 0) { - // - // Someone else owns it. - // - CpuPause(); - } -} - -void details::helper::ThreadMutex::unlock() { - - InterlockedCompareExchange32( - &(this->locked), - 1, // Compare: locked - 0 // Exchange: unlocked - ); -} diff --git a/src/helper/uefi_futures.hpp b/src/helper/uefi_futures.hpp index 2565782d..b7af1038 100644 --- a/src/helper/uefi_futures.hpp +++ b/src/helper/uefi_futures.hpp @@ -27,6 +27,7 @@ extern "C" { #include #include #include +#include "./uefi_utils.hpp" //COPY from oopetris, to make this header more independent @@ -43,31 +44,6 @@ namespace helper::uefi::future { namespace details { - - namespace helper { - - //TODO: we could use a c++ wrapper of the SPIN_LOCK from "SynchronizationLib.h" instead - struct ThreadMutex { - private: - volatile UINT32 locked; - - public: - ThreadMutex() noexcept; - - ThreadMutex(const ThreadMutex& other) = delete; - ThreadMutex& operator=(const ThreadMutex& other) = delete; - - ThreadMutex(ThreadMutex&& other) noexcept; - ThreadMutex& operator=(ThreadMutex&& other) noexcept; - - ~ThreadMutex() noexcept; - - void lock(); - void unlock(); - }; - - } // namespace helper - struct CpuJumpState { jmp_buf jump_state; }; @@ -82,7 +58,7 @@ namespace details { struct GlobalSignalState { __sighandler_t* old_sig_handler; - helper::ThreadMutex mutex; + uefi::helper::ThreadMutex mutex; }; struct MainCPUState { @@ -162,7 +138,6 @@ namespace uefi::helper { }; mutable std::variant m_state; - // void __internal_poll(void) const { std::optional> new_value = std::visit( @@ -181,7 +156,7 @@ namespace uefi::helper { } case details::thread_state::aborted: default: { - return ErrorState{ state.thread.state() }; + return ErrorState{ state.thread->state() }; } } }, diff --git a/src/helper/uefi_utils.cpp b/src/helper/uefi_utils.cpp index 77c46991..1fa0aa87 100644 --- a/src/helper/uefi_utils.cpp +++ b/src/helper/uefi_utils.cpp @@ -11,9 +11,14 @@ #include #include +extern "C" { +#include +#include +} -std::shared_ptr uefi::get_debug_sink() { - return std::make_shared([](const spdlog::details::log_msg& msg) { + +std::shared_ptr uefi::get_debug_sink() { + return std::make_shared([](const spdlog::details::log_msg& msg) { const std::string message = std::string{ msg.payload.begin(), msg.payload.end() }; @@ -41,6 +46,55 @@ std::shared_ptr uefi::get_debug_sink() { } +uefi::helper::ThreadMutex::ThreadMutex() noexcept : locked{ 0 } { + // +} + +uefi::helper::ThreadMutex::ThreadMutex(ThreadMutex&& other) noexcept : locked{ 0 } { + ASSERT(!other.locked); + + other.locked = 0; +} + +uefi::helper::ThreadMutex& uefi::helper::ThreadMutex::operator=(ThreadMutex&& other) noexcept { + ASSERT(!other.locked); + + this->locked = other.locked; + other.locked = 0; + + return *this; +} + +uefi::helper::ThreadMutex::~ThreadMutex() noexcept { + ASSERT(!this->locked); +} + +//TODO: use this as kibc mutex, implement std::mutex with this and so the libc and libcxx has correct mutexes! +// but should i use spinlocks or atomics here? +// also this doesn't depend on oopetris specific things, so its possible +void uefi::helper::ThreadMutex::lock() { + while (InterlockedCompareExchange32( + &(this->locked), + 0, // Compare: unlocked + 1 // Exchange: locked + ) + != 0) { + // + // Someone else owns it. + // + CpuPause(); + } +} + +void uefi::helper::ThreadMutex::unlock() { + + InterlockedCompareExchange32( + &(this->locked), + 1, // Compare: locked + 0 // Exchange: unlocked + ); +} + [[nodiscard]] std::string uefi::map_efi_status_to_string(EFI_STATUS status) { switch (status) { @@ -327,12 +381,14 @@ int EFIAPI _f_romfs_Open( wchar_t* MPath ) { if (filp->Oflags != O_RDONLY) { + DEBUG((DEBUG_ERROR, "%a %a:%d: IN OPEN %s\n", __func__, __FILE__, __LINE__, Path)); errno = EINVAL; return -1; } char* strPath = (char*) AllocateZeroPool(PATH_MAX); if (strPath == NULL) { + DEBUG((DEBUG_ERROR, "%a %a:%d: IN OPEN %s\n", __func__, __FILE__, __LINE__, Path)); errno = ENOMEM; return -1; } @@ -340,17 +396,20 @@ int EFIAPI _f_romfs_Open( size_t convert_result = wcstombs(strPath, Path, PATH_MAX); if (convert_result == ((size_t) -1) || convert_result > PATH_MAX) { + DEBUG((DEBUG_ERROR, "%a %a:%d: IN OPEN %s\n", __func__, __FILE__, __LINE__, Path)); errno = EINVAL; return -1; } + DEBUG((DEBUG_ERROR, "%a %a:%d: path: %a\n", __func__, __FILE__, __LINE__, strPath)); + // Call the EFI's Open function EFILE* file = eopen(strPath, "r"); if (file == NULL) { filp->f_iflags = 0; // Release our reservation on this FD // Set errno based upon Status errno = eerrno; - + DEBUG((DEBUG_ERROR, "%a %a:%d: IN OPEN %s\n", __func__, __FILE__, __LINE__, Path)); FreePool(strPath); return -1; } @@ -367,6 +426,7 @@ int EFIAPI _f_romfs_Open( filp->f_offset = 0; filp->f_ops = &Gip->Abstraction; + DEBUG((DEBUG_ERROR, "%a %a:%d: IN OPEN %s\n", __func__, __FILE__, __LINE__, Path)); return 0; } diff --git a/src/helper/uefi_utils.hpp b/src/helper/uefi_utils.hpp index ec910ea5..923dc6a2 100644 --- a/src/helper/uefi_utils.hpp +++ b/src/helper/uefi_utils.hpp @@ -12,6 +12,7 @@ #include "helper/spdlog_wrapper.hpp" #include +#include #include #include @@ -21,7 +22,49 @@ namespace uefi { - [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::shared_ptr get_debug_sink(); + namespace helper { + + //TODO: we could use a c++ wrapper of the SPIN_LOCK from "SynchronizationLib.h" instead, or is that not atomic? + struct ThreadMutex { + private: + volatile UINT32 locked; + + public: + ThreadMutex() noexcept; + + ThreadMutex(const ThreadMutex& other) = delete; + ThreadMutex& operator=(const ThreadMutex& other) = delete; + + ThreadMutex(ThreadMutex&& other) noexcept; + ThreadMutex& operator=(ThreadMutex&& other) noexcept; + + ~ThreadMutex() noexcept; + + void lock(); + void unlock(); + }; + + } // namespace helper + + namespace spdlog_helper { + using callback_sink = spdlog::sinks::callback_sink; + + namespace details { + struct console_mutex { + using mutex_t = uefi::helper::ThreadMutex; + static mutex_t& mutex() { + static mutex_t s_mutex; + return s_mutex; + } + }; + } // namespace details + + using stdout_color_sink = spdlog::sinks::ansicolor_stdout_sink; + using stderr_color_sink = spdlog::sinks::ansicolor_stderr_sink; + } // namespace spdlog_helper + + + [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::shared_ptr get_debug_sink(); [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::string map_efi_status_to_string(EFI_STATUS status); diff --git a/src/helper/uefi_utils_spdlog_sink.cpp b/src/helper/uefi_utils_spdlog_sink.cpp new file mode 100644 index 00000000..a998639b --- /dev/null +++ b/src/helper/uefi_utils_spdlog_sink.cpp @@ -0,0 +1,21 @@ +// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) + +#ifndef SPDLOG_COMPILED_LIB +#error Please define SPDLOG_COMPILED_LIB to compile this file. +#endif + +#include + +#include +#include + +#include + +#include "./uefi_utils.hpp" + +// instantiate the sink template for this mutex +template class SPDLOG_API spdlog::sinks::base_sink; + +template class SPDLOG_API spdlog::sinks::ansicolor_stdout_sink; +template class SPDLOG_API spdlog::sinks::ansicolor_stderr_sink; From 48de12f9b2796f3aeac2d1149fd63bbda6bc85eb Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 4 Sep 2026 00:04:42 +0200 Subject: [PATCH 137/143] feat: add libc malloc threadsafe implementation --- .../0001-feat-make-LibC-support-C.patch | 37 ++++- ...x-fix-naming-of-LibCType-to-LibCtype.patch | 6 +- .../0003-feat-add-c-and-c-constructors.patch | 6 +- ...at-make-malloc-from-libc-thread-safe.patch | 145 ++++++++++++++++++ 4 files changed, 184 insertions(+), 10 deletions(-) create mode 100644 platforms/uefi/edk2-libc/0004-feat-make-malloc-from-libc-thread-safe.patch diff --git a/platforms/uefi/edk2-libc/0001-feat-make-LibC-support-C.patch b/platforms/uefi/edk2-libc/0001-feat-make-LibC-support-C.patch index 12837fbe..f272d7f4 100644 --- a/platforms/uefi/edk2-libc/0001-feat-make-LibC-support-C.patch +++ b/platforms/uefi/edk2-libc/0001-feat-make-LibC-support-C.patch @@ -1,12 +1,13 @@ -From f7003762ba238197634d4769c49e2d7c98757552 Mon Sep 17 00:00:00 2001 +From 6e93936dd09957371357102cb5ecbb61160b696d Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 21 Aug 2026 18:28:16 +0200 -Subject: [PATCH 1/3] feat: make LibC support C++ - make the includes support +Subject: [PATCH 1/5] feat: make LibC support C++ - make the includes support c++ - fix some other small libc related things --- StdLib/Include/assert.h | 7 +++++++ StdLib/Include/math.h | 8 ++++++++ + StdLib/Include/sys/EfiCdefs.h | 17 +++++++++++++++++ StdLib/Include/time.h | 3 ++- StdLib/Include/wchar.h | 3 +++ StdLib/LibC/Math/s_ceil.c | 4 ++++ @@ -14,7 +15,7 @@ Subject: [PATCH 1/3] feat: make LibC support C++ - make the includes support StdLib/LibC/Stdio/ftello.c | 13 +++++++++++++ StdLib/LibC/Stdio/vasprintf.c | 9 +++------ StdLib/LibC/gdtoa/gdtoa.inf | 3 +++ - 9 files changed, 44 insertions(+), 7 deletions(-) + 10 files changed, 61 insertions(+), 7 deletions(-) diff --git a/StdLib/Include/assert.h b/StdLib/Include/assert.h index 26c7037..5296e9a 100644 @@ -66,6 +67,34 @@ index 3041120..9eb0be2 100644 /** Compute the absolute value of Arg. @param[in] Arg The value to compute the absolute value of. +diff --git a/StdLib/Include/sys/EfiCdefs.h b/StdLib/Include/sys/EfiCdefs.h +index 72862fa..63f19c4 100644 +--- a/StdLib/Include/sys/EfiCdefs.h ++++ b/StdLib/Include/sys/EfiCdefs.h +@@ -88,6 +88,23 @@ + #include + #define __warn_references(sym,msg) + ++// define USE_WEAK_ALIASES to use them ++ ++#ifdef USE_WEAK_ALIASES ++ ++// Source - https://stackoverflow.com/a/34893039 ++// Posted by Sam Liao ++// Retrieved 2026-08-28, License - CC BY-SA 3.0 ++ ++/* Define ALIASNAME as a weak alias for NAME. ++ If weak aliases are not available, this defines a strong alias. */ ++# define weak_alias(aliasname, name) _weak_alias (aliasname, name) ++# define _weak_alias(aliasname, name) __weak_alias (aliasname, name) ++# define __weak_alias(aliasname, name) \ ++ extern __typeof (name) aliasname __attribute__ ((weak, alias (#name))); ++ ++#endif ++ + /* NULL is defined by the automatic inclusion of Base.h by the build tools. */ + + #ifdef __GNUC__ diff --git a/StdLib/Include/time.h b/StdLib/Include/time.h index ecef1e2..7d7f70e 100644 --- a/StdLib/Include/time.h @@ -184,5 +213,5 @@ index 9d975bb..44af305 100644 StdLib/StdLib.dec StdLibPrivateInternalFiles/DoNotUse.dec -- -2.53.0 +2.55.0 diff --git a/platforms/uefi/edk2-libc/0002-fix-fix-naming-of-LibCType-to-LibCtype.patch b/platforms/uefi/edk2-libc/0002-fix-fix-naming-of-LibCType-to-LibCtype.patch index e49efa98..16f19d6b 100644 --- a/platforms/uefi/edk2-libc/0002-fix-fix-naming-of-LibCType-to-LibCtype.patch +++ b/platforms/uefi/edk2-libc/0002-fix-fix-naming-of-LibCType-to-LibCtype.patch @@ -1,7 +1,7 @@ -From 064d91037d5661b0520c1620f1de61310bd3eae4 Mon Sep 17 00:00:00 2001 +From 05696c4b8475bb9a54f048db298594978c90488a Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 21 Aug 2026 18:28:44 +0200 -Subject: [PATCH 2/3] fix: fix naming of LibCType to LibCtype +Subject: [PATCH 2/5] fix: fix naming of LibCType to LibCtype --- StdLib/LibC/Locale/Locale.inf | 2 +- @@ -74,5 +74,5 @@ index 8083e2b..4d08302 100644 LibMath|StdLib/LibC/Math/Math.inf LibSignal|StdLib/LibC/Signal/Signal.inf -- -2.53.0 +2.55.0 diff --git a/platforms/uefi/edk2-libc/0003-feat-add-c-and-c-constructors.patch b/platforms/uefi/edk2-libc/0003-feat-add-c-and-c-constructors.patch index e5665d6d..b08e57dc 100644 --- a/platforms/uefi/edk2-libc/0003-feat-add-c-and-c-constructors.patch +++ b/platforms/uefi/edk2-libc/0003-feat-add-c-and-c-constructors.patch @@ -1,7 +1,7 @@ -From 7ea2fb646693a14f43ae8e85d861b67dc7e4ae43 Mon Sep 17 00:00:00 2001 +From b7727eb603653b41282f0543c192e7f9f3707c75 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 25 Aug 2026 17:06:59 +0200 -Subject: [PATCH 3/3] feat: add c and c++ constructors - add libcxx and libc +Subject: [PATCH 3/5] feat: add c and c++ constructors - add libcxx and libc interlaving constructors and destructors, that are invoked before .init_array and .fini_array - use better option to run libc initializer, use the same mechanism as the init_array and fini_array one, but with other @@ -185,5 +185,5 @@ index 4d08302..d6f2b73 100644 + + GCC:*_*_*_CC_FLAGS = -Wprio-ctor-dtor -- -2.53.0 +2.55.0 diff --git a/platforms/uefi/edk2-libc/0004-feat-make-malloc-from-libc-thread-safe.patch b/platforms/uefi/edk2-libc/0004-feat-make-malloc-from-libc-thread-safe.patch new file mode 100644 index 00000000..8178e774 --- /dev/null +++ b/platforms/uefi/edk2-libc/0004-feat-make-malloc-from-libc-thread-safe.patch @@ -0,0 +1,145 @@ +From d068559b2bab247684f65d6ac5f632d982a96905 Mon Sep 17 00:00:00 2001 +From: Totto16 +Date: Fri, 4 Sep 2026 00:03:01 +0200 +Subject: [PATCH 4/5] feat: make malloc from libc thread safe + +--- + StdLib/LibC/StdLib/Malloc.c | 54 ++++++++++++++++++++++++++++++++++- + StdLib/LibC/StdLib/StdLib.inf | 2 ++ + 2 files changed, 55 insertions(+), 1 deletion(-) + +diff --git a/StdLib/LibC/StdLib/Malloc.c b/StdLib/LibC/StdLib/Malloc.c +index 7bf8827..6835aaf 100644 +--- a/StdLib/LibC/StdLib/Malloc.c ++++ b/StdLib/LibC/StdLib/Malloc.c +@@ -29,7 +29,7 @@ + #include + #include + #include +- ++#include + #include + + #include +@@ -62,6 +62,37 @@ typedef struct { + // List of memory allocated by malloc/calloc/etc. + static LIST_ENTRY MemPoolHead = INITIALIZE_LIST_HEAD_VARIABLE(MemPoolHead); + ++static SPIN_LOCK MemorySpinLock = {}; ++ ++EFI_STATUS ++EFIAPI ++LibStdLibConstructor ( ++ IN EFI_HANDLE ImageHandle, ++ IN EFI_SYSTEM_TABLE *SystemTable ++ ) ++{ ++ SPIN_LOCK * spin_lock = InitializeSpinLock(&MemorySpinLock); ++ ++ if(spin_lock == NULL){ ++ return EFI_LOAD_ERROR; ++ } ++ return EFI_SUCCESS; ++} ++ ++EFI_STATUS ++EFIAPI ++LibStdLibDestructor ( ++ IN EFI_HANDLE ImageHandle, ++ IN EFI_SYSTEM_TABLE *SystemTable ++ ) ++{ ++ return EFI_SUCCESS; ++} ++ ++#define SPIN_LOCK_ACQUIRE(lock) ASSERT(AcquireSpinLock(lock) != NULL) ++#define SPIN_LOCK_RELEASE(lock) ASSERT(ReleaseSpinLock(lock) != NULL) ++ ++ + /****************************/ + + /** The malloc function allocates space for an object whose size is specified +@@ -103,6 +134,9 @@ malloc(size_t Size) + NodeSize = (UINTN)(Size + sizeof(CPOOL_HEAD)); + + DEBUG((DEBUG_POOL, "malloc(%d): NodeSz: %d", Size, NodeSize)); ++ ++ SPIN_LOCK_ACQUIRE(&MemorySpinLock); ++ { + + Status = gBS->AllocatePool( EfiLoaderData, NodeSize, (void**)&Head); + if( Status != EFI_SUCCESS) { +@@ -124,6 +158,9 @@ malloc(size_t Size) + DEBUG((DEBUG_POOL, " Head: %p, Returns %p\n", Head, RetVal)); + } + ++ } ++ SPIN_LOCK_RELEASE(&MemorySpinLock); ++ + return RetVal; + } + +@@ -176,6 +213,9 @@ free(void *Ptr) + { + CPOOL_HEAD *Head; + ++ SPIN_LOCK_ACQUIRE(&MemorySpinLock); ++ { ++ + Head = BASE_CR(Ptr, CPOOL_HEAD, Data); + assert(Head != NULL); + DEBUG((DEBUG_POOL, "free(%p): Head: %p\n", Ptr, Head)); +@@ -191,6 +231,10 @@ free(void *Ptr) + Ptr, Head->Signature, CPOOL_HEAD_SIGNATURE)); + } + } ++ ++ } ++ SPIN_LOCK_RELEASE(&MemorySpinLock); ++ + DEBUG((DEBUG_POOL, "free Done\n")); + } + +@@ -245,6 +289,9 @@ realloc(void *Ptr, size_t ReqSize) + size_t NewSize; + size_t NumCpy; + ++ SPIN_LOCK_ACQUIRE(&MemorySpinLock); ++ { ++ + // Find out the size of the OLD memory region + if( Ptr != NULL) { + Head = BASE_CR (Ptr, CPOOL_HEAD, Data); +@@ -253,11 +300,16 @@ realloc(void *Ptr, size_t ReqSize) + errno = EFAULT; + DEBUG((DEBUG_ERROR, "ERROR realloc(0x%p): Signature is 0x%8X, expected 0x%8X\n", + Ptr, Head->Signature, CPOOL_HEAD_SIGNATURE)); ++ ++ SPIN_LOCK_RELEASE(&MemorySpinLock); + return NULL; + } + OldSize = (size_t)Head->Size; + } + ++ } ++ SPIN_LOCK_RELEASE(&MemorySpinLock); ++ + // At this point, Ptr is either NULL or a valid pointer to an allocated space + NewSize = (size_t)(ReqSize + (sizeof(CPOOL_HEAD))); + +diff --git a/StdLib/LibC/StdLib/StdLib.inf b/StdLib/LibC/StdLib/StdLib.inf +index 968e6a7..299dbfa 100644 +--- a/StdLib/LibC/StdLib/StdLib.inf ++++ b/StdLib/LibC/StdLib/StdLib.inf +@@ -20,6 +20,8 @@ + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + LIBRARY_CLASS = LibStdLib ++ CONSTRUCTOR = LibStdLibConstructor ++ DESTRUCTOR = LibStdLibDestructor + + # + # VALID_ARCHITECTURES = IA32 X64 +-- +2.55.0 + From 0546d4ecb14891133f59570a3af4edac0ea52ede Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 4 Sep 2026 16:12:10 +0200 Subject: [PATCH 138/143] feat: try to add dependencies on files from the used in files - this correctly rebuilds the .efi and invokes the edk2 build script, when one of the source files changes, which is the case, if some library files are changed when developing and patching those --- platforms/uefi/compile-final.sh | 1 + platforms/uefi/extract-definitions.sh | 2 +- platforms/uefi/extract-dependency-tree.sh | 173 +++++++++++++++++++++ src/executables/platforms/uefi/meson.build | 18 ++- 4 files changed, 191 insertions(+), 3 deletions(-) create mode 100755 platforms/uefi/extract-dependency-tree.sh diff --git a/platforms/uefi/compile-final.sh b/platforms/uefi/compile-final.sh index f244b2f1..84084995 100755 --- a/platforms/uefi/compile-final.sh +++ b/platforms/uefi/compile-final.sh @@ -58,6 +58,7 @@ fi -b "$EDK2_TARGET_PROPERTIES_BUILDTYPE" \ -t "$EDK2_TARGET_PROPERTIES_TOOLCHAIN" \ -D "OOPETRIS_RUNTIME_TARGET=$EDK2_TARGET_PROPERTIES_RUNTIME_TARGET" \ + -n 0 \ -w # -v # verbose ##TODO: un-hardcode this diff --git a/platforms/uefi/extract-definitions.sh b/platforms/uefi/extract-definitions.sh index f19f12ae..2493997d 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" "LibGdtoa") +C_LIBRARIES=("LibC" "LibCtype" "LibLocale" "LibMath" "LibSignal" "LibStdio" "LibStdLib" "LibString" "LibTime" "LibThread" "LibUefi" "LibWchar" "LibGdtoa") CPP_LIBRARIES=("LibCXX" "LibCXXABI") MAPPINGS_FILE="$(realpath "$SCRIPT_DIR/../../src/executables/platforms/uefi/mappings.json")" diff --git a/platforms/uefi/extract-dependency-tree.sh b/platforms/uefi/extract-dependency-tree.sh new file mode 100755 index 00000000..3f99903c --- /dev/null +++ b/platforms/uefi/extract-dependency-tree.sh @@ -0,0 +1,173 @@ +#!/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 + BUILD_INF="$(realpath "$1")" + PSEUDO_DEST_FILE="$(realpath "$2")" + DEPS_DEST_FILE="$(realpath "$3")" +else + echo "Too many arguments given, expected 3" >&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_TOOLS_DIR="$(jq -M -r -c '.["edk2_tools_dir"]' "$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")" +EDK2_TARGET_PROPERTIES_RUNTIME_TARGET="$(jq -M -r -c '.["runtime_target"]' "$UEFI_INFO_FILE")" + +BUILD_NAME=$(basename -- $"$BUILD_INF") + +BUILD_FILE_TARGET="GeneratedPackages/$BUILD_NAME" + +BUILD_FILE_TARGET_ABS="$EDK2_TOOLS_DIR/$BUILD_FILE_TARGET" + +if ! [ -e "$BUILD_FILE_TARGET_ABS" ]; then + echo "Build file is not in the expected place: $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 + +analyze_inf_file() { + local INF_FILE="$1" + + # add inf file + cat <>"$DEPS_DEST_FILE" +$INF_FILE +EOF + + # add sources + + local PARENT_FOLDER="$(dirname "$INF_FILE")" + + local sources + + mapfile -t sources < <( + awk ' + /^\[Sources\]/ { in_sources=1; next } + /^\[/ { in_sources=0 } + in_sources { + gsub(/^[[:space:]]+|[[:space:]]+$/, "") + if ($0 != "" && $0 !~ /^#/) + print + } + ' "$INF_FILE" + ) + + for SRC in "${sources[@]}"; do + + if [[ "${SRC:0:1}" != "/" ]]; then + SRC="${PARENT_FOLDER}/${SRC}" + fi + + if [[ "$SRC" =~ ^.*\$\(OPENSSL_PATH\).*$ ]]; then + SRC="${SRC//\$(OPENSSL_PATH)/openssl}" + fi + + cat <>"$DEPS_DEST_FILE" +$SRC +EOF + + done + +} + +REPORT_FILE="$WORKSPACE/BuildReport.txt" + +# generate build report +"$EDK2_BUILD_COMMAND" -a "$EDK2_TARGET_PROPERTIES_ARCH" \ + -p "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" \ + -m "$BUILD_NAME" \ + -b "$EDK2_TARGET_PROPERTIES_BUILDTYPE" \ + -t "$EDK2_TARGET_PROPERTIES_TOOLCHAIN" \ + -D "OOPETRIS_RUNTIME_TARGET=$EDK2_TARGET_PROPERTIES_RUNTIME_TARGET" \ + -n 0 \ + -w \ + -Y PCD \ + -Y LIBRARY \ + -Y FLASH \ + -Y DEPEX \ + -Y BUILD_FLAGS \ + -Y FIXED_ADDRESS \ + -Y HASH \ + -Y EXECUTION_ORDER \ + -Y COMPILE_INFO \ + -y "$REPORT_FILE" + +# analyze dependencies + +rm -f "$DEPS_DEST_FILE" +validate_parent_dir "$DEPS_DEST_FILE" +touch "$DEPS_DEST_FILE" + +line="" + +analyze_state="unknown" +analyze_buffer="" + +while IFS="" read -r line; do + + if [ "$analyze_state" == "unknown" ]; then + if [[ "$line" =~ ^\>-+\<$ ]]; then + analyze_state="line" + fi + elif [ "$analyze_state" == "line" ]; then + if [[ "$line" == "Library" ]]; then + analyze_state="libs" + else + analyze_state="unknown" + fi + elif [ "$analyze_state" == "libs" ]; then + if [[ "$line" =~ ^\<-+\>$ ]]; then + analyze_state="unknown" + if [ "$analyze_buffer" != "" ]; then + echo "Line Analyze buffer is not empty" >&2 + exit 2 + fi + elif [[ "$line" =~ ^\{.*$ ]] || [[ "$line" =~ ^-+$ ]]; then + # skip line + if [ "$analyze_buffer" != "" ]; then + echo "Line Analyze buffer is not empty" >&2 + exit 2 + fi + else + analyze_buffer="${analyze_buffer}${line}" + + if [[ "$analyze_buffer" =~ ^.*\.inf$ ]]; then + analyze_inf_file "$analyze_buffer" + analyze_buffer="" + fi + + fi + fi + +done <"$REPORT_FILE" + +analyze_inf_file "$BUILD_INF" + +date +%s >"$PSEUDO_DEST_FILE" diff --git a/src/executables/platforms/uefi/meson.build b/src/executables/platforms/uefi/meson.build index 568ea9e4..5ad6f134 100644 --- a/src/executables/platforms/uefi/meson.build +++ b/src/executables/platforms/uefi/meson.build @@ -95,17 +95,31 @@ _uefi_extract_defs = custom_target( ) +_uefi_extract_dep_tree_exe = find_program( + 'extract-dependency-tree.sh', + dirs: [meson.project_source_root() / 'platforms' / 'uefi'], + required: true, +) + +_uefi_dependencies = custom_target( + _uefi_exe_name + '.deps', + command: [_uefi_extract_dep_tree_exe, _uefi_extract_defs, '@OUTPUT@', '@DEPFILE@'], + depends: [_uefi_extract_defs], + depfile: _uefi_exe_name + '.depfile.deps', + output: [_uefi_exe_name + '.pseudo.deps'], + build_by_default: false, +) + _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], + depends: [_uefi_extract_defs, _uefi_dependencies], output: [_uefi_exe_name + '.efi'], build_by_default: true, ) From e13046e6ab946d4d90b464c6eb6da91f7ee24924 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 4 Sep 2026 20:18:20 +0200 Subject: [PATCH 139/143] feat: correctly add the dependencies for the final build artifact - use correct syntax and use it for correct target --- platforms/uefi/compile-final.sh | 158 ++++++++++++++++++- platforms/uefi/extract-dependency-tree.sh | 173 --------------------- src/executables/platforms/uefi/meson.build | 21 +-- 3 files changed, 160 insertions(+), 192 deletions(-) delete mode 100755 platforms/uefi/extract-dependency-tree.sh diff --git a/platforms/uefi/compile-final.sh b/platforms/uefi/compile-final.sh index 84084995..9de55698 100755 --- a/platforms/uefi/compile-final.sh +++ b/platforms/uefi/compile-final.sh @@ -12,9 +12,11 @@ SCRIPT_DIR="$(realpath "$(dirname -- "${BASH_SOURCE[0]}")")" # shellcheck source=./platforms/helper.sh source "$SCRIPT_DIR/../helper.sh" -if [ "$#" -eq 2 ]; then +if [ "$#" -eq 3 ]; then BUILD_INF="$(realpath "$1")" DEST_FILE="$(realpath "$2")" + DEST_FILE_ORIG="$2" + DEPS_DEST_FILE="$(realpath "$3")" else echo "Too many arguments given, expected 2" >&2 exit 1 @@ -52,6 +54,160 @@ else fi fi +# dep file generation + +escape_filename_for_ninja_depfile() { + local NAME="$1" + + NAME=${NAME//\\/\\\\} # backslash + NAME=${NAME// /\\ } # spaces + NAME=${NAME//#/\\#} # # + NAME=${NAME//$/\$\$} # $ + printf '%s' "$NAME" + +} + +add_dep_file() { + local FILE="$1" + + if ! [ -e "$FILE" ]; then + echo "Dependency file doesn't exist: '$FILE'" >&2 + exit 2 + fi + + echo -n "$(escape_filename_for_ninja_depfile "${FILE}") " >>"$DEPS_DEST_FILE" + +} + +analyze_inf_file() { + local INF_FILE="$1" + + # add inf file + add_dep_file "$INF_FILE" + + # add sources + + local PARENT_FOLDER="$(dirname "$INF_FILE")" + + local sources + + mapfile -t sources < <( + awk ' + /^\[Sources\]/ { in_sources=1; next } + /^\[/ { in_sources=0 } + in_sources { + gsub(/^[[:space:]]+|[[:space:]]+$/, "") + if ($0 != "" && $0 !~ /^#/) + print + } + ' "$INF_FILE" + ) + + for SRC in "${sources[@]}"; do + + if [[ "${SRC:0:1}" != "/" ]]; then + SRC="${PARENT_FOLDER}/${SRC}" + fi + + if [[ "$SRC" =~ ^.*\$\(OPENSSL_PATH\).*$ ]]; then + SRC="${SRC//\$(OPENSSL_PATH)/openssl}" + fi + + if [[ "$SRC" =~ ^.*\$\(OPENSSL_GEN_PATH\).*$ ]]; then + SRC="${SRC//\$(OPENSSL_GEN_PATH)/OpensslGen}" + fi + + if [[ "$SRC" =~ ^.*\|.*$ ]]; then + SRC="${SRC%%|*}" + fi + + if [[ "$SRC" =~ ^.*#.*$ ]]; then + SRC="${SRC%%#*}" + fi + + SRC="${SRC%"${SRC##*[![:space:]]}"}" + + add_dep_file "$SRC" + + done + +} + +REPORT_FILE="$WORKSPACE/BuildReport.txt" + +# generate build report +"$EDK2_BUILD_COMMAND" -a "$EDK2_TARGET_PROPERTIES_ARCH" \ + -p "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" \ + -m "$BUILD_NAME" \ + -b "$EDK2_TARGET_PROPERTIES_BUILDTYPE" \ + -t "$EDK2_TARGET_PROPERTIES_TOOLCHAIN" \ + -D "OOPETRIS_RUNTIME_TARGET=$EDK2_TARGET_PROPERTIES_RUNTIME_TARGET" \ + -n 0 \ + -w \ + -Y PCD \ + -Y LIBRARY \ + -Y FLASH \ + -Y DEPEX \ + -Y BUILD_FLAGS \ + -Y FIXED_ADDRESS \ + -Y HASH \ + -Y EXECUTION_ORDER \ + -Y COMPILE_INFO \ + -y "$REPORT_FILE" + +# analyze dependencies + +rm -f "$DEPS_DEST_FILE" +validate_parent_dir "$DEPS_DEST_FILE" +echo -n "$(escape_filename_for_ninja_depfile "${DEST_FILE_ORIG}"): " >"$DEPS_DEST_FILE" + +line="" + +analyze_state="unknown" +analyze_buffer="" + +while IFS="" read -r line; do + + if [ "$analyze_state" == "unknown" ]; then + if [[ "$line" =~ ^\>-+\<$ ]]; then + analyze_state="line" + fi + elif [ "$analyze_state" == "line" ]; then + if [[ "$line" == "Library" ]]; then + analyze_state="libs" + else + analyze_state="unknown" + fi + elif [ "$analyze_state" == "libs" ]; then + if [[ "$line" =~ ^\<-+\>$ ]]; then + analyze_state="unknown" + if [ "$analyze_buffer" != "" ]; then + echo "Line Analyze buffer is not empty" >&2 + exit 2 + fi + elif [[ "$line" =~ ^\{.*$ ]] || [[ "$line" =~ ^-+$ ]]; then + # skip line + if [ "$analyze_buffer" != "" ]; then + echo "Line Analyze buffer is not empty" >&2 + exit 2 + fi + else + analyze_buffer="${analyze_buffer}${line}" + + if [[ "$analyze_buffer" =~ ^.*\.inf$ ]]; then + analyze_inf_file "$analyze_buffer" + analyze_buffer="" + fi + + fi + fi + +done <"$REPORT_FILE" + +analyze_inf_file "$BUILD_INF" + +# final build + "$EDK2_BUILD_COMMAND" -a "$EDK2_TARGET_PROPERTIES_ARCH" \ -p "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" \ -m "$BUILD_NAME" \ diff --git a/platforms/uefi/extract-dependency-tree.sh b/platforms/uefi/extract-dependency-tree.sh deleted file mode 100755 index 3f99903c..00000000 --- a/platforms/uefi/extract-dependency-tree.sh +++ /dev/null @@ -1,173 +0,0 @@ -#!/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 - BUILD_INF="$(realpath "$1")" - PSEUDO_DEST_FILE="$(realpath "$2")" - DEPS_DEST_FILE="$(realpath "$3")" -else - echo "Too many arguments given, expected 3" >&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_TOOLS_DIR="$(jq -M -r -c '.["edk2_tools_dir"]' "$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")" -EDK2_TARGET_PROPERTIES_RUNTIME_TARGET="$(jq -M -r -c '.["runtime_target"]' "$UEFI_INFO_FILE")" - -BUILD_NAME=$(basename -- $"$BUILD_INF") - -BUILD_FILE_TARGET="GeneratedPackages/$BUILD_NAME" - -BUILD_FILE_TARGET_ABS="$EDK2_TOOLS_DIR/$BUILD_FILE_TARGET" - -if ! [ -e "$BUILD_FILE_TARGET_ABS" ]; then - echo "Build file is not in the expected place: $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 - -analyze_inf_file() { - local INF_FILE="$1" - - # add inf file - cat <>"$DEPS_DEST_FILE" -$INF_FILE -EOF - - # add sources - - local PARENT_FOLDER="$(dirname "$INF_FILE")" - - local sources - - mapfile -t sources < <( - awk ' - /^\[Sources\]/ { in_sources=1; next } - /^\[/ { in_sources=0 } - in_sources { - gsub(/^[[:space:]]+|[[:space:]]+$/, "") - if ($0 != "" && $0 !~ /^#/) - print - } - ' "$INF_FILE" - ) - - for SRC in "${sources[@]}"; do - - if [[ "${SRC:0:1}" != "/" ]]; then - SRC="${PARENT_FOLDER}/${SRC}" - fi - - if [[ "$SRC" =~ ^.*\$\(OPENSSL_PATH\).*$ ]]; then - SRC="${SRC//\$(OPENSSL_PATH)/openssl}" - fi - - cat <>"$DEPS_DEST_FILE" -$SRC -EOF - - done - -} - -REPORT_FILE="$WORKSPACE/BuildReport.txt" - -# generate build report -"$EDK2_BUILD_COMMAND" -a "$EDK2_TARGET_PROPERTIES_ARCH" \ - -p "$EDK2_TARGET_PROPERTIES_ACTIVE_PLATFORM" \ - -m "$BUILD_NAME" \ - -b "$EDK2_TARGET_PROPERTIES_BUILDTYPE" \ - -t "$EDK2_TARGET_PROPERTIES_TOOLCHAIN" \ - -D "OOPETRIS_RUNTIME_TARGET=$EDK2_TARGET_PROPERTIES_RUNTIME_TARGET" \ - -n 0 \ - -w \ - -Y PCD \ - -Y LIBRARY \ - -Y FLASH \ - -Y DEPEX \ - -Y BUILD_FLAGS \ - -Y FIXED_ADDRESS \ - -Y HASH \ - -Y EXECUTION_ORDER \ - -Y COMPILE_INFO \ - -y "$REPORT_FILE" - -# analyze dependencies - -rm -f "$DEPS_DEST_FILE" -validate_parent_dir "$DEPS_DEST_FILE" -touch "$DEPS_DEST_FILE" - -line="" - -analyze_state="unknown" -analyze_buffer="" - -while IFS="" read -r line; do - - if [ "$analyze_state" == "unknown" ]; then - if [[ "$line" =~ ^\>-+\<$ ]]; then - analyze_state="line" - fi - elif [ "$analyze_state" == "line" ]; then - if [[ "$line" == "Library" ]]; then - analyze_state="libs" - else - analyze_state="unknown" - fi - elif [ "$analyze_state" == "libs" ]; then - if [[ "$line" =~ ^\<-+\>$ ]]; then - analyze_state="unknown" - if [ "$analyze_buffer" != "" ]; then - echo "Line Analyze buffer is not empty" >&2 - exit 2 - fi - elif [[ "$line" =~ ^\{.*$ ]] || [[ "$line" =~ ^-+$ ]]; then - # skip line - if [ "$analyze_buffer" != "" ]; then - echo "Line Analyze buffer is not empty" >&2 - exit 2 - fi - else - analyze_buffer="${analyze_buffer}${line}" - - if [[ "$analyze_buffer" =~ ^.*\.inf$ ]]; then - analyze_inf_file "$analyze_buffer" - analyze_buffer="" - fi - - fi - fi - -done <"$REPORT_FILE" - -analyze_inf_file "$BUILD_INF" - -date +%s >"$PSEUDO_DEST_FILE" diff --git a/src/executables/platforms/uefi/meson.build b/src/executables/platforms/uefi/meson.build index 5ad6f134..4e317760 100644 --- a/src/executables/platforms/uefi/meson.build +++ b/src/executables/platforms/uefi/meson.build @@ -94,22 +94,6 @@ _uefi_extract_defs = custom_target( build_by_default: true, ) - -_uefi_extract_dep_tree_exe = find_program( - 'extract-dependency-tree.sh', - dirs: [meson.project_source_root() / 'platforms' / 'uefi'], - required: true, -) - -_uefi_dependencies = custom_target( - _uefi_exe_name + '.deps', - command: [_uefi_extract_dep_tree_exe, _uefi_extract_defs, '@OUTPUT@', '@DEPFILE@'], - depends: [_uefi_extract_defs], - depfile: _uefi_exe_name + '.depfile.deps', - output: [_uefi_exe_name + '.pseudo.deps'], - build_by_default: false, -) - _uefi_compile_final_exe = find_program( 'compile-final.sh', dirs: [meson.project_source_root() / 'platforms' / 'uefi'], @@ -118,8 +102,9 @@ _uefi_compile_final_exe = find_program( oopetris_efi = custom_target( _uefi_exe_name + '.efi', - command: [_uefi_compile_final_exe, _uefi_extract_defs, '@OUTPUT@'], - depends: [_uefi_extract_defs, _uefi_dependencies], + command: [_uefi_compile_final_exe, _uefi_extract_defs, '@OUTPUT@', '@DEPFILE@'], + depends: [_uefi_extract_defs], + depfile: _uefi_exe_name + '.efi.deps', output: [_uefi_exe_name + '.efi'], build_by_default: true, ) From 11fee17754d9098702a89135183d2cb06160890b Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 4 Sep 2026 21:15:32 +0200 Subject: [PATCH 140/143] feat: use std::mutex - use the new C11 implementation of mutexes instead of the custom ones --- src/executables/game/main.cpp | 2 +- src/helper/meson.build | 3 +- src/helper/uefi_futures.cpp | 25 +++++++------ src/helper/uefi_futures.hpp | 4 +- src/helper/uefi_utils.cpp | 53 +-------------------------- src/helper/uefi_utils.hpp | 45 +---------------------- src/helper/uefi_utils_spdlog_sink.cpp | 21 ----------- 7 files changed, 21 insertions(+), 132 deletions(-) delete mode 100644 src/helper/uefi_utils_spdlog_sink.cpp diff --git a/src/executables/game/main.cpp b/src/executables/game/main.cpp index db1bfa40..e6325557 100644 --- a/src/executables/game/main.cpp +++ b/src/executables/game/main.cpp @@ -60,7 +60,7 @@ namespace { #elif defined(__UEFI__) sinks.push_back(uefi::get_debug_sink()); // is outputted to serial, handled by edk2-libc - sinks.push_back(std::make_shared(spdlog::color_mode::never)); + sinks.push_back(std::make_shared(spdlog::color_mode::never)); #elif defined(__EMSCRIPTEN__) sinks.push_back(web::get_console_sink()); #else diff --git a/src/helper/meson.build b/src/helper/meson.build index d279b7c6..f5572185 100644 --- a/src/helper/meson.build +++ b/src/helper/meson.build @@ -19,8 +19,7 @@ if meson.is_cross_build() and host_machine.system() == 'uefi' 'uefi_futures.cpp', 'uefi_futures.hpp', 'uefi_utils.cpp', - 'uefi_utils.hpp', - 'uefi_utils_spdlog_sink.cpp', + 'uefi_utils.hpp' ) elif meson.is_cross_build() and host_machine.system() == 'emscripten' graphics_src_files += files( diff --git a/src/helper/uefi_futures.cpp b/src/helper/uefi_futures.cpp index 3bea9aae..7be80275 100644 --- a/src/helper/uefi_futures.cpp +++ b/src/helper/uefi_futures.cpp @@ -4,6 +4,7 @@ extern "C" { #include #include +#include } details::MainCPUState* details::__cpu_state = nullptr; @@ -13,16 +14,16 @@ static UINTN my_cpu_id_impl(EFI_MP_SERVICES_PROTOCOL* Mp) { ASSERT(Mp); - UINTN BspNumber; + UINTN CpuNUmber; - EFI_STATUS Status = Mp->WhoAmI(Mp, &BspNumber); + EFI_STATUS Status = Mp->WhoAmI(Mp, &CpuNUmber); if (EFI_ERROR(Status)) { EFI_DEBUG((DEBUG_ERROR, "ERROR: couldn't execute WhoAmI: %r\n", Status)); abort(); } - return BspNumber; + return CpuNUmber; } @@ -64,7 +65,7 @@ static details::SecondaryCPUState* __impl_get_cpu_state_by_id(UINTN cpu_id) { static void __impl_uefi_thread_abort_signal_handler(int actual_signal) { //TODO: assert actual_signal == SIGABRT - const std::lock_guard scope_lock(details::__cpu_state->signal_state.mutex); + const std::lock_guard scope_lock(details::__cpu_state->signal_state.mutex); UINTN cpu_id = details::my_cpu_id(); @@ -102,8 +103,11 @@ void details::init_cpu_state() { return; } - __cpu_state = - new details::MainCPUState(nullptr, 0, 0, std::vector{}, GlobalSignalState{ nullptr }); + __cpu_state = new details::MainCPUState( + nullptr, 0, 0, std::vector{}, GlobalSignalState{ nullptr, {} } + ); + + efi_threads_init(); if (!gBS) { @@ -137,8 +141,7 @@ void details::init_cpu_state() { //TODO: inline this in start_detached_thread - - __cpu_state->signal_state = GlobalSignalState{ old_sig_handler, {} }; + __cpu_state->signal_state.old_sig_handler = old_sig_handler; __cpu_state->cpus = std::vector{}; __cpu_state->cpus.reserve(__cpu_state->NumberOfProcessors - 1); @@ -240,7 +243,7 @@ struct details::DetachedThreadStateImpl { details::SecondaryCPUState* cpu_to_execute_on_ref; // mutex to protect state, that can be used by the AP (when writing the result) and the BSP (when using poll) - uefi::helper::ThreadMutex data_mutex; + std::mutex data_mutex; DetachedThreadStateImpl(ThreadInfo* info_ref, details::SecondaryCPUState* cpu_to_execute_on_ref) : DoneEvent{}, @@ -253,7 +256,7 @@ struct details::DetachedThreadStateImpl { } void terminate(std::optional error) { - const std::lock_guard scope_lock(this->data_mutex); + const std::lock_guard scope_lock(this->data_mutex); this->run_state = { true, error }; } @@ -264,7 +267,7 @@ struct details::DetachedThreadStateImpl { } details::thread_state poll(void) { - const std::lock_guard scope_lock(this->data_mutex); + const std::lock_guard scope_lock(this->data_mutex); if (this->run_state.first) { return details::thread_state::running; diff --git a/src/helper/uefi_futures.hpp b/src/helper/uefi_futures.hpp index b7af1038..69c2ca84 100644 --- a/src/helper/uefi_futures.hpp +++ b/src/helper/uefi_futures.hpp @@ -21,13 +21,13 @@ extern "C" { #include } +#include "./uefi_utils.hpp" #include #include #include #include #include #include -#include "./uefi_utils.hpp" //COPY from oopetris, to make this header more independent @@ -58,7 +58,7 @@ namespace details { struct GlobalSignalState { __sighandler_t* old_sig_handler; - uefi::helper::ThreadMutex mutex; + std::mutex mutex; }; struct MainCPUState { diff --git a/src/helper/uefi_utils.cpp b/src/helper/uefi_utils.cpp index 1fa0aa87..fb0503b5 100644 --- a/src/helper/uefi_utils.cpp +++ b/src/helper/uefi_utils.cpp @@ -17,8 +17,8 @@ extern "C" { } -std::shared_ptr uefi::get_debug_sink() { - return std::make_shared([](const spdlog::details::log_msg& msg) { +std::shared_ptr uefi::get_debug_sink() { + return std::make_shared([](const spdlog::details::log_msg& msg) { const std::string message = std::string{ msg.payload.begin(), msg.payload.end() }; @@ -46,55 +46,6 @@ std::shared_ptr uefi::get_debug_sink() { } -uefi::helper::ThreadMutex::ThreadMutex() noexcept : locked{ 0 } { - // -} - -uefi::helper::ThreadMutex::ThreadMutex(ThreadMutex&& other) noexcept : locked{ 0 } { - ASSERT(!other.locked); - - other.locked = 0; -} - -uefi::helper::ThreadMutex& uefi::helper::ThreadMutex::operator=(ThreadMutex&& other) noexcept { - ASSERT(!other.locked); - - this->locked = other.locked; - other.locked = 0; - - return *this; -} - -uefi::helper::ThreadMutex::~ThreadMutex() noexcept { - ASSERT(!this->locked); -} - -//TODO: use this as kibc mutex, implement std::mutex with this and so the libc and libcxx has correct mutexes! -// but should i use spinlocks or atomics here? -// also this doesn't depend on oopetris specific things, so its possible -void uefi::helper::ThreadMutex::lock() { - while (InterlockedCompareExchange32( - &(this->locked), - 0, // Compare: unlocked - 1 // Exchange: locked - ) - != 0) { - // - // Someone else owns it. - // - CpuPause(); - } -} - -void uefi::helper::ThreadMutex::unlock() { - - InterlockedCompareExchange32( - &(this->locked), - 1, // Compare: locked - 0 // Exchange: unlocked - ); -} - [[nodiscard]] std::string uefi::map_efi_status_to_string(EFI_STATUS status) { switch (status) { diff --git a/src/helper/uefi_utils.hpp b/src/helper/uefi_utils.hpp index 923dc6a2..144dd366 100644 --- a/src/helper/uefi_utils.hpp +++ b/src/helper/uefi_utils.hpp @@ -12,7 +12,6 @@ #include "helper/spdlog_wrapper.hpp" #include -#include #include #include @@ -22,49 +21,7 @@ namespace uefi { - namespace helper { - - //TODO: we could use a c++ wrapper of the SPIN_LOCK from "SynchronizationLib.h" instead, or is that not atomic? - struct ThreadMutex { - private: - volatile UINT32 locked; - - public: - ThreadMutex() noexcept; - - ThreadMutex(const ThreadMutex& other) = delete; - ThreadMutex& operator=(const ThreadMutex& other) = delete; - - ThreadMutex(ThreadMutex&& other) noexcept; - ThreadMutex& operator=(ThreadMutex&& other) noexcept; - - ~ThreadMutex() noexcept; - - void lock(); - void unlock(); - }; - - } // namespace helper - - namespace spdlog_helper { - using callback_sink = spdlog::sinks::callback_sink; - - namespace details { - struct console_mutex { - using mutex_t = uefi::helper::ThreadMutex; - static mutex_t& mutex() { - static mutex_t s_mutex; - return s_mutex; - } - }; - } // namespace details - - using stdout_color_sink = spdlog::sinks::ansicolor_stdout_sink; - using stderr_color_sink = spdlog::sinks::ansicolor_stderr_sink; - } // namespace spdlog_helper - - - [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::shared_ptr get_debug_sink(); + [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::shared_ptr get_debug_sink(); [[nodiscard]] OOPETRIS_GRAPHICS_EXPORTED std::string map_efi_status_to_string(EFI_STATUS status); diff --git a/src/helper/uefi_utils_spdlog_sink.cpp b/src/helper/uefi_utils_spdlog_sink.cpp deleted file mode 100644 index a998639b..00000000 --- a/src/helper/uefi_utils_spdlog_sink.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) - -#ifndef SPDLOG_COMPILED_LIB -#error Please define SPDLOG_COMPILED_LIB to compile this file. -#endif - -#include - -#include -#include - -#include - -#include "./uefi_utils.hpp" - -// instantiate the sink template for this mutex -template class SPDLOG_API spdlog::sinks::base_sink; - -template class SPDLOG_API spdlog::sinks::ansicolor_stdout_sink; -template class SPDLOG_API spdlog::sinks::ansicolor_stderr_sink; From c9244c518dab113b66c0641d133810e20134fdeb Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 4 Sep 2026 22:01:53 +0200 Subject: [PATCH 141/143] feat: fix uefi linking wirh c-embed (it has no tls (yet)) --- src/helper/uefi_utils.cpp | 24 +++++++++---------- subprojects/c-embed.wrap | 2 +- .../packagefiles/c-embed-thread-local.diff | 22 +++++++++++++++++ 3 files changed, 35 insertions(+), 13 deletions(-) create mode 100644 subprojects/packagefiles/c-embed-thread-local.diff diff --git a/src/helper/uefi_utils.cpp b/src/helper/uefi_utils.cpp index fb0503b5..7b6415a0 100644 --- a/src/helper/uefi_utils.cpp +++ b/src/helper/uefi_utils.cpp @@ -482,19 +482,19 @@ __dtor__rom_fs(void) { void uefi::platform_init() { - // auto status = __ctor_rom_fs(); - // if (EFI_ERROR(status)) { - // utils::throw_( - // std::runtime_error{ fmt::format("can't initialize ROM fs: {}", map_efi_status_to_string(status)) } - // ); - // } + auto status = __ctor_rom_fs(); + if (EFI_ERROR(status)) { + utils::throw_( + std::runtime_error{ fmt::format("can't initialize ROM fs: {}", map_efi_status_to_string(status)) } + ); + } } void uefi::platform_exit() { - // auto status = __dtor__rom_fs(); - // if (EFI_ERROR(status)) { - // utils::throw_( - // std::runtime_error{ fmt::format("can't deinitialize ROM fs: {}", map_efi_status_to_string(status)) } - // ); - // } + auto status = __dtor__rom_fs(); + if (EFI_ERROR(status)) { + utils::throw_( + std::runtime_error{ fmt::format("can't deinitialize ROM fs: {}", map_efi_status_to_string(status)) } + ); + } } diff --git a/subprojects/c-embed.wrap b/subprojects/c-embed.wrap index 204f9b25..e0bc0524 100644 --- a/subprojects/c-embed.wrap +++ b/subprojects/c-embed.wrap @@ -3,7 +3,7 @@ url = https://github.com/weigert/c-embed.git revision = main depth = 1 patch_directory = c-embed -diff_files = c-embed-system-checked.diff +diff_files = c-embed-system-checked.diff, c-embed-thread-local.diff [provide] diff --git a/subprojects/packagefiles/c-embed-thread-local.diff b/subprojects/packagefiles/c-embed-thread-local.diff new file mode 100644 index 00000000..997e0d92 --- /dev/null +++ b/subprojects/packagefiles/c-embed-thread-local.diff @@ -0,0 +1,22 @@ +diff --git a/c-embed.h b/c-embed.h +index cf365b8..767d5ca 100644 +--- a/c-embed.h ++++ b/c-embed.h +@@ -46,7 +46,16 @@ typedef struct EFILE_S EFILE; + + // Error Handling + +-__thread int eerrcode = 0; ++#if defined(__UEFI__) ++#define THREAD_LOCAL ++#else ++#define THREAD_LOCAL __thread ++#endif ++ ++ ++THREAD_LOCAL int eerrcode = 0; ++ ++ + #define ethrow(err) { (eerrcode = (err)); return NULL; } + #define eerrno (eerrcode) + From 46b7f1ada7b395298ed8168689deed2f631fc9de Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 4 Sep 2026 22:50:56 +0200 Subject: [PATCH 142/143] feat: fix c-embed again --- src/helper/uefi_futures.cpp | 4 +- src/helper/uefi_utils.cpp | 119 ++++++++++++-- .../packagefiles/c-embed-relative_root.diff | 152 ++++++++++++++++++ 3 files changed, 256 insertions(+), 19 deletions(-) create mode 100644 subprojects/packagefiles/c-embed-relative_root.diff diff --git a/src/helper/uefi_futures.cpp b/src/helper/uefi_futures.cpp index 7be80275..1e92aae8 100644 --- a/src/helper/uefi_futures.cpp +++ b/src/helper/uefi_futures.cpp @@ -223,8 +223,8 @@ struct ThreadLocalState { ThreadLocalState(const ThreadLocalState& other) = delete; ThreadLocalState& operator=(const ThreadLocalState& other) = delete; - ThreadLocalState(ThreadLocalState&& other) noexcept; - ThreadLocalState& operator=(ThreadLocalState&& other) noexcept; + ThreadLocalState(ThreadLocalState&& other) noexcept = delete; + ThreadLocalState& operator=(ThreadLocalState&& other) noexcept = delete; ~ThreadLocalState() { diff --git a/src/helper/uefi_utils.cpp b/src/helper/uefi_utils.cpp index 7b6415a0..094afcc5 100644 --- a/src/helper/uefi_utils.cpp +++ b/src/helper/uefi_utils.cpp @@ -184,6 +184,8 @@ static int EFIAPI _f_romfs_Delete(struct __filedes* filp) { return -1; } +[[nodiscard]] static int eerrno_to_errno(int eerrno); + /** EFI specific operations for setting the position within a file. @param[in] filp Pointer to a file descriptor structure. @@ -199,7 +201,7 @@ static off_t EFIAPI _f_romfs_Seek(struct __filedes* filp, off_t offset, int when int result = eseek(file, offset, whence); if (result != 0) { - errno = eerrno; + errno = eerrno_to_errno(eerrno); return EOF; } @@ -312,6 +314,81 @@ static int EFIAPI _f_romfs_Ioctl(struct __filedes* filp, ULONGN cmd, va_list arg return -1; } + +struct PathConversion { +private: + const wchar_t* m_original; + char* m_converted; + +public: + PathConversion(const wchar_t* value, char* converted) : m_original{ value }, m_converted{ converted } { + // + } + + static std::optional init(const wchar_t* value) { + char* converted = (char*) AllocateZeroPool(PATH_MAX + 1); + if (converted == NULL) { + DEBUG((DEBUG_ERROR, "%a %a:%d: IN PathConversion::init %s\n", __func__, __FILE__, __LINE__, value)); + errno = ENOMEM; + return std::nullopt; + } + + size_t convert_result = wcstombs(converted, value, PATH_MAX); + + if (convert_result == ((size_t) -1) || convert_result > PATH_MAX) { + DEBUG((DEBUG_ERROR, "%a %a:%d: IN PathConversion::init %s\n", __func__, __FILE__, __LINE__, value)); + errno = EINVAL; + return std::nullopt; + } + + converted[convert_result] = '\0'; + + // replace "\" with "/" for c-embed + + for (size_t i = 0; i < convert_result; ++i) { + if (converted[i] == '\\') { + converted[i] = '/'; + } + } + + + return PathConversion(value, converted); + } + + PathConversion(const PathConversion& other) = delete; + PathConversion& operator=(const PathConversion& other) = delete; + + + PathConversion(PathConversion&& other) noexcept : m_original{ other.m_original }, m_converted{ other.m_converted } { + other.m_original = nullptr; + other.m_converted = nullptr; + } + + PathConversion& operator=(PathConversion&& other) noexcept { + if (this != &other) { + this->m_original = other.m_original; + this->m_converted = other.m_converted; + + other.m_original = nullptr; + other.m_converted = nullptr; + } + + return *this; + } + + + [[nodiscard]] char* path() const { + return m_converted; + } + + ~PathConversion() { + if (m_converted != nullptr) { + FreePool(m_converted); + m_converted = nullptr; + } + } +}; + /** EFI specific operations for opening a file. @param[in] DevNode Pointer to the Device control structure for this stream. @@ -337,35 +414,25 @@ int EFIAPI _f_romfs_Open( return -1; } - char* strPath = (char*) AllocateZeroPool(PATH_MAX); - if (strPath == NULL) { - DEBUG((DEBUG_ERROR, "%a %a:%d: IN OPEN %s\n", __func__, __FILE__, __LINE__, Path)); - errno = ENOMEM; - return -1; - } - size_t convert_result = wcstombs(strPath, Path, PATH_MAX); + std::optional conversion = PathConversion::init(Path); - if (convert_result == ((size_t) -1) || convert_result > PATH_MAX) { - DEBUG((DEBUG_ERROR, "%a %a:%d: IN OPEN %s\n", __func__, __FILE__, __LINE__, Path)); - errno = EINVAL; + if (not conversion.has_value()) { return -1; } - DEBUG((DEBUG_ERROR, "%a %a:%d: path: %a\n", __func__, __FILE__, __LINE__, strPath)); + DEBUG((DEBUG_ERROR, "%a %a:%d: path: %a\n", __func__, __FILE__, __LINE__, conversion->path())); // Call the EFI's Open function - EFILE* file = eopen(strPath, "r"); + EFILE* file = eopen(conversion->path(), "r"); if (file == NULL) { filp->f_iflags = 0; // Release our reservation on this FD // Set errno based upon Status - errno = eerrno; - DEBUG((DEBUG_ERROR, "%a %a:%d: IN OPEN %s\n", __func__, __FILE__, __LINE__, Path)); - FreePool(strPath); + errno = eerrno_to_errno(eerrno); + DEBUG((DEBUG_ERROR, "%a %a:%d: IN OPEN %s: errno -> %a\n", __func__, __FILE__, __LINE__, Path, eerrstr(eerrno))); return -1; } - FreePool(strPath); // Successfully got a regular File (note c-embed doesnÄt support to open directories) filp->f_iflags |= S_IFREG; @@ -471,6 +538,24 @@ __ctor_rom_fs(void) { } +[[nodiscard]] static int eerrno_to_errno(int eerrno) { + switch (eerrno) { + case EERRCODE_SUCCESS: + return 0; + case EERRCODE_NOFILE: + return ENOENT; + case EERRCODE_NOMAP: + return ENODEV; + case EERRCODE_NULLSTREAM: + return EINVAL; + case EERRCODE_OOBSTREAMPOS: + return EINVAL; + default: + return EINVAL; + }; +} + + RETURN_STATUS EFIAPI __dtor__rom_fs(void) { diff --git a/subprojects/packagefiles/c-embed-relative_root.diff b/subprojects/packagefiles/c-embed-relative_root.diff new file mode 100644 index 00000000..1eae5576 --- /dev/null +++ b/subprojects/packagefiles/c-embed-relative_root.diff @@ -0,0 +1,152 @@ +diff --git a/c-embed.c b/c-embed.c +index e233d4a..2b34a7e 100644 +--- a/c-embed.c ++++ b/c-embed.c +@@ -23,16 +23,36 @@ FILE* fs = NULL; // Virtual Filesystem + FILE* file = NULL; // Embed Target File Pointer + u_int32_t pos = 0; // Current Position + +-void cembed(char* filename){ ++void cembed(const char* const filename, const char* root_dir){ + + file = fopen(filename, "rb"); // Open the Embed Target File + if(file == NULL){ + printf("Failed to open file %s.", filename); + return; + } ++ u_int32_t filename_hash = hash(filename); ++ ++ if(root_dir != NULL){ ++ ++ const char* filename_relative = filename; ++ const size_t filename_len = strlen(filename); ++ const size_t root_len = strlen(root_dir); ++ if(filename_len < root_len){ ++ fprintf(stderr, "Invalid file root: %s\n",root_dir); ++ exit(2); ++ } ++ for(size_t i = 0; i < root_len; ++i){ ++ if(filename[i] == root_dir[i]){ ++ filename_relative++; ++ } ++ } ++ ++ filename_hash = hash(filename_relative); ++ } ++ + + fseek(file, 0, SEEK_END); // Define Map +- EMAP map = {hash(filename), pos, (u_int32_t)ftell(file)}; ++ EMAP map = {filename_hash, pos, (u_int32_t)ftell(file)}; + rewind (file); + + char* buf = malloc(sizeof(char)*(map.size)); +@@ -61,14 +81,15 @@ void cembed(char* filename){ + #define CEMBED_DIRENT_DIR 4 + #define CEMBED_MAXPATH 512 + +-void iterdir(char* d){ ++void iterdir(const char* const d, const char* root_dir){ + + char* fullpath = (char*)malloc(CEMBED_MAXPATH*sizeof(char)); + + DIR *dir; + struct dirent *ent; +- +- if ((dir = opendir(d)) != NULL) { ++ dir = opendir(d); ++ ++ if (dir != NULL) { + + while ((ent = readdir(dir)) != NULL) { + +@@ -79,14 +100,14 @@ void iterdir(char* d){ + strcpy(fullpath, d); + strcat(fullpath, "/"); + strcat(fullpath, ent->d_name); +- cembed(fullpath); ++ cembed(fullpath, root_dir); + } + + else if(ent->d_type == CEMBED_DIRENT_DIR){ + strcpy(fullpath, d); + strcat(fullpath, "/"); + strcat(fullpath, ent->d_name); +- iterdir(fullpath); ++ iterdir(fullpath, root_dir); + } + + } +@@ -98,7 +119,7 @@ void iterdir(char* d){ + else { + + strcpy(fullpath, d); +- cembed(fullpath); ++ cembed(fullpath, root_dir); + + } + +@@ -106,6 +127,28 @@ void iterdir(char* d){ + + } + ++static bool is_directory(const char* file){ ++ DIR *dir = opendir(file); ++ if (dir != NULL) { ++ closedir(dir); ++ return true; ++ } ++ ++ return false; ++} ++ ++static void iterdir_start(const char* const d){ ++ ++ if(is_directory(d)){ ++ iterdir(d, d); ++ return; ++ } ++ ++ iterdir(d, NULL); ++ ++ ++} ++ + void system_checked(const char *command){ + + int result = system(command); +@@ -123,8 +166,10 @@ int main(int argc, char* argv[]){ + + char fmt[CEMBED_MAXPATH]; + +- if(argc <= 1) +- return 0; ++ if(argc <= 1){ ++ fprintf(stderr, "Invalid amount of arguments: %d\n", argc); ++ return 1; ++ } + + sprintf(fmt, "if [ ! -d %s ]; then mkdir %s; fi;", CEMBED_TMPDIR, CEMBED_TMPDIR); + system(fmt); +@@ -140,7 +185,7 @@ int main(int argc, char* argv[]){ + } + + for(int i = 1; i < argc; i++) +- iterdir(argv[i]); ++ iterdir_start(argv[i]); + + fclose(ms); + fclose(fs); +diff --git a/c-embed.h b/c-embed.h +index 767d5ca..b6a6ba8 100644 +--- a/c-embed.h ++++ b/c-embed.h +@@ -17,7 +17,7 @@ + #include + #include + +-u_int32_t hash(char * key){ // Hash Function: MurmurOAAT64 ++u_int32_t hash(const char * key){ // Hash Function: MurmurOAAT64 + u_int32_t h = 3323198485ul; + for (;*key;++key) { + h ^= *key; From 80eaaf0f8c88d673fe1ff24667301a5b786adb02 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 4 Sep 2026 23:44:40 +0200 Subject: [PATCH 143/143] feat: use forked c-embed, as i don't want to add too many patches --- platforms/uefi/c-embed-wrapper.sh | 4 +- subprojects/c-embed.wrap | 7 +- .../packagefiles/c-embed-relative_root.diff | 152 ------------------ .../packagefiles/c-embed-system-checked.diff | 24 --- .../packagefiles/c-embed-thread-local.diff | 22 --- subprojects/packagefiles/c-embed/meson.build | 39 ----- 6 files changed, 4 insertions(+), 244 deletions(-) delete mode 100644 subprojects/packagefiles/c-embed-relative_root.diff delete mode 100644 subprojects/packagefiles/c-embed-system-checked.diff delete mode 100644 subprojects/packagefiles/c-embed-thread-local.diff delete mode 100644 subprojects/packagefiles/c-embed/meson.build diff --git a/platforms/uefi/c-embed-wrapper.sh b/platforms/uefi/c-embed-wrapper.sh index bd5898f7..822c1856 100755 --- a/platforms/uefi/c-embed-wrapper.sh +++ b/platforms/uefi/c-embed-wrapper.sh @@ -28,8 +28,6 @@ else exit 1 fi -"$C_EMBED_EXE" "$INPUT_FOLDER" - PARENT_DIR="$(dirname "$OUTPUT_FILE")" if [[ ! -d "$PARENT_DIR" ]]; then @@ -38,6 +36,8 @@ fi REAL_O_FILE="$PARENT_DIR/c-embed_compiled.o" +"$C_EMBED_EXE" -r -a elf64-x86-64 -o "$REAL_O_FILE" "$INPUT_FOLDER" + mv "./c-embed.o" "$REAL_O_FILE" # create a "extern_object" json description for the automatic inf creation process to generate the inf for this file, as if it was compiled via the edk2 toolchain, but it wasn't diff --git a/subprojects/c-embed.wrap b/subprojects/c-embed.wrap index e0bc0524..5b0f798b 100644 --- a/subprojects/c-embed.wrap +++ b/subprojects/c-embed.wrap @@ -1,10 +1,7 @@ [wrap-git] -url = https://github.com/weigert/c-embed.git -revision = main +url = https://github.com/Totto16/c-embed.git +revision = fork depth = 1 -patch_directory = c-embed -diff_files = c-embed-system-checked.diff, c-embed-thread-local.diff - [provide] dependency_names = c-embed diff --git a/subprojects/packagefiles/c-embed-relative_root.diff b/subprojects/packagefiles/c-embed-relative_root.diff deleted file mode 100644 index 1eae5576..00000000 --- a/subprojects/packagefiles/c-embed-relative_root.diff +++ /dev/null @@ -1,152 +0,0 @@ -diff --git a/c-embed.c b/c-embed.c -index e233d4a..2b34a7e 100644 ---- a/c-embed.c -+++ b/c-embed.c -@@ -23,16 +23,36 @@ FILE* fs = NULL; // Virtual Filesystem - FILE* file = NULL; // Embed Target File Pointer - u_int32_t pos = 0; // Current Position - --void cembed(char* filename){ -+void cembed(const char* const filename, const char* root_dir){ - - file = fopen(filename, "rb"); // Open the Embed Target File - if(file == NULL){ - printf("Failed to open file %s.", filename); - return; - } -+ u_int32_t filename_hash = hash(filename); -+ -+ if(root_dir != NULL){ -+ -+ const char* filename_relative = filename; -+ const size_t filename_len = strlen(filename); -+ const size_t root_len = strlen(root_dir); -+ if(filename_len < root_len){ -+ fprintf(stderr, "Invalid file root: %s\n",root_dir); -+ exit(2); -+ } -+ for(size_t i = 0; i < root_len; ++i){ -+ if(filename[i] == root_dir[i]){ -+ filename_relative++; -+ } -+ } -+ -+ filename_hash = hash(filename_relative); -+ } -+ - - fseek(file, 0, SEEK_END); // Define Map -- EMAP map = {hash(filename), pos, (u_int32_t)ftell(file)}; -+ EMAP map = {filename_hash, pos, (u_int32_t)ftell(file)}; - rewind (file); - - char* buf = malloc(sizeof(char)*(map.size)); -@@ -61,14 +81,15 @@ void cembed(char* filename){ - #define CEMBED_DIRENT_DIR 4 - #define CEMBED_MAXPATH 512 - --void iterdir(char* d){ -+void iterdir(const char* const d, const char* root_dir){ - - char* fullpath = (char*)malloc(CEMBED_MAXPATH*sizeof(char)); - - DIR *dir; - struct dirent *ent; -- -- if ((dir = opendir(d)) != NULL) { -+ dir = opendir(d); -+ -+ if (dir != NULL) { - - while ((ent = readdir(dir)) != NULL) { - -@@ -79,14 +100,14 @@ void iterdir(char* d){ - strcpy(fullpath, d); - strcat(fullpath, "/"); - strcat(fullpath, ent->d_name); -- cembed(fullpath); -+ cembed(fullpath, root_dir); - } - - else if(ent->d_type == CEMBED_DIRENT_DIR){ - strcpy(fullpath, d); - strcat(fullpath, "/"); - strcat(fullpath, ent->d_name); -- iterdir(fullpath); -+ iterdir(fullpath, root_dir); - } - - } -@@ -98,7 +119,7 @@ void iterdir(char* d){ - else { - - strcpy(fullpath, d); -- cembed(fullpath); -+ cembed(fullpath, root_dir); - - } - -@@ -106,6 +127,28 @@ void iterdir(char* d){ - - } - -+static bool is_directory(const char* file){ -+ DIR *dir = opendir(file); -+ if (dir != NULL) { -+ closedir(dir); -+ return true; -+ } -+ -+ return false; -+} -+ -+static void iterdir_start(const char* const d){ -+ -+ if(is_directory(d)){ -+ iterdir(d, d); -+ return; -+ } -+ -+ iterdir(d, NULL); -+ -+ -+} -+ - void system_checked(const char *command){ - - int result = system(command); -@@ -123,8 +166,10 @@ int main(int argc, char* argv[]){ - - char fmt[CEMBED_MAXPATH]; - -- if(argc <= 1) -- return 0; -+ if(argc <= 1){ -+ fprintf(stderr, "Invalid amount of arguments: %d\n", argc); -+ return 1; -+ } - - sprintf(fmt, "if [ ! -d %s ]; then mkdir %s; fi;", CEMBED_TMPDIR, CEMBED_TMPDIR); - system(fmt); -@@ -140,7 +185,7 @@ int main(int argc, char* argv[]){ - } - - for(int i = 1; i < argc; i++) -- iterdir(argv[i]); -+ iterdir_start(argv[i]); - - fclose(ms); - fclose(fs); -diff --git a/c-embed.h b/c-embed.h -index 767d5ca..b6a6ba8 100644 ---- a/c-embed.h -+++ b/c-embed.h -@@ -17,7 +17,7 @@ - #include - #include - --u_int32_t hash(char * key){ // Hash Function: MurmurOAAT64 -+u_int32_t hash(const char * key){ // Hash Function: MurmurOAAT64 - u_int32_t h = 3323198485ul; - for (;*key;++key) { - h ^= *key; diff --git a/subprojects/packagefiles/c-embed-system-checked.diff b/subprojects/packagefiles/c-embed-system-checked.diff deleted file mode 100644 index 52e3e0cb..00000000 --- a/subprojects/packagefiles/c-embed-system-checked.diff +++ /dev/null @@ -1,24 +0,0 @@ -diff --git a/c-embed.c b/c-embed.c -index bdcec8d..e233d4a 100644 ---- a/c-embed.c -+++ b/c-embed.c -@@ -106,6 +106,19 @@ void iterdir(char* d){ - - } - -+void system_checked(const char *command){ -+ -+ int result = system(command); -+ -+ if(result != 0){ -+ fprintf(stderr, "system() failed with %d: %s\n", result, command); -+ exit(1); -+ } -+ -+} -+ -+#define system system_checked -+ - int main(int argc, char* argv[]){ - - char fmt[CEMBED_MAXPATH]; diff --git a/subprojects/packagefiles/c-embed-thread-local.diff b/subprojects/packagefiles/c-embed-thread-local.diff deleted file mode 100644 index 997e0d92..00000000 --- a/subprojects/packagefiles/c-embed-thread-local.diff +++ /dev/null @@ -1,22 +0,0 @@ -diff --git a/c-embed.h b/c-embed.h -index cf365b8..767d5ca 100644 ---- a/c-embed.h -+++ b/c-embed.h -@@ -46,7 +46,16 @@ typedef struct EFILE_S EFILE; - - // Error Handling - --__thread int eerrcode = 0; -+#if defined(__UEFI__) -+#define THREAD_LOCAL -+#else -+#define THREAD_LOCAL __thread -+#endif -+ -+ -+THREAD_LOCAL int eerrcode = 0; -+ -+ - #define ethrow(err) { (eerrcode = (err)); return NULL; } - #define eerrno (eerrcode) - diff --git a/subprojects/packagefiles/c-embed/meson.build b/subprojects/packagefiles/c-embed/meson.build deleted file mode 100644 index 0633c253..00000000 --- a/subprojects/packagefiles/c-embed/meson.build +++ /dev/null @@ -1,39 +0,0 @@ -project( - 'c-embed', - 'c', - meson_version: '>=1.12.0', - version: '0.0.1', - license: 'MIT', - default_options: { - 'optimization': '3', - 'warning_level': '2', - 'werror': true, - 'c_std': ['c11'], - 'b_ndebug': 'if-release', - }, -) - -inc_dirs = include_directories('.') - - - -c_embed_exe = executable( - 'c-embed', - files('c-embed.c'), - include_directories: inc_dirs, - native: true, -) - -meson.override_find_program( - 'c-embed', - c_embed_exe, - native: true, -) - - -c_embed_dep = declare_dependency( - include_directories: inc_dirs, - version: meson.project_version(), -) - -meson.override_dependency('c-embed', c_embed_dep)