Bladeren bron

[cmake] Improve support for android build (#798)

* [cmake] Add BUILD_SHARED_LIBS option

This is a standard cmake option for toggling between shared/static
library builds:

https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html

* [cmake] Improve support for android build

CMakeLists.txt now fetches the required dependencies for android,
allowing for a more convenient build.

* [sdl] Fix compatibility with opengl es

* [sdl] Use gl es 3.2 header on android

This is required to support the following functions:
- glColorMaski (https://registry.khronos.org/OpenGL-Refpages/es3/html/glColorMask.xhtml)
- glGetProgramResourceIndex (https://registry.khronos.org/OpenGL-Refpages/es3/html/glGetProgramResourceIndex.xhtml)

* [hlc] Fix hlc_main.c for android sdks < 33

The functions in execinfo.h are only available with android sdk 33 and
above.

* [ci] Add android build

minSdkVersion/ANDROID_PLATFORM 24 is required by libuv:

https://github.com/libuv/libuv/blob/6cf854c11b1a6c5b629282ac334097ac8e6abb9e/SUPPORTED_PLATFORMS.md?plain=1#L13
tobil4sk 3 weken geleden
bovenliggende
commit
3b70a828dc

+ 17 - 0
.github/workflows/build.yml

@@ -278,6 +278,23 @@ jobs:
         path: ${{ env.HASHLINK_DISTRIBUTION }}
 
 
+  build-android:
+    runs-on: ubuntu-latest
+    steps:
+
+    - name: "SCM Checkout"
+      uses: actions/checkout@v4
+
+    - name: "Build: Hashlink"
+      run: |
+        set -ex
+        mkdir build
+        cd build
+        cmake .. -G Ninja --toolchain $ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake \
+          -DANDROID_PLATFORM=24 -DANDROID_ABI=arm64-v8a -DBUILD_SHARED_LIBS=OFF \
+          -DBUILD_TESTING=OFF -DWITH_VM=OFF
+        cmake --build .
+
   ###########################################################
   publish-latest-release:
   ###########################################################

+ 9 - 2
CMakeLists.txt

@@ -24,6 +24,7 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm|aarch64")
 endif()
 
 option(WITH_VM "Whether to build the Hashlink virtual machine" ${WITH_VM_DEFAULT})
+option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
 
 # force Unicode over Multi-byte
 if(MSVC)
@@ -133,7 +134,7 @@ if(IOS_PLATFORM)
     )
 endif()
 
-add_library(libhl SHARED
+add_library(libhl
     ${pcre_srcs}
     src/gc.c
     ${std_srcs}
@@ -192,7 +193,13 @@ endif()
 if(WIN32)
     target_link_libraries(libhl ws2_32 user32)
 else()
-    target_link_libraries(libhl m dl pthread)
+    target_link_libraries(libhl m dl)
+
+    if(ANDROID)
+        target_link_libraries(libhl log)
+    else()
+        target_link_libraries(libhl pthread)
+    endif()
 endif()
 
 if(BUILD_TESTING)

+ 11 - 1
libs/CMakeLists.txt

@@ -1,14 +1,24 @@
 set(INCLUDES_BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../include)
 
+if (BUILD_SHARED_LIBS)
+    set(HDLL_SUFFIX .hdll)
+else()
+    set(HDLL_SUFFIX .hdll${CMAKE_STATIC_LIBRARY_SUFFIX})
+endif()
+
 function(set_as_hdll target)
     set_target_properties(${target}.hdll
         PROPERTIES
         PREFIX ""
         OUTPUT_NAME ${target}
-        SUFFIX .hdll
+        SUFFIX ${HDLL_SUFFIX}
     )
 endfunction()
 
+if (ANDROID)
+    include(ExternalProject)
+endif()
+
 if(WIN32)
     add_subdirectory(directx)
 endif()

+ 2 - 2
libs/directx/CMakeLists.txt

@@ -3,7 +3,7 @@ option(WITH_DIRECTX "Build directx.hdll." ON)
 if(WITH_DIRECTX)
     find_package(DirectX)
 
-    add_library(directx.hdll SHARED
+    add_library(directx.hdll
         directx.cpp
         gamecontroller.c
         window.c
@@ -30,7 +30,7 @@ endif()
 option(WITH_DX12 "Build dx12.hdll." ON)
 
 if(WITH_DX12)
-    add_library(dx12.hdll SHARED
+    add_library(dx12.hdll
         dx12.cpp
     )
 

+ 78 - 46
libs/fmt/CMakeLists.txt

@@ -1,20 +1,19 @@
 set(MINIMP3_INCLUDE_DIR ${INCLUDES_BASE_DIR}/minimp3)
 set(MIKKTSPACE_INCLUDE_DIR ${INCLUDES_BASE_DIR}/mikktspace)
 
-if(WIN32)
-    set(ZLIB_INCLUDE_DIRS ${INCLUDES_BASE_DIR}/zlib)
+add_library(fmt.hdll
+    fmt.c
+    sha1.c
+    dxt.c
+    mikkt.c
+    ${MIKKTSPACE_INCLUDE_DIR}/mikktspace.c
+)
+
+if (WIN32 OR ANDROID)
     set(PNG_INCLUDE_DIRS ${INCLUDES_BASE_DIR}/png)
     set(VORBIS_INCLUDE_DIR ${INCLUDES_BASE_DIR}/vorbis)
 
-    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
-        set(TurboJPEG_INCLUDE_DIRS ${INCLUDES_BASE_DIR}/turbojpeg ${INCLUDES_BASE_DIR}/turbojpeg/x64)
-        find_library(TurboJPEG_LIBRARIES simd PATHS ${INCLUDES_BASE_DIR}/turbojpeg/x64)
-    else()
-        set(TurboJPEG_INCLUDE_DIRS ${INCLUDES_BASE_DIR}/turbojpeg ${INCLUDES_BASE_DIR}/turbojpeg/x86)
-        find_library(TurboJPEG_LIBRARIES simd PATHS ${INCLUDES_BASE_DIR}/turbojpeg/x86)
-    endif()
-
-    add_library(fmt.hdll SHARED
+    target_sources(fmt.hdll PRIVATE
         ${INCLUDES_BASE_DIR}/png/png.c
         ${INCLUDES_BASE_DIR}/png/pngerror.c
         ${INCLUDES_BASE_DIR}/png/pngget.c
@@ -30,6 +29,48 @@ if(WIN32)
         ${INCLUDES_BASE_DIR}/png/pngwrite.c
         ${INCLUDES_BASE_DIR}/png/pngwtran.c
         ${INCLUDES_BASE_DIR}/png/pngwutil.c
+        ${INCLUDES_BASE_DIR}/vorbis/bitrate.c
+        ${INCLUDES_BASE_DIR}/vorbis/bitwise.c
+        ${INCLUDES_BASE_DIR}/vorbis/block.c
+        ${INCLUDES_BASE_DIR}/vorbis/codebook.c
+        ${INCLUDES_BASE_DIR}/vorbis/envelope.c
+        ${INCLUDES_BASE_DIR}/vorbis/floor0.c
+        ${INCLUDES_BASE_DIR}/vorbis/floor1.c
+        ${INCLUDES_BASE_DIR}/vorbis/framing.c
+        ${INCLUDES_BASE_DIR}/vorbis/info.c
+        ${INCLUDES_BASE_DIR}/vorbis/lookup.c
+        ${INCLUDES_BASE_DIR}/vorbis/lpc.c
+        ${INCLUDES_BASE_DIR}/vorbis/lsp.c
+        ${INCLUDES_BASE_DIR}/vorbis/mapping0.c
+        ${INCLUDES_BASE_DIR}/vorbis/mdct.c
+        ${INCLUDES_BASE_DIR}/vorbis/psy.c
+        ${INCLUDES_BASE_DIR}/vorbis/registry.c
+        ${INCLUDES_BASE_DIR}/vorbis/res0.c
+        ${INCLUDES_BASE_DIR}/vorbis/sharedbook.c
+        ${INCLUDES_BASE_DIR}/vorbis/smallft.c
+        ${INCLUDES_BASE_DIR}/vorbis/synthesis.c
+        ${INCLUDES_BASE_DIR}/vorbis/vorbisfile.c
+        ${INCLUDES_BASE_DIR}/vorbis/window.c
+    )
+
+    if (ANDROID)
+        # TODO: enable
+        target_compile_definitions(fmt.hdll PRIVATE PNG_ARM_NEON_OPT=0)
+    endif()
+endif()
+
+if(WIN32)
+    set(ZLIB_INCLUDE_DIRS ${INCLUDES_BASE_DIR}/zlib)
+
+    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+        set(TurboJPEG_INCLUDE_DIRS ${INCLUDES_BASE_DIR}/turbojpeg ${INCLUDES_BASE_DIR}/turbojpeg/x64)
+        find_library(TurboJPEG_LIBRARIES simd PATHS ${INCLUDES_BASE_DIR}/turbojpeg/x64)
+    else()
+        set(TurboJPEG_INCLUDE_DIRS ${INCLUDES_BASE_DIR}/turbojpeg ${INCLUDES_BASE_DIR}/turbojpeg/x86)
+        find_library(TurboJPEG_LIBRARIES simd PATHS ${INCLUDES_BASE_DIR}/turbojpeg/x86)
+    endif()
+
+    target_sources(fmt.hdll PRIVATE
         ${INCLUDES_BASE_DIR}/turbojpeg/jaricom.c
         ${INCLUDES_BASE_DIR}/turbojpeg/jcapimin.c
         ${INCLUDES_BASE_DIR}/turbojpeg/jcapistd.c
@@ -92,34 +133,33 @@ if(WIN32)
         ${INCLUDES_BASE_DIR}/zlib/inftrees.c
         ${INCLUDES_BASE_DIR}/zlib/trees.c
         ${INCLUDES_BASE_DIR}/zlib/zutil.c
-        ${INCLUDES_BASE_DIR}/vorbis/bitrate.c
-        ${INCLUDES_BASE_DIR}/vorbis/bitwise.c
-        ${INCLUDES_BASE_DIR}/vorbis/block.c
-        ${INCLUDES_BASE_DIR}/vorbis/codebook.c
-        ${INCLUDES_BASE_DIR}/vorbis/envelope.c
-        ${INCLUDES_BASE_DIR}/vorbis/floor0.c
-        ${INCLUDES_BASE_DIR}/vorbis/floor1.c
-        ${INCLUDES_BASE_DIR}/vorbis/framing.c
-        ${INCLUDES_BASE_DIR}/vorbis/info.c
-        ${INCLUDES_BASE_DIR}/vorbis/lookup.c
-        ${INCLUDES_BASE_DIR}/vorbis/lpc.c
-        ${INCLUDES_BASE_DIR}/vorbis/lsp.c
-        ${INCLUDES_BASE_DIR}/vorbis/mapping0.c
-        ${INCLUDES_BASE_DIR}/vorbis/mdct.c
-        ${INCLUDES_BASE_DIR}/vorbis/psy.c
-        ${INCLUDES_BASE_DIR}/vorbis/registry.c
-        ${INCLUDES_BASE_DIR}/vorbis/res0.c
-        ${INCLUDES_BASE_DIR}/vorbis/sharedbook.c
-        ${INCLUDES_BASE_DIR}/vorbis/smallft.c
-        ${INCLUDES_BASE_DIR}/vorbis/synthesis.c
-        ${INCLUDES_BASE_DIR}/vorbis/vorbisfile.c
-        ${INCLUDES_BASE_DIR}/vorbis/window.c
-        fmt.c
-        sha1.c
-        dxt.c
-        mikkt.c
-        ${MIKKTSPACE_INCLUDE_DIR}/mikktspace.c
     )
+elseif(ANDROID)
+    find_package(ZLIB REQUIRED)
+
+	ExternalProject_Add(turbojpeg-project
+        URL https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/3.1.1/libjpeg-turbo-3.1.1.tar.gz
+        URL_HASH SHA256=aadc97ea91f6ef078b0ae3a62bba69e008d9a7db19b34e4ac973b19b71b4217c
+        CMAKE_ARGS
+            -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
+            -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
+            -DANDROID_PLATFORM=${ANDROID_PLATFORM}
+            -DANDROID_ABI=${CMAKE_ANDROID_ARCH_ABI}
+            -DBUILD_SHARED_LIBS=OFF
+        # INSTALL_BYPRODUCTS in CMake 3.26+
+        BUILD_BYPRODUCTS <INSTALL_DIR>/${CMAKE_INSTALL_LIBDIR}/libturbojpeg.a
+        DOWNLOAD_EXTRACT_TIMESTAMP true
+    )
+
+    ExternalProject_Get_Property(turbojpeg-project INSTALL_DIR)
+
+    add_library(turbojpeg STATIC IMPORTED)
+    set_target_properties(turbojpeg PROPERTIES IMPORTED_LOCATION ${INSTALL_DIR}/${CMAKE_INSTALL_LIBDIR}/libturbojpeg.a)
+
+    set(TurboJPEG_INCLUDE_DIRS ${INSTALL_DIR}/${CMAKE_INSTALL_INCLUDEDIR})
+    set(TurboJPEG_LIBRARIES turbojpeg)
+
+    add_dependencies(turbojpeg turbojpeg-project)
 else()
     find_package(ZLIB REQUIRED)
     find_package(PNG REQUIRED)
@@ -133,14 +173,6 @@ else()
     if(NOT OGGVORBIS_FOUND)
         pkg_check_modules(OGGVORBIS REQUIRED vorbis vorbisenc vorbisfile)
     endif()
-
-    add_library(fmt.hdll SHARED
-        fmt.c
-        sha1.c
-        dxt.c
-        mikkt.c
-        ${MIKKTSPACE_INCLUDE_DIR}/mikktspace.c
-    )
 endif()
 
 set_as_hdll(fmt)

+ 1 - 1
libs/heaps/CMakeLists.txt

@@ -5,7 +5,7 @@ set(HEAPS_INCLUDE_DIRS
     .
 )
 
-add_library(heaps.hdll SHARED
+add_library(heaps.hdll
     ${INCLUDES_BASE_DIR}/mikktspace/mikktspace.c
     ${INCLUDES_BASE_DIR}/meshoptimizer/allocator.cpp
     ${INCLUDES_BASE_DIR}/meshoptimizer/overdrawoptimizer.cpp

+ 24 - 2
libs/openal/CMakeLists.txt

@@ -1,3 +1,5 @@
+add_library(openal.hdll openal.c)
+
 if(WIN32)
     if(MSVC)
         set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO")
@@ -10,12 +12,32 @@ if(WIN32)
     endif()
 
     set(OPENAL_INCLUDE_DIR ${INCLUDES_BASE_DIR}/openal/include)
+elseif(ANDROID)
+	ExternalProject_Add(openal-soft
+        URL https://github.com/kcat/openal-soft/archive/refs/tags/1.24.3.tar.gz
+        URL_HASH SHA256=7e1fecdeb45e7f78722b776c5cf30bd33934b961d7fd2a11e0494e064cc631ce
+        CMAKE_ARGS
+            -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
+            -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
+            -DANDROID_PLATFORM=${ANDROID_PLATFORM}
+            -DANDROID_ABI=${CMAKE_ANDROID_ARCH_ABI}
+        # INSTALL_BYPRODUCTS in CMake 3.26+
+        BUILD_BYPRODUCTS <INSTALL_DIR>/${CMAKE_INSTALL_LIBDIR}/libopenal.so
+        DOWNLOAD_EXTRACT_TIMESTAMP true
+    )
+    ExternalProject_Get_Property(openal-soft INSTALL_DIR)
+
+    add_library(openal SHARED IMPORTED)
+    set_target_properties(openal PROPERTIES IMPORTED_LOCATION ${INSTALL_DIR}/${CMAKE_INSTALL_LIBDIR}/libopenal.so)
+
+    set(OPENAL_INCLUDE_DIR ${INSTALL_DIR}/${CMAKE_INSTALL_INCLUDEDIR})
+    set(OPENAL_LIBRARY openal)
+
+    add_dependencies(openal openal-soft)
 else()
     find_package(OpenAL REQUIRED)
 endif()
 
-add_library(openal.hdll SHARED openal.c)
-
 set_as_hdll(openal)
 
 target_link_libraries(openal.hdll

+ 37 - 7
libs/sdl/CMakeLists.txt

@@ -1,12 +1,38 @@
-if(WIN32)
-    set(SDL2_PATH ${INCLUDES_BASE_DIR}/sdl)
-endif()
-find_package(SDL2 REQUIRED)
-
-add_library(sdl.hdll SHARED
+add_library(sdl.hdll
     sdl.c
     gl.c
 )
+
+if (ANDROID)
+	ExternalProject_Add(sdl2-project
+        URL https://github.com/libsdl-org/SDL/releases/download/release-2.32.8/SDL2-2.32.8.tar.gz
+        URL_HASH SHA256=0ca83e9c9b31e18288c7ec811108e58bac1f1bb5ec6577ad386830eac51c787e
+        CMAKE_ARGS
+            -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
+            -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
+            -DANDROID_PLATFORM=${ANDROID_PLATFORM}
+            -DANDROID_ABI=${CMAKE_ANDROID_ARCH_ABI}
+        # INSTALL_BYPRODUCTS in CMake 3.26+
+        BUILD_BYPRODUCTS <INSTALL_DIR>/${CMAKE_INSTALL_LIBDIR}/libSDL2.so
+        DOWNLOAD_EXTRACT_TIMESTAMP true
+    )
+    ExternalProject_Get_Property(sdl2-project INSTALL_DIR)
+
+    add_library(sdl2 SHARED IMPORTED)
+    set_target_properties(sdl2 PROPERTIES IMPORTED_LOCATION ${INSTALL_DIR}/${CMAKE_INSTALL_LIBDIR}/libSDL2.so)
+
+    set(SDL2_INCLUDE_DIR ${INSTALL_DIR}/${CMAKE_INSTALL_INCLUDEDIR}/SDL2)
+    set(SDL2_LIBRARY sdl2)
+
+    add_dependencies(sdl2 sdl2-project)
+else()
+    if(WIN32)
+        set(SDL2_PATH ${INCLUDES_BASE_DIR}/sdl)
+    endif()
+
+    find_package(SDL2 REQUIRED)
+endif()
+
 set_as_hdll(sdl)
 target_include_directories(sdl.hdll
     PRIVATE
@@ -25,7 +51,11 @@ if(WIN32)
     )
 endif()
 
-if(APPLE OR UNIX)
+if(ANDROID)
+    target_link_libraries(sdl.hdll m OpenSLES dl log android GLESv1_CM GLESv2 EGL GLESv3)
+endif()
+
+if((APPLE OR UNIX) AND NOT ANDROID)
     find_package(OpenGL REQUIRED)
     target_include_directories(sdl.hdll
         PRIVATE

+ 3 - 1
libs/sdl/gl.c

@@ -24,7 +24,7 @@
 #	define HL_GLES
 #elif defined(HL_ANDROID)
 #	include <SDL.h>
-#	include <GLES3/gl3.h>
+#	include <GLES3/gl32.h>
 #	include <GLES3/gl3ext.h>
 #	define HL_GLES
 #else
@@ -42,6 +42,8 @@
 #	define glFramebufferTexture(...) ES_NOT_SUPPORTED
 #	define glDispatchCompute(...) ES_NOT_SUPPORTED
 #	define glMemoryBarrier(...) ES_NOT_SUPPORTED
+#	define glGetBufferSubData(...) ES_NOT_SUPPORTED
+#	define glShaderStorageBlockBinding(...) ES_NOT_SUPPORTED
 #	define glPolygonMode(face,mode) if( mode != 0x1B02 ) ES_NOT_SUPPORTED
 #	define glGetQueryObjectiv glGetQueryObjectuiv
 #	define glClearDepth glClearDepthf

+ 1 - 1
libs/sqlite/CMakeLists.txt

@@ -1,4 +1,4 @@
-add_library(sqlite.hdll SHARED
+add_library(sqlite.hdll
     sqlite.c
     ${INCLUDES_BASE_DIR}/sqlite/src/sqlite3.c
 )

+ 28 - 6
libs/ssl/CMakeLists.txt

@@ -1,8 +1,12 @@
+add_library(ssl.hdll
+    ssl.c
+)
+
 if (WIN32)
     set(MBEDTLS_INCLUDE_DIRS ${INCLUDES_BASE_DIR}/mbedtls/include .)
     set(MBEDTLS_LIBRARIES crypt32)
 
-    add_library(ssl.hdll SHARED
+    target_sources(ssl.hdll PRIVATE
         ${INCLUDES_BASE_DIR}/mbedtls/library/aes.c
         ${INCLUDES_BASE_DIR}/mbedtls/library/aesce.c
         ${INCLUDES_BASE_DIR}/mbedtls/library/aesni.c
@@ -111,19 +115,37 @@ if (WIN32)
         ${INCLUDES_BASE_DIR}/mbedtls/library/x509write.c
         ${INCLUDES_BASE_DIR}/mbedtls/library/x509write_crt.c
         ${INCLUDES_BASE_DIR}/mbedtls/library/x509write_csr.c
-        ssl.c
     )
 
     target_compile_definitions(ssl.hdll
         PRIVATE
         MBEDTLS_USER_CONFIG_FILE="mbedtls_user_config.h"
     )
+elseif(ANDROID)
+	ExternalProject_Add(mbedtls-project
+        URL https://github.com/Mbed-TLS/mbedtls/releases/download/mbedtls-3.6.4/mbedtls-3.6.4.tar.bz2
+        URL_HASH SHA256=ec35b18a6c593cf98c3e30db8b98ff93e8940a8c4e690e66b41dfc011d678110
+        CMAKE_ARGS
+            -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
+            -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
+            -DANDROID_PLATFORM=${ANDROID_PLATFORM}
+            -DANDROID_ABI=${CMAKE_ANDROID_ARCH_ABI}
+            -DBUILD_SHARED_LIBS=OFF
+        # INSTALL_BYPRODUCTS in CMake 3.26+
+        BUILD_BYPRODUCTS <INSTALL_DIR>/${CMAKE_INSTALL_LIBDIR}/libmbedtls.a
+        DOWNLOAD_EXTRACT_TIMESTAMP true
+    )
+    ExternalProject_Get_Property(mbedtls-project INSTALL_DIR)
+
+    add_library(mbedtls STATIC IMPORTED)
+    set_target_properties(mbedtls PROPERTIES IMPORTED_LOCATION ${INSTALL_DIR}/${CMAKE_INSTALL_LIBDIR}/libmbedtls.a)
+
+    set(MBEDTLS_INCLUDE_DIRS ${INSTALL_DIR}/include)
+    set(MBEDTLS_LIBRARIES mbedtls)
+
+    add_dependencies(mbedtls mbedtls-project)
 else()
     find_package(MbedTLS REQUIRED)
-
-    add_library(ssl.hdll SHARED
-        ssl.c
-    )
 endif()
 
 set_as_hdll(ssl)

+ 1 - 1
libs/ui/CMakeLists.txt

@@ -1,4 +1,4 @@
-add_library(ui.hdll SHARED ui_stub.c)
+add_library(ui.hdll ui_stub.c)
 
 if(WIN32)
     set_target_properties(ui.hdll PROPERTIES SOURCES ui_win.c)

+ 25 - 1
libs/uv/CMakeLists.txt

@@ -1,4 +1,4 @@
-add_library(uv.hdll SHARED
+add_library(uv.hdll
     uv.c
 )
 
@@ -37,6 +37,30 @@ if(WIN32)
             ${INCLUDES_BASE_DIR}/libuv/src/win/winapi.c
             ${INCLUDES_BASE_DIR}/libuv/src/win/winsock.c
     )
+elseif(ANDROID)
+	ExternalProject_Add(libuv-project
+        URL https://github.com/libuv/libuv/archive/refs/tags/v1.51.0.tar.gz
+        URL_HASH SHA256=27e55cf7083913bfb6826ca78cde9de7647cded648d35f24163f2d31bb9f51cd
+        CMAKE_ARGS
+            -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
+            -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
+            -DANDROID_PLATFORM=${ANDROID_PLATFORM}
+            -DANDROID_ABI=${CMAKE_ANDROID_ARCH_ABI}
+            -DLIBUV_BUILD_SHARED=OFF
+            -DLIBUV_BUILD_TESTS=OFF
+        # INSTALL_BYPRODUCTS in CMake 3.26+
+        BUILD_BYPRODUCTS <INSTALL_DIR>/${CMAKE_INSTALL_LIBDIR}/libuv.a
+        DOWNLOAD_EXTRACT_TIMESTAMP true
+    )
+    ExternalProject_Get_Property(libuv-project INSTALL_DIR)
+
+    add_library(libuv STATIC IMPORTED)
+    set_target_properties(libuv PROPERTIES IMPORTED_LOCATION ${INSTALL_DIR}/${CMAKE_INSTALL_LIBDIR}/libuv.a)
+
+    set(LibUV_INCLUDE_DIRS ${INSTALL_DIR}/${CMAKE_INSTALL_INCLUDEDIR})
+    set(LibUV_LIBRARIES libuv)
+
+    add_dependencies(libuv libuv-project)
 else()
     find_package(LibUV)
 endif()

+ 1 - 1
libs/video/CMakeLists.txt

@@ -9,7 +9,7 @@ if(WIN32)
     find_library(FFMPEG_LIBRARY_swscale swscale PATHS ${INCLUDES_BASE_DIR}/ffmpeg/lib)
     set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARY_avcodec} ${FFMPEG_LIBRARY_avformat} ${FFMPEG_LIBRARY_avutil} ${FFMPEG_LIBRARY_swscale})
 
-    add_library(video.hdll SHARED video.c)
+    add_library(video.hdll video.c)
 
     set_as_hdll(video)
 

+ 7 - 3
src/hlc_main.c

@@ -67,7 +67,11 @@ extern void sys_global_exit();
 #	define _CrtCheckMemory()
 #endif
 
-#if defined(HL_LINUX) || defined(HL_MAC)
+#if defined(HL_LINUX) && (!defined(HL_ANDROID) || __ANDROID_MIN_SDK_VERSION__ >= 33)
+#define HL_LINUX_BACKTRACE
+#endif
+
+#if defined(HL_LINUX_BACKTRACE) || defined(HL_MAC)
 #	include <execinfo.h>
 #endif
 
@@ -96,7 +100,7 @@ static uchar *hlc_resolve_symbol( void *addr, uchar *out, int *outSize ) {
 		*outSize = usprintf(out,*outSize,USTR("%s(%s:%d)"),data.sym.Name,wcsrchr(line.FileName,'\\')+1,(int)line.LineNumber);
 		return out;
 	}
-#elif defined(HL_LINUX) || defined(HL_MAC)
+#elif defined(HL_LINUX_BACKTRACE) || defined(HL_MAC)
 	void *array[1];
 	char **strings;
 	array[0] = addr;
@@ -124,7 +128,7 @@ static int hlc_capture_stack( void **stack, int size ) {
 #	endif
 #	ifdef HL_WIN_DESKTOP
 	count = CaptureStackBackTrace(2, size, stack, NULL) - 8; // 8 startup
-#	elif defined(HL_LINUX)
+#	elif defined(HL_LINUX_BACKTRACE)
 	count = backtrace(stack, size) - 8;
 #	elif defined(HL_MAC)
 	count = backtrace(stack, size) - 6;