如何在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
相关产品推荐
相关产品推荐

