You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Compose Multiplatform中配置桌面端多构建变体?

如何在Jetbrains Compose Multiplatform中生成区分内部/外部的Windows MSI安装包

1. 配置Gradle构建变体与源码目录

在桌面模块的build.gradle.kts中,通过自定义构建类型和源码集,实现类似Android产品风味的区分逻辑:

plugins {
    kotlin("jvm")
    id("org.jetbrains.compose")
}

// 定义内部/外部两种构建类型
val internal = create("internal")
val external = create("external")

// 配置对应源码集,区分不同版本的代码资源
sourceSets {
    val internalMain by creating {
        kotlin.srcDir("src/internalMain/kotlin")
        resources.srcDir("src/internalMain/resources")
        // 继承主源码集的通用代码
        compileClasspath += sourceSets.main.get().output
        runtimeClasspath += sourceSets.main.get().output
    }
    val externalMain by creating {
        kotlin.srcDir("src/externalMain/kotlin")
        resources.srcDir("src/externalMain/resources")
        compileClasspath += sourceSets.main.get().output
        runtimeClasspath += sourceSets.main.get().output
    }
}

// 为每种构建类型注册运行与打包任务
listOf(internal, external).forEach { buildType ->
    val sourceSet = sourceSets.getByName("${buildType.name}Main")
    
    // 注册运行任务
    tasks.register<JavaExec>("run${buildType.name.replaceFirstChar(Char::uppercase)}") {
        dependsOn(sourceSet.classesTaskName)
        mainClass.set("你的应用主类路径,比如com.example.MainKt")
        classpath(sourceSet.runtimeClasspath)
        jvmArgs("-Djava.awt.headless=false")
    }

    // 注册MSI打包任务,指定不同输出文件名
    tasks.register<org.jetbrains.compose.desktop.application.tasks.MsiTask>("package${buildType.name.replaceFirstChar(Char::uppercase)}Msi") {
        dependsOn(tasks.compose.desktop.application)
        outputFile.set(layout.buildDirectory.file("compose/binaries/main/msi/App${buildType.name.replaceFirstChar(Char::uppercase)}.msi"))
        // 复用主应用的基础配置
        applicationName.set(compose.desktop.application.applicationName)
        version.set(compose.desktop.application.version)
        vendor.set(compose.desktop.application.vendor)
        // 按需添加安装包额外配置,比如图标、权限等
    }
}

2. 分离敏感代码与版本判断逻辑

代码分离

创建对应目录存放版本专属代码:

  • src/internalMain/kotlin:存放内部版本专属的敏感逻辑代码
  • src/externalMain/kotlin:存放外部版本的替代实现(如空实现或公开逻辑)
  • src/main/kotlin:存放所有版本共用的通用代码

编译时版本判断

可以通过Gradle生成编译常量,让代码在编译阶段区分版本:
在build.gradle.kts中添加:

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs += when (name) {
            "compileInternalMainKotlin" -> "-DIS_INTERNAL=true"
            "compileExternalMainKotlin" -> "-DIS_INTERNAL=false"
            else -> ""
        }
    }
}

在源码中读取常量判断版本:

val isInternal = System.getProperty("IS_INTERNAL") == "true"

if (isInternal) {
    // 执行内部版本敏感逻辑
} else {
    // 执行外部版本公开逻辑
}

或者更优雅的方式是生成BuildConfig类:

tasks.register<GenerateBuildConfig>("generateBuildConfig") {
    val buildType = project.findProperty("buildType") ?: "external"
    outputDir.set(file("src/${buildType}Main/kotlin/你的包路径"))
    packageName.set("你的包路径")
    buildConfigField("boolean", "IS_INTERNAL", buildType == "internal")
}

// 让编译任务依赖BuildConfig生成
tasks.withType<KotlinCompile> {
    dependsOn("generateBuildConfig")
}

之后在代码中直接使用:

import 你的包路径.BuildConfig

if (BuildConfig.IS_INTERNAL) {
    // 内部版本逻辑
}

3. 构建对应安装包

执行以下Gradle命令生成MSI:

  • 生成内部版本:./gradlew packageInternalMsi
  • 生成外部版本:./gradlew packageExternalMsi

生成的安装包会存放在build/compose/binaries/main/msi/目录下,对应文件名AppInternal.msi和AppExternal.msi。


内容的提问来源于stack exchange,提问作者SVK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 02:19:49