# SDL: harmonyos: Port SDL3 to HarmonyOS/OpenHarmony.

**URL:** <https://discourse.libsdl.org/t/sdl-harmonyos-port-sdl3-to-harmonyos-openharmony/69320>\
**Category:** SDL Commits\
**Created:** [September 15, 2026, 4:34pm UTC](https://discourse.libsdl.org/t/sdl-harmonyos-port-sdl3-to-harmonyos-openharmony/69320 "2026-09-15T16:34:38Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![SDLPushPostBot](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/sdlpushpostbot/32/4370_2.png) [@SDLPushPostBot](https://discourse.libsdl.org/u/SDLPushPostBot)\
**Post date:** [September 15, 2026, 4:34pm UTC](https://discourse.libsdl.org/t/sdl-harmonyos-port-sdl3-to-harmonyos-openharmony/69320/1 "2026-09-15T16:34:38Z")

</div>

> <https://github.com/libsdl-org/SDL/commit/a24429c192cfee5ae92697f12f219cad27635fb4>
>
> This is my port of SDL3 to HarmonyOS/OpenHarmony. It has been tested on real
> har…dware from Huawei, and commercial games are being prepped to ship with it
> already.
> 
> There is \_heavy\_ documentation in docs/README-harmonyos.md, including how to
> set up a development environment and project, build, and debug, for the
> completely uninitiated.
> 
> This work was sponsored by Outfit7: https://outfit7.com/
> 
> Fixes #9837.

```diff
From a24429c192cfee5ae92697f12f219cad27635fb4 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Tue, 9 Jun 2026 00:52:31 -0400
Subject: [PATCH] harmonyos: Port SDL3 to HarmonyOS/OpenHarmony.

This is my port of SDL3 to HarmonyOS/OpenHarmony. It has been tested on real
hardware from Huawei, and commercial games are being prepped to ship with it
already.

There is _heavy_ documentation in docs/README-harmonyos.md, including how to
set up a development environment and project, build, and debug, for the
completely uninitiated.

This work was sponsored by Outfit7: https://outfit7.com/

Fixes #9837.
---
 .gitignore | 10 +
 CMakeLists.txt | 169 ++-
 build-scripts/harmonyos-tool.sh | 209 +++
 cmake/PreseedOpenHarmonyCache.cmake | 188 +++
 cmake/macros.cmake | 2 +-
 cmake/sdlcompilers.cmake | 5 +
 docs/README-harmonyos.md | 872 ++++++++++++
 docs/README-platforms.md | 1 +
 include/SDL3/SDL_iostream.h | 13 +-
 include/SDL3/SDL_keyboard.h | 7 +
 include/SDL3/SDL_main.h | 13 +
 include/SDL3/SDL_main_impl.h | 7 +
 include/SDL3/SDL_platform_defines.h | 11 +
 include/SDL3/SDL_system.h | 95 +-
 include/SDL3/SDL_video.h | 12 +
 include/build_config/SDL_build_config.h.cmake | 5 +
 openharmony-project/.gitignore | 12 +
 openharmony-project/AppScope/app.json5 | 11 +
 .../resources/base/element/string.json | 8 +
 .../resources/base/media/background.png | Bin 0 -> 91942 bytes
 .../resources/base/media/foreground.png | Bin 0 -> 15325 bytes
 .../resources/base/media/layered_image.json | 7 +
 openharmony-project/build-profile.json5 | 42 +
 openharmony-project/code-linter.json5 | 32 +
 openharmony-project/entry/.gitignore | 6 +
 openharmony-project/entry/build-profile.json5 | 45 +
 openharmony-project/entry/hvigorfile.ts | 6 +
 .../entry/obfuscation-rules.txt | 23 +
 .../entry/oh-package-lock.json5 | 19 +
 openharmony-project/entry/oh-package.json5 | 11 +
 .../entry/src/main/cpp/CMakeLists.txt | 18 +
 .../src/main/cpp/types/libSDL3/Index.d.ts | 1 +
 .../main/cpp/types/libSDL3/oh-package.json5 | 7 +
 .../main/ets/entryability/EntryAbility.ets | 28 +
 .../entrybackupability/EntryBackupAbility.ets | 16 +
 .../entry/src/main/ets/pages/Index.ets | 15 +
 .../entry/src/main/module.json5 | 67 +
 .../main/resources/base/element/color.json | 8 +
 .../main/resources/base/element/float.json | 8 +
 .../main/resources/base/element/string.json | 33 +
 .../main/resources/base/media/background.png | Bin 0 -> 91942 bytes
 .../main/resources/base/media/foreground.png | Bin 0 -> 8805 bytes
 .../resources/base/media/layered_image.json | 7 +
 .../main/resources/base/media/startIcon.png | Bin 0 -> 20093 bytes
 .../resources/base/profile/backup_config.json | 3 +
 .../resources/base/profile/main_pages.json | 5 +
 .../main/resources/dark/element/color.json | 8 +
 .../hvigor/hvigor-config.json5 | 23 +
 openharmony-project/hvigorfile.ts | 6 +
 openharmony-project/oh-package-lock.json5 | 28 +
 openharmony-project/oh-package.json5 | 10 +
 src/SDL.c | 7 +
 src/SDL_log.c | 29 +-
 src/audio/SDL_audio.c | 3 +
 src/audio/SDL_sysaudio.h | 1 +
 src/audio/ohaudio/SDL_ohaudio.c | 648 +++++++++
 src/audio/ohaudio/SDL_ohaudio.h | 38 +
 src/audio/ohaudio/SDL_ohaudiofuncs.h | 62 +
 src/camera/SDL_camera.c | 3 +
 src/camera/SDL_syscamera.h | 1 +
 .../openharmony/SDL_camera_openharmony.c | 775 +++++++++++
 src/core/SDL_core_unsupported.c | 22 +
 src/core/SDL_core_unsupported.h | 8 +
 src/core/android/SDL_android.h | 4 +
 src/core/openharmony/SDL_openharmony.c | 1207 +++++++++++++++++
 src/core/openharmony/SDL_openharmony.h | 66 +
 src/cpuinfo/SDL_cpuinfo.c | 2 +-
 src/dynapi/SDL_dynapi.exports | 3 +
 src/dynapi/SDL_dynapi.h | 2 +
 src/dynapi/SDL_dynapi.sym | 3 +
 src/dynapi/SDL_dynapi_overrides.h | 3 +
 src/dynapi/SDL_dynapi_procs.h | 3 +
 src/events/SDL_keyboard.c | 6 +-
 src/filesystem/SDL_filesystem.c | 2 +-
 .../openharmony/SDL_sysfilesystem.c | 78 ++
 src/filesystem/posix/SDL_sysfsops.c | 36 +-
 src/io/SDL_iostream.c | 38 +-
 src/locale/openharmony/SDL_syslocale.c | 36 +
 src/locale/psp/SDL_syslocale.c | 1 -
 src/main/SDL_main_callbacks.c | 9 +-
 src/main/generic/SDL_sysmain_callbacks.c | 1 +
 src/main/openharmony/SDL_sysmain_callbacks.c | 60 +
 src/main/openharmony/SDL_sysmain_runapp.c | 102 ++
 src/misc/android/SDL_sysurl.c | 5 +
 src/misc/openharmony/SDL_sysurl.c | 34 +
 src/power/SDL_power.c | 3 +
 src/power/SDL_syspower.h | 1 +
 src/power/openharmony/SDL_syspower.c | 46 +
 src/render/SDL_render.c | 2 +-
 src/thread/pthread/SDL_systhread.c | 16 +-
 src/video/SDL_egl.c | 4 +
 src/video/SDL_sysvideo.h | 1 +
 src/video/SDL_video.c | 3 +
 src/video/SDL_vulkan_internal.h | 3 +
 .../openharmony/SDL_openharmonyclipboard.c | 220 +++
 .../openharmony/SDL_openharmonyclipboard.h | 34 +
 src/video/openharmony/SDL_openharmonyevents.c | 574 ++++++++
 src/video/openharmony/SDL_openharmonyevents.h | 33 +
 .../openharmony/SDL_openharmonykeyboard.c | 93 ++
 .../openharmony/SDL_openharmonykeyboard.h | 29 +
 src/video/openharmony/SDL_openharmonymouse.c | 76 ++
 src/video/openharmony/SDL_openharmonymouse.h | 30 +
 src/video/openharmony/SDL_openharmonyopengl.c | 79 ++
 src/video/openharmony/SDL_openharmonyopengl.h | 31 +
 src/video/openharmony/SDL_openharmonyvideo.c | 280 ++++
 src/video/openharmony/SDL_openharmonyvideo.h | 47 +
 src/video/openharmony/SDL_openharmonyvulkan.c | 174 +++
 src/video/openharmony/SDL_openharmonyvulkan.h | 52 +
 src/video/openharmony/SDL_openharmonywindow.c | 187 +++
 src/video/openharmony/SDL_openharmonywindow.h | 51 +
 test/CMakeLists.txt | 4 +-
 test/testclipboard.c | 6 +-
 test/testsymbols.c | 6 +
 test/testurl.c | 4 +-
 test/testvulkan.c | 90 +-
 115 files changed, 7518 insertions(+), 91 deletions(-)
 create mode 100755 build-scripts/harmonyos-tool.sh
 create mode 100644 cmake/PreseedOpenHarmonyCache.cmake
 create mode 100644 docs/README-harmonyos.md
 create mode 100644 openharmony-project/.gitignore
 create mode 100644 openharmony-project/AppScope/app.json5
 create mode 100644 openharmony-project/AppScope/resources/base/element/string.json
 create mode 100644 openharmony-project/AppScope/resources/base/media/background.png
 create mode 100644 openharmony-project/AppScope/resources/base/media/foreground.png
 create mode 100644 openharmony-project/AppScope/resources/base/media/layered_image.json
 create mode 100644 openharmony-project/build-profile.json5
 create mode 100644 openharmony-project/code-linter.json5
 create mode 100644 openharmony-project/entry/.gitignore
 create mode 100644 openharmony-project/entry/build-profile.json5
 create mode 100644 openharmony-project/entry/hvigorfile.ts
 create mode 100644 openharmony-project/entry/obfuscation-rules.txt
 create mode 100644 openharmony-project/entry/oh-package-lock.json5
 create mode 100644 openharmony-project/entry/oh-package.json5
 create mode 100644 openharmony-project/entry/src/main/cpp/CMakeLists.txt
 create mode 100644 openharmony-project/entry/src/main/cpp/types/libSDL3/Index.d.ts
 create mode 100644 openharmony-project/entry/src/main/cpp/types/libSDL3/oh-package.json5
 create mode 100644 openharmony-project/entry/src/main/ets/entryability/EntryAbility.ets
 create mode 100644 openharmony-project/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets
 create mode 100644 openharmony-project/entry/src/main/ets/pages/Index.ets
 create mode 100644 openharmony-project/entry/src/main/module.json5
 create mode 100644 openharmony-project/entry/src/main/resources/base/element/color.json
 create mode 100644 openharmony-project/entry/src/main/resources/base/element/float.json
 create mode 100644 openharmony-project/entry/src/main/resources/base/element/string.json
 create mode 100644 openharmony-project/entry/src/main/resources/base/media/background.png
 create mode 100644 openharmony-project/entry/src/main/resources/base/media/foreground.png
 create mode 100644 openharmony-project/entry/src/main/resources/base/media/layered_image.json
 create mode 100644 openharmony-project/entry/src/main/resources/base/media/startIcon.png
 create mode 100644 openharmony-project/entry/src/main/resources/base/profile/backup_config.json
 create mode 100644 openharmony-project/entry/src/main/resources/base/profile/main_pages.json
 create mode 100644 openharmony-project/entry/src/main/resources/dark/element/color.json
 create mode 100644 openharmony-project/hvigor/hvigor-config.json5
 create mode 100644 openharmony-project/hvigorfile.ts
 create mode 100644 openharmony-project/oh-package-lock.json5
 create mode 100644 openharmony-project/oh-package.json5
 create mode 100644 src/audio/ohaudio/SDL_ohaudio.c
 create mode 100644 src/audio/ohaudio/SDL_ohaudio.h
 create mode 100644 src/audio/ohaudio/SDL_ohaudiofuncs.h
 create mode 100644 src/camera/openharmony/SDL_camera_openharmony.c
 create mode 100644 src/core/openharmony/SDL_openharmony.c
 create mode 100644 src/core/openharmony/SDL_openharmony.h
 create mode 100644 src/filesystem/openharmony/SDL_sysfilesystem.c
 create mode 100644 src/locale/openharmony/SDL_syslocale.c
 create mode 100644 src/main/openharmony/SDL_sysmain_callbacks.c
 create mode 100644 src/main/openharmony/SDL_sysmain_runapp.c
 create mode 100644 src/misc/openharmony/SDL_sysurl.c
 create mode 100644 src/power/openharmony/SDL_syspower.c
 create mode 100644 src/video/openharmony/SDL_openharmonyclipboard.c
 create mode 100644 src/video/openharmony/SDL_openharmonyclipboard.h
 create mode 100644 src/video/openharmony/SDL_openharmonyevents.c
 create mode 100644 src/video/openharmony/SDL_openharmonyevents.h
 create mode 100644 src/video/openharmony/SDL_openharmonykeyboard.c
 create mode 100644 src/video/openharmony/SDL_openharmonykeyboard.h
 create mode 100644 src/video/openharmony/SDL_openharmonymouse.c
 create mode 100644 src/video/openharmony/SDL_openharmonymouse.h
 create mode 100644 src/video/openharmony/SDL_openharmonyopengl.c
 create mode 100644 src/video/openharmony/SDL_openharmonyopengl.h
 create mode 100644 src/video/openharmony/SDL_openharmonyvideo.c
 create mode 100644 src/video/openharmony/SDL_openharmonyvideo.h
 create mode 100644 src/video/openharmony/SDL_openharmonyvulkan.c
 create mode 100644 src/video/openharmony/SDL_openharmonyvulkan.h
 create mode 100644 src/video/openharmony/SDL_openharmonywindow.c
 create mode 100644 src/video/openharmony/SDL_openharmonywindow.h

diff --git a/.gitignore b/.gitignore
index 6ae2fd4100812..b419000db2b78 100644
--- a/.gitignore
+++ b/.gitignore
@@ -99,6 +99,16 @@ out/
 android-project/local.properties
 android-project/.gradle/
 
+# for OpenHarmony/HarmonyOS
+openharmony-project/entry/src/main/cpp/CMakeLists.txt
+openharmony-project/entry/src/main/cpp/*.c
+openharmony-project/entry/src/main/cpp/*.h
+openharmony-project/entry/src/main/cpp/SDL
+openharmony-project/entry/src/main/resources/rawfile
+openharmony-project/AppScope/app.json5
+openharmony-project/AppScope/resources/base/element/string.json
+openharmony-project/build-profile.json5
+
 test/checkkeys
 test/checkkeysthreads
 test/gamepadmap
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4cabec1374754..d0095516e16ac 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -78,6 +78,7 @@ include("${SDL3_SOURCE_DIR}/cmake/GetGitRevisionDescription.cmake")
 include("${SDL3_SOURCE_DIR}/cmake/3rdparty.cmake")
 include("${SDL3_SOURCE_DIR}/cmake/PreseedMSVCCache.cmake")
 include("${SDL3_SOURCE_DIR}/cmake/PreseedEmscriptenCache.cmake")
+include("${SDL3_SOURCE_DIR}/cmake/PreseedOpenHarmonyCache.cmake")
 include("${SDL3_SOURCE_DIR}/cmake/PreseedHaikuCache.cmake")
 include("${SDL3_SOURCE_DIR}/cmake/PreseedNokiaNGageCache.cmake")
 include("${SDL3_SOURCE_DIR}/cmake/PreseedDOSCache.cmake")
@@ -322,7 +323,7 @@ dep_option(SDL_SSE4_2 "Use SSE4.2 assembly routines" ON "SDL_ASSEMB
 dep_option(SDL_MMX "Use MMX assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF)
 dep_option(SDL_ALTIVEC "Use Altivec assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_POWERPC32 OR SDL_CPU_POWERPC64" OFF)
 dep_option(SDL_ARMNEON "Use NEON assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_ARM32 OR SDL_CPU_ARM64" OFF)
-dep_option(SDL_ARMSVE2 "Use SVE2 assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_ARM64" OFF)
+dep_option(SDL_ARMSVE2 "Use SVE2 assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_ARM64 AND NOT OHOS" OFF)
 dep_option(SDL_LSX "Use LSX assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_LOONGARCH64" OFF)
 dep_option(SDL_LASX "Use LASX assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_LOONGARCH64" OFF)
 
@@ -385,7 +386,7 @@ dep_option(SDL_RENDER_D3D12 "Enable the Direct3D 12 render driver" ON "SD
 dep_option(SDL_RENDER_METAL "Enable the Metal render driver" ON "SDL_RENDER;APPLE" OFF)
 dep_option(SDL_RENDER_GPU "Enable the SDL_GPU render driver" ON "SDL_RENDER;SDL_GPU" OFF)
 dep_option(SDL_VIVANTE "Use Vivante EGL video driver" ON "${UNIX_SYS};SDL_CPU_ARM32" OFF)
-dep_option(SDL_VULKAN "Enable Vulkan support" "${SDL_VULKAN_DEFAULT}" "SDL_VIDEO;ANDROID OR APPLE OR LINUX OR FREEBSD OR OPENBSD OR WINDOWS OR CYGWIN" OFF)
+dep_option(SDL_VULKAN "Enable Vulkan support" "${SDL_VULKAN_DEFAULT}" "SDL_VIDEO;ANDROID OR APPLE OR LINUX OR FREEBSD OR OPENBSD OR WINDOWS OR CYGWIN OR OHOS" OFF)
 dep_option(SDL_RENDER_VULKAN "Enable the Vulkan render driver" ON "SDL_RENDER;SDL_VULKAN" OFF)
 dep_option(SDL_METAL "Enable Metal support" ON "APPLE" OFF)
 set_option(SDL_OPENVR "Use OpenVR video driver" OFF)
@@ -1724,6 +1725,170 @@ if(ANDROID)
     target_link_options(SDL3-static INTERFACE "-Wl,-u,JNI_OnLoad")
   endif()
 
+elseif(OHOS) # OpenHarmony/HarmonyOS
+ sdl_glob_sources(
+ "${SDL3_SOURCE_DIR}/src/core/openharmony/*.c"
+ "${SDL3_SOURCE_DIR}/src/core/openharmony/*.h"
+ )
+
+ sdl_link_dependency(openharmonycore LIBS libace_napi.z.so libace_ndk.z.so deviceinfo_ndk.z rawfile.z hilog_ndk.z ohcommonevent)
+
+ sdl_glob_sources(
+ "${SDL3_SOURCE_DIR}/src/main/openharmony/*.c"
+ "${SDL3_SOURCE_DIR}/src/main/openharmony/*.h"
+ )
+ set(HAVE_SDL_MAIN_CALLBACKS TRUE)
+
+ sdl_glob_sources(
+ "${SDL3_SOURCE_DIR}/src/misc/openharmony/*.c"
+ "${SDL3_SOURCE_DIR}/src/misc/openharmony/*.h"
+ )
+ set(HAVE_SDL_MISC TRUE)
+
+ if(SDL_AUDIO)
+ set(SDL_AUDIO_DRIVER_OHAUDIO 1)
+ sdl_glob_sources(
+ "${SDL3_SOURCE_DIR}/src/audio/ohaudio/*.c"
+ "${SDL3_SOURCE_DIR}/src/audio/ohaudio/*.h"
+ )
+
+ set(HAVE_SDL_AUDIO TRUE)
+ endif()
+
+ set(SDL_FILESYSTEM_OPENHARMONY 1)
+ sdl_glob_sources(
+ "${SDL3_SOURCE_DIR}/src/filesystem/openharmony/*.c"
+ "${SDL3_SOURCE_DIR}/src/filesystem/openharmony/*.h"
+ )
+ sdl_link_dependency(openharmonyfs LIBS ability_runtime)
+ set(HAVE_SDL_FILESYSTEM TRUE)
+
+ set(SDL_FSOPS_POSIX 1)
+ sdl_sources("${SDL3_SOURCE_DIR}/src/filesystem/posix/SDL_sysfsops.c")
+ set(HAVE_SDL_FSOPS TRUE)
+
+if (False) # !!! FIXME
+ if(SDL_HAPTIC)
+ set(SDL_HAPTIC_OPENHARMONY 1)
+ sdl_glob_sources(
+ "${SDL3_SOURCE_DIR}/src/haptic/openharmony/*.c"
+ "${SDL3_SOURCE_DIR}/src/haptic/openharmony/*.h"
+ )
+ set(HAVE_SDL_HAPTIC TRUE)
+ endif()
+
+ # !!! FIXME: any chance HIDAPI would work here?
+ CheckHIDAPI()
+
+ if(SDL_JOYSTICK)
+ set(SDL_JOYSTICK_OPENHARMONY 1)
+ sdl_glob_sources(
+ "${SDL3_SOURCE_DIR}/src/joystick/openharmony/*.c"
+ "${SDL3_SOURCE_DIR}/src/joystick/openharmony/*.h"
+ )
+ set(HAVE_SDL_JOYSTICK TRUE)
+ endif()
+endif()
+
+ set(SDL_LOADSO_DLOPEN 1)
+ sdl_glob_sources(
+ "${SDL3_SOURCE_DIR}/src/loadso/dlopen/*.c"
+ "${SDL3_SOURCE_DIR}/src/loadso/dlopen/*.h"
+ )
+ set(HAVE_SDL_LOADSO TRUE)
+
+ if(SDL_POWER)
+ set(SDL_POWER_OPENHARMONY 1)
+ sdl_glob_sources(
+ "${SDL3_SOURCE_DIR}/src/power/openharmony/*.c"
+ "${SDL3_SOURCE_DIR}/src/power/openharmony/*.h"
+ )
+ sdl_link_dependency(openharmonypower LIBS ohbattery_info)
+ set(HAVE_SDL_POWER TRUE)
+ endif()
+
+ sdl_glob_sources(
+ "${SDL3_SOURCE_DIR}/src/locale/openharmony/*.c"
+ "${SDL3_SOURCE_DIR}/src/locale/openharmony/*.h"
+ )
+ set(HAVE_SDL_LOCALE TRUE)
+
+ set(SDL_TIME_UNIX 1)
+ sdl_glob_sources(
+ "${SDL3_SOURCE_DIR}/src/time/unix/*.c"
+ "${SDL3_SOURCE_DIR}/src/time/unix/*.h"
+ )
+ set(HAVE_SDL_TIME TRUE)
+
+ set(SDL_TIMER_UNIX 1)
+ sdl_glob_sources(
+ "${SDL3_SOURCE_DIR}/src/timer/unix/*.c"
+ "${SDL3_SOURCE_DIR}/src/timer/unix/*.h"
+ )
+ set(HAVE_SDL_TIMERS TRUE)
+
+if(False)
+ if(SDL_SENSOR)
+ set(SDL_SENSOR_OPENHARMONY 1)
+ set(HAVE_SDL_SENSORS TRUE)
+ sdl_glob_sources(
+ "${SDL3_SOURCE_DIR}/src/sensor/openharmony/*.c"
+ "${SDL3_SOURCE_DIR}/src/sensor/openharmony/*.h"
+ )
+ endif()
+endif()
+
+ if(SDL_CAMERA)
+ set(SDL_CAMERA_DRIVER_OPENHARMONY 1)
+ set(HAVE_CAMERA TRUE)
+ sdl_glob_sources(
+ "${SDL3_SOURCE_DIR}/src/camera/openharmony/*.c"
+ "${SDL3_SOURCE_DIR}/src/camera/openharmony/*.h"
+ )
+ sdl_link_dependency(openharmonycamera LIBS ohcamera ohimage image_receiver native_image native_buffer)
+ endif()
+
+ if(SDL_VIDEO)
+ set(SDL_VIDEO_DRIVER_OPENHARMONY 1)
+ sdl_glob_sources(
+ "${SDL3_SOURCE_DIR}/src/video/openharmony/*.c"
+ "${SDL3_SOURCE_DIR}/src/video/openharmony/*.h"
+ )
+ set(HAVE_SDL_VIDEO TRUE)
+ sdl_link_dependency(openharmonyvideo LIBS native_display_manager pasteboard udmf)
+
+ # Core stuff
+ # find_library(ANDROID_DL_LIBRARY dl)
+ # FIXME failing dlopen https://github.com/android-ndk/ndk/issues/929
+# !!! FIXME
+# sdl_link_dependency(android_video LIBS dl log android)
+ sdl_compile_definitions(PRIVATE "GL_GLEXT_PROTOTYPES")
+
+ #enable gles
+ if(SDL_OPENGLES)
+ set(SDL_VIDEO_OPENGL_EGL 1)
+ set(HAVE_OPENGLES TRUE)
+ set(SDL_VIDEO_OPENGL_ES2 1)
+ set(SDL_VIDEO_RENDER_OGL_ES2 1)
+ #sdl_link_dependency(opengles LIBS GLESv3)
+ endif()
+
+ if(SDL_VULKAN)
+ set(SDL_VIDEO_VULKAN 1)
+ set(HAVE_VULKAN TRUE)
+ if(SDL_RENDER_VULKAN)
+ set(SDL_VIDEO_RENDER_VULKAN 1)
+ set(HAVE_RENDER_VULKAN TRUE)
+ endif()
+ endif()
+ endif()
+
+ CheckPTHREAD()
+
+ if(SDL_CLOCK_GETTIME)
+ set(HAVE_CLOCK_GETTIME 1)
+ endif()
+
 elseif(EMSCRIPTEN)
   # Hide noisy warnings that intend to aid mostly during initial stages of porting a new
   # project. Uncomment at will for verbose cross-compiling -I/../ path info.
diff --git a/build-scripts/harmonyos-tool.sh b/build-scripts/harmonyos-tool.sh
new file mode 100755
index 0000000000000..684b7241dbf93
--- /dev/null
+++ b/build-scripts/harmonyos-tool.sh
@@ -0,0 +1,209 @@
+#!/usr/bin/bash
+
+HVIGORWPATH=`which hvigorw 2>/dev/null`
+if ["x$HVIGORWPATH" == "x"]; then
+ echo "Couldn't find hvigorw!"
+ echo "Please make sure the HarmonyOS command line tools are in your PATH." 1>&2
+ exit 1
+fi
+
+HDCPATH=`which hdc 2>/dev/null`
+if ["x$HDCPATH" == "x"]; then
+ echo "Couldn't find hdc!"
+ echo "Please make sure the HarmonyOS command line tools are in your PATH." 1>&2
+ exit 1
+fi
+
+CLTBINPATH=`dirname "$HVIGORWPATH"`
+CLTPATH=`dirname "$CLTBINPATH"`
+CLT=`realpath "$CLTPATH"`
+#echo "CLT is '$CLT'"
+
+need_usage=0
+
+APPJSON=""
+PROJDIR="$1"
+if ["x$PROJDIR" == "x"]; then
+ need_usage=1
+else
+ PROJDIR=`realpath "$PROJDIR"`
+ APPJSON="$PROJDIR/AppScope/app.json5"
+ if [! -f "$APPJSON"]; then
+ echo "Can't find '$APPJSON'. Is project directory correct?" 1>&2
+ echo "" 1>&2
+ need_usage=1
+ fi
+fi
+
+do_clean=0
+do_build=0
+do_uninstall=0
+do_install=0
+do_kill=0
+do_launch=0
+do_log=0
+do_debug=0
+do_anything=0
+
+shift # dump projectdir
+while [$# -gt 0]; do
+ do_anything=1
+ case $1 in
+ --clean)
+ do_clean=1
+ shift
+ ;;
+ --build)
+ do_build=1
+ shift
+ ;;
+ --install)
+ do_install=1
+ shift
+ ;;
+ --uninstall)
+ do_uninstall=1
+ shift
+ ;;
+ --kill)
+ do_kill=1
+ shift
+ ;;
+ --launch)
+ do_launch=1
+ shift
+ ;;
+ --log)
+ do_log=1
+ shift
+ ;;
+ --debug)
+ do_launch=1
+ do_debug=1
+ shift
+ ;;
+ *)
+ echo "Unknown option '$1'" 1>&2
+ need_usage=1
+ shift
+ ;;
+ esac
+done
+
+if ["$do_anything" == "0"]; then
+ need_usage=1
+fi
+
+if ["$need_usage" == "1"]; then
+ echo "USAGE: $0 <project_dir> [--kill] [--uninstall] [--build] [--install] [--launch] [--debug] [--log]" 1>&2
+ echo "" 1>&2
+ exit 1
+fi
+
+if ["$do_build" == "1"]; then
+ if ["$do_debug" == "1"]; then
+ do_install=1
+ elif ["$do_launch" == "1"]; then
+ do_install=1
+ fi
+fi
+
+# Here we go!
+
+BUNDLE=`grep -F bundleName "$PROJDIR/AppScope/app.json5" |perl -w -p -e 's/\A\s*\"bundleName\"\s*\:\s*\"(.*?)\".*?\Z/$1/i;'`
+if ["x$BUNDLE" == "x"]; then
+ echo "Failed to determine bundle name! Aborting!" 1>&2
+ exit 1
+fi
+
+echo "BUNDLE is '$BUNDLE'"
+
+#set -x
+
+cd "$PROJDIR"
+
+if ["$do_kill" == "1"]; then
+ echo "KILLING..."
+ hdc shell aa force-stop $BUNDLE || exit 1
+fi
+
+if ["$do_uninstall" == "1"]; then
+ echo "UNINSTALLING..."
+ hdc uninstall $BUNDLE || exit 1
+fi
+
+if ["$do_clean" == "1"]; then
+ echo "CLEANING..."
+ hvigorw clean || exit 1
+fi
+
+if ["$do_build" == "1"]; then
+ echo "BUILDING..."
+ hvigorw assembleHap || exit 1
+fi
+
+if ["$do_debug" == "1"]; then
+ hdc shell mkdir -p data/local/tmp/debugserver/$BUNDLE
+ hdc file send "$CLT/sdk/default/hms/native/lldb/aarch64-linux-ohos/lldb-server" data/local/tmp/debugserver/$BUNDLE
+ hdc shell chmod 755 data/local/tmp/debugserver/$BUNDLE/lldb-server
+fi
+
+if ["$do_install" == "1"]; then
+ echo "INSTALLING..."
+ hdc install "$PROJDIR/entry/build/default/outputs/default/entry-default-signed.hap" || exit 1
+fi
+
+# Catch sigint, kill the backgrounded `hdc hilog` then exit.
+trap_sigint() {
+ if ["$HILOGPID" != ""]; then
+ kill -9 "$HILOGPID"
+ fi
+ wait "$HILOGPID" 2>/dev/null
+ echo ""
+ #echo "Killed $HILOGPID"
+ exit 0
+}
+
+HILOGPID=""
+if ["$do_log" == "1"]; then
+ trap trap_sigint INT
+
+ # This wild bash syntax puts `hdc` in the background, and pipes its output through `grep`, but `$!` will have hdc's process ID.
+ # The ridiculous perl regular expression basically filters out a ton of garbage from each line of the log. You can remove it entirely and just grep for the bundle name, though!
+ hdc hilog > >(grep -F --line-buffered "/$BUNDLE/" |perl -w -p -e 's/\A\d+\-\d+\s+(\d+\:\d+\:\d+)\.\d+\s+\d+\s+\d+\s+(.)\s+.*?\/.*?\/(.*?)\:\s+/$1 $2 $3: /;') & HILOGPID="$!"
+fi
+
+if ["$do_launch" == "1"]; then
+ echo "LAUNCHING..."
+ # !!! FIXME: maybe this makes the process wait on launch until debugger is attached?
+ #hdc shell aa appdebug -b $BUNDLE
+ hdc shell aa start -a EntryAbility -b $BUNDLE || exit 1
+fi
+
+if ["$do_debug" == "1"]; then
+ echo "DEBUGGING..."
+ hdc shell aa attach -b $BUNDLE
+ hdc shell aa process -a EntryAbility -b $BUNDLE -D "/data/local/tmp/debugserver/$BUNDLE/lldb-server platform --listen unix-abstract:///lldb-server/platform.sock"
+
+ PID=`hdc shell ps -w -o PID,ARGS |grep -F "$BUNDLE" |head -n 1 |awk '{print $1}'`
+ if ["x$PID" == "x"]; then
+ echo "Failed to determine PID! Aborting!" 1>&2
+ exit 1
+ fi
+
+ echo "PID is $PID"
+
+ trap - INT
+ "$CLT/sdk/default/openharmony/native/llvm/bin/lldb" \
+ -O "platform select remote-ohos" \
+ -O "platform connect unix-abstract-connect:///lldb-server/platform.sock" \
+ -O "settings append target.exec-search-paths \"$PROJDIR/entry/build/default/intermediates/cmake/default/obj/arm64-v8a\"" \
+ -O "attach $PID"
+ trap trap_sigint INT
+fi
+
+if ["$HILOGPID" != ""]; then
+ #echo "$0: WAITING ON $HILOGPID"
+ wait "$HILOGPID"
+fi
+
diff --git a/cmake/PreseedOpenHarmonyCache.cmake b/cmake/PreseedOpenHarmonyCache.cmake
new file mode 100644
index 0000000000000..b78c24aeb9c98
--- /dev/null
+++ b/cmake/PreseedOpenHarmonyCache.cmake
@@ -0,0 +1,188 @@
+if(OHOS)
+ function(SDL_Preseed_CMakeCache)
+ set(COMPILER_SUPPORTS_FDIAGNOSTICS_COLOR_ALWAYS "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_FDIAGNOSTICS_COLOR_ALWAYS")
+ set(COMPILER_SUPPORTS_GCC_ATOMICS "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_GCC_ATOMICS")
+ set(COMPILER_SUPPORTS_SYNC_LOCK_TEST_AND_SET "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_SYNC_LOCK_TEST_AND_SET")
+ set(HAVE_CLANG_COMMENT_BLOCK_COMMANDS "1" CACHE INTERNAL "Test HAVE_CLANG_COMMENT_BLOCK_COMMANDS")
+ set(HAVE_ALLOCA_H "1" CACHE INTERNAL "Have include alloca.h")
+ set(HAVE_LIBM "1" CACHE INTERNAL "Have library m")
+ set(HAVE_POSIX_SPAWN "1" CACHE INTERNAL "Have symbol posix_spawn")
+ set(HAVE_FSEEKO "1" CACHE INTERNAL "Have symbol fseeko")
+ set(HAVE_OFF64_T "1" CACHE INTERNAL "Have symbol off64_t")
+ set(LIBC_HAS_ABS "1" CACHE INTERNAL "Have symbol abs")
+ set(LIBC_HAS_ACOS "1" CACHE INTERNAL "Have symbol acos")
+ set(LIBC_HAS_ACOSF "1" CACHE INTERNAL "Have symbol acosf")
+ set(LIBC_HAS_ASIN "1" CACHE INTERNAL "Have symbol asin")
+ set(LIBC_HAS_ASINF "1" CACHE INTERNAL "Have symbol asinf")
+ set(LIBC_HAS_ATAN "1" CACHE INTERNAL "Have symbol atan")
+ set(LIBC_HAS_ATAN2 "1" CACHE INTERNAL "Have symbol atan2")
+ set(LIBC_HAS_ATAN2F "1" CACHE INTERNAL "Have symbol atan2f")
+ set(LIBC_HAS_ATANF "1" CACHE INTERNAL "Have symbol atanf")
+ set(LIBC_HAS_ATOF "1" CACHE INTERNAL "Have symbol atof")
+ set(LIBC_HAS_ATOI "1" CACHE INTERNAL "Have symbol atoi")
+ set(LIBC_HAS_BCOPY "1" CACHE INTERNAL "Have symbol bcopy")
+ set(LIBC_HAS_CALLOC "1" CACHE INTERNAL "Have symbol calloc")
+ set(LIBC_HAS_CEIL "1" CACHE INTERNAL "Have symbol ceil")
+ set(LIBC_HAS_CEILF "1" CACHE INTERNAL "Have symbol ceilf")
+ set(LIBC_HAS_COPYSIGN "1" CACHE INTERNAL "Have symbol copysign")
+ set(LIBC_HAS_COPYSIGNF "1" CACHE INTERNAL "Have symbol copysignf")
+ set(LIBC_HAS_COS "1" CACHE INTERNAL "Have symbol cos")
+ set(LIBC_HAS_COSF "1" CACHE INTERNAL "Have symbol cosf")
+ set(LIBC_HAS_EXP "1" CACHE INTERNAL "Have symbol exp")
+ set(LIBC_HAS_EXPF "1" CACHE INTERNAL "Have symbol expf")
+ set(LIBC_HAS_FABS "1" CACHE INTERNAL "Have symbol fabs")
+ set(LIBC_HAS_FABSF "1" CACHE INTERNAL "Have symbol fabsf")
+ set(LIBC_HAS_FLOAT_H "1" CACHE INTERNAL "Have include float.h")
+ set(LIBC_HAS_FLOOR "1" CACHE INTERNAL "Have symbol floor")
+ set(LIBC_HAS_FLOORF "1" CACHE INTERNAL "Have symbol floorf")
+ set(LIBC_HAS_FMOD "1" CACHE INTERNAL "Have symbol fmod")
+ set(LIBC_HAS_FMODF "1" CACHE INTERNAL "Have symbol fmodf")
+ set(LIBC_HAS_FOPEN64 "1" CACHE INTERNAL "Have symbol fopen64")
+ set(LIBC_HAS_FREE "1" CACHE INTERNAL "Have symbol free")
+ set(LIBC_HAS_FSEEKO "1" CACHE INTERNAL "Have symbol fseeko")
+ set(LIBC_HAS_FSEEKO64 "1" CACHE INTERNAL "Have symbol fseeko64 (broken in DJGPP)")
+ set(LIBC_HAS_GETENV "1" CACHE INTERNAL "Have symbol getenv")
+ set(LIBC_HAS_ICONV_H "1" CACHE INTERNAL "Have include iconv.h")
+ set(LIBC_HAS_INDEX "1" CACHE INTERNAL "Have symbol index")
+ set(LIBC_HAS_INTTYPES_H "1" CACHE INTERNAL "Have include inttypes.h")
+ set(LIBC_HAS_ISINF "" CACHE INTERNAL "Have include isinf(double)")
+ set(LIBC_ISINF_HANDLES_FLOAT "" CACHE INTERNAL "Have include isinf(float)")
+ set(LIBC_HAS_ISINFF "" CACHE INTERNAL "Have include isinff(float)")
+ set(LIBC_HAS_ISNAN "" CACHE INTERNAL "Have include isnan(double)")
+ set(LIBC_ISNAN_HANDLES_FLOAT "" CACHE INTERNAL "Have include isnan(float)")
+ set(LIBC_HAS_ISNANF "" CACHE INTERNAL "Have include isnanf(float)")
+ set(LIBC_HAS_ITOA "" CACHE INTERNAL "Have symbol itoa")
+ set(LIBC_HAS_LIMITS_H "1" CACHE INTERNAL "Have include limits.h")
+ set(LIBC_HAS_LOG "1" CACHE INTERNAL "Have symbol log")
+ set(LIBC_HAS_LOG10 "1" CACHE INTERNAL "Have symbol log10")
+ set(LIBC_HAS_LOG10F "1" CACHE INTERNAL "Have symbol log10f")
+ set(LIBC_HAS_LOGF "1" CACHE INT

```

(Patch may be truncated, please check the link at the top of this post.)
