Skip to content

Commit

Permalink
feat: Initialize Android support
Browse files Browse the repository at this point in the history
Signed-off-by: Cryolitia PukNgae <[email protected]>
  • Loading branch information
Cryolitia committed Jul 29, 2024
1 parent 78cf637 commit d7ddfd4
Show file tree
Hide file tree
Showing 10 changed files with 114 additions and 21 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,25 @@ cmake --build . --parallel -t vgg_container
cmake --install . --prefix <path/to/vgg_ios/VggRuntime/external>
```

#### Android Building example

We currently only support Android NDK = 27 and Android API_LEVEL >= 24.

You need to download Android NDK r27 from here: https://github.com/android/ndk/releases/tag/r27

Build & install `vgg_container` libraries for [vgg_android](https://github.com/verygoodgraphics/vgg_android).

```bash
mkdir build.android
cd build.android
# For x86_64
cmake .. -DCMAKE_TOOLCHAIN_FILE=<android_ndk_path>/build/cmake/android.toolchain.cmake -DVGG_VAR_TARGET="Android-x86_64" -DANDROID_NDK=<android_ndk_path> -DANDROID_PLATFORM=android-24
# For arm64
cmake .. -DCMAKE_TOOLCHAIN_FILE=<android_ndk_path>/build/cmake/android.toolchain.cmake -DVGG_VAR_TARGET="Android-arm64-v8a" -DANDROID_NDK=<android_ndk_path> -DANDROID_PLATFORM=android-24
cmake --build . --parallel
cmake --install . --prefix <path/to/vgg_android/VggRuntime/external>
```

#### Qt building example

Build & install `vgg_container` libraries for [vgg_qt](https://github.com/verygoodgraphics/vgg_qt).
Expand Down
8 changes: 5 additions & 3 deletions cmake/ImportSkia.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ message(STATUS "${NINJA_COMMAND} is found.")

set(SKIA_LIB_LINK_TYPE "dynamic")
if(VGG_VAR_TARGET STREQUAL "WASM"
OR VGG_VAR_TARGET MATCHES "^iOS")
OR VGG_VAR_TARGET MATCHES "^iOS"
OR VGG_VAR_TARGET MATCHES "^Android")
set(SKIA_LIB_LINK_TYPE "static")
endif()

Expand Down Expand Up @@ -167,7 +168,8 @@ endforeach(ITEM)

foreach(LIB_NAME ${SKIA_LIB_NAMES})
unset(FOUND_LIB_${LIB_NAME} CACHE)
if(VGG_VAR_TARGET STREQUAL "WASM")
if(VGG_VAR_TARGET STREQUAL "WASM"
OR VGG_VAR_TARGET MATCHES "^Android")
set(FOUND_LIB_${LIB_NAME} "${SKIA_LIB_DIR}/lib${LIB_NAME}.a")
else()
find_library(FOUND_LIB_${LIB_NAME} NAMES ${LIB_NAME} ${LIB_NAME}.dll PATHS ${SKIA_LIB_DIR})
Expand All @@ -185,6 +187,6 @@ foreach(LIB_NAME ${SKIA_LIB_NAMES})
target_include_directories(skia::${LIB_NAME} INTERFACE ${SKIA_INCLUDE_DIRS})
list(APPEND SKIA_LIBS skia::${LIB_NAME})
else()
message(STATUS "${LIB_NAME} not found in " ${SKIA_LIB_DIR})
message(FATAL_ERROR "${LIB_NAME} not found in " ${SKIA_LIB_DIR})
endif()
endforeach(LIB_NAME)
44 changes: 43 additions & 1 deletion cmake/SkiaUtils.cmake
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
# Please refer to the skia build document for all supported featuers.
# Only those needed are covered here.
# https://skia.org/docs/user/build/
if(NOT VGG_CONTAINER_FOR_QT AND NOT VGG_VAR_TARGET MATCHES "^iOS")
if(NOT VGG_CONTAINER_FOR_QT
AND NOT VGG_VAR_TARGET MATCHES "^iOS"
AND NOT VGG_VAR_TARGET MATCHES "^Android")
find_package(Vulkan)
endif()

if(Vulkan_FOUND)
set(VULKAN_AVAILABLE "true")
else()
set(VULKAN_AVAILABLE "false")
endif()
if (VGG_VAR_TARGET MATCHES "^Android")
string(REPLACE "android-" "" api_level ${ANDROID_PLATFORM})
if(NOT api_level LESS 24)
message(STATUS "Found Android API Level ${api_level}, vulkan enabled.")
set(VULKAN_AVAILABLE "true")
else()
message(STATUS "Found Android API Level ${api_level}, vulkan only support API_LEVEL>=24, disabled")
set(VULKAN_AVAILABLE "false")
endif()
endif()

set(SKIA_PRESET_FEATURES_FOR_LINUX
"skia_use_egl=true
skia_use_freetype=true
Expand Down Expand Up @@ -208,6 +222,20 @@ skia_use_system_zlib=false
skia_use_vulkan=false
skia_use_zlib=true")

set(SKIA_PRESET_FEATURES_FOR_ANDROID
"is_official_build=true
ndk_api=${api_level}
skia_use_system_freetype2=false
skia_use_system_libpng=false
skia_use_system_libjpeg_turbo=false
skia_use_system_harfbuzz=false
skia_use_system_libwebp=false
skia_use_expat=true
skia_use_freetype=true
skia_use_system_expat=false
skia_use_system_icu=false
skia_use_vulkan=${VULKAN_AVAILABLE}")

cmake_minimum_required(VERSION 3.19) # for string(JSON ...)

function(list_from_json out_var json)
Expand Down Expand Up @@ -268,6 +296,20 @@ elseif(platform MATCHES "^iOS")
foreach(OPT ${SKIA_PRESET_FEATURES_FOR_IOS})
string(APPEND OPTIONS " ${OPT}")
endforeach(OPT)
elseif(platform MATCHES "^Android")
if(platform STREQUAL "Android-armeabi-v7a")
string(APPEND OPTIONS " target_cpu=\"arm\"")
elseif(platform STREQUAL "Android-arm64-v8a")
string(APPEND OPTIONS " target_cpu=\"arm64\"")
elseif(platform STREQUAL "Android-x86_64")
string(APPEND OPTIONS " target_cpu=\"x64\"")
else()
message(FATAL_ERROR "target type for skia build is not supported: " ${platform})
endif()
string(APPEND OPTIONS " ndk=\"${ANDROID_NDK}\"")
foreach(OPT ${SKIA_PRESET_FEATURES_FOR_ANDROID})
string(APPEND OPTIONS " ${OPT}")
endforeach(OPT)
else()
message(FATAL_ERROR "target type for skia build is invalid: " ${platform})
endif()
Expand Down
4 changes: 4 additions & 0 deletions cmake/VGGVars.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ else()
if (VGG_VAR_TARGET MATCHES "^iOS")
set(VGG_VAR_TARGET_PLATFORM "iOS" CACHE STRING "" FORCE)
set(VGG_VAR_TARGET_ARCH "ARM" CACHE STRING "" FORCE)
elseif (VGG_VAR_TARGET MATCHES "^Android")
if(NOT DEFINED ANDROID_NDK)
message(FATAL_ERROR "ANDROID_NDK must be set.")
endif()
elseif (VGG_VAR_TARGET STREQUAL "WASM")
set(VGG_VAR_TARGET_PLATFORM "WASM" CACHE STRING "" FORCE)
set(VGG_VAR_TARGET_ARCH "WASM" CACHE STRING "" FORCE)
Expand Down
4 changes: 3 additions & 1 deletion config/DepsConfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
"url": "https://github.com/nodejs-mobile/nodejs-mobile/archive/refs/tags/v18.17.2.tar.gz",
"filename": "nodejs-mobile-v18.17.2.tar.gz",
"ios-binary-url": "https://github.com/nodejs-mobile/nodejs-mobile/releases/download/v18.17.2/nodejs-mobile-v18.17.2-ios.zip",
"ios-binary-filename": "nodejs-mobile-v18.17.2-ios.zip"
"ios-binary-filename": "nodejs-mobile-v18.17.2-ios.zip",
"android-binary-url": "https://github.com/nodejs-mobile/nodejs-mobile/releases/download/v18.17.2/nodejs-mobile-v18.17.2-android.zip",
"android-binary-filename": "nodejs-mobile-v18.17.2-android.zip"
},
"sdl2": {
"url": "https://github.com/libsdl-org/SDL/releases/download/release-2.28.5/SDL2-devel-2.28.5-VC.zip",
Expand Down
35 changes: 25 additions & 10 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ if(MSVC)
"string(STRIP \"\${SDL2_LIBRARIES}\" SDL2_LIBRARIES)")
endif()

if(VGG_VAR_TARGET MATCHES "^iOS")
if(VGG_VAR_TARGET MATCHES "^iOS"
OR VGG_VAR_TARGET MATCHES "^Android")
# Download src
set(NODE_FOLDER "nodejs-mobile" CACHE STRING "node folder name" FORCE)
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${NODE_FOLDER}")
Expand All @@ -85,13 +86,21 @@ if(VGG_VAR_TARGET MATCHES "^iOS")
file(RENAME ${NODEJS_MOBILE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/${NODE_FOLDER}")
endif()

# Download the pre-built binary (NodeMobile.xcframework)
set(LIB_NODE_FOLDER "nodejs-mobile-ios" CACHE STRING "lib node folder name" FORCE)
# Download the iOS pre-built binary (NodeMobile.xcframework)
set(LIB_NODE_FOLDER "nodejs-mobile-lib" CACHE STRING "lib node folder name" FORCE)
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NODE_FOLDER}")
string(JSON NODEJS_URL ERROR_VARIABLE NODEJS_URL_NOTFOUND GET ${DEPS_CONFIG} nodejs-mobile ios-binary-url)
string(JSON NODEJS_FILENAME ERROR_VARIABLE NODEJS_FILENAME_NOTFOUND GET ${DEPS_CONFIG} nodejs-mobile ios-binary-filename)
if(NODEJS_URL_NOTFOUND OR NODEJS_FILENAME_NOTFOUND)
message(FATAL_ERROR "Nodejs-mobile ios binary url or filename not found in config/DepsConfig.json")
if(VGG_VAR_TARGET MATCHES "^iOS")
string(JSON NODEJS_URL ERROR_VARIABLE NODEJS_URL_NOTFOUND GET ${DEPS_CONFIG} nodejs-mobile ios-binary-url)
string(JSON NODEJS_FILENAME ERROR_VARIABLE NODEJS_FILENAME_NOTFOUND GET ${DEPS_CONFIG} nodejs-mobile ios-binary-filename)
if(NODEJS_URL_NOTFOUND OR NODEJS_FILENAME_NOTFOUND)
message(FATAL_ERROR "Nodejs-mobile ios binary url or filename not found in config/DepsConfig.json")
endif()
elseif(VGG_VAR_TARGET MATCHES "^Android")
string(JSON NODEJS_URL ERROR_VARIABLE NODEJS_URL_NOTFOUND GET ${DEPS_CONFIG} nodejs-mobile android-binary-url)
string(JSON NODEJS_FILENAME ERROR_VARIABLE NODEJS_FILENAME_NOTFOUND GET ${DEPS_CONFIG} nodejs-mobile android-binary-filename)
if(NODEJS_URL_NOTFOUND OR NODEJS_FILENAME_NOTFOUND)
message(FATAL_ERROR "Nodejs-mobile android binary url or filename not found in config/DepsConfig.json")
endif()
endif()

set(LIB_DOWNLOAD_AT_PATH "${CMAKE_SOURCE_DIR}/downloads/${NODEJS_FILENAME}")
Expand All @@ -103,7 +112,11 @@ if(VGG_VAR_TARGET MATCHES "^iOS")
endif()

file(ARCHIVE_EXTRACT INPUT ${LIB_DOWNLOAD_AT_PATH} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR})
file(GLOB LIB_NODEJS_MOBILE_DIR LIST_DIRECTORIES true nodejs-mobile-*-ios)
if(VGG_VAR_TARGET MATCHES "^iOS")
file(GLOB LIB_NODEJS_MOBILE_DIR LIST_DIRECTORIES true nodejs-mobile-*-ios)
elseif(VGG_VAR_TARGET MATCHES "^Android")
file(GLOB LIB_NODEJS_MOBILE_DIR LIST_DIRECTORIES true nodejs-mobile-*-android)
endif()
file(RENAME ${LIB_NODEJS_MOBILE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NODE_FOLDER}")
endif()

Expand Down Expand Up @@ -158,7 +171,8 @@ target_include_directories(vgg_libnode PUBLIC
${NODE_FOLDER}/deps/uv/include
${NODE_FOLDER}/deps/v8/include)

if(NOT VGG_VAR_TARGET MATCHES "^iOS")
if(NOT VGG_VAR_TARGET MATCHES "^iOS"
AND NOT VGG_VAR_TARGET MATCHES "^Android")
if(NOT MSVC)
add_dependencies(vgg_libnode vgg_libnode_building)
endif()
Expand Down Expand Up @@ -202,7 +216,8 @@ set(LIBNODE_DEPS
zlib
vgg_libnode_stub
)
if(VGG_VAR_TARGET MATCHES "^iOS")
if(VGG_VAR_TARGET MATCHES "^iOS"
OR VGG_VAR_TARGET MATCHES "^Android")
target_link_libraries(vgg_libnode PRIVATE
vgg_libnode_stub
)
Expand Down
5 changes: 4 additions & 1 deletion src/Entry/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
if(NOT EMSCRIPTEN)
add_subdirectory(SDL)
if (NOT VGG_VAR_TARGET MATCHES "^iOS"
AND NOT VGG_VAR_TARGET MATCHES "^Android")
add_subdirectory(SDL)
endif()
add_subdirectory(Exporter)
add_subdirectory(Container)
else()
Expand Down
2 changes: 1 addition & 1 deletion src/Entry/SDL/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ if(MSVC)
"${SDL2_DLL_PATH}"
"${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}"
)
endif()
endif()
10 changes: 7 additions & 3 deletions src/Layer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ if(LAYER_SHARED_LIBRARY)
target_compile_definitions(vgg_layer PUBLIC -DLAYER_SHARED_LIBRARY)
else()
add_library(vgg_layer STATIC)
if(VGG_VAR_TARGET MATCHES "^iOS")
if(VGG_VAR_TARGET MATCHES "^iOS"
OR VGG_VAR_TARGET MATCHES "^Android")
target_compile_options(vgg_layer PUBLIC -fno-rtti)
endif()
endif()
Expand All @@ -27,7 +28,8 @@ target_include_directories(
${VGG_CONTRIB_JSON_INCLUDE}
${VGG_CONTRIB_RAPIDFUZZCPP_INCLUDE})

if(NOT VGG_VAR_TARGET MATCHES "^iOS")
if(NOT VGG_VAR_TARGET MATCHES "^iOS"
AND NOT VGG_VAR_TARGET MATCHES "^Android")
# find OpenGL library
cmake_policy(SET CMP0072 NEW)
find_package(OpenGL REQUIRED)
Expand All @@ -37,7 +39,9 @@ target_include_directories(vgg_layer PUBLIC ${VGG_CONTRIB_JSON_INCLUDE})
# REFACTOR:: make skia hidden from public
target_link_libraries(vgg_layer PUBLIC ${SKIA_LIBS} glm)
target_link_libraries(vgg_layer PRIVATE ${OPENGL_LIBRARIES} vgg_utility)
if(NOT VGG_CONTAINER_FOR_QT AND NOT VGG_VAR_TARGET MATCHES "^iOS")
if(NOT VGG_CONTAINER_FOR_QT
AND NOT VGG_VAR_TARGET MATCHES "^iOS"
AND NOT VGG_VAR_TARGET MATCHES "^Android")
find_package(Vulkan)
endif()
if(Vulkan_FOUND)
Expand Down
4 changes: 3 additions & 1 deletion test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
if (EMSCRIPTEN)
if (EMSCRIPTEN
OR VGG_VAR_TARGET MATCHES "^iOS"
OR VGG_VAR_TARGET MATCHES "^Android")
else()
add_subdirectory(render)
if(NOT ENABLE_UNIT_TEST)
Expand Down

0 comments on commit d7ddfd4

Please sign in to comment.