Skip to content

Commit 1b423bc

Browse files
committed
feat: Initialize Android support
Signed-off-by: Cryolitia PukNgae <[email protected]>
1 parent 78cf637 commit 1b423bc

11 files changed

+115
-22
lines changed

README.md

+19
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,25 @@ cmake --build . --parallel -t vgg_container
106106
cmake --install . --prefix <path/to/vgg_ios/VggRuntime/external>
107107
```
108108

109+
#### Android Building example
110+
111+
We currently only support Android NDK = 27 and Android API_LEVEL >= 24.
112+
113+
You need to download Android NDK r27 from here: https://github.com/android/ndk/releases/tag/r27
114+
115+
Build & install `vgg_container` libraries for [vgg_android](https://github.com/verygoodgraphics/vgg_android).
116+
117+
```bash
118+
mkdir build.android
119+
cd build.android
120+
# For x86_64
121+
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
122+
# For arm64
123+
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
124+
cmake --build . --parallel
125+
cmake --install . --prefix <path/to/vgg_android/VggRuntime/external>
126+
```
127+
109128
#### Qt building example
110129

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

cmake/ImportSkia.cmake

+5-3
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ message(STATUS "${NINJA_COMMAND} is found.")
103103

104104
set(SKIA_LIB_LINK_TYPE "dynamic")
105105
if(VGG_VAR_TARGET STREQUAL "WASM"
106-
OR VGG_VAR_TARGET MATCHES "^iOS")
106+
OR VGG_VAR_TARGET MATCHES "^iOS"
107+
OR VGG_VAR_TARGET MATCHES "^Android")
107108
set(SKIA_LIB_LINK_TYPE "static")
108109
endif()
109110

@@ -167,7 +168,8 @@ endforeach(ITEM)
167168

168169
foreach(LIB_NAME ${SKIA_LIB_NAMES})
169170
unset(FOUND_LIB_${LIB_NAME} CACHE)
170-
if(VGG_VAR_TARGET STREQUAL "WASM")
171+
if(VGG_VAR_TARGET STREQUAL "WASM"
172+
OR VGG_VAR_TARGET MATCHES "^Android")
171173
set(FOUND_LIB_${LIB_NAME} "${SKIA_LIB_DIR}/lib${LIB_NAME}.a")
172174
else()
173175
find_library(FOUND_LIB_${LIB_NAME} NAMES ${LIB_NAME} ${LIB_NAME}.dll PATHS ${SKIA_LIB_DIR})
@@ -185,6 +187,6 @@ foreach(LIB_NAME ${SKIA_LIB_NAMES})
185187
target_include_directories(skia::${LIB_NAME} INTERFACE ${SKIA_INCLUDE_DIRS})
186188
list(APPEND SKIA_LIBS skia::${LIB_NAME})
187189
else()
188-
message(STATUS "${LIB_NAME} not found in " ${SKIA_LIB_DIR})
190+
message(FATAL_ERROR "${LIB_NAME} not found in " ${SKIA_LIB_DIR})
189191
endif()
190192
endforeach(LIB_NAME)

cmake/SkiaUtils.cmake

+43-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,28 @@
11
# Please refer to the skia build document for all supported featuers.
22
# Only those needed are covered here.
33
# https://skia.org/docs/user/build/
4-
if(NOT VGG_CONTAINER_FOR_QT AND NOT VGG_VAR_TARGET MATCHES "^iOS")
4+
if(NOT VGG_CONTAINER_FOR_QT
5+
AND NOT VGG_VAR_TARGET MATCHES "^iOS"
6+
AND NOT VGG_VAR_TARGET MATCHES "^Android")
57
find_package(Vulkan)
68
endif()
9+
710
if(Vulkan_FOUND)
811
set(VULKAN_AVAILABLE "true")
912
else()
1013
set(VULKAN_AVAILABLE "false")
1114
endif()
15+
if (VGG_VAR_TARGET MATCHES "^Android")
16+
string(REPLACE "android-" "" api_level ${ANDROID_PLATFORM})
17+
if(NOT api_level LESS 24)
18+
message(STATUS "Found Android API Level ${api_level}, vulkan enabled.")
19+
set(VULKAN_AVAILABLE "true")
20+
else()
21+
message(STATUS "Found Android API Level ${api_level}, vulkan only support API_LEVEL>=24, disabled")
22+
set(VULKAN_AVAILABLE "false")
23+
endif()
24+
endif()
25+
1226
set(SKIA_PRESET_FEATURES_FOR_LINUX
1327
"skia_use_egl=true
1428
skia_use_freetype=true
@@ -208,6 +222,20 @@ skia_use_system_zlib=false
208222
skia_use_vulkan=false
209223
skia_use_zlib=true")
210224

225+
set(SKIA_PRESET_FEATURES_FOR_ANDROID
226+
"is_official_build=true
227+
ndk_api=${api_level}
228+
skia_use_system_freetype2=false
229+
skia_use_system_libpng=false
230+
skia_use_system_libjpeg_turbo=false
231+
skia_use_system_harfbuzz=false
232+
skia_use_system_libwebp=false
233+
skia_use_expat=true
234+
skia_use_freetype=true
235+
skia_use_system_expat=false
236+
skia_use_system_icu=false
237+
skia_use_vulkan=${VULKAN_AVAILABLE}")
238+
211239
cmake_minimum_required(VERSION 3.19) # for string(JSON ...)
212240

213241
function(list_from_json out_var json)
@@ -268,6 +296,20 @@ elseif(platform MATCHES "^iOS")
268296
foreach(OPT ${SKIA_PRESET_FEATURES_FOR_IOS})
269297
string(APPEND OPTIONS " ${OPT}")
270298
endforeach(OPT)
299+
elseif(platform MATCHES "^Android")
300+
if(platform STREQUAL "Android-armeabi-v7a")
301+
string(APPEND OPTIONS " target_cpu=\"arm\"")
302+
elseif(platform STREQUAL "Android-arm64-v8a")
303+
string(APPEND OPTIONS " target_cpu=\"arm64\"")
304+
elseif(platform STREQUAL "Android-x86_64")
305+
string(APPEND OPTIONS " target_cpu=\"x64\"")
306+
else()
307+
message(FATAL_ERROR "target type for skia build is not supported: " ${platform})
308+
endif()
309+
string(APPEND OPTIONS " ndk=\"${ANDROID_NDK}\"")
310+
foreach(OPT ${SKIA_PRESET_FEATURES_FOR_ANDROID})
311+
string(APPEND OPTIONS " ${OPT}")
312+
endforeach(OPT)
271313
else()
272314
message(FATAL_ERROR "target type for skia build is invalid: " ${platform})
273315
endif()

cmake/VGGVars.cmake

+4
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,10 @@ else()
172172
if (VGG_VAR_TARGET MATCHES "^iOS")
173173
set(VGG_VAR_TARGET_PLATFORM "iOS" CACHE STRING "" FORCE)
174174
set(VGG_VAR_TARGET_ARCH "ARM" CACHE STRING "" FORCE)
175+
elseif (VGG_VAR_TARGET MATCHES "^Android")
176+
if(NOT DEFINED ANDROID_NDK)
177+
message(FATAL_ERROR "ANDROID_NDK must be set.")
178+
endif()
175179
elseif (VGG_VAR_TARGET STREQUAL "WASM")
176180
set(VGG_VAR_TARGET_PLATFORM "WASM" CACHE STRING "" FORCE)
177181
set(VGG_VAR_TARGET_ARCH "WASM" CACHE STRING "" FORCE)

config/DepsConfig.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
"url": "https://github.com/nodejs-mobile/nodejs-mobile/archive/refs/tags/v18.17.2.tar.gz",
1515
"filename": "nodejs-mobile-v18.17.2.tar.gz",
1616
"ios-binary-url": "https://github.com/nodejs-mobile/nodejs-mobile/releases/download/v18.17.2/nodejs-mobile-v18.17.2-ios.zip",
17-
"ios-binary-filename": "nodejs-mobile-v18.17.2-ios.zip"
17+
"ios-binary-filename": "nodejs-mobile-v18.17.2-ios.zip",
18+
"android-binary-url": "https://github.com/nodejs-mobile/nodejs-mobile/releases/download/v18.17.2/nodejs-mobile-v18.17.2-android.zip",
19+
"android-binary-filename": "nodejs-mobile-v18.17.2-android.zip"
1820
},
1921
"sdl2": {
2022
"url": "https://github.com/libsdl-org/SDL/releases/download/release-2.28.5/SDL2-devel-2.28.5-VC.zip",

lib/CMakeLists.txt

+25-10
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ if(MSVC)
6262
"string(STRIP \"\${SDL2_LIBRARIES}\" SDL2_LIBRARIES)")
6363
endif()
6464

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

88-
# Download the pre-built binary (NodeMobile.xcframework)
89-
set(LIB_NODE_FOLDER "nodejs-mobile-ios" CACHE STRING "lib node folder name" FORCE)
89+
# Download the iOS pre-built binary (NodeMobile.xcframework)
90+
set(LIB_NODE_FOLDER "nodejs-mobile-lib" CACHE STRING "lib node folder name" FORCE)
9091
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NODE_FOLDER}")
91-
string(JSON NODEJS_URL ERROR_VARIABLE NODEJS_URL_NOTFOUND GET ${DEPS_CONFIG} nodejs-mobile ios-binary-url)
92-
string(JSON NODEJS_FILENAME ERROR_VARIABLE NODEJS_FILENAME_NOTFOUND GET ${DEPS_CONFIG} nodejs-mobile ios-binary-filename)
93-
if(NODEJS_URL_NOTFOUND OR NODEJS_FILENAME_NOTFOUND)
94-
message(FATAL_ERROR "Nodejs-mobile ios binary url or filename not found in config/DepsConfig.json")
92+
if(VGG_VAR_TARGET MATCHES "^iOS")
93+
string(JSON NODEJS_URL ERROR_VARIABLE NODEJS_URL_NOTFOUND GET ${DEPS_CONFIG} nodejs-mobile ios-binary-url)
94+
string(JSON NODEJS_FILENAME ERROR_VARIABLE NODEJS_FILENAME_NOTFOUND GET ${DEPS_CONFIG} nodejs-mobile ios-binary-filename)
95+
if(NODEJS_URL_NOTFOUND OR NODEJS_FILENAME_NOTFOUND)
96+
message(FATAL_ERROR "Nodejs-mobile ios binary url or filename not found in config/DepsConfig.json")
97+
endif()
98+
elseif(VGG_VAR_TARGET MATCHES "^Android")
99+
string(JSON NODEJS_URL ERROR_VARIABLE NODEJS_URL_NOTFOUND GET ${DEPS_CONFIG} nodejs-mobile android-binary-url)
100+
string(JSON NODEJS_FILENAME ERROR_VARIABLE NODEJS_FILENAME_NOTFOUND GET ${DEPS_CONFIG} nodejs-mobile android-binary-filename)
101+
if(NODEJS_URL_NOTFOUND OR NODEJS_FILENAME_NOTFOUND)
102+
message(FATAL_ERROR "Nodejs-mobile android binary url or filename not found in config/DepsConfig.json")
103+
endif()
95104
endif()
96105

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

105114
file(ARCHIVE_EXTRACT INPUT ${LIB_DOWNLOAD_AT_PATH} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR})
106-
file(GLOB LIB_NODEJS_MOBILE_DIR LIST_DIRECTORIES true nodejs-mobile-*-ios)
115+
if(VGG_VAR_TARGET MATCHES "^iOS")
116+
file(GLOB LIB_NODEJS_MOBILE_DIR LIST_DIRECTORIES true nodejs-mobile-*-ios)
117+
elseif(VGG_VAR_TARGET MATCHES "^Android")
118+
file(GLOB LIB_NODEJS_MOBILE_DIR LIST_DIRECTORIES true nodejs-mobile-*-android)
119+
endif()
107120
file(RENAME ${LIB_NODEJS_MOBILE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NODE_FOLDER}")
108121
endif()
109122

@@ -158,7 +171,8 @@ target_include_directories(vgg_libnode PUBLIC
158171
${NODE_FOLDER}/deps/uv/include
159172
${NODE_FOLDER}/deps/v8/include)
160173

161-
if(NOT VGG_VAR_TARGET MATCHES "^iOS")
174+
if(NOT VGG_VAR_TARGET MATCHES "^iOS"
175+
AND NOT VGG_VAR_TARGET MATCHES "^Android")
162176
if(NOT MSVC)
163177
add_dependencies(vgg_libnode vgg_libnode_building)
164178
endif()
@@ -202,7 +216,8 @@ set(LIBNODE_DEPS
202216
zlib
203217
vgg_libnode_stub
204218
)
205-
if(VGG_VAR_TARGET MATCHES "^iOS")
219+
if(VGG_VAR_TARGET MATCHES "^iOS"
220+
NOT VGG_VAR_TARGET MATCHES "^Android")
206221
target_link_libraries(vgg_libnode PRIVATE
207222
vgg_libnode_stub
208223
)

src/Entry/CMakeLists.txt

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
if(NOT EMSCRIPTEN)
2-
add_subdirectory(SDL)
2+
if (NOT VGG_VAR_TARGET MATCHES "^iOS"
3+
AND NOT VGG_VAR_TARGET MATCHES "^Android")
4+
add_subdirectory(SDL)
5+
endif()
36
add_subdirectory(Exporter)
47
add_subdirectory(Container)
58
else()

src/Entry/Common/GPU/Vulkan/VulkanObject.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,7 @@ struct VkSwapchainObject
692692
swapInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
693693
swapInfo.presentMode = this->surface->m_supportedPresentMode[0];
694694
swapInfo.clipped = true;
695-
swapInfo.oldSwapchain = NULL;
695+
swapInfo.oldSwapchain = VK_NULL_HANDLE;
696696
swapInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
697697

698698
// Destroy old swap chain

src/Entry/SDL/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@ if(MSVC)
4040
"${SDL2_DLL_PATH}"
4141
"${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}"
4242
)
43-
endif()
43+
endif()

src/Layer/CMakeLists.txt

+7-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ if(LAYER_SHARED_LIBRARY)
55
target_compile_definitions(vgg_layer PUBLIC -DLAYER_SHARED_LIBRARY)
66
else()
77
add_library(vgg_layer STATIC)
8-
if(VGG_VAR_TARGET MATCHES "^iOS")
8+
if(VGG_VAR_TARGET MATCHES "^iOS"
9+
OR VGG_VAR_TARGET MATCHES "^Android")
910
target_compile_options(vgg_layer PUBLIC -fno-rtti)
1011
endif()
1112
endif()
@@ -27,7 +28,8 @@ target_include_directories(
2728
${VGG_CONTRIB_JSON_INCLUDE}
2829
${VGG_CONTRIB_RAPIDFUZZCPP_INCLUDE})
2930

30-
if(NOT VGG_VAR_TARGET MATCHES "^iOS")
31+
if(NOT VGG_VAR_TARGET MATCHES "^iOS"
32+
AND NOT VGG_VAR_TARGET MATCHES "^Android")
3133
# find OpenGL library
3234
cmake_policy(SET CMP0072 NEW)
3335
find_package(OpenGL REQUIRED)
@@ -37,7 +39,9 @@ target_include_directories(vgg_layer PUBLIC ${VGG_CONTRIB_JSON_INCLUDE})
3739
# REFACTOR:: make skia hidden from public
3840
target_link_libraries(vgg_layer PUBLIC ${SKIA_LIBS} glm)
3941
target_link_libraries(vgg_layer PRIVATE ${OPENGL_LIBRARIES} vgg_utility)
40-
if(NOT VGG_CONTAINER_FOR_QT AND NOT VGG_VAR_TARGET MATCHES "^iOS")
42+
if(NOT VGG_CONTAINER_FOR_QT
43+
AND NOT VGG_VAR_TARGET MATCHES "^iOS"
44+
AND NOT VGG_VAR_TARGET MATCHES "^Android")
4145
find_package(Vulkan)
4246
endif()
4347
if(Vulkan_FOUND)

test/CMakeLists.txt

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
if (EMSCRIPTEN)
1+
if (EMSCRIPTEN
2+
OR VGG_VAR_TARGET MATCHES "^iOS"
3+
OR VGG_VAR_TARGET MATCHES "^Android")
24
else()
35
add_subdirectory(render)
46
if(NOT ENABLE_UNIT_TEST)

0 commit comments

Comments
 (0)