diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml index 89a41d7b..fa90d0d7 100644 --- a/.github/workflows/build-and-deploy.yml +++ b/.github/workflows/build-and-deploy.yml @@ -50,7 +50,7 @@ jobs: && github.event_name != 'pull_request' steps: - name: Checkout - uses: actions/checkout@v3.4.0 + uses: actions/checkout@v3.5.0 with: token: ${{ secrets.DEPLOYMENT_TOKEN }} - name: Find the version of Node from package.json diff --git a/src/main/kotlin/io/github/gciatto/kt/mpp/DefaultProperties.kt b/src/main/kotlin/io/github/gciatto/kt/mpp/DefaultProperties.kt index 50f1dab8..e9354875 100644 --- a/src/main/kotlin/io/github/gciatto/kt/mpp/DefaultProperties.kt +++ b/src/main/kotlin/io/github/gciatto/kt/mpp/DefaultProperties.kt @@ -97,6 +97,110 @@ interface DefaultProperties { defaultValue = false ) + val ktTargetNativeDisable: PropertyDescriptor + get() = PropertyDescriptor( + name = "ktTargetNativeDisable", + description = "If true, disables the Native target on a multi-platform project", + mandatory = false, + defaultValue = false + ) + + val linuxX64Disable: PropertyDescriptor + get() = PropertyDescriptor( + name = "linuxX64Disable", + description = "If true, disables the Linux x64 target on a multi-platform project", + mandatory = false, + defaultValue = false + ) + + val linuxArm64Disable: PropertyDescriptor + get() = PropertyDescriptor( + name = "linuxArm64Disable", + description = "If true, disables the Linux ARM64 target on a multi-platform project", + mandatory = false, + defaultValue = false + ) + + val mingwX64Disable: PropertyDescriptor + get() = PropertyDescriptor( + name = "mingwX64Disable", + description = "If true, disables the MinGW x64 target on a multi-platform project", + mandatory = false, + defaultValue = false + ) + + val macosX64Disable: PropertyDescriptor + get() = PropertyDescriptor( + name = "macosX64Disable", + description = "If true, disables the macOS x64 target on a multi-platform project", + mandatory = false, + defaultValue = false + ) + + val macosArm64Disable: PropertyDescriptor + get() = PropertyDescriptor( + name = "macosArm64Disable", + description = "If true, disables the macOS ARM64 target on a multi-platform project", + mandatory = false, + defaultValue = false + ) + + val iosDisable: PropertyDescriptor + get() = PropertyDescriptor( + name = "iosDisable", + description = "If true, disables the iOS target on a multi-platform project", + mandatory = false, + defaultValue = false + ) + + val watchOsDisable: PropertyDescriptor + get() = PropertyDescriptor( + name = "watchOsDisable", + description = "If true, disables the watchOS target on a multi-platform project", + mandatory = false, + defaultValue = false + ) + + val tvOsDisable: PropertyDescriptor + get() = PropertyDescriptor( + name = "tvOsDisable", + description = "If true, disables the tvOS target on a multi-platform project", + mandatory = false, + defaultValue = false + ) + + val nativeStaticLib: PropertyDescriptor + get() = PropertyDescriptor( + name = "nativeStaticLib", + description = "If true, the native target will be compiled as a static library", + mandatory = false, + defaultValue = true + ) + + val nativeSharedLib: PropertyDescriptor + get() = PropertyDescriptor( + name = "nativeSharedLib", + description = "If true, the native target will be compiled as a shared library", + mandatory = false, + defaultValue = true + ) + + val nativeExecutable: PropertyDescriptor + get() = PropertyDescriptor( + name = "nativeExecutable", + description = "If true, the native target will be compiled as an executable", + mandatory = false, + defaultValue = true + ) + + val nativeCrossCompilationEnable: PropertyDescriptor + get() = PropertyDescriptor( + name = "nativeCrossCompilationEnable", + description = "If true, enables cross-compilation for all compatible native targets", + mandatory = false, + defaultValue = false + ) + val mavenPassword: PropertyDescriptor get() = PropertyDescriptor( name = "mavenPassword", diff --git a/src/main/kotlin/io/github/gciatto/kt/mpp/MultiplatformPlugin.kt b/src/main/kotlin/io/github/gciatto/kt/mpp/MultiplatformPlugin.kt index ee673cb2..89faeb16 100644 --- a/src/main/kotlin/io/github/gciatto/kt/mpp/MultiplatformPlugin.kt +++ b/src/main/kotlin/io/github/gciatto/kt/mpp/MultiplatformPlugin.kt @@ -2,9 +2,15 @@ package io.github.gciatto.kt.mpp import org.gradle.api.Project import org.gradle.api.logging.LogLevel +import org.gradle.api.publish.maven.tasks.AbstractPublishToMaven +import org.gradle.api.publish.tasks.GenerateModuleMetadata +import org.gradle.internal.os.OperatingSystem import org.gradle.kotlin.dsl.apply +import org.gradle.kotlin.dsl.get +import org.gradle.kotlin.dsl.withType import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsTargetDsl import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget @@ -17,6 +23,7 @@ class MultiplatformPlugin : AbstractKotlinProjectPlugin("multiplatform") { configureNodeVersionFromCatalogIfPossible() val ktTargetJvmDisable = getBooleanProperty("ktTargetJvmDisable") val ktTargetJsDisable = getBooleanProperty("ktTargetJsDisable") + val ktTargetNativeDisable = getBooleanProperty("ktTargetNativeDisable") configure(KotlinMultiplatformExtension::class) { if (ktTargetJvmDisable) { log("disable JVM target", LogLevel.WARN) @@ -28,6 +35,11 @@ class MultiplatformPlugin : AbstractKotlinProjectPlugin("multiplatform") { } else { js { configureJs() } } + if (ktTargetNativeDisable) { + log("disable Native target", LogLevel.WARN) + } else { + configureNative() + } dependenciesFor("commonMain") { addMainDependencies(project, "common", skipBom = false) } @@ -46,7 +58,7 @@ class MultiplatformPlugin : AbstractKotlinProjectPlugin("multiplatform") { private fun KotlinMultiplatformExtension.dependenciesFor( sourceSet: String, - action: KotlinDependencyHandler.() -> Unit + action: KotlinDependencyHandler.() -> Unit, ) = sourceSets.getByName(sourceSet).dependencies(action) context(Project, KotlinMultiplatformExtension) @@ -82,6 +94,81 @@ class MultiplatformPlugin : AbstractKotlinProjectPlugin("multiplatform") { } } + context(Project) + private fun KotlinMultiplatformExtension.configureNative() { + val disableLinuxX64 = getBooleanProperty("linuxX64Disable") + val disableLinuxArm64 = getBooleanProperty("linuxArm64Disable") + val disableMingwX64 = getBooleanProperty("mingwX64Disable") + val disableMacosX64 = getBooleanProperty("macosX64Disable") + val disableMacosArm64 = getBooleanProperty("macosArm64Disable") + val disableIos = getBooleanProperty("iosDisable") + val disableWatchos = getBooleanProperty("watchosDisable") + val disableTvos = getBooleanProperty("tvosDisable") + val nativeCrossCompilationEnable = getBooleanProperty("nativeCrossCompilationEnable") + val nativeStaticLib = getBooleanProperty("nativeStaticLib") + val nativeSharedLib = getBooleanProperty("nativeSharedLib") + val nativeExecutable = getBooleanProperty("nativeExecutable") + + sourceSets.create("nativeMain").dependsOn(sourceSets["commonMain"]) + sourceSets.create("nativeTest").dependsOn(sourceSets["commonTest"]) + + val nativeSetup: KotlinNativeTarget.() -> Unit = { + compilations["main"].defaultSourceSet.dependsOn(sourceSets["nativeMain"]) + compilations["test"].defaultSourceSet.dependsOn(sourceSets["nativeTest"]) + binaries { + if (nativeStaticLib) { staticLib() } + if (nativeSharedLib) { sharedLib() } + if (nativeExecutable) { executable() } + } + } + + if (!disableLinuxX64) linuxX64(nativeSetup) + if (!disableLinuxArm64) linuxArm64(nativeSetup) + + if (!disableMingwX64) mingwX64(nativeSetup) + + if (!disableMacosX64) macosX64(nativeSetup) + if (!disableMacosArm64) macosArm64(nativeSetup) + if (!disableIos) ios(nativeSetup) + if (!disableWatchos) watchos(nativeSetup) + if (!disableTvos) tvos(nativeSetup) + + if (!nativeCrossCompilationEnable) { + disableCrossCompilation() + } else { + log("Cross compilation for native target enabled", LogLevel.WARN) + } + } + + context(Project) + private fun KotlinMultiplatformExtension.disableCrossCompilation() { + // Disable cross compilation + val os = OperatingSystem.current() + val excludeTargets = when { + os.isLinux -> targets.filterNot { "linux" in it.name } + os.isWindows -> targets.filterNot { "mingw" in it.name } + os.isMacOsX -> targets.filter { "linux" in it.name || "mingw" in it.name } + else -> emptyList() + }.mapNotNull { it as? KotlinNativeTarget } + + configure(excludeTargets) { target -> + target.compilations.configureEach { nativeCompilation -> + nativeCompilation.cinterops.configureEach { tasks[it.interopProcessingTaskName].enabled = false } + nativeCompilation.compileTaskProvider.get().enabled = false + tasks[nativeCompilation.processResourcesTaskName].enabled = false + } + target.binaries.configureEach { it.linkTask.enabled = false } + + target.mavenPublication { + tasks.withType() + .configureEach { maven -> maven.onlyIf { maven.publication != this@mavenPublication } } + tasks.withType().configureEach { metadata -> + metadata.onlyIf { metadata.publication.get() != this@mavenPublication } + } + } + } + } + override fun PropertiesHelperExtension.declareProperties() { addProperty(allWarningsAsErrors) addProperty(ktCompilerArgs) @@ -90,6 +177,19 @@ class MultiplatformPlugin : AbstractKotlinProjectPlugin("multiplatform") { addProperty(mochaTimeout) addProperty(ktTargetJvmDisable) addProperty(ktTargetJsDisable) + addProperty(ktTargetNativeDisable) + addProperty(linuxX64Disable) + addProperty(linuxArm64Disable) + addProperty(mingwX64Disable) + addProperty(macosX64Disable) + addProperty(macosArm64Disable) + addProperty(iosDisable) + addProperty(watchOsDisable) + addProperty(tvOsDisable) + addProperty(nativeCrossCompilationEnable) + addProperty(nativeStaticLib) + addProperty(nativeSharedLib) + addProperty(nativeExecutable) addProperty(versionsFromCatalog) addProperty(nodeVersion) } diff --git a/src/test/resources/io/github/gciatto/kt/mpp/test/test0/gradle.properties b/src/test/resources/io/github/gciatto/kt/mpp/test/test0/gradle.properties index 60226f4a..4988225c 100644 --- a/src/test/resources/io/github/gciatto/kt/mpp/test/test0/gradle.properties +++ b/src/test/resources/io/github/gciatto/kt/mpp/test/test0/gradle.properties @@ -30,6 +30,19 @@ npmRepo=https://registry.npmjs.org npmDryRun=true ktTargetJvmDisable=false ktTargetJsDisable=false +ktTargetNativeDisable=false +linuxX64Disable=false +linuxArm64Disable=false +mingwX64Disable=false +macosX64Disable=false +macosArm64Disable=false +iosDisable=false +watchosDisable=false +tvosDisable=false +nativeCrossCompilationEnable=false +nativeStaticLib=true +nativeSharedLib=true +nativeExecutable=false allWarningsAsErrors=true versionsFromCatalog= nodeVersion=