diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt index 6f414e1ab1d..65cac5c5610 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt @@ -71,7 +71,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration private val suffix = produce.suffix(target) val outputName = configuration.get(KonanConfigKeys.OUTPUT)?.removeSuffixIfPresent(suffix) ?: produce.name.toLowerCase() val outputFile = outputName - .prefixIfNot(prefix) + .prefixBaseNameIfNot(prefix) .suffixIfNot(suffix) val tempFiles = TempFiles(outputName) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/util/util.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/util/util.kt index 6bf93c570d5..7eeda2ba277 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/util/util.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/util/util.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.backend.konan.util import kotlin.system.measureTimeMillis +import org.jetbrains.kotlin.konan.file.* fun printMillisec(message: String, body: () -> Unit) { val msec = measureTimeMillis{ @@ -39,6 +40,13 @@ fun nTabs(amount: Int): String { fun String.prefixIfNot(prefix: String) = if (this.startsWith(prefix)) this else "$prefix$this" +fun String.prefixBaseNameIfNot(prefix: String): String { + val file = File(this) + val name = file.name + val directory = file.parent + return "$directory/${name.prefixIfNot(prefix)}" +} + fun String.suffixIfNot(suffix: String) = if (this.endsWith(suffix)) this else "$this$suffix" diff --git a/backend.native/tests/build.gradle b/backend.native/tests/build.gradle index 0bbbb74fa10..4e5783a9269 100644 --- a/backend.native/tests/build.gradle +++ b/backend.native/tests/build.gradle @@ -2336,6 +2336,12 @@ if (isMac()) { } } +task produce_dynamic(type: DynamicKonanTest) { + source = "produce_dynamic/simple/hello.kt" + cSource = "$projectDir/produce_dynamic/simple/main.c" + goldValue = "Hello, dynamic!\n" +} + task buildKonanTests(type: BuildKonanTest) { compileList = [ "codegen", "datagen", "lower", "runtime", "serialization"] diff --git a/backend.native/tests/produce_dynamic/simple/hello.kt b/backend.native/tests/produce_dynamic/simple/hello.kt new file mode 100644 index 00000000000..1f6b3fead7b --- /dev/null +++ b/backend.native/tests/produce_dynamic/simple/hello.kt @@ -0,0 +1,4 @@ + +fun hello() { + println("Hello, dynamic!") +} diff --git a/backend.native/tests/produce_dynamic/simple/main.c b/backend.native/tests/produce_dynamic/simple/main.c new file mode 100644 index 00000000000..66eb6ce9481 --- /dev/null +++ b/backend.native/tests/produce_dynamic/simple/main.c @@ -0,0 +1,7 @@ +#include "testlib_api.h" + +int main(void) { + testlib_symbols()->kotlin.root.hello(); + return 0; +} + diff --git a/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/KonanTest.groovy b/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/KonanTest.groovy index 5cd3cca4a3c..586290f6703 100644 --- a/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/KonanTest.groovy +++ b/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/KonanTest.groovy @@ -492,14 +492,45 @@ class LinkKonanTest extends KonanTest { protected String lib void compileTest(List filesToCompile, String exe) { - def libDir = project.file(lib).absolutePath - def libBc = "${libDir}.bc" + def libname = "testklib" + def klib = "$outputDirectory/$libname" - runCompiler(lib, libBc, ['-produce', 'library'] + ((flags != null) ? flags :[])) - runCompiler(filesToCompile, exe, ['-library', libBc] + ((flags != null) ? flags :[])) + runCompiler(lib, klib, ['-produce', 'library'] + ((flags != null) ? flags :[])) + runCompiler(filesToCompile, exe, ['-library', klib] + ((flags != null) ? flags :[])) } } +class DynamicKonanTest extends KonanTest { + protected String cSource + + void compileTest(List filesToCompile, String exe) { + def libname = "testlib" + def dylib = "$outputDirectory/$libname" + def realExe = "${exe}.${targetManager.target.family.exeSuffix}" + + runCompiler(filesToCompile, dylib, ['-produce', 'dynamic'] + ((flags != null) ? flags :[])) + runClang([cSource], realExe, ['-I', outputDirectory, '-L', outputDirectory, '-l', libname]) + } + + void runClang(List cSources, String output, List moreArgs) { + def log = new ByteArrayOutputStream() + project.execKonanClang(project.testTarget) { + workingDir outputDirectory + + executable "clang" + args cSources + args '-o', output + args moreArgs + args "-Wl,-rpath,$outputDirectory" + + standardOutput = log + errorOutput = log + } + def logString = log.toString("UTF-8") + project.file("${output}.compilation.log").write(logString) + println(logString) + } +} class RunExternalTestGroup extends RunStandaloneKonanTest { def groupDirectory = "."