diff --git a/kotlin-native/Interop/Indexer/build.gradle.kts b/kotlin-native/Interop/Indexer/build.gradle.kts index 3563f7166b2..3c2dfe9c567 100644 --- a/kotlin-native/Interop/Indexer/build.gradle.kts +++ b/kotlin-native/Interop/Indexer/build.gradle.kts @@ -17,14 +17,13 @@ plugins { id("kotlin.native.build-tools-conventions") id("native-interop-plugin") id("native") + id("native-dependencies") } - val libclangextProject = project(":kotlin-native:libclangext") val libclangextTask = libclangextProject.path + ":build" val libclangextDir = libclangextProject.buildDir val libclangextIsEnabled = libclangextProject.findProperty("isEnabled")!! as Boolean -val llvmDir = project.findProperty("llvmDir") val libclang = @@ -34,11 +33,11 @@ val libclang = "lib/${System.mapLibraryName("clang")}" } -val cflags = mutableListOf( "-I$llvmDir/include", +val cflags = mutableListOf( "-I${nativeDependencies.llvmPath}/include", "-I${project(":kotlin-native:libclangext").projectDir.absolutePath}/src/main/include", *platformManager.hostPlatform.clangForJni.hostCompilerArgsForJni) -val ldflags = mutableListOf("$llvmDir/$libclang", "-L${libclangextDir.absolutePath}", "-lclangext") +val ldflags = mutableListOf("${nativeDependencies.llvmPath}/$libclang", "-L${libclangextDir.absolutePath}", "-lclangext") if (libclangextIsEnabled) { assert(HostManager.hostIsMac) @@ -74,7 +73,7 @@ if (libclangextIsEnabled) { "clangTooling", "clangFormat", "LLVMTarget", "LLVMMC", "LLVMLinker", "LLVMTransformUtils", "LLVMBitWriter", "LLVMBitReader", "LLVMAnalysis", "LLVMProfileData", "LLVMCore", "LLVMSupport", "LLVMBinaryFormat", "LLVMDemangle" - ).map { "$llvmDir/lib/lib${it}.a" } + ).map { "${nativeDependencies.llvmPath}/lib/lib${it}.a" } ldflags.addAll(llvmLibs) ldflags.addAll(listOf("-lpthread", "-lz", "-lm", "-lcurses")) @@ -93,12 +92,12 @@ native { val cxxflags = listOf("-std=c++11", *cflags.toTypedArray()) suffixes { (".c" to ".$obj") { - tool(*platformManager.hostPlatform.clangForJni.clangC("").toTypedArray()) + tool(*hostPlatform.clangForJni.clangC("").toTypedArray()) flags(*cflags.toTypedArray(), "-c", "-o", ruleOut(), ruleInFirst()) } (".cpp" to ".$obj") { - tool(*platformManager.hostPlatform.clangForJni.clangCXX("").toTypedArray()) + tool(*hostPlatform.clangForJni.clangCXX("").toTypedArray()) flags(*cxxflags.toTypedArray(), "-c", "-o", ruleOut(), ruleInFirst()) } @@ -115,7 +114,7 @@ native { sourceSets["main-cpp"]!!.transform(".cpp" to ".$obj")) target(solib("clangstubs"), *objSet) { - tool(*platformManager.hostPlatform.clangForJni.clangCXX("").toTypedArray()) + tool(*hostPlatform.clangForJni.clangCXX("").toTypedArray()) flags( "-shared", "-o", ruleOut(), *ruleInAll(), @@ -182,11 +181,12 @@ tasks.withType().configureEach { project(":kotlin-native:Interop:Runtime") ) dependsOn(projectsWithNativeLibs.map { "${it.path}:nativelibs" }) + dependsOn(nativeDependencies.llvmDependency) systemProperty("java.library.path", projectsWithNativeLibs.joinToString(File.pathSeparator) { File(it.buildDir, "nativelibs").absolutePath }) - systemProperty("kotlin.native.llvm.libclang", "$llvmDir/" + if (HostManager.hostIsMingw) { + systemProperty("kotlin.native.llvm.libclang", "${nativeDependencies.llvmPath}/" + if (HostManager.hostIsMingw) { "bin/libclang.dll" } else { "lib/${System.mapLibraryName("clang")}" diff --git a/kotlin-native/Interop/Runtime/build.gradle.kts b/kotlin-native/Interop/Runtime/build.gradle.kts index 81e4409e407..055fd674f65 100644 --- a/kotlin-native/Interop/Runtime/build.gradle.kts +++ b/kotlin-native/Interop/Runtime/build.gradle.kts @@ -10,19 +10,18 @@ import org.jetbrains.kotlin.* plugins { id("org.jetbrains.kotlin.jvm") id("native") + id("native-dependencies") } native { val isWindows = PlatformInfo.isWindows() val obj = if (isWindows) "obj" else "o" val lib = if (isWindows) "lib" else "a" - val host = rootProject.project(":kotlin-native").extra["hostName"] - val hostLibffiDir = rootProject.project(":kotlin-native").extra["${host}LibffiDir"] - val cflags = mutableListOf("-I$hostLibffiDir/include", - *platformManager.hostPlatform.clangForJni.hostCompilerArgsForJni) + val cflags = mutableListOf("-I${nativeDependencies.libffiPath}/include", + *hostPlatform.clangForJni.hostCompilerArgsForJni) suffixes { (".c" to ".$obj") { - tool(*platformManager.hostPlatform.clangForJni.clangC("").toTypedArray()) + tool(*hostPlatform.clangForJni.clangC("").toTypedArray()) flags( *cflags.toTypedArray(), "-c", "-o", ruleOut(), ruleInFirst()) } } @@ -34,15 +33,16 @@ native { val objSet = sourceSets["callbacks"]!!.transform(".c" to ".$obj") target(solib("callbacks"), objSet) { - tool(*platformManager.hostPlatform.clangForJni.clangCXX("").toTypedArray()) + tool(*hostPlatform.clangForJni.clangCXX("").toTypedArray()) flags("-shared", "-o",ruleOut(), *ruleInAll(), "-L${project(":kotlin-native:libclangext").buildDir}", - "$hostLibffiDir/lib/libffi.$lib", + "${nativeDependencies.libffiPath}/lib/libffi.$lib", "-lclangext") } tasks.named(solib("callbacks")).configure { dependsOn(":kotlin-native:libclangext:${lib("clangext")}") + dependsOn(nativeDependencies.libffiDependency) } } diff --git a/kotlin-native/Interop/StubGenerator/build.gradle.kts b/kotlin-native/Interop/StubGenerator/build.gradle.kts index 89181027ff7..7f9c3f4e597 100644 --- a/kotlin-native/Interop/StubGenerator/build.gradle.kts +++ b/kotlin-native/Interop/StubGenerator/build.gradle.kts @@ -21,6 +21,7 @@ buildscript { plugins { kotlin("jvm") application + id("native-dependencies") } application { @@ -59,11 +60,11 @@ tasks { project(":kotlin-native:Interop:Runtime") ) dependsOn(projectsWithNativeLibs.map { "${it.path}:nativelibs" }) + dependsOn(nativeDependencies.llvmDependency) systemProperty("java.library.path", projectsWithNativeLibs.joinToString(File.pathSeparator) { File(it.buildDir, "nativelibs").absolutePath }) - val llvmDir = project.findProperty("llvmDir") - val libclangPath = "$llvmDir/" + if (org.jetbrains.kotlin.konan.target.HostManager.hostIsMingw) { + val libclangPath = "${nativeDependencies.llvmPath}/" + if (org.jetbrains.kotlin.konan.target.HostManager.hostIsMingw) { "bin/libclang.dll" } else { "lib/${System.mapLibraryName("clang")}" diff --git a/kotlin-native/backend.native/build.gradle b/kotlin-native/backend.native/build.gradle index 8380bbc671b..67058e8657b 100644 --- a/kotlin-native/backend.native/build.gradle +++ b/kotlin-native/backend.native/build.gradle @@ -87,7 +87,7 @@ kotlinNativeInterop { // For some reason, this worked fine before macOS 12.3. // // To enforce linking with proper libc++, pass the default path explicitly: - linkerOpts "-L${platformManager.hostPlatform.absoluteTargetSysRoot}/usr/lib" + linkerOpts "-L${hostPlatform.absoluteTargetSysRoot}/usr/lib" } linkerOpts "-L$llvmDir/lib", "-L${rootProject.project(':kotlin-native:llvmDebugInfoC').buildDir}", "-L${rootProject.project(':kotlin-native:libllvmext').buildDir}" } diff --git a/kotlin-native/backend.native/tests/build.gradle b/kotlin-native/backend.native/tests/build.gradle index 13cdf64b18d..9cba29f728b 100644 --- a/kotlin-native/backend.native/tests/build.gradle +++ b/kotlin-native/backend.native/tests/build.gradle @@ -25,6 +25,7 @@ buildscript { apply plugin: 'konan' apply plugin: 'kotlin' apply plugin: 'kotlin.native.build-tools-conventions' +apply plugin: 'native-dependencies' configurations { cli_bc @@ -258,7 +259,7 @@ Task linkTest(String name, Closure configureClosure) { * Creates a task for a dynamic test. Configures runner and adds library and test build tasks. */ Task dynamicTest(String name, Closure configureClosure) { - return KotlinNativeTestKt.createTest(project, name, KonanDynamicTest) { task -> + return KotlinNativeTestKt.createTest(project, name, KonanDynamicTest) { KonanDynamicTest task -> task.configure(configureClosure) if (task.enabled) { konanArtifacts { @@ -284,6 +285,8 @@ Task dynamicTest(String name, Closure configureClosure) { } def buildTask = UtilsKt.findKonanBuildTask(project, name, target) UtilsKt.dependsOnDist(buildTask) + task.dependsOn(nativeDependencies.llvmDependency) + task.dependsOn(nativeDependencies.targetDependency(target)) } } } @@ -3737,6 +3740,8 @@ int customCompare(const char* str1, const char* str2) { void createInterop(String name, Closure conf) { konanArtifacts { interop(name, targets: [target.name]) { + dependsOn(nativeDependencies.llvmDependency) + dependsOn(nativeDependencies.targetDependency(target)) conf(it) noDefaultLibs(true) noEndorsedLibs(true) @@ -4126,7 +4131,7 @@ createInterop("exceptions_cCallback") { * Creates a task for the interop test. Configures runner and adds library and test build tasks. */ Task interopTestBase(String name, boolean multiFile, boolean interop2ForMainOnly, Closure configureClosure) { - return KotlinNativeTestKt.createTest(project, name, KonanInteropTest) { task -> + return KotlinNativeTestKt.createTest(project, name, KonanInteropTest) { KonanInteropTest task -> task.configure(configureClosure) if (task.enabled) { konanArtifacts { @@ -4167,6 +4172,8 @@ Task interopTestBase(String name, boolean multiFile, boolean interop2ForMainOnly extraOpts project.globalTestArgs } } + task.dependsOn(nativeDependencies.llvmDependency) + task.dependsOn(nativeDependencies.targetDependency(target)) } } } @@ -5846,7 +5853,7 @@ pluginTest("runtime_basic_init", "nopPlugin") { Task fileCheckTest(String name, Closure configureClosure) { - return project.tasks.create(name, FileCheckTest) { task -> + return project.tasks.create(name, FileCheckTest) { FileCheckTest task -> task.configure(configureClosure) task.llvmIr = project.file("$testOutputFileCheck/$name/$target/out.${task.phaseToCheck}.ll") @@ -5904,6 +5911,7 @@ Task fileCheckTest(String name, Closure configureClosure) { } UtilsKt.dependsOnKonanBuildingTask(task, name, target) } + task.dependsOn(nativeDependencies.llvmDependency) } } } diff --git a/kotlin-native/build-tools/build.gradle.kts b/kotlin-native/build-tools/build.gradle.kts index 3a8227d387f..ba5b41a6e70 100644 --- a/kotlin-native/build-tools/build.gradle.kts +++ b/kotlin-native/build-tools/build.gradle.kts @@ -123,5 +123,13 @@ gradlePlugin { id = "native" implementationClass = "org.jetbrains.kotlin.tools.NativePlugin" } + create("nativeDependenciesDownloader") { + id = "native-dependencies-downloader" + implementationClass = "org.jetbrains.kotlin.dependencies.NativeDependenciesDownloaderPlugin" + } + create("nativeDependencies") { + id = "native-dependencies" + implementationClass = "org.jetbrains.kotlin.dependencies.NativeDependenciesPlugin" + } } } diff --git a/kotlin-native/build-tools/src/main/groovy/org/jetbrains/kotlin/NativeInteropPlugin.groovy b/kotlin-native/build-tools/src/main/groovy/org/jetbrains/kotlin/NativeInteropPlugin.groovy index 2871a795c25..2ebdc068eb1 100644 --- a/kotlin-native/build-tools/src/main/groovy/org/jetbrains/kotlin/NativeInteropPlugin.groovy +++ b/kotlin-native/build-tools/src/main/groovy/org/jetbrains/kotlin/NativeInteropPlugin.groovy @@ -27,6 +27,8 @@ import org.gradle.api.internal.CollectionCallbackActionDecorator import org.gradle.api.tasks.JavaExec import org.gradle.api.tasks.SourceSet import org.gradle.internal.reflect.Instantiator +import org.jetbrains.kotlin.dependencies.NativeDependenciesExtension +import org.jetbrains.kotlin.konan.target.Platform class NamedNativeInteropConfig implements Named { @@ -155,6 +157,14 @@ class NamedNativeInteropConfig implements Named { return new File(project.buildDir, "interopTemp") } + String getLlvmDir() { + return project.extensions.nativeDependencies.llvmPath + } + + Platform getHostPlatform() { + return project.extensions.nativeDependencies.hostPlatform + } + NamedNativeInteropConfig(Project project, String name, String target = null, String flavor = 'jvm') { this.name = name this.project = project @@ -194,7 +204,8 @@ class NamedNativeInteropConfig implements Named { } genTask.configure { - dependsOn ":kotlin-native:dependencies:update" + dependsOn project.extensions.nativeDependencies.hostPlatformDependency + dependsOn project.extensions.nativeDependencies.llvmDependency dependsOn ":kotlin-native:Interop:Indexer:nativelibs" dependsOn ":kotlin-native:Interop:Runtime:nativelibs" classpath = project.configurations.interopStubGenerator @@ -293,6 +304,8 @@ class NativeInteropPlugin implements Plugin { @Override void apply(Project prj) { + prj.plugins.apply("native-dependencies") + prj.extensions.add("kotlinNativeInterop", new NativeInteropExtension(prj)) prj.configurations { diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/bitcode/CompileToBitcodePlugin.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/bitcode/CompileToBitcodePlugin.kt index dd02bb002ae..83d1c019b99 100644 --- a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/bitcode/CompileToBitcodePlugin.kt +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/bitcode/CompileToBitcodePlugin.kt @@ -25,6 +25,8 @@ import org.gradle.kotlin.dsl.* import org.gradle.language.base.plugins.LifecycleBasePlugin import org.jetbrains.kotlin.ExecClang import org.jetbrains.kotlin.cpp.* +import org.jetbrains.kotlin.dependencies.NativeDependenciesExtension +import org.jetbrains.kotlin.dependencies.NativeDependenciesPlugin import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.SanitizerKind import org.jetbrains.kotlin.konan.target.TargetDomainObjectContainer @@ -207,6 +209,7 @@ open class CompileToBitcodeExtension @Inject constructor(val project: Project) : private val compilationDatabase = project.extensions.getByType() private val execClang = project.extensions.getByType() + private val nativeDependencies = project.extensions.getByType() /** * Compiles source files into bitcode files. @@ -228,8 +231,8 @@ open class CompileToBitcodeExtension @Inject constructor(val project: Project) : this.inputFiles.setIncludes(this@SourceSet.inputFiles.includes) this.inputFiles.setExcludes(this@SourceSet.inputFiles.excludes) this.workingDirectory.set(module.compilerWorkingDirectory) - // TODO: Should depend only on the toolchain needed to build for the _target - dependsOn(":kotlin-native:dependencies:update") + dependsOn(nativeDependencies.llvmDependency) + dependsOn(nativeDependencies.targetDependency(_target)) dependsOn(this@SourceSet.dependencies) onlyIf { this@SourceSet.onlyIf.get().all { it.isSatisfiedBy(this@SourceSet) } @@ -249,8 +252,8 @@ open class CompileToBitcodeExtension @Inject constructor(val project: Project) : // Compile task depends on the toolchain (including headers) and on the source code (e.g. googletest). // compdb task should also have these dependencies. This way the generated database will point to the // code that actually exists. - // TODO: Should depend only on the toolchain needed to build for the _target - dependsOn(":kotlin-native:dependencies:update") + dependsOn(nativeDependencies.llvmDependency) + dependsOn(nativeDependencies.targetDependency(_target)) dependsOn(this@SourceSet.dependencies) } } @@ -662,6 +665,7 @@ open class CompileToBitcodePlugin : Plugin { project.apply() project.apply() project.apply() + project.apply() project.extensions.create("bitcode", project) } } diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/cpp/CppConsumerPlugin.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/cpp/CppConsumerPlugin.kt index 7e141a2a93d..aa2905753e4 100644 --- a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/cpp/CppConsumerPlugin.kt +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/cpp/CppConsumerPlugin.kt @@ -7,22 +7,8 @@ package org.jetbrains.kotlin.cpp import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.api.attributes.AttributeDisambiguationRule -import org.gradle.api.attributes.MultipleCandidatesDetails import org.jetbrains.kotlin.bitcode.CompileToBitcodePlugin -import org.jetbrains.kotlin.konan.target.TargetWithSanitizer - -private class TargetDisambiguationRule : AttributeDisambiguationRule { - override fun execute(details: MultipleCandidatesDetails) = details.run { - if (consumerValue == null) { - // If the consumer didn't want a specific target, provide host target if it's available. - val default = TargetWithSanitizer.host - if (candidateValues.contains(default)) { - closestMatch(default) - } - } - } -} +import org.jetbrains.kotlin.konan.target.registerTargetWithSanitizerAttribute /** * Plugin for projects that depend upon C++-built projects. @@ -36,9 +22,7 @@ private class TargetDisambiguationRule : AttributeDisambiguationRule { override fun apply(project: Project) { project.dependencies.attributesSchema { - attribute(TargetWithSanitizer.TARGET_ATTRIBUTE) { - disambiguationRules.add(TargetDisambiguationRule::class.java) - } + registerTargetWithSanitizerAttribute() } } diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/cpp/GitClangFormatPlugin.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/cpp/GitClangFormatPlugin.kt index ded398fa679..209efe67592 100644 --- a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/cpp/GitClangFormatPlugin.kt +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/cpp/GitClangFormatPlugin.kt @@ -8,12 +8,17 @@ package org.jetbrains.kotlin.cpp import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.* +import org.jetbrains.kotlin.dependencies.NativeDependenciesExtension +import org.jetbrains.kotlin.dependencies.NativeDependenciesPlugin /** * Plugin for [GitClangFormat] that creates a task `clangFormat` that will format project sources in the current branch. */ open class GitClangFormatPlugin : Plugin { override fun apply(target: Project) { + target.apply() + val nativeDependencies = target.extensions.getByType() + val directory = target.layout.projectDirectory.toString() target.tasks.register("clangFormat") { description = "Run clang-format in $directory" @@ -22,8 +27,7 @@ open class GitClangFormatPlugin : Plugin { this.directory.convention(directory) interactive.convention(false) // Needs LLVM toolchain. - // TODO: It does not need every dependency ever, only LLVM toolchain for the host. - dependsOn(":kotlin-native:dependencies:update") + dependsOn(nativeDependencies.llvmDependency) } } diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/dependencies/NativeDependenciesBasePlugin.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/dependencies/NativeDependenciesBasePlugin.kt new file mode 100644 index 00000000000..4252db2ce50 --- /dev/null +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/dependencies/NativeDependenciesBasePlugin.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.dependencies + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.jetbrains.kotlin.konan.target.registerTargetWithSanitizerAttribute + +/** + * Base plugin for projects that use native dependencies. + * + * For defining native dependencies see [NativeDependenciesDownloaderPlugin]. + * For consuming native dependencies see [NativeDependenciesPlugin] + * + * @see NativeDependenciesDownloaderPlugin + * @see NativeDependenciesPlugin + */ +// TODO: Consider making it more like a standard gradle plugins that also +// creates default configurations and lifecycle tasks. +class NativeDependenciesBasePlugin : Plugin { + override fun apply(project: Project) { + project.dependencies.attributesSchema { + registerTargetWithSanitizerAttribute() + } + } +} \ No newline at end of file diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/dependencies/NativeDependenciesDownloader.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/dependencies/NativeDependenciesDownloader.kt new file mode 100644 index 00000000000..3d09abc9a7d --- /dev/null +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/dependencies/NativeDependenciesDownloader.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.dependencies + +import org.gradle.api.DefaultTask +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.UntrackedTask +import org.jetbrains.kotlin.konan.util.DependencyProcessor + +/** + * Downloader of native dependencies. + * + * Serves as a Gradle task wrapper around [DependencyProcessor]. + */ +@UntrackedTask(because = "Output is large and work avoidance is performed in DependencyProcessor anyway") +abstract class NativeDependenciesDownloader : DefaultTask() { + /** + * [DependencyProcessor] that will perform downloading + */ + @get:Internal + abstract val dependencyProcessor: Property + + @TaskAction + fun downloadAndExtract() { + dependencyProcessor.get().run() + } +} \ No newline at end of file diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/dependencies/NativeDependenciesDownloaderPlugin.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/dependencies/NativeDependenciesDownloaderPlugin.kt new file mode 100644 index 00000000000..943ba4b0c94 --- /dev/null +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/dependencies/NativeDependenciesDownloaderPlugin.kt @@ -0,0 +1,158 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.dependencies + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.artifacts.Configuration +import org.gradle.api.attributes.Usage +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.logging.LogLevel +import org.gradle.api.provider.Property +import org.gradle.kotlin.dsl.* +import org.jetbrains.kotlin.konan.properties.KonanPropertiesLoader +import org.jetbrains.kotlin.konan.target.PlatformManager +import org.jetbrains.kotlin.konan.target.TargetDomainObjectContainer +import org.jetbrains.kotlin.konan.target.TargetWithSanitizer +import org.jetbrains.kotlin.konan.util.DependencyProcessor +import org.jetbrains.kotlin.utils.capitalized +import javax.inject.Inject + +/** + * Downloading native dependencies. + * + * An embedder must provide [dependenciesDirectory] and [repositoryURL] and then provide a list + * of targets. + * To configure for all targets: + * ``` + * nativeDependenciesDownloader { + * dependenciesDir.set(…) + * baseUrl.set(…) + * allTargets {} + * } + * ``` + * To download for host and `someTarget` only: + * ``` + * nativeDependenciesDownloader { + * dependenciesDir.set(…) + * baseUrl.set(…) + * hostTarget {} + * target(someTarget) {} + * } + * ``` + * + * Apply [plugin][NativeDependenciesDownloaderPlugin] to create this extension. + * The extension name is `nativeDependenciesDownloader`. + * + * @see NativeDependenciesDownloaderPlugin + */ +abstract class NativeDependenciesDownloaderExtension @Inject constructor(private val project: Project) : TargetDomainObjectContainer(project) { + init { + this.factory = { target -> + project.objects.newInstance(this, target) + } + } + + /** + * Outgoing configuration with all native dependencies. + */ + val nativeDependenciesElements: Configuration by project.configurations.creating { + description = "Native dependencies" + isCanBeConsumed = true + isCanBeResolved = false + attributes { + attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(NativeDependenciesUsage.NATIVE_DEPENDENCY)) + } + } + + /** + * Root directory where to place all dependencies. + */ + abstract val dependenciesDirectory: DirectoryProperty + + /** + * Dependency repository. + */ + abstract val repositoryURL: Property + + abstract class Target @Inject constructor( + private val owner: NativeDependenciesDownloaderExtension, + private val _target: TargetWithSanitizer, + ) { + val target by _target::target + val sanitizer by _target::sanitizer + + private val project by owner::project + + private val platformManager = project.extensions.getByType() + + private val loader: KonanPropertiesLoader = platformManager.loader(target).let { + require(it is KonanPropertiesLoader) { + "loader for $target must implement ${KonanPropertiesLoader::class}" + } + it + } + + private val dependencyProcessor by lazy { + DependencyProcessor( + owner.dependenciesDirectory.apply { finalizeValue() }.asFile.get(), + loader, + owner.repositoryURL.apply { finalizeValue() }.get(), + keepUnstable = false) { url, currentBytes, totalBytes -> + // TODO: Consider using logger. + print("\nDownloading dependency for $_target: $url (${currentBytes}/${totalBytes}). ") + }.apply { + showInfo = project.logger.isEnabled(LogLevel.INFO) + } + } + + val dependencies by loader::dependencies + + val task = project.tasks.register("nativeDependencies${_target.name.capitalized}") { + description = "Download dependencies for $_target" + group = "native dependencies" + dependencyProcessor.set(this@Target.dependencyProcessor) + } + + init { + owner.nativeDependenciesElements.outgoing { + variants { + create("$_target") { + attributes { + attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, _target) + } + dependencies.forEach { dependency -> + artifact(dependencyProcessor.resolve(dependency)) { + name = dependency + type = "directory" + extension = "" + builtBy(task) + } + } + } + } + } + } + } +} + +/** + * Downloading native dependencies. + * + * Provides [extension][NativeDependenciesDownloaderExtension] named `nativeDependenciesDownloader` + * that configures native dependencies. + * + * To consume native dependencies use [NativeDependenciesPlugin]. + * + * @see NativeDependenciesPlugin + * @see NativeDependenciesDownloaderExtension + */ +open class NativeDependenciesDownloaderPlugin : Plugin { + override fun apply(project: Project) { + project.apply() + project.extensions.create("nativeDependenciesDownloader", project) + } +} \ No newline at end of file diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/dependencies/NativeDependenciesPlugin.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/dependencies/NativeDependenciesPlugin.kt new file mode 100644 index 00000000000..6d7292e558b --- /dev/null +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/dependencies/NativeDependenciesPlugin.kt @@ -0,0 +1,131 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.dependencies + +import org.gradle.api.Buildable +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.artifacts.Configuration +import org.gradle.api.attributes.Usage +import org.gradle.api.file.FileCollection +import org.gradle.kotlin.dsl.* +import org.jetbrains.kotlin.konan.target.* +import javax.inject.Inject + +/** + * Consuming native dependencies. + * + * Creates resolvable [nativeDependencies] configuration with default dependency + * on `:kotlin-native:dependencies` (that project must provide native dependencies by using [NativeDependenciesDownloaderPlugin]) + * + * [llvmPath], [libffiPath] and [hostPlatform] are accessors that can be used during configuration + * phase and do not anyhow force the actual dependencies to be downloaded. So, anytime these + * accessors are used, make sure that execution of related tasks (or configurations resolving) + * depend on [llvmDependency], [libffiDependency] and [hostPlatformDependency] respectively. + * + * Apply [plugin][NativeDependenciesPlugin] to create this extension. + * The extension name is `nativeDependencies`. + * + * @see NativeDependenciesPlugin + */ +abstract class NativeDependenciesExtension @Inject constructor(private val project: Project) { + private val platformManager = project.extensions.getByType() + + val nativeDependencies: Configuration by project.configurations.creating { + description = "Native dependencies" + isCanBeConsumed = false + isCanBeResolved = true + attributes { + attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(NativeDependenciesUsage.NATIVE_DEPENDENCY)) + } + defaultDependencies { + add(project.dependencies.project(":kotlin-native:dependencies")) + } + } + + private val llvmFileCollection: FileCollection = nativeDependencies.incoming.artifacts.artifactFiles.filter { + it.name == platformManager.hostPlatform.llvmHome + } + + private val libffiFileCollection: FileCollection = nativeDependencies.incoming.artifacts.artifactFiles.filter { + it.name == platformManager.hostPlatform.libffiDir + } + + /** + * Dependency on host LLVM. + */ + val llvmDependency: Buildable by ::llvmFileCollection + + /** + * Absolute path to host LLVM. Can be used during configuration. + * Note: this will not force LLVM to be downloaded. Make sure to depend + * on [llvmDependency] in tasks that need it. + */ + val llvmPath: String + get() = llvmFileCollection.singleFile.canonicalPath + + /** + * Dependency on host libffi. + */ + val libffiDependency: Buildable by ::libffiFileCollection + + /** + * Absolute path to host libffi. Can be used during configuration. + * Note: this will not force libffi to be downloaded. Make sure to depend + * on [libffiDependency] in tasks that need it. + */ + val libffiPath: String + get() = libffiFileCollection.singleFile.canonicalPath + + /** + * Dependency on host platform. + * + * Equivalent to calling [targetDependency] with host target + */ + val hostPlatformDependency: Buildable + get() = targetDependency() + + /** + * [Platform] for host. Can be used during configuration. + * Note: this will not force platform dependency to be downloaded. Make sure to depend + * on [hostPlatformDependency] in tasks that need it. + */ + val hostPlatform: Platform + get() = platformManager.hostPlatform + + /** + * Dependency on [target] platform. + */ + fun targetDependency(target: TargetWithSanitizer = TargetWithSanitizer.host): Buildable = + nativeDependencies.incoming.artifactView { + attributes { + attribute(TargetWithSanitizer.TARGET_ATTRIBUTE, target) + } + }.files + + /** + * Dependency on [target] platform. + */ + // TODO: Remove when all build.gradle are gone. + fun targetDependency(target: KonanTarget): Buildable = targetDependency(target.withSanitizer()) +} + +/** + * Consuming native dependencies. + * + * Provides [extension][NativeDependenciesExtension] named `nativeDependencies` that manages native dependencies. + * + * To provide native dependencies use [NativeDependenciesDownloaderPlugin]. + * + * @see NativeDependenciesDownloaderPlugin + * @see NativeDependenciesExtension + */ +class NativeDependenciesPlugin : Plugin { + override fun apply(project: Project) { + project.apply() + project.extensions.create("nativeDependencies", project) + } +} \ No newline at end of file diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/dependencies/NativeDependenciesUsage.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/dependencies/NativeDependenciesUsage.kt new file mode 100644 index 00000000000..d5fb97641e6 --- /dev/null +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/dependencies/NativeDependenciesUsage.kt @@ -0,0 +1,20 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.dependencies + +import org.gradle.api.attributes.Attribute +import org.gradle.api.attributes.Usage + +object NativeDependenciesUsage { + /** + * Directories with native dependencies. + */ + @JvmField + val NATIVE_DEPENDENCY = "native-dependency" + + @JvmField + val USAGE_ATTRIBUTE: Attribute = Usage.USAGE_ATTRIBUTE +} \ No newline at end of file diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/konan/target/TargetWithSanitizer.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/konan/target/TargetWithSanitizer.kt index 35fcf342d06..01b071ed4e9 100644 --- a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/konan/target/TargetWithSanitizer.kt +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/konan/target/TargetWithSanitizer.kt @@ -7,6 +7,9 @@ package org.jetbrains.kotlin.konan.target import org.gradle.api.Named import org.gradle.api.attributes.Attribute +import org.gradle.api.attributes.AttributeDisambiguationRule +import org.gradle.api.attributes.AttributesSchema +import org.gradle.api.attributes.MultipleCandidatesDetails import java.io.Serializable /** @@ -54,3 +57,24 @@ val PlatformManager.allTargetsWithSanitizers target.withSanitizer(it) } } + +private class TargetDisambiguationRule : AttributeDisambiguationRule { + override fun execute(details: MultipleCandidatesDetails) = details.run { + if (consumerValue == null) { + // If the consumer didn't want a specific target, provide host target if it's available. + val default = TargetWithSanitizer.host + if (candidateValues.contains(default)) { + closestMatch(default) + } + } + } +} + +/** + * Register [TargetWithSanitizer] attribute with [AttributesSchema]. + */ +fun AttributesSchema.registerTargetWithSanitizerAttribute() { + attribute(TargetWithSanitizer.TARGET_ATTRIBUTE) { + disambiguationRules.add(TargetDisambiguationRule::class.java) + } +} \ No newline at end of file diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/tools/NativePlugin.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/tools/NativePlugin.kt index 6c1efa84a78..895eeae5f48 100644 --- a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/tools/NativePlugin.kt +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/tools/NativePlugin.kt @@ -11,9 +11,10 @@ import org.gradle.api.Project import org.gradle.api.file.FileCollection import org.gradle.api.plugins.BasePlugin import org.gradle.api.tasks.* -import org.gradle.kotlin.dsl.apply -import org.gradle.kotlin.dsl.withType +import org.gradle.kotlin.dsl.* import org.gradle.language.base.plugins.LifecycleBasePlugin +import org.jetbrains.kotlin.dependencies.NativeDependenciesExtension +import org.jetbrains.kotlin.dependencies.NativeDependenciesPlugin import org.jetbrains.kotlin.konan.target.HostManager.Companion.hostIsMac import org.jetbrains.kotlin.konan.target.HostManager.Companion.hostIsMingw import java.io.File @@ -35,6 +36,7 @@ import kotlin.collections.toTypedArray open class NativePlugin : Plugin { override fun apply(project: Project) { project.apply() + project.apply() project.extensions.create("native", NativeToolsExtension::class.java, project) } } @@ -84,7 +86,9 @@ class ToolPatternImpl(val extension: NativeToolsExtension, val output:String, va task.input = input.map { extension.project.file(it) } - task.dependsOn(":kotlin-native:dependencies:update") + val nativeDependenciesExtension = extension.project.extensions.getByType() + task.dependsOn(nativeDependenciesExtension.hostPlatformDependency) + task.dependsOn(nativeDependenciesExtension.llvmDependency) if (configureDepencies) task.input.forEach { task.dependsOn(it.name) } val file = extension.project.file(output) @@ -183,6 +187,11 @@ class ToolConfigurationPatterns( open class NativeToolsExtension(val project: Project) { + private val nativeDependenciesExtension = project.extensions.getByType() + + val llvmDir by nativeDependenciesExtension::llvmPath + val hostPlatform by nativeDependenciesExtension::hostPlatform + val sourceSets = SourceSets(project, this, mutableMapOf()) val toolPatterns = ToolConfigurationPatterns(this, mutableMapOf, ToolPatternConfiguration>()) val cleanupFiles = mutableListOf() diff --git a/kotlin-native/build.gradle b/kotlin-native/build.gradle index 6e5bf70adff..948280cc8d3 100644 --- a/kotlin-native/build.gradle +++ b/kotlin-native/build.gradle @@ -79,10 +79,6 @@ ext { } allprojects { - if (path != ":kotlin-native:dependencies") { - evaluationDependsOn(":kotlin-native:dependencies") - } - repositories { mavenCentral() maven { @@ -249,7 +245,6 @@ tasks.register("distCompiler", Copy) { if (!UtilsKt.isDefaultNativeHome(project)) { enabled = false } else { - dependsOn ":kotlin-native:dependencies:update" dependsOn ':kotlin-native:shadowJar' dependsOn ":kotlin-native-compiler-embeddable:kotlin-native-compiler-embeddable" } diff --git a/kotlin-native/dependencies/build.gradle b/kotlin-native/dependencies/build.gradle deleted file mode 100644 index 83b2b889898..00000000000 --- a/kotlin-native/dependencies/build.gradle +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license - * that can be found in the LICENSE file. - */ -import groovy.transform.stc.ClosureParams -import groovy.transform.stc.FromString -import org.jetbrains.kotlin.konan.target.* -import org.jetbrains.kotlin.konan.properties.KonanPropertiesLoader -import org.jetbrains.kotlin.konan.util.ArchiveType -import org.jetbrains.kotlin.konan.util.DependencyProcessor - -buildscript { - apply from: "$rootDir/kotlin-native/gradle/kotlinGradlePlugin.gradle" - - repositories { - mavenCentral() - } -} - -/** - * Downloads dependencies from the given URL into the given directory. - * The set of dependencies is determined by konanPropertiesLoader. - */ -class NativeDep extends DefaultTask { - static final String baseUrl = "https://cache-redirector.jetbrains.com/download.jetbrains.com/kotlin/native" - - @Internal - KonanPropertiesLoader konanPropertiesLoader = null - - @Internal - final File getBaseOutDir() { - final File res = project.rootProject.project(":kotlin-native").ext.dependenciesDir - res.mkdirs() - return res - } - - @TaskAction - void downloadAndExtract() { - def downloader = new DependencyProcessor(baseOutDir, konanPropertiesLoader, baseUrl, false, ArchiveType.systemDefault, { url, currentBytes, totalBytes -> - print("\n$name Downloading dependency: $url (${currentBytes}/${totalBytes}). ") - }) - downloader.showInfo = project.logger.isEnabled(LogLevel.INFO) - downloader.run() - } -} - -enum DependencyKind { - LLVM( "llvm", { it.llvmHome }, { "llvmDir" } ), - LIBFFI( "libffi", { it.libffiDir } ) - - - DependencyKind(String name, - @ClosureParams(value = FromString.class, options = "KonanPropertiesLoader") Closure dirGetter, - @ClosureParams(value = FromString.class, options = "KonanTarget") Closure propertyNameGetter = - {target -> "${target.visibleName}${name.capitalize()}Dir"}) { - this.name = name - this.dirGetter = dirGetter - this.propertyNameGetter = propertyNameGetter - } - - private String name - private Closure dirGetter // KonanProperties -> String - private Closure propertyNameGetter // KonanTarget -> String - - String getDirectory(KonanPropertiesLoader properties) { - return dirGetter(properties) - } - - String getPropertyName(KonanTarget target) { - return propertyNameGetter(target) - } - - String toString() { return name } -} - -def platformManager = rootProject.project(":kotlin-native").ext.platformManager - -EnabledTargetsKt.enabledTargets(platformManager).each { target -> - def loader = platformManager.loader(target) - - tasks.register("${target}Dependencies", NativeDep) { - konanPropertiesLoader = loader - } - - // Also resolves all dependencies: - final DependencyProcessor dependencyProcessor = new DependencyProcessor( - rootProject.project(":kotlin-native").ext.dependenciesDir, - loader.properties, - loader.dependencies, - NativeDep.baseUrl, - false, - ArchiveType.systemDefault, - { url, currentBytes, totalBytes -> - print("\n(no-task) Downloading dependency: $url (${currentBytes}/${totalBytes}). ") - }) - - DependencyKind.values().each { kind -> - def dir = kind.getDirectory(loader) - if (dir != null) { - String path = dependencyProcessor.resolve(dir).canonicalPath - rootProject.project(":kotlin-native").ext.set(kind.getPropertyName(target), path) - } - } -} - -tasks.register("update") { - dependsOn tasks.withType(NativeDep) - mustRunAfter(tasks.withType(NativeDep)) -} -rootProject.project(":kotlin-native").ext.nativeDependencies = tasks.withType(NativeDep) - -tasks.register("rmDotKonan", Delete) { - def dir = System.getenv("KONAN_DATA_DIR") ?: "${System.getProperty("user.home")}/.konan" - delete dir -} - diff --git a/kotlin-native/dependencies/build.gradle.kts b/kotlin-native/dependencies/build.gradle.kts new file mode 100644 index 00000000000..c273cd392de --- /dev/null +++ b/kotlin-native/dependencies/build.gradle.kts @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +import java.io.File +import org.jetbrains.kotlin.konan.target.allTargetsWithSanitizers + +plugins { + id("native-dependencies-downloader") + id("native-dependencies") +} + +nativeDependenciesDownloader { + repositoryURL.set("https://cache-redirector.jetbrains.com/download.jetbrains.com/kotlin/native") + dependenciesDirectory.set(rootProject.project(":kotlin-native").property("dependenciesDir") as File) + + allTargets {} +} + +/** + * Download all dependencies. + */ +val update by tasks.registering { + platformManager.allTargetsWithSanitizers.forEach { + dependsOn(nativeDependencies.targetDependency(it)) + } +} + +// TODO: This sort of task probably belongs to :kotlin-native +val rmDotKonan by tasks.registering(Delete::class) { + val dir = System.getenv("KONAN_DATA_DIR") ?: "${System.getProperty("user.home")}/.konan" + delete(dir) +} diff --git a/kotlin-native/libclangext/build.gradle.kts b/kotlin-native/libclangext/build.gradle.kts index cf5e8d10a6b..f82c6b5e1f9 100644 --- a/kotlin-native/libclangext/build.gradle.kts +++ b/kotlin-native/libclangext/build.gradle.kts @@ -29,14 +29,14 @@ native { val obj = if (isWindows) "obj" else "o" val cxxflags = mutableListOf("--std=c++17", "-g", "-Isrc/main/include", - "-I${project.findProperty("llvmDir")}/include", + "-I$llvmDir/include", "-DLLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING=1") if (libclangextEnabled) { cxxflags += "-DLIBCLANGEXT_ENABLE=1" } suffixes { (".cpp" to ".$obj") { - tool(*platformManager.hostPlatform.clangForJni.clangCXX("").toTypedArray()) + tool(*hostPlatform.clangForJni.clangCXX("").toTypedArray()) flags(*cxxflags.toTypedArray(), "-c", "-o", ruleOut(), ruleInFirst()) } } @@ -47,7 +47,7 @@ native { } val objSet = sourceSets["main"]!!.transform(".cpp" to ".$obj") target(lib("clangext"), objSet) { - tool(*platformManager.hostPlatform.clangForJni.llvmAr("").toTypedArray()) + tool(*hostPlatform.clangForJni.llvmAr("").toTypedArray()) flags("-qcv", ruleOut(), *ruleInAll()) } } \ No newline at end of file diff --git a/kotlin-native/libllvmext/build.gradle.kts b/kotlin-native/libllvmext/build.gradle.kts index defea47378b..5fed13e7178 100644 --- a/kotlin-native/libllvmext/build.gradle.kts +++ b/kotlin-native/libllvmext/build.gradle.kts @@ -16,18 +16,17 @@ import org.jetbrains.kotlin.tools.lib import org.jetbrains.kotlin.* -import org.jetbrains.kotlin.konan.target.ClangArgs import org.jetbrains.kotlin.konan.target.Family.* import org.jetbrains.kotlin.konan.target.HostManager plugins { id("kotlin.native.build-tools-conventions") id("native") + id("native-dependencies") } native { val obj = if (HostManager.hostIsMingw) "obj" else "o" - val llvmDir = project.findProperty("llvmDir") val cxxflags = mutableListOf( "--std=c++17", "-I${llvmDir}/include", @@ -47,7 +46,7 @@ native { } suffixes { (".cpp" to ".$obj") { - tool(*platformManager.hostPlatform.clangForJni.clangCXX("").toTypedArray()) + tool(*hostPlatform.clangForJni.clangCXX("").toTypedArray()) flags(*cxxflags.toTypedArray(), "-c", "-o", ruleOut(), ruleInFirst()) } @@ -60,14 +59,15 @@ native { val objSet = sourceSets["main"]!!.transform(".cpp" to ".$obj") target(lib("llvmext"), objSet) { - tool(*platformManager.hostPlatform.clangForJni.llvmAr("").toTypedArray()) + tool(*hostPlatform.clangForJni.llvmAr("").toTypedArray()) flags("-qcv", ruleOut(), *ruleInAll()) } } val printLlvmDir by tasks.registering { + dependsOn(nativeDependencies.llvmDependency) doLast { - println(project.findProperty("llvmDir")) + println(nativeDependencies.llvmPath) } } diff --git a/kotlin-native/llvmDebugInfoC/build.gradle.kts b/kotlin-native/llvmDebugInfoC/build.gradle.kts index 1458abb3fa0..81c0d3c113f 100644 --- a/kotlin-native/llvmDebugInfoC/build.gradle.kts +++ b/kotlin-native/llvmDebugInfoC/build.gradle.kts @@ -15,17 +15,12 @@ */ import org.jetbrains.kotlin.tools.lib -import org.jetbrains.kotlin.* -import org.jetbrains.kotlin.* -import org.jetbrains.kotlin.konan.target.ClangArgs import org.jetbrains.kotlin.konan.target.HostManager plugins { id("native") } -val llvmDir = project.findProperty("llvmDir") - native { val obj = if (HostManager.hostIsMingw) "obj" else "o" val cxxflags = mutableListOf( @@ -35,7 +30,7 @@ native { ) suffixes { (".cpp" to ".$obj") { - tool(*platformManager.hostPlatform.clangForJni.clangCXX("").toTypedArray()) + tool(*hostPlatform.clangForJni.clangCXX("").toTypedArray()) flags(*cxxflags.toTypedArray(), "-c", "-o", ruleOut(), ruleInFirst()) } @@ -48,7 +43,7 @@ native { val objSet = sourceSets["main"]!!.transform(".cpp" to ".$obj") target(lib("debugInfo"), objSet) { - tool(*platformManager.hostPlatform.clangForJni.llvmAr("").toTypedArray()) + tool(*hostPlatform.clangForJni.llvmAr("").toTypedArray()) flags("-qcv", ruleOut(), *ruleInAll()) } }