From a46511b110f2db27595ee2410ab20040831e3594 Mon Sep 17 00:00:00 2001 From: shifujun Date: Wed, 25 Dec 2024 20:25:59 +0800 Subject: [PATCH] =?UTF-8?q?build:=20=E4=BF=AE=E5=A4=8DIDE=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E7=9B=B4=E6=8E=A5Run=E9=A1=B9=E7=9B=AE=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 经过反复分析现有代码,无法在不改动SDK层代码的前提下修复这个问题。 主要是因为Shadow的Gradle plugin有硬编码outputs目录的情况。 并且这个Plugin还假设了Gradle配置阶段就能确定apk的最终路径, 这与现状不符。目前是配置完成后,IDE还能决定将apk的输出路径改到intermediates中。 所以很难简单的修复这个假设的错误。 考虑到主要要解决的问题还是Shdaow自身项目希望能在IDE中直接run起来。 决定还是将intermediates中的apk直接复制到原本的路径。这样其他代码都不用改动。 fix #1263 --- build.gradle | 2 + buildScripts/gradle/fix_issue_1263.gradle | 76 +++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 buildScripts/gradle/fix_issue_1263.gradle diff --git a/build.gradle b/build.gradle index 41f9f11e1..ade15e038 100644 --- a/build.gradle +++ b/build.gradle @@ -31,3 +31,5 @@ buildscript { apply from: 'buildScripts/gradle/common.gradle' apply from: "buildScripts/gradle/maven.gradle" + +apply from: "buildScripts/gradle/fix_issue_1263.gradle" diff --git a/buildScripts/gradle/fix_issue_1263.gradle b/buildScripts/gradle/fix_issue_1263.gradle new file mode 100644 index 000000000..c039a01bc --- /dev/null +++ b/buildScripts/gradle/fix_issue_1263.gradle @@ -0,0 +1,76 @@ +/** + * 这个脚本通过hook create*ApkListingFileRedirect任务, + * 在它执行完成后,即生成了apk_ide_redirect_file,也应该生成了apk之后, + * 补充一个复制build/intermediates/apk到build/outputs/apk的操作。 + * + * 采用这个修复方式是因为Shadow的打包代码设计不是很合理,难以通过少量改动, + * 保证引用项目不引入任何兼容性问题。 + * + * 详见issue #1263 + */ +buildscript { + dependencies { + classpath files(rootProject.buildscript.configurations.classpath) + } +} +def taskList = [ + ":sample-loader:createDebugApkListingFileRedirect", + ":sample-loader:createReleaseApkListingFileRedirect", + ":sample-runtime:createDebugApkListingFileRedirect", + ":sample-runtime:createReleaseApkListingFileRedirect", + ":sample-manager:createDebugApkListingFileRedirect", + ":sample-manager:createReleaseApkListingFileRedirect", + ":sample-app:createPluginDebugApkListingFileRedirect", + ":sample-app:createPluginReleaseApkListingFileRedirect", + ":sample-base:createPluginDebugApkListingFileRedirect", + ":sample-base:createPluginReleaseApkListingFileRedirect", + + ":test-dynamic-loader:createDebugApkListingFileRedirect", + ":test-dynamic-loader:createReleaseApkListingFileRedirect", + ":test-dynamic-runtime:createDebugApkListingFileRedirect", + ":test-dynamic-runtime:createReleaseApkListingFileRedirect", + ":test-dynamic-manager:createDebugApkListingFileRedirect", + ":test-dynamic-manager:createReleaseApkListingFileRedirect", + ":plugin-service-for-host:createPluginDebugApkListingFileRedirect", + ":plugin-service-for-host:createPluginReleaseApkListingFileRedirect", + ":test-plugin-androidx-cases:createPluginDebugApkListingFileRedirect", + ":test-plugin-androidx-cases:createPluginReleaseApkListingFileRedirect", + ":test-plugin-general-cases:createPluginDebugApkListingFileRedirect", + ":test-plugin-general-cases:createPluginReleaseApkListingFileRedirect", + + ":sample-hello-apk:createDebugApkListingFileRedirect", + ":sample-hello-apk:createReleaseApkListingFileRedirect", +] + +afterEvaluate { + taskList.forEach { + def t = tasks.findByPath(it) + copyApkAfterTask(t) + } +} + +def copyApkAfterTask(t) { + t.doLast { + def redirectFile = t.getOutputs().getFiles().singleFile + def listingFile = redirectFile.readLines().get(1).replaceFirst("listingFile=", "") + def metadataFile = new File(redirectFile.parentFile, listingFile) + def metadata = new org.json.JSONObject(metadataFile.text) + def outputFile = metadata.getJSONArray("elements").getJSONObject(0).getString("outputFile") + def apkFile = new File(metadataFile.parentFile, outputFile) + def testRelativePath = redirectFile.relativePath(apkFile) + def needCopy = !testRelativePath.matches("^(\\.\\.${File.separatorChar})+outputs${File.separatorChar}.+") + if (needCopy) { + def matchPath = new File("/build/intermediates").toPath().toString() + def intermediatesDir = new File(apkFile.toPath().normalize().toString().find("^.+?$matchPath")) + def outputsDir = new File(intermediatesDir.parentFile, "outputs") + def r = copy { + from intermediatesDir + into outputsDir + include 'apk/**' + } + if (r.didWork) { + getLogger().info("copy apk from ${intermediatesDir.path} to ${outputsDir.path}") + } + } + } +}