打包 Compose Desktop 应用程序后添加自定义 Gradle 任务

问题描述 投票:0回答:1

我正在使用 Jetpack Compose 构建桌面应用程序,发现当我为 macOS 打包应用程序时,需要手动步骤来设置应用程序二进制文件的可执行权限。要删除此手动步骤,我想添加一个 Gradle 任务,该任务会在应用程序打包后自动执行此操作。

tasks.register<Copy>("setExecutablePermission") {
    description = "Sets executable permission for the generated .app bundle on macOS"
    doLast {
        val osName = System.getProperty("os.name")
        if (osName.startsWith("Mac OS")) {
            val appBundle = file("${layout.buildDirectory}/compose/binaries/main/app/simple-card-game.app")
            if (appBundle.exists()) {
                val executableFile = file("${appBundle}/Contents/MacOS/simple-card-game")
                executableFile.setExecutable(true, false)
                println("Executable permission set for: $executableFile")
            } else {
                println("Warning: .app bundle not found. Skipping setExecutablePermission task.")
            }
        } else {
            println("Not running on macOS. Skipping setExecutablePermission task.")
        }
    }

    project.afterEvaluate {
        val packageTask = tasks.findByName("createDistributable")
        if (packageTask != null) packageTask.finalizedBy(this) else println("Warning: 'createDistributable' task not found.")
    }
}

但是,我无法将此自定义任务添加到执行图中。

以下块没有任何效果。我已经尝试过

finalizedBy
mustRunAfter
将其与
createDistributable
packageDistributionForCurrentOS
package
甚至
jar
链接起来,但我的任务似乎仍然没有添加。

project.afterEvaluate {
    val packageTask = tasks.findByName("createDistributable")
    if (packageTask != null) packageTask.finalizedBy(this) else println("Warning: 'createDistributable' task not found.")
}

有关如何将自定义任务添加到 Compose 桌面应用程序打包过程或至少如何调试它的任何提示?

gradle kotlin-multiplatform compose-desktop
1个回答
0
投票

您的任务依赖项已添加到另一个任务的配置块中

您的块没有任何效果的原因是它位于

register
setExecutablePermission
块内部。
register
执行惰性配置,因此只有当
setExecutablePermission
位于 Gradle 为给定的构建调用进行计算的任务执行图中时,才会调用这样的块。

未选择该任务,因此不会执行任何代码(即使执行了,在构建生命周期中添加任何任务依赖项也为时已晚)。

在另一个块之外添加依赖项

相反,您需要做的是在这样的块之外配置

createDistributable
。为此,首先获取对新任务的引用1

val setExecutablePermissionTask = tasks.register<Copy>("setExecutablePermission") {
    // ...
}

然后你可以这样做:

tasks.named("createDistributable") {
    finalizedBy(setExecutablePermissionTask)
}
使用

named
是因为它是惰性的,因此可以防止不必要的任务配置。因此它与
register
相同,但用于现有任务2

还有,
afterEvaluate
...

此外,我不确定你为什么要使用

afterEvaluate
。 (也许希望它能神奇地让它发挥作用;我不会为此责怪你。我曾经经历过。)

然而,使用

afterEvaluate
不仅很少有必要,而且是邪恶的,只能作为最后的手段。仅在特殊情况下,或者当您必须解决它在另一个插件中的使用时才有必要。 Gradle 有一个完整的惰性配置 API,这在很大程度上是为了防止使用像
afterEvaluate
这样的膏药。

它之所以是邪恶的,是因为它迫使你考虑这些钩子的运行顺序,而改变顺序或引入新的钩子可能很难推理并引入意想不到的行为。


1您可以只使用名称,但我希望您同意这更优雅、更干燥。

2我认为没有必要像您的代码那样检查任务是否存在。这不会因构建而异,例如根据用户配置。相反,这样的任务要么由插件添加,以便调用起作用,要么不起作用,并且构建失败并会告诉您该任务不存在,从而使您可以轻松解决问题。

© www.soinside.com 2019 - 2024. All rights reserved.