From 6b97a7657d8314efb1803c1965e1f9815e027a48 Mon Sep 17 00:00:00 2001 From: Pavel Punegov Date: Mon, 12 Sep 2022 17:08:09 +0200 Subject: [PATCH] [K/N] Publish bundles to maven Makes build be able to publish bundles to the maven. It uses common properties and settings as all other Kotlin publications. Add usage of the Gradle base plugin and correct version and name setting for archive tasks --- .../main/kotlin/org/jetbrains/kotlin/Utils.kt | 36 +--- kotlin-native/build.gradle | 160 +++++++++++++++--- 2 files changed, 143 insertions(+), 53 deletions(-) diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/Utils.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/Utils.kt index da4a0e9230d..3aa82dfec2b 100644 --- a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/Utils.kt +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/Utils.kt @@ -8,9 +8,6 @@ package org.jetbrains.kotlin import org.gradle.api.Project import org.gradle.api.Task -import org.gradle.api.tasks.TaskState -import org.gradle.api.logging.LogLevel -import org.gradle.api.tasks.TaskCollection import org.jetbrains.kotlin.konan.properties.loadProperties import org.jetbrains.kotlin.konan.properties.propertyList import org.jetbrains.kotlin.konan.properties.saveProperties @@ -22,37 +19,7 @@ import java.net.HttpURLConnection import java.net.URL import java.nio.file.Path import org.jetbrains.kotlin.konan.file.File as KFile -import org.gradle.nativeplatform.toolchain.internal.* -import org.gradle.nativeplatform.toolchain.plugins.ClangCompilerPlugin -import org.gradle.api.Incubating -import org.gradle.api.NamedDomainObjectFactory -import org.gradle.api.NonNullApi -import org.gradle.api.Plugin -import org.gradle.api.internal.file.FileResolver -import org.gradle.api.internal.plugins.PotentialPlugin import org.gradle.api.tasks.TaskProvider -import org.gradle.internal.operations.BuildOperationExecutor -import org.gradle.internal.os.OperatingSystem -import org.gradle.internal.reflect.Instantiator -import org.gradle.internal.service.ServiceRegistry -import org.gradle.internal.work.WorkerLeaseService -import org.gradle.model.Defaults -import org.gradle.model.RuleSource -import org.gradle.nativeplatform.internal.CompilerOutputFileNamingSchemeFactory -import org.gradle.nativeplatform.platform.internal.NativePlatformInternal -import org.gradle.nativeplatform.plugins.NativeComponentPlugin -import org.gradle.nativeplatform.toolchain.Clang -import org.gradle.nativeplatform.toolchain.internal.clang.ClangToolChain -import org.gradle.nativeplatform.toolchain.internal.gcc.AbstractGccCompatibleToolChain -import org.gradle.nativeplatform.toolchain.internal.gcc.DefaultGccPlatformToolChain -import org.gradle.nativeplatform.toolchain.internal.gcc.metadata.SystemLibraryDiscovery -import org.gradle.nativeplatform.toolchain.internal.metadata.CompilerMetaDataProviderFactory -import org.gradle.nativeplatform.toolchain.internal.tools.CommandLineToolSearchResult -import org.gradle.nativeplatform.toolchain.internal.tools.GccCommandLineToolConfigurationInternal -import org.gradle.nativeplatform.toolchain.internal.tools.ToolSearchPath -import org.gradle.process.internal.ExecActionFactory -import java.io.ByteArrayOutputStream -import java.net.URI import java.util.* import kotlin.collections.HashSet @@ -106,6 +73,9 @@ val kotlinNativeHome val Project.useCustomDist get() = validPropertiesNames.any { hasProperty(it) } +val Project.nativeBundlesLocation + get() = file(findProperty("nativeBundlesLocation") ?: project.projectDir) + private val libraryRegexp = Regex("""^import\s+platform\.(\S+)\..*$""") fun File.dependencies() = readLines().filter(libraryRegexp::containsMatchIn) diff --git a/kotlin-native/build.gradle b/kotlin-native/build.gradle index b723c81a1b3..61058b8b247 100644 --- a/kotlin-native/build.gradle +++ b/kotlin-native/build.gradle @@ -26,6 +26,7 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import org.apache.tools.ant.filters.ReplaceTokens import org.jetbrains.kotlin.UtilsKt import java.util.concurrent.ConcurrentHashMap +import plugins.KotlinBuildPublishingPluginKt buildscript { apply from: "gradle/kotlinGradlePlugin.gradle" @@ -164,6 +165,8 @@ dependencies { } apply plugin: CompilationDatabasePlugin +apply plugin: 'maven-publish' +apply plugin: BasePlugin //task sharedJar { // dependsOn gradle.includedBuild('shared').task(':jar') @@ -181,7 +184,8 @@ task dist_compiler(dependsOn: "distCompiler") task dist_runtime(dependsOn: "distRuntime") task cross_dist(dependsOn: "crossDist") task list_dist(dependsOn: "listDist") -task build { + +tasks.named("build") { dependsOn 'dist', 'distPlatformLibs' } @@ -541,7 +545,8 @@ task bundle { task bundleRegular(type: (isWindows()) ? Zip : Tar) { def simpleOsName = HostManager.platformName() - archiveBaseName.set("kotlin-native-$simpleOsName-$konanVersionFull") + archiveBaseName.set("kotlin-native-$simpleOsName") + archiveVersion.set(konanVersionFull.toString()) from(UtilsKt.getKotlinNativeDist(project)) { include '**' exclude 'dependencies' @@ -550,19 +555,20 @@ task bundleRegular(type: (isWindows()) ? Zip : Tar) { exclude 'klib/platform' // Exclude platform libraries caches too. Keep caches for stdlib and endorsed libs. exclude 'klib/cache/*/org.jetbrains.kotlin.native.platform.*/**' - into archiveBaseName + into "${archiveBaseName.get()}-${archiveVersion.get()}" } } task bundlePrebuilt(type: (isWindows()) ? Zip : Tar) { dependsOn("crossDistPlatformLibs") def simpleOsName = HostManager.platformName() - archiveBaseName.set("kotlin-native-prebuilt-$simpleOsName-$konanVersionFull") + archiveBaseName.set("kotlin-native-prebuilt-$simpleOsName") + archiveVersion.set(konanVersionFull.toString()) from(UtilsKt.getKotlinNativeDist(project)) { include '**' exclude 'dependencies' exclude 'klib/testLibrary' - into archiveBaseName + into "${archiveBaseName.get()}-${archiveVersion.get()}" } } @@ -572,11 +578,11 @@ void configurePackingLicensesToBundle(AbstractArchiveTask task, boolean contains if (!containsPlatformLibraries || !isMac()) { exclude '**/xcode_license.pdf' } - into task.archiveBaseName + into "${task.archiveBaseName.get()}-${task.archiveVersion.get()}" } task.from(project.rootProject.file("license")) { - into "${task.archiveBaseName.get()}/licenses" + into "${task.archiveBaseName.get()}-${task.archiveVersion.get()}/licenses" } } @@ -591,7 +597,7 @@ configure([bundleRegular, bundlePrebuilt]) { dependsOn("distDef") from(project.projectDir) { include 'RELEASE_NOTES.md' - into baseName + into "${archiveBaseName.get()}-${archiveVersion.get()}" } destinationDirectory.set(file('.')) @@ -608,11 +614,12 @@ task 'tc-dist'(type: (isWindows()) ? Zip : Tar) { dependsOn('dist') dependsOn('distSources') def simpleOsName = HostManager.platformName() - archiveBaseName.set("kotlin-native-dist-$simpleOsName-$konanVersionFull") + archiveBaseName.set("kotlin-native-dist-$simpleOsName") + archiveVersion.set(konanVersionFull.toString()) from(UtilsKt.getKotlinNativeDist(project)) { include '**' exclude 'dependencies' - into archiveBaseName + into "${archiveBaseName.get()}-${archiveVersion.get()}" } destinationDirectory.set(file('.')) @@ -710,16 +717,6 @@ task teamcityCompilerVersion { } } -task clean(type: Delete) { - dependsOn subprojects.collect { it.tasks.matching { it.name == "clean" } } - doFirst { - delete distDir - delete buildDir - delete bundle.outputs.files - delete "${projectDir}/compile_commands.json" - } -} - task pusher(type: KotlinBuildPusher){ kotlinVersion = project.kotlinVersion konanVersion = project.ext.kotlinNativeVersion @@ -770,3 +767,126 @@ task "checkStdlibAbiCompatibility"(type: CompareDistributionSignatures) { } onMismatchMode = CompareDistributionSignatures.OnMismatchMode.FAIL } +// FIXME: should be a part of Host/TargetManager +String platformName(KonanTarget target) { + def result + switch (target) { + case KonanTarget.LINUX_X64: + result ="linux-x86_64" + break + case KonanTarget.MACOS_X64: + result = "macos-x86_64" + break + case KonanTarget.MACOS_ARM64: + result = "macos-aarch64" + break + case KonanTarget.MINGW_X64: + result = "windows-x86_64" + break + default: + throw TargetSupportException("Unknown host target") + } + return result +} + +Map createConfigurations(List bundles) { + def hostTargets = platformManager.enabledByHost.keySet() + def result = hostTargets.collectEntries { target -> + [ (target): bundles.find { it.name.contains(platformName(target)) }] + } + result.retainAll { it.value != null } + def missingBundles = hostTargets - result.keySet() + if (!missingBundles.isEmpty()) { + println("Some of the archive bundles are missing for targets $missingBundles:") + println(result) + throw new IllegalArgumentException("Bundle archives are missing for $missingBundles") + } + result.each { target, file -> + if (!file.name.contains(konanVersionFull.toString())) { + throw new IllegalArgumentException("Incorrect version specified for the publish: ${file.name}") + } + } + return result +} + +def bundlesLocationFiles = UtilsKt.getNativeBundlesLocation(project) + .listFiles() + .toList() + +KotlinBuildPublishingPluginKt.configureDefaultPublishing( + /* receiver = */ project, + /* signingRequired = */ KotlinBuildPublishingPluginKt.getSignLibraryPublication(project) +) + +tasks.named("clean", Delete) { + dependsOn subprojects.collect { it.tasks.matching { it.name == "clean" } } + doFirst { + delete distDir + delete buildDir + delete bundle.outputs.files + delete "${projectDir}/compile_commands.json" + } +} + +publishing { + publications { + def publishBundlesFromLocation = UtilsKt.getNativeBundlesLocation(project) != project.projectDir + register("Bundle", MavenPublication) { mvn -> + mvn.groupId = project.group.toString() + mvn.artifactId = project.name + mvn.version = konanVersionFull + + if (publishBundlesFromLocation) { + def bundleArchives = bundlesLocationFiles + .findAll { it.name.startsWith("kotlin-native") && !it.name.contains("prebuilt") } + def bundleConfigs = createConfigurations(bundleArchives) + bundleConfigs.forEach { target, file -> + mvn.artifact(file) { + classifier = platformName(target) + extension = (target.family == Family.MINGW) ? 'zip' : 'tar.gz' + } + } + } else { + mvn.artifact(bundleRegular) { + classifier = HostManager.platformName() + extension = (isWindows()) ? 'zip' : 'tar.gz' + } + } + + KotlinBuildPublishingPluginKt.configureKotlinPomAttributes( + /* receiver = */ mvn, + /* project = */ project, + /* explicitDescription = */ "Kotlin/Native bundle", + /* packaging = */ "pom" + ) + } + register("BundlePrebuilt", MavenPublication) { mvn -> + mvn.groupId = project.group.toString() + mvn.artifactId = project.name + "-prebuilt" + mvn.version = konanVersionFull + + if (publishBundlesFromLocation) { + def prebuiltBundleArchives = bundlesLocationFiles + .findAll { it.name.startsWith("kotlin-native-prebuilt") } + def bundlePrebuiltConfigs = createConfigurations(prebuiltBundleArchives) + bundlePrebuiltConfigs.forEach { target, file -> + mvn.artifact(file) { + classifier = platformName(target) + extension = (target.family == Family.MINGW) ? 'zip' : 'tar.gz' + } + } + } else { + mvn.artifact(bundlePrebuilt) { + classifier = HostManager.platformName() + extension = (isWindows()) ? 'zip' : 'tar.gz' + } + } + KotlinBuildPublishingPluginKt.configureKotlinPomAttributes( + /* receiver = */ mvn, + /* project = */ project, + /* explicitDescription = */ "Kotlin/Native bundle (prebuilt platform libs)", + /* packaging = */ "pom" + ) + } + } +} \ No newline at end of file