diff options
Diffstat (limited to 'src/contrib/SDL-3.2.20/cmake/android/SdlAndroidFunctions.cmake')
-rw-r--r-- | src/contrib/SDL-3.2.20/cmake/android/SdlAndroidFunctions.cmake | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/src/contrib/SDL-3.2.20/cmake/android/SdlAndroidFunctions.cmake b/src/contrib/SDL-3.2.20/cmake/android/SdlAndroidFunctions.cmake new file mode 100644 index 0000000..4acce47 --- /dev/null +++ b/src/contrib/SDL-3.2.20/cmake/android/SdlAndroidFunctions.cmake | |||
@@ -0,0 +1,276 @@ | |||
1 | #[=======================================================================[ | ||
2 | |||
3 | This CMake script contains functions to build an Android APK. | ||
4 | It is (currently) limited to packaging binaries for a single architecture. | ||
5 | |||
6 | #]=======================================================================] | ||
7 | |||
8 | cmake_minimum_required(VERSION 3.7...3.28) | ||
9 | |||
10 | if(NOT PROJECT_NAME MATCHES "^SDL.*") | ||
11 | message(WARNING "This module is internal to SDL and is currently not supported.") | ||
12 | endif() | ||
13 | |||
14 | function(_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) | ||
21 | endfunction() | ||
22 | |||
23 | function(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}") | ||
31 | endfunction() | ||
32 | |||
33 | function(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}") | ||
85 | endfunction() | ||
86 | |||
87 | function(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}") | ||
148 | endfunction() | ||
149 | |||
150 | function(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}") | ||
219 | endfunction() | ||
220 | |||
221 | function(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}") | ||
246 | endfunction() | ||
247 | |||
248 | function(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}") | ||
276 | endfunction() | ||