diff options
| author | ruki <[email protected]> | 2025-12-16 23:56:05 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2025-12-16 23:56:05 +0800 |
| commit | 7b542ebe22e833bd56dd1eb0271aa5aa7c0b45a8 (patch) | |
| tree | fa04d0cac2a24c1afe1a11614f5c633938434c80 /xmake/rules/platform/android | |
| parent | cb4c88034ab1d4dc5dedb0dbe56f5e868cae0ecd (diff) | |
move ndk rules to android
Diffstat (limited to 'xmake/rules/platform/android')
| -rw-r--r-- | xmake/rules/platform/android/install.lua | 34 | ||||
| -rw-r--r-- | xmake/rules/platform/android/load.lua | 44 | ||||
| -rw-r--r-- | xmake/rules/platform/android/package.lua | 103 | ||||
| -rw-r--r-- | xmake/rules/platform/android/run.lua | 56 | ||||
| -rw-r--r-- | xmake/rules/platform/android/uninstall.lua | 32 | ||||
| -rw-r--r-- | xmake/rules/platform/android/xmake.lua | 53 |
6 files changed, 322 insertions, 0 deletions
diff --git a/xmake/rules/platform/android/install.lua b/xmake/rules/platform/android/install.lua new file mode 100644 index 000000000..ec340ac00 --- /dev/null +++ b/xmake/rules/platform/android/install.lua @@ -0,0 +1,34 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-present, Xmake Open Source Community. +-- +-- @author keosu +-- @file install.lua +-- + +-- imports + +function main(target) + + local android_sdkdir = target:toolchain("ndk"):config("android_sdk") + local adb = path.join(android_sdkdir, "platform-tools", "adb") + + local final_apk = path.join(target:targetdir(), target:basename() .. ".apk") + assert(os.isfile(final_apk), "apk file %s not found!", final_apk) + + cprint("installing %s ...", final_apk) + os.vrunv(adb, {"install", "-r", final_apk}) + cprint("install ok") +end diff --git a/xmake/rules/platform/android/load.lua b/xmake/rules/platform/android/load.lua new file mode 100644 index 000000000..3e49d9533 --- /dev/null +++ b/xmake/rules/platform/android/load.lua @@ -0,0 +1,44 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-present, Xmake Open Source Community. +-- +-- @author keosu +-- @file load.lua +-- + +function main(target) + + -- only for android target + if not target:is_plat("android") then + wprint("rule(android.native_app): only for android system!") + target:rule_enable("android.native_app", false) + return + end + + local toolchain_ndk = target:toolchain("ndk") + local ndk_root = toolchain_ndk:config("ndk") + if not ndk_root then + raise("NDK path not set! Please set NDK path properly.") + end + + -- set target kind + target:set("kind", "shared") + + -- add glue file to target + local native_app_glue_file = path.join(ndk_root, "sources", "android", "native_app_glue", "android_native_app_glue.c") + local native_app_glue_dir = path.directory(native_app_glue_file) + target:add("files", native_app_glue_file) + target:add("includedirs", native_app_glue_dir) +end diff --git a/xmake/rules/platform/android/package.lua b/xmake/rules/platform/android/package.lua new file mode 100644 index 000000000..00142a85f --- /dev/null +++ b/xmake/rules/platform/android/package.lua @@ -0,0 +1,103 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-present, Xmake Open Source Community. +-- +-- @author keosu +-- @file package.lua +-- + +-- imports +import("core.project.depend") +import("utils.progress") + +function main(target, opt) + + local conf = target:extraconf("rules", "android.native_app") + local android_sdk_version = conf.android_sdk_version + local android_manifest = conf.android_manifest + local android_res = conf.android_res + local android_assets = conf.android_assets + local keystore = conf.keystore + local keystore_pass = conf.keystore_pass + + assert(android_sdk_version, "android sdk version not set") + assert(android_manifest, "android manifest not set") + + local final_apk = path.join(target:targetdir(), target:basename() .. ".apk") + + -- add dependencies + local depfiles = {target:targetfile(), android_manifest, keystore} + if android_res and os.isdir(android_res) then + table.join2(depfiles, os.files(path.join(android_res, "**"))) + end + if android_assets and os.isdir(android_assets) then + table.join2(depfiles, os.files(path.join(android_assets, "**"))) + end + + depend.on_changed(function () + progress.show(opt.progress, "${color.build.target}packing.apk %s", final_apk) + + local tmp_path = path.join(target:targetdir(), "temp") + os.mkdir(tmp_path) + os.mkdir(path.join(tmp_path, "lib")) + os.mkdir(path.join(tmp_path, "lib", target:arch())) + + -- copy the target library to temp folder with name libmain.so + local libfile = path.join(tmp_path, "lib", target:arch(), "libmain.so") + os.cp(target:targetfile(), libfile) + + -- get android tool path + local android_sdkdir = target:toolchain("ndk"):config("android_sdk") + local android_build_toolver = target:toolchain("ndk"):config("build_toolver") + local sdk_tool_path = path.join(android_sdkdir, "build-tools", android_build_toolver) + + local aapt = path.join(sdk_tool_path, "aapt" .. (is_host("windows") and ".exe" or "")) + local zipalign = path.join(sdk_tool_path, "zipalign" .. (is_host("windows") and ".exe" or "")) + local apksigner = path.join(sdk_tool_path, "apksigner" .. (is_host("windows") and ".bat" or "")) + + -- pack resources + local resonly_apk = path.join(tmp_path, "res_only.apk") + local androidjar = path.join(android_sdkdir, "platforms", string.format("android-%s", android_sdk_version), + "android.jar") + assert(os.isfile(androidjar), "%s not found", androidjar) + local aapt_argv = {"package", "-f", "-M", android_manifest, "-I", androidjar, "-F", resonly_apk} + + if android_res and not os.emptydir(android_res) then + table.insert(aapt_argv, "-S") + table.insert(aapt_argv, android_res) + end + + if android_assets and not os.emptydir(android_assets) then + table.insert(aapt_argv, "-A") + table.insert(aapt_argv, android_assets) + end + + os.vrunv(aapt, aapt_argv) + + -- pack libs + os.vrunv(aapt, {"add", "res_only.apk", "lib/" .. target:arch() .."/libmain.so"}, {curdir = tmp_path}) + + -- align apk + local aligned_apk = path.join(tmp_path, "unsigned.apk") + local zipalign_argv = {"-f", "4", "res_only.apk", "unsigned.apk"} + + os.vrunv(zipalign, zipalign_argv, {curdir = tmp_path}) + + -- sign apk + local apksigner_argv = {"sign", "--ks", keystore, "--ks-pass", string.format("pass:%s", keystore_pass), "--out", + final_apk, "--in", aligned_apk} + os.vrunv(apksigner, apksigner_argv) + end, {dependfile = target:dependfile(final_apk), files = depfiles, values = {android_sdk_version, keystore_pass}}) +end diff --git a/xmake/rules/platform/android/run.lua b/xmake/rules/platform/android/run.lua new file mode 100644 index 000000000..657dad4e8 --- /dev/null +++ b/xmake/rules/platform/android/run.lua @@ -0,0 +1,56 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-present, Xmake Open Source Community. +-- +-- @author keosu +-- @file run.lua +-- + +-- imports +import("core.base.tty") +import("install", {alias = "install_app"}) + +function main(target) + + -- install it first + install_app(target) + + local conf = target:extraconf("rules", "android.native_app") + local package_name = conf.package_name + local activity_name = conf.activity_name or "android.app.NativeActivity" + + local android_sdkdir = target:toolchain("ndk"):config("android_sdk") + local adb = path.join(android_sdkdir, "platform-tools", "adb") + + local run_argv = {"shell", "am", "start", "-n", package_name .. "/" .. activity_name} + + cprint("running %s ...", package_name) + os.vrunv(adb, run_argv) + + -- show logcat + local logcat_argv = {"logcat"} + if io.isatty() and (tty.has_color8() or tty.has_color256()) then + table.insert(logcat_argv, "-v") + table.insert(logcat_argv, "color") + end + local logcat_filters = conf.logcat_filters + if logcat_filters then + table.insert(logcat_argv, "-s") + for _, filter in ipairs(logcat_filters) do + table.insert(logcat_argv, filter) + end + end + os.execv(adb, logcat_argv) +end diff --git a/xmake/rules/platform/android/uninstall.lua b/xmake/rules/platform/android/uninstall.lua new file mode 100644 index 000000000..24564d631 --- /dev/null +++ b/xmake/rules/platform/android/uninstall.lua @@ -0,0 +1,32 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-present, Xmake Open Source Community. +-- +-- @author ruki +-- @file uninstall.lua +-- + +function main(target) + + local conf = target:extraconf("rules", "android.native_app") + local package_name = conf.package_name + + local android_sdkdir = target:toolchain("ndk"):config("android_sdk") + local adb = path.join(android_sdkdir, "platform-tools", "adb") + + cprint("uninstalling %s ...", package_name) + os.vrunv(adb, {"uninstall", package_name}) + cprint("uninstall ok") +end diff --git a/xmake/rules/platform/android/xmake.lua b/xmake/rules/platform/android/xmake.lua new file mode 100644 index 000000000..0c58d7d09 --- /dev/null +++ b/xmake/rules/platform/android/xmake.lua @@ -0,0 +1,53 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-present, Xmake Open Source Community. +-- +-- @author keosu +-- @file xmake.lua +-- + +-- define rule: build android native app with NDK +-- +-- @code +-- target("test") +-- set_kind("binary") +-- add_rules("android.native_app", { +-- android_sdk_version = "35", +-- android_manifest = "android/AndroidManifest.xml", +-- android_res = "android/res", +-- android_assets = "android/assets", +-- keystore = "android/debug.jks", +-- keystore_pass = "123456", +-- package_name = "com.raylib.demo", +-- logcat_filters = {"raydemo_android", "raylib"} +-- }) +-- @endcode +-- +rule("android.native_app") + + -- we must set_kind and add some glue files to target + on_load("load") + + -- generate android apk package + after_build("package") + + -- install android package with adb + on_install("install") + + -- uninstall android package with adb + on_uninstall("uninstall") + + -- run android app through adb + on_run("run") |
