Atlas - SdlAndroidFunctions.cmake
Home / ext / SDL / cmake / android Lines: 1 | Size: 10333 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1#[=======================================================================[ 2 3This CMake script contains functions to build an Android APK. 4It is (currently) limited to packaging binaries for a single architecture. 5 6#]=======================================================================] 7 8cmake_minimum_required(VERSION 3.7...3.28) 9 10if(NOT PROJECT_NAME MATCHES "^SDL.*") 11 message(WARNING "This module is internal to SDL and is currently not supported.") 12endif() 13 14function(_sdl_create_outdir_for_target OUTDIRECTORY TARGET) 15 set(outdir "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TARGET}.dir") 16 # Some CMake versions have a slow `cmake -E make_directory` implementation 17 if(NOT IS_DIRECTORY "${outdir}") 18 execute_process(COMMAND "${CMAKE_COMMAND}" -E make_directory "${outdir}") 19 endif() 20 set("${OUTDIRECTORY}" "${outdir}" PARENT_SCOPE) 21endfunction() 22 23function(sdl_create_android_debug_keystore TARGET) 24 set(output "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_debug.keystore") 25 add_custom_command(OUTPUT ${output} 26 COMMAND ${CMAKE_COMMAND} -E rm -f "${output}" 27 COMMAND SdlAndroid::keytool -genkey -keystore "${output}" -storepass android -alias androiddebugkey -keypass android -keyalg RSA -keysize 2048 -validity 10000 -dname "C=US, O=Android, CN=Android Debug" 28 ) 29 add_custom_target(${TARGET} DEPENDS "${output}") 30 set_property(TARGET ${TARGET} PROPERTY OUTPUT "${output}") 31endfunction() 32 33function(sdl_android_compile_resources TARGET) 34 cmake_parse_arguments(arg "" "RESFOLDER" "RESOURCES" ${ARGN}) 35 36 if(NOT arg_RESFOLDER AND NOT arg_RESOURCES) 37 message(FATAL_ERROR "Missing RESFOLDER or RESOURCES argument (need one or both)") 38 endif() 39 _sdl_create_outdir_for_target(outdir "${TARGET}") 40 set(out_files "") 41 42 set(res_files "") 43 if(arg_RESFOLDER) 44 get_filename_component(arg_RESFOLDER "${arg_RESFOLDER}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") 45 file(GLOB_RECURSE res_folder_files "${arg_RESFOLDER}/*") 46 list(APPEND res_files ${res_folder_files}) 47 48 foreach(res_file IN LISTS res_files) 49 file(RELATIVE_PATH rel_res_file "${arg_RESFOLDER}" "${res_file}") 50 string(REPLACE "/" "_" rel_comp_path "${rel_res_file}") 51 if(res_file MATCHES ".*res/values.*\\.xml$") 52 string(REGEX REPLACE "\\.xml" ".arsc" rel_comp_path "${rel_comp_path}") 53 endif() 54 set(comp_path "${outdir}/${rel_comp_path}.flat") 55 add_custom_command( 56 OUTPUT "${comp_path}" 57 COMMAND SdlAndroid::aapt2 compile -o "${outdir}" "${res_file}" 58 DEPENDS ${res_file} 59 ) 60 list(APPEND out_files "${comp_path}") 61 endforeach() 62 endif() 63 64 if(arg_RESOURCES) 65 list(APPEND res_files ${arg_RESOURCES}) 66 foreach(res_file IN LISTS arg_RESOURCES) 67 string(REGEX REPLACE ".*/res/" "" rel_res_file ${res_file}) 68 string(REPLACE "/" "_" rel_comp_path "${rel_res_file}") 69 if(res_file MATCHES ".*res/values.*\\.xml$") 70 string(REGEX REPLACE "\\.xml" ".arsc" rel_comp_path "${rel_comp_path}") 71 endif() 72 set(comp_path "${outdir}/${rel_comp_path}.flat") 73 add_custom_command( 74 OUTPUT "${comp_path}" 75 COMMAND SdlAndroid::aapt2 compile -o "${outdir}" "${res_file}" 76 DEPENDS ${res_file} 77 ) 78 list(APPEND out_files "${comp_path}") 79 endforeach() 80 endif() 81 82 add_custom_target(${TARGET} DEPENDS ${out_files}) 83 set_property(TARGET "${TARGET}" PROPERTY OUTPUTS "${out_files}") 84 set_property(TARGET "${TARGET}" PROPERTY SOURCES "${res_files}") 85endfunction() 86 87function(sdl_android_link_resources TARGET) 88 cmake_parse_arguments(arg "NO_DEBUG" "MIN_SDK_VERSION;TARGET_SDK_VERSION;ANDROID_JAR;OUTPUT_APK;MANIFEST;PACKAGE" "RES_TARGETS" ${ARGN}) 89 90 if(arg_MANIFEST) 91 get_filename_component(arg_MANIFEST "${arg_MANIFEST}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") 92 else() 93 message(FATAL_ERROR "sdl_add_android_link_resources_target requires a Android MANIFEST path (${arg_MANIFEST})") 94 endif() 95 if(NOT arg_PACKAGE) 96 file(READ "${arg_MANIFEST}" manifest_contents) 97 string(REGEX MATCH "package=\"([a-zA-Z0-9_.]+)\"" package_match "${manifest_contents}") 98 if(NOT package_match) 99 message(FATAL_ERROR "Could not extract package from Android manifest (${arg_MANIFEST})") 100 endif() 101 set(arg_PACKAGE "${CMAKE_MATCH_1}") 102 endif() 103 104 set(depends "") 105 106 _sdl_create_outdir_for_target(outdir "${TARGET}") 107 string(REPLACE "." "/" java_r_path "${arg_PACKAGE}") 108 get_filename_component(java_r_path "${java_r_path}" ABSOLUTE BASE_DIR "${outdir}") 109 set(java_r_path "${java_r_path}/R.java") 110 111 set(command SdlAndroid::aapt2 link) 112 if(NOT arg_NO_DEBUG) 113 list(APPEND command --debug-mode) 114 endif() 115 if(arg_MIN_SDK_VERSION) 116 list(APPEND command --min-sdk-version ${arg_MIN_SDK_VERSION}) 117 endif() 118 if(arg_TARGET_SDK_VERSION) 119 list(APPEND command --target-sdk-version ${arg_TARGET_SDK_VERSION}) 120 endif() 121 if(arg_ANDROID_JAR) 122 list(APPEND command -I "${arg_ANDROID_JAR}") 123 else() 124 list(APPEND command -I "${SDL_ANDROID_PLATFORM_ANDROID_JAR}") 125 endif() 126 if(NOT arg_OUTPUT_APK) 127 set(arg_OUTPUT_APK "${TARGET}.apk") 128 endif() 129 get_filename_component(arg_OUTPUT_APK "${arg_OUTPUT_APK}" ABSOLUTE BASE_DIR "${outdir}") 130 list(APPEND command -o "${arg_OUTPUT_APK}") 131 list(APPEND command --java "${outdir}") 132 list(APPEND command --manifest "${arg_MANIFEST}") 133 foreach(res_target IN LISTS arg_RES_TARGETS) 134 list(APPEND command $<TARGET_PROPERTY:${res_target},OUTPUTS>) 135 list(APPEND depends $<TARGET_PROPERTY:${res_target},OUTPUTS>) 136 endforeach() 137 add_custom_command( 138 OUTPUT "${arg_OUTPUT_APK}" "${java_r_path}" 139 COMMAND ${command} 140 DEPENDS ${depends} ${arg_MANIFEST} 141 COMMAND_EXPAND_LISTS 142 VERBATIM 143 ) 144 add_custom_target(${TARGET} DEPENDS "${arg_OUTPUT_APK}" "${java_r_path}") 145 set_property(TARGET ${TARGET} PROPERTY OUTPUT "${arg_OUTPUT_APK}") 146 set_property(TARGET ${TARGET} PROPERTY JAVA_R "${java_r_path}") 147 set_property(TARGET ${TARGET} PROPERTY OUTPUTS "${${arg_OUTPUT_APK}};${java_r_path}") 148endfunction() 149 150function(sdl_add_to_apk_unaligned TARGET) 151 cmake_parse_arguments(arg "" "APK_IN;NAME;OUTDIR" "ASSETS;NATIVE_LIBS;DEX" ${ARGN}) 152 153 if(NOT arg_APK_IN) 154 message(FATAL_ERROR "Missing APK_IN argument") 155 endif() 156 157 if(NOT TARGET ${arg_APK_IN}) 158 message(FATAL_ERROR "APK_IN (${arg_APK_IN}) must be a target providing an apk") 159 endif() 160 161 _sdl_create_outdir_for_target(workdir ${TARGET}) 162 163 if(NOT arg_OUTDIR) 164 set(arg_OUTDIR "${CMAKE_CURRENT_BINARY_DIR}") 165 endif() 166 167 if(NOT arg_NAME) 168 string(REGEX REPLACE "[:-]+" "." arg_NAME "${TARGET}") 169 if(NOT arg_NAME MATCHES "\\.apk") 170 set(arg_NAME "${arg_NAME}.apk") 171 endif() 172 endif() 173 get_filename_component(apk_file "${arg_NAME}" ABSOLUTE BASE_DIR "${arg_OUTDIR}") 174 175 set(apk_libdir "lib/${ANDROID_ABI}") 176 177 set(depends "") 178 179 set(commands 180 COMMAND "${CMAKE_COMMAND}" -E remove_directory -rf "${apk_libdir}" "assets" 181 COMMAND "${CMAKE_COMMAND}" -E make_directory "${apk_libdir}" "assets" 182 COMMAND "${CMAKE_COMMAND}" -E copy "$<TARGET_PROPERTY:${arg_APK_IN},OUTPUT>" "${apk_file}" 183 ) 184 185 set(dex_i "1") 186 foreach(dex IN LISTS arg_DEX) 187 set(suffix "${dex_i}") 188 if(suffix STREQUAL "1") 189 set(suffix "") 190 endif() 191 list(APPEND commands 192 COMMAND "${CMAKE_COMMAND}" -E copy "$<TARGET_PROPERTY:${dex},OUTPUT>" "classes${suffix}.dex" 193 COMMAND SdlAndroid::zip -u -q -j "${apk_file}" "classes${suffix}.dex" 194 ) 195 math(EXPR dex_i "${dex_i}+1") 196 list(APPEND depends "$<TARGET_PROPERTY:${dex},OUTPUT>") 197 endforeach() 198 199 foreach(native_lib IN LISTS arg_NATIVE_LIBS) 200 list(APPEND commands 201 COMMAND "${CMAKE_COMMAND}" -E copy $<TARGET_FILE:${native_lib}> "${apk_libdir}/$<TARGET_FILE_NAME:${native_lib}>" 202 COMMAND SdlAndroid::zip -u -q "${apk_file}" "${apk_libdir}/$<TARGET_FILE_NAME:${native_lib}>" 203 ) 204 endforeach() 205 if(arg_ASSETS) 206 list(APPEND commands 207 COMMAND "${CMAKE_COMMAND}" -E copy ${arg_ASSETS} "assets" 208 COMMAND SdlAndroid::zip -u -r -q "${apk_file}" "assets" 209 ) 210 endif() 211 212 add_custom_command(OUTPUT "${apk_file}" 213 ${commands} 214 DEPENDS ${arg_NATIVE_LIBS} ${depends} "$<TARGET_PROPERTY:${arg_APK_IN},OUTPUT>" 215 WORKING_DIRECTORY "${workdir}" 216 ) 217 add_custom_target(${TARGET} DEPENDS "${apk_file}") 218 set_property(TARGET ${TARGET} PROPERTY OUTPUT "${apk_file}") 219endfunction() 220 221function(sdl_apk_align TARGET APK_IN) 222 cmake_parse_arguments(arg "" "NAME;OUTDIR" "" ${ARGN}) 223 224 if(NOT TARGET ${arg_APK_IN}) 225 message(FATAL_ERROR "APK_IN (${arg_APK_IN}) must be a target providing an apk") 226 endif() 227 228 if(NOT arg_OUTDIR) 229 set(arg_OUTDIR "${CMAKE_CURRENT_BINARY_DIR}") 230 endif() 231 232 if(NOT arg_NAME) 233 string(REGEX REPLACE "[:-]+" "." arg_NAME "${TARGET}") 234 if(NOT arg_NAME MATCHES "\\.apk") 235 set(arg_NAME "${arg_NAME}.apk") 236 endif() 237 endif() 238 get_filename_component(apk_file "${arg_NAME}" ABSOLUTE BASE_DIR "${arg_OUTDIR}") 239 240 add_custom_command(OUTPUT "${apk_file}" 241 COMMAND SdlAndroid::zipalign -f 4 "$<TARGET_PROPERTY:${APK_IN},OUTPUT>" "${apk_file}" 242 DEPENDS "$<TARGET_PROPERTY:${APK_IN},OUTPUT>" 243 ) 244 add_custom_target(${TARGET} DEPENDS "${apk_file}") 245 set_property(TARGET ${TARGET} PROPERTY OUTPUT "${apk_file}") 246endfunction() 247 248function(sdl_apk_sign TARGET APK_IN) 249 cmake_parse_arguments(arg "" "OUTPUT;KEYSTORE" "" ${ARGN}) 250 251 if(NOT TARGET ${arg_APK_IN}) 252 message(FATAL_ERROR "APK_IN (${arg_APK_IN}) must be a target providing an apk") 253 endif() 254 255 if(NOT TARGET ${arg_KEYSTORE}) 256 message(FATAL_ERROR "APK_KEYSTORE (${APK_KEYSTORE}) must be a target providing a keystore") 257 endif() 258 259 if(NOT arg_OUTPUT) 260 string(REGEX REPLACE "[:-]+" "." arg_OUTPUT "${TARGET}") 261 if(NOT arg_OUTPUT MATCHES "\\.apk") 262 set(arg_OUTPUT "${arg_OUTPUT}.apk") 263 endif() 264 endif() 265 get_filename_component(apk_file "${arg_OUTPUT}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}") 266 267 add_custom_command(OUTPUT "${apk_file}" 268 COMMAND SdlAndroid::apksigner sign 269 --ks "$<TARGET_PROPERTY:${arg_KEYSTORE},OUTPUT>" 270 --ks-pass pass:android --in "$<TARGET_PROPERTY:${APK_IN},OUTPUT>" --out "${apk_file}" 271 DEPENDS "$<TARGET_PROPERTY:${APK_IN},OUTPUT>" "$<TARGET_PROPERTY:${arg_KEYSTORE},OUTPUT>" 272 BYPRODUCTS "${apk_file}.idsig" 273 ) 274 add_custom_target(${TARGET} DEPENDS "${apk_file}") 275 set_property(TARGET ${TARGET} PROPERTY OUTPUT "${apk_file}") 276endfunction() 277[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.