configurations { cli_bc } dependencies { cli_bc project(path: ':backend.native', configuration: 'cli_bc') } abstract class KonanTest extends DefaultTask { protected String source def backendNative = project.project(":backend.native") def runtimeProject = project.project(":runtime") def llvmLlc = llvmTool("llc") def runtimeBc = new File("${runtimeProject.buildDir.canonicalPath}/runtime.bc") def stdlibKtBc = new File("${runtimeProject.buildDir.canonicalPath}/stdlib.kt.bc") def mainC = 'main.c' String goldValue = null String testData = null public KonanTest(){ dependsOn([project.project(":runtime").tasks['build'], project.parent.tasks['build'], project.project(":backend.native").tasks['stdlib']]) } abstract void compileTest(File sourceS, File runtimeS, File libraryPath, File out) private File kt2bc(String ktSource) { def sourceKt = project.file(ktSource) def sourceBc = new File("${sourceKt.absolutePath}.bc") println "${runtimeBc}" project.javaexec { main = 'org.jetbrains.kotlin.cli.bc.K2NativeKt' classpath = project.configurations.cli_bc jvmArgs "-ea" args "-output", "${sourceBc.absolutePath}", "-runtime", "${runtimeBc.absolutePath}", "-library", "${stdlibKtBc.absolutePath}", "${sourceKt.absolutePath}" String libraryPath = "${project.llvmDir}/lib:${backendNative.buildDir.canonicalPath}/nativelibs" environment 'LD_LIBRARY_PATH' : libraryPath environment 'DYLD_LIBRARY_PATH' : libraryPath } return sourceBc } @TaskAction void executeTest() { def sourceS = bc2s(kt2bc(source)) def exe = new File(sourceS.absolutePath.replace(".kt.S", "")) def libraryPath = new File("${runtimeProject.file('src/main/bc').absolutePath}") compileTest(sourceS, bc2s(runtimeBc), stdlibKtBc, exe) println "execution :${exe.absolutePath}" def out = null project.exec { commandLine "${exe.absolutePath}" if (testData != null) { standardInput = new ByteArrayInputStream(testData.bytes) } if (goldValue != null) { out = new ByteArrayOutputStream() standardOutput = out } } if (goldValue != null && goldValue != out.toString()) throw new RuntimeException("test failed") } private File bc2s(File bcFile) { def outputFile = new File("${bcFile.absolutePath.replace(".bc",".S")}") println "${bcFile.absolutePath} -> ${outputFile.absolutePath}" println "tool: ${llvmLlc}" project.exec { commandLine "${llvmLlc}", "-o", "${outputFile.absolutePath}" , "${bcFile}" } return outputFile } private String llvmTool(String tool) { return "${project.llvmDir}/bin/${tool}" } private linux() { return project.isLinux() } // TODO: stop copy-pasting protected String linkDl() { if (linux()) { return "-ldl" } else { return "" } } protected String linkM() { if (linux()) { return "-lm" } else { return "" } } protected String rdynamic() { if (linux()) { return "-rdynamic" } else { return "" } } } class UnitKonanTest extends KonanTest { void compileTest(File sourceS, File runtimeS, File stdlibKtBc, File exe) { def testC = sourceS.absolutePath.replace(".kt.S", "-test.c") project.execClang { commandLine "clang", "${testC}", "${runtimeS.absolutePath}", "${stdlibKtBc.absolutePath}", "${sourceS.absolutePath}", "${mainC}", "-o", "${exe.absolutePath}", linkDl(), linkM(), rdynamic() } } } class RunKonanTest extends KonanTest { void compileTest(File sourceS, File runtimeS, File libraryPath, File exe) { project.execClang { commandLine "clang", "-DRUN_TEST", "${runtimeS.absolutePath}", "${stdlibKtBc.absolutePath}", "${sourceS.absolutePath}", "${mainC}", "-o", "${exe.absolutePath}", linkDl(), linkM(), rdynamic() } } } class LinkKonanTest extends KonanTest { protected String lib private File dir2bc(String ktSources) { def sourcesKt = project.file(ktSources) def libBc = new File("${sourcesKt.absolutePath}/bc/libout.kt.bc") def libPath = "${libBc.absolutePath}" project.javaexec { main = 'org.jetbrains.kotlin.cli.bc.K2NativeKt' classpath = project.configurations.cli_bc jvmArgs "-ea" args "-output", "${libPath}", "-runtime", "${runtimeBc.absolutePath}", sourcesKt String libraryPath = "${project.llvmDir}/lib:${backendNative.buildDir.canonicalPath}/nativelibs" environment 'LD_LIBRARY_PATH' : libraryPath environment 'DYLD_LIBRARY_PATH' : libraryPath } return libBc } private File link(String ktSource, File libBc) { def sourceKt = project.file(ktSource) def outPath = "${sourceKt.absolutePath.replace('.kt', '.kt.bc')}" def outBc = new File(outPath) project.javaexec { main = 'org.jetbrains.kotlin.cli.bc.K2NativeKt' classpath = project.configurations.cli_bc jvmArgs "-ea" args "-output", outPath, "-runtime", "${runtimeBc.absolutePath}", "-library", "${libBc.absolutePath}", "${sourceKt.absolutePath}" String libraryPath = "${project.llvmDir}/lib:${backendNative.buildDir.canonicalPath}/nativelibs" environment 'LD_LIBRARY_PATH' : libraryPath environment 'DYLD_LIBRARY_PATH' : libraryPath } return outBc } void compileTest(File sourceS, File runtimeS, File stdlibKtBc, File exe) { def testC = sourceS.absolutePath.replace(".kt.S", "-test.c") project.execClang { commandLine "clang", "${testC}", "${runtimeS.absolutePath}", "${stdlibKtBc.absolutePath}", "${sourceS.absolutePath}", "${mainC}", "-o", "${exe.absolutePath}", linkDl(), rdynamic() } } @TaskAction void executeTest() { def libBc = dir2bc(lib) def outBc = link(source, libBc) } } task run() { dependsOn(tasks.withType(KonanTest)) } task sum (type:UnitKonanTest) { source = "codegen/function/sum.kt" } // FIXME (https://github.com/JetBrains/kotlin-native/pull/74) //task method_call(type: UnitKonanTest) { // source = "codegen/object/method_call.kt" //} task fields(type: UnitKonanTest) { source = "codegen/object/fields.kt" } /*task objectInitialization(type: UnitKonanTest) { source = "codegen/object/initialization.kt" }*/ /* task objectBasic(type: KonanTest) { source = "$codegen/klass/basic.kt" } */ task check_type(type: UnitKonanTest) { source = "codegen/basics/check_type.kt" } task aritmetic(type: UnitKonanTest) { source = "codegen/function/arithmetic.kt" } task sum1(type: UnitKonanTest) { source = "codegen/function/sum_foo_bar.kt" } task sum2(type: UnitKonanTest) { source = "codegen/function/sum_imm.kt" } task sum_3const(type: UnitKonanTest) { source = "codegen/function/sum_3const.kt" } task local_variable(type: UnitKonanTest) { source = "codegen/basics/local_variable.kt" } task cast_simple(type: UnitKonanTest) { source = "codegen/basics/cast_simple.kt" } task hello0(type: RunKonanTest) { goldValue = "Hello, world!\n" source = "runtime/basic/hello0.kt" } task hello1(type: RunKonanTest) { goldValue = "Hello World" testData = "Hello World" source = "runtime/basic/hello1.kt" } task hello2(type: RunKonanTest) { goldValue = "you entered 'Hello World'" testData = "Hello World" source = "runtime/basic/hello2.kt" } task hello3(type: RunKonanTest) { goldValue = "239\ntrue\n3.14159\nA\n" source = "runtime/basic/hello3.kt" } task tostring0(type: RunKonanTest) { goldValue = "127\n-1\n239\nA\n1122334455\n112233445566778899\n3.14159\n1E+27\n1E-300\ntrue\nfalse\n" source = "runtime/basic/tostring0.kt" } task tostring1(type: RunKonanTest) { goldValue = "ello\n" source = "runtime/basic/tostring1.kt" } task array0(type: RunKonanTest) { goldValue = "5\n6\n7\n8\n9\n10\n11\n12\n13\n" source = "runtime/basic/array0.kt" } task array1(type: RunKonanTest) { goldValue = "4 2\n1-1\n69\n38\n" source = "runtime/basic/array1.kt" } task if_else(type: UnitKonanTest) { source = "codegen/branching/if_else.kt" } task when2(type: UnitKonanTest) { source = "codegen/branching/when2.kt" } task when5(type: UnitKonanTest) { source = "codegen/branching/when5.kt" } task when_through(type: UnitKonanTest) { source = "codegen/branching/when_through.kt" } task advanced_when2(type: UnitKonanTest) { source = "codegen/branching/advanced_when2.kt" } task advanced_when5(type: UnitKonanTest) { source = "codegen/branching/advanced_when5.kt" } task bool_yes(type: UnitKonanTest) { source = "codegen/function/boolean.kt" } task plus_eq(type: UnitKonanTest) { source = "codegen/function/plus_eq.kt" } task minus_eq(type: UnitKonanTest) { source = "codegen/function/minus_eq.kt" } task eqeq(type: UnitKonanTest) { source = "codegen/function/eqeq.kt" } task cycle(type: UnitKonanTest) { source = "codegen/cycles/cycle.kt" } task cycle_do(type: UnitKonanTest) { source = "codegen/cycles/cycle_do.kt" } task abstract_super(type: UnitKonanTest) { source = "datagen/rtti/abstract_super.kt" } task vtable1(type: UnitKonanTest) { source = "datagen/rtti/vtable1.kt" } task strdedup1(type: RunKonanTest) { goldValue = "true\ntrue\n" source = "datagen/literals/strdedup1.kt" } task intrinsic(type: UnitKonanTest) { source = "codegen/function/intrinsic.kt" } task link(type: LinkKonanTest) { source = "link/src/bar.kt" lib = "link/lib" }