gradle-plugin: Add tests for incremental build
This commit is contained in:
@@ -66,7 +66,6 @@ test {
|
|||||||
dependsOn ':dist'
|
dependsOn ':dist'
|
||||||
//testLogging.showStandardStreams = true
|
//testLogging.showStandardStreams = true
|
||||||
systemProperty("konan.home", rootProject.file('dist'))
|
systemProperty("konan.home", rootProject.file('dist'))
|
||||||
systemProperty("konan.root", rootProject.projectDir)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
|
|||||||
@@ -1,134 +0,0 @@
|
|||||||
import org.gradle.testkit.runner.GradleRunner
|
|
||||||
import org.gradle.testkit.runner.TaskOutcome
|
|
||||||
import org.junit.Rule
|
|
||||||
import org.junit.rules.TemporaryFolder
|
|
||||||
import spock.lang.Specification
|
|
||||||
|
|
||||||
class KonanProjectGenerator {
|
|
||||||
static void generateBuildFile(File buildFile) {
|
|
||||||
buildFile.write("""
|
|
||||||
plugins { id 'konan' }
|
|
||||||
|
|
||||||
konanInterop {
|
|
||||||
stdio { }
|
|
||||||
}
|
|
||||||
|
|
||||||
konanArtifacts {
|
|
||||||
main { useInterop 'stdio' }
|
|
||||||
}
|
|
||||||
""".stripIndent()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
static void generateSrcFile(File srcFile) {
|
|
||||||
srcFile.write("""
|
|
||||||
import kotlinx.cinterop.*
|
|
||||||
import stdio.*
|
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
|
||||||
printf("%d\\n", 42)
|
|
||||||
}
|
|
||||||
""".stripIndent()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
static void generateDefFile(File defFile) {
|
|
||||||
defFile.write("""
|
|
||||||
headers = stdio.h stdlib.h string.h
|
|
||||||
excludeDependentModules.osx = true
|
|
||||||
""".stripIndent()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
static void generatePropertiesFile(File propertiesFile, String konanHome) {
|
|
||||||
propertiesFile.write("konan.home=$konanHome")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class IncrementalSpecification extends Specification {
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
TemporaryFolder projectDir = new TemporaryFolder()
|
|
||||||
|
|
||||||
File buildFile
|
|
||||||
File srcFile
|
|
||||||
File defFile
|
|
||||||
File propertiesFile
|
|
||||||
|
|
||||||
String konanHome = System.getProperty("konan.home") ?: { throw new IllegalStateException("konan.home isn't specified") }()
|
|
||||||
String konanRoot = System.getProperty("konan.root") ?: { throw new IllegalStateException("konan.root isn't specified") }()
|
|
||||||
|
|
||||||
def interopTasks = [":genStdioInteropStubs", ":compileStdioInteropStubs"].toSet()
|
|
||||||
def compilationTasks = [":compileKonanMain", ":compileKonan", ":build"].toSet()
|
|
||||||
|
|
||||||
def buildingTasks = interopTasks + compilationTasks
|
|
||||||
def downloadTask = ":downloadKonanCompiler"
|
|
||||||
def konanTasks = buildingTasks + downloadTask
|
|
||||||
|
|
||||||
def setup() {
|
|
||||||
buildFile = projectDir.newFile("build.gradle")
|
|
||||||
projectDir.newFolder("src", "main", "kotlin")
|
|
||||||
projectDir.newFolder("src", "main", "c_interop")
|
|
||||||
srcFile = projectDir.newFile("src/main/kotlin/main.kt")
|
|
||||||
defFile = projectDir.newFile("src/main/c_interop/stdio.def")
|
|
||||||
propertiesFile = projectDir.newFile("gradle.properties")
|
|
||||||
|
|
||||||
KonanProjectGenerator.generateBuildFile(buildFile)
|
|
||||||
KonanProjectGenerator.generateDefFile(defFile)
|
|
||||||
KonanProjectGenerator.generateSrcFile(srcFile)
|
|
||||||
KonanProjectGenerator.generatePropertiesFile(propertiesFile, konanHome)
|
|
||||||
}
|
|
||||||
|
|
||||||
def 'Compilation is up-to-date if there is no changes'() {
|
|
||||||
when:
|
|
||||||
def runner = GradleRunner.create()
|
|
||||||
.withProjectDir(projectDir.root)
|
|
||||||
.withArguments('build')
|
|
||||||
.withPluginClasspath()
|
|
||||||
def result = runner.build()
|
|
||||||
def upToDateResult = runner.build()
|
|
||||||
|
|
||||||
then:
|
|
||||||
result.tasks.collect { it.path }.containsAll(buildingTasks)
|
|
||||||
result.taskPaths(TaskOutcome.SUCCESS).containsAll(buildingTasks)
|
|
||||||
upToDateResult.taskPaths(TaskOutcome.UP_TO_DATE).containsAll(buildingTasks)
|
|
||||||
result.task(downloadTask).outcome == TaskOutcome.SUCCESS
|
|
||||||
upToDateResult.task(downloadTask).outcome == TaskOutcome.SUCCESS
|
|
||||||
}
|
|
||||||
|
|
||||||
def 'Source change should cause recompilation'() {
|
|
||||||
when:
|
|
||||||
def runner = GradleRunner.create()
|
|
||||||
.withProjectDir(projectDir.root)
|
|
||||||
.withArguments('build')
|
|
||||||
.withPluginClasspath()
|
|
||||||
def result = runner.build()
|
|
||||||
srcFile.append("\n // Some change in the source file")
|
|
||||||
def secondResult = runner.build()
|
|
||||||
|
|
||||||
then:
|
|
||||||
result.taskPaths(TaskOutcome.SUCCESS).containsAll(buildingTasks)
|
|
||||||
secondResult.taskPaths(TaskOutcome.SUCCESS).containsAll(compilationTasks)
|
|
||||||
secondResult.taskPaths(TaskOutcome.UP_TO_DATE).containsAll(interopTasks)
|
|
||||||
}
|
|
||||||
|
|
||||||
def 'Def-file change should cause recompilation'() {
|
|
||||||
when:
|
|
||||||
def runner = GradleRunner.create()
|
|
||||||
.withProjectDir(projectDir.root)
|
|
||||||
.withArguments('build')
|
|
||||||
.withPluginClasspath()
|
|
||||||
def result = runner.build()
|
|
||||||
defFile.append("\n # Some change in the def-file")
|
|
||||||
def secondResult = runner.build()
|
|
||||||
|
|
||||||
then:
|
|
||||||
result.taskPaths(TaskOutcome.SUCCESS).containsAll(buildingTasks)
|
|
||||||
secondResult.taskPaths(TaskOutcome.SUCCESS).containsAll(buildingTasks)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Add checks for artifact/interop parameters.
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
+322
@@ -0,0 +1,322 @@
|
|||||||
|
package org.jetbrains.kotlin.gradle.plugin.test
|
||||||
|
|
||||||
|
import org.gradle.testkit.runner.BuildResult
|
||||||
|
import org.gradle.testkit.runner.TaskOutcome
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.rules.TemporaryFolder
|
||||||
|
import spock.lang.IgnoreIf
|
||||||
|
import spock.lang.Specification
|
||||||
|
import spock.lang.Unroll
|
||||||
|
|
||||||
|
class IncrementalSpecification extends Specification {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
TemporaryFolder tmpFolder = new TemporaryFolder()
|
||||||
|
|
||||||
|
Tuple buildTwice(KonanInteropProject project, Closure change) {
|
||||||
|
def runner = project.createRunner().withArguments('build')
|
||||||
|
def firstResult = runner.build()
|
||||||
|
change(project)
|
||||||
|
def secondResult = runner.build()
|
||||||
|
return new Tuple(project, firstResult, secondResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
Tuple buildTwice(Closure change) {
|
||||||
|
return buildTwice(KonanInteropProject.create(tmpFolder), change)
|
||||||
|
}
|
||||||
|
|
||||||
|
Tuple buildTwiceEmpty(Closure change) {
|
||||||
|
def project = KonanInteropProject.createEmpty(tmpFolder)
|
||||||
|
project.generateSrcFile("main.kt")
|
||||||
|
return buildTwice(project, change)
|
||||||
|
}
|
||||||
|
|
||||||
|
Boolean noRecompilationHappened(KonanInteropProject project, BuildResult firstResult, BuildResult secondResult) {
|
||||||
|
return project.with {
|
||||||
|
firstResult.tasks.collect { it.path }.containsAll(buildingTasks) &&
|
||||||
|
firstResult.taskPaths(TaskOutcome.SUCCESS).containsAll(buildingTasks) &&
|
||||||
|
secondResult.taskPaths(TaskOutcome.UP_TO_DATE).containsAll(buildingTasks) &&
|
||||||
|
firstResult.task(downloadTask).outcome == TaskOutcome.SUCCESS &&
|
||||||
|
secondResult.task(downloadTask).outcome == TaskOutcome.SUCCESS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Boolean onlyRecompilationHappened(KonanInteropProject project, BuildResult firstResult, BuildResult secondResult) {
|
||||||
|
return project.with {
|
||||||
|
firstResult.taskPaths(TaskOutcome.SUCCESS).containsAll(buildingTasks) &&
|
||||||
|
secondResult.taskPaths(TaskOutcome.SUCCESS).containsAll(compilationTasks) &&
|
||||||
|
secondResult.taskPaths(TaskOutcome.UP_TO_DATE).containsAll(interopTasks)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Boolean recompilationAndInteropProcessingHappened(KonanInteropProject project, BuildResult firstResult, BuildResult secondResult) {
|
||||||
|
return project.with {
|
||||||
|
firstResult.taskPaths(TaskOutcome.SUCCESS).containsAll(buildingTasks) &&
|
||||||
|
secondResult.taskPaths(TaskOutcome.SUCCESS).containsAll(buildingTasks)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//region tests =====================================================================================================
|
||||||
|
def 'Compilation is up-to-date if there is no changes'() {
|
||||||
|
when:
|
||||||
|
def results = buildTwice {}
|
||||||
|
|
||||||
|
then:
|
||||||
|
noRecompilationHappened(*results)
|
||||||
|
}
|
||||||
|
|
||||||
|
def 'Source change should cause only recompilation'() {
|
||||||
|
when:
|
||||||
|
def results = buildTwice { KonanInteropProject project ->
|
||||||
|
project.srcFiles[0].append("\n // Some change in the source file")
|
||||||
|
}
|
||||||
|
|
||||||
|
then:
|
||||||
|
onlyRecompilationHappened(*results)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
def 'Def-file change should cause recompilation and interop reprocessing'() {
|
||||||
|
when:
|
||||||
|
def results = buildTwice { KonanInteropProject project ->
|
||||||
|
project.defFiles[0].append("\n # Some change in the def-file")
|
||||||
|
}
|
||||||
|
|
||||||
|
then:
|
||||||
|
recompilationAndInteropProcessingHappened(*results)
|
||||||
|
}
|
||||||
|
|
||||||
|
def 'Compilation is up-to-date if there is no changes in empty project'() {
|
||||||
|
when:
|
||||||
|
def results = buildTwiceEmpty {}
|
||||||
|
|
||||||
|
then:
|
||||||
|
noRecompilationHappened(*results)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unroll("#parameter change for a compilation task should cause only recompilation")
|
||||||
|
def 'Parameter changes should cause only recompilaton'() {
|
||||||
|
when:
|
||||||
|
def results = buildTwiceEmpty { KonanInteropProject project ->
|
||||||
|
project.buildFile.append("konanArtifacts['main'].$appending")
|
||||||
|
}
|
||||||
|
|
||||||
|
then:
|
||||||
|
onlyRecompilationHappened(*results)
|
||||||
|
|
||||||
|
|
||||||
|
where:
|
||||||
|
parameter | appending
|
||||||
|
"outputDir" | "outputDir 'build/new/outputDir'"
|
||||||
|
"produce" | "produce 'library'"
|
||||||
|
"enableOptimization" | "enableOptimization()"
|
||||||
|
"linkerOpts" | "linkerOpts '--help'"
|
||||||
|
"languageVersion" | "languageVersion '1.2'"
|
||||||
|
"apiVersion" | "apiVersion '1.0'"
|
||||||
|
"enableAssertions" | "enableAssertions()"
|
||||||
|
"enableDebug" | "enableDebug true"
|
||||||
|
"outputName" | "outputName 'foo'"
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
def 'inputFiles change for a compilation task should cause only recompilation'() {
|
||||||
|
when:
|
||||||
|
def project = KonanInteropProject.createEmpty(tmpFolder) { KonanInteropProject it ->
|
||||||
|
it.generateSrcFile('main.kt')
|
||||||
|
it.newFolder('src', 'foo', 'kotlin')
|
||||||
|
it.generateSrcFile('src/foo/kotlin/', 'bar.kt', """
|
||||||
|
fun bar() { println("Hello!") }
|
||||||
|
""".stripIndent())
|
||||||
|
}
|
||||||
|
def results = buildTwice(project) { KonanInteropProject it ->
|
||||||
|
it.buildFile.append('konanArtifacts[\'main\'].inputFiles project.fileTree(\'src/foo/kotlin\')')
|
||||||
|
}
|
||||||
|
|
||||||
|
then:
|
||||||
|
onlyRecompilationHappened(*results)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unroll("#parameter change for a compilation task should cause only recompilation")
|
||||||
|
def 'Library changes should cause only recompilaton'() {
|
||||||
|
when:
|
||||||
|
def project = KonanInteropProject.createEmpty(tmpFolder) { KonanInteropProject it ->
|
||||||
|
it.generateSrcFile('main.kt')
|
||||||
|
it.newFolder('src', 'lib', 'kotlin')
|
||||||
|
it.generateSrcFile("src/lib/kotlin", "lib.kt", "fun bar() { println(\"Hello!\") }")
|
||||||
|
it.buildFile.append("""
|
||||||
|
konanArtifacts {
|
||||||
|
lib {
|
||||||
|
inputFiles fileTree('src/lib/kotlin')
|
||||||
|
produce '$produce'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""".stripIndent())
|
||||||
|
}
|
||||||
|
def results = buildTwice(project) { KonanInteropProject it ->
|
||||||
|
it.buildFile.append("konanArtifacts['main'].$parameter konanArtifacts[\'lib\'].compilationTask.artifactPath")
|
||||||
|
}
|
||||||
|
|
||||||
|
then:
|
||||||
|
onlyRecompilationHappened(*results)
|
||||||
|
|
||||||
|
where:
|
||||||
|
parameter | produce
|
||||||
|
"library" | "library"
|
||||||
|
"nativeLibrary" | "bitcode"
|
||||||
|
}
|
||||||
|
|
||||||
|
def 'useInterop change for a compilation task should cause only recompilation'() {
|
||||||
|
when:
|
||||||
|
def project = KonanInteropProject.createEmpty(tmpFolder) { KonanInteropProject it ->
|
||||||
|
it.generateSrcFile('main.kt')
|
||||||
|
it.buildFile.append("konanInterop { foo {} }\n")
|
||||||
|
}
|
||||||
|
def results = buildTwice(project) { KonanInteropProject it ->
|
||||||
|
it.buildFile.append('konanArtifacts[\'main\'].useInterop "foo"\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
then:
|
||||||
|
onlyRecompilationHappened(*results)
|
||||||
|
}
|
||||||
|
|
||||||
|
def 'manifest parameter change for a compilation task should cause only recompilation'() {
|
||||||
|
when:
|
||||||
|
def project = KonanInteropProject.createEmpty(tmpFolder) { KonanInteropProject it ->
|
||||||
|
it.generateSrcFile('main.kt')
|
||||||
|
}
|
||||||
|
def results = buildTwice(project) { KonanInteropProject it ->
|
||||||
|
def manifest = it.generateSrcFile('manifest', "#some manifest file")
|
||||||
|
it.buildFile.append("konanArtifacts['main'].manifest '${manifest.canonicalPath}'")
|
||||||
|
}
|
||||||
|
|
||||||
|
then:
|
||||||
|
onlyRecompilationHappened(*results)
|
||||||
|
}
|
||||||
|
|
||||||
|
def 'manifest file change should cause only recompilation'() {
|
||||||
|
when:
|
||||||
|
def manifest
|
||||||
|
def project = KonanInteropProject.createEmpty(tmpFolder) { KonanInteropProject it ->
|
||||||
|
it.generateSrcFile('main.kt')
|
||||||
|
manifest = it.generateSrcFile('manifest', "#some manifest file\n")
|
||||||
|
it.buildFile.append("konanArtifacts['main'].manifest '${manifest.canonicalPath}'")
|
||||||
|
}
|
||||||
|
def results = buildTwice(project) { KonanInteropProject it ->
|
||||||
|
manifest.append("#something else\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
then:
|
||||||
|
onlyRecompilationHappened(*results)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unroll("#parameter change for an interop task should cause recompilation and interop reprocessing")
|
||||||
|
def 'Parameter change for an interop task should cause recompilation and interop reprocessing'() {
|
||||||
|
when:
|
||||||
|
def results = buildTwiceEmpty { KonanInteropProject project ->
|
||||||
|
project.buildFile.append("konanInterop['stdio'].$appending")
|
||||||
|
}
|
||||||
|
|
||||||
|
then:
|
||||||
|
recompilationAndInteropProcessingHappened(*results)
|
||||||
|
|
||||||
|
where:
|
||||||
|
parameter | appending
|
||||||
|
"pkg" | "pkg 'org.sample'"
|
||||||
|
"compilerOpts" | "compilerOpts '-g'"
|
||||||
|
"linkerOpts" | "linkerOpts '--help'"
|
||||||
|
"includeDirs" | "includeDirs 'src'"
|
||||||
|
}
|
||||||
|
|
||||||
|
def 'defFile change for an interop task should cause recompilation and interop reprocessing'() {
|
||||||
|
when:
|
||||||
|
def project = KonanInteropProject.createEmpty(tmpFolder)
|
||||||
|
project.generateSrcFile('main.kt')
|
||||||
|
def defFile = project.generateDefFile("foo.def", "#some content")
|
||||||
|
def results = buildTwice(project) { KonanInteropProject it ->
|
||||||
|
it.buildFile.append("konanInterop['stdio'].defFile file('${defFile.canonicalPath}')\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
then:
|
||||||
|
recompilationAndInteropProcessingHappened(*results)
|
||||||
|
}
|
||||||
|
|
||||||
|
def 'header change for an interop task should cause recompilation and interop reprocessing'() {
|
||||||
|
when:
|
||||||
|
def project = KonanInteropProject.createEmpty(tmpFolder)
|
||||||
|
project.generateSrcFile('main.kt')
|
||||||
|
def header = project.generateSrcFile('header.h', "#define CONST 1")
|
||||||
|
def results = buildTwice(project) { KonanInteropProject it ->
|
||||||
|
it.buildFile.append("konanInterop['stdio'].headers '${header.canonicalPath}'\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
then:
|
||||||
|
recompilationAndInteropProcessingHappened(*results)
|
||||||
|
}
|
||||||
|
|
||||||
|
def 'link change for an interop task should cause recompilation and interop reprocessing'() {
|
||||||
|
when:
|
||||||
|
def project = KonanInteropProject.createEmpty(tmpFolder) { KonanInteropProject it ->
|
||||||
|
it.generateSrcFile('main.kt')
|
||||||
|
it.newFolder('src', 'lib', 'kotlin')
|
||||||
|
it.buildFile.append("""
|
||||||
|
konanArtifacts {
|
||||||
|
lib {
|
||||||
|
inputFiles fileTree('src/lib/kotlin')
|
||||||
|
produce 'bitcode'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""".stripIndent())
|
||||||
|
}
|
||||||
|
def results = buildTwice(project) { KonanInteropProject it ->
|
||||||
|
it.buildFile.append("""
|
||||||
|
konanInterop['stdio'].generateStubsTask.dependsOn(konanArtifacts['lib'].compilationTask)
|
||||||
|
konanInterop['stdio'].link files(konanArtifacts['lib'].compilationTask.artifactPath)
|
||||||
|
""".stripIndent())
|
||||||
|
}
|
||||||
|
|
||||||
|
then:
|
||||||
|
recompilationAndInteropProcessingHappened(*results)
|
||||||
|
}
|
||||||
|
|
||||||
|
def 'konan version change should cause recompilation and interop reprocessing'() {
|
||||||
|
when:
|
||||||
|
def project = KonanInteropProject.createEmpty(tmpFolder) { KonanInteropProject it ->
|
||||||
|
it.generateSrcFile('main.kt')
|
||||||
|
it.propertiesFile.append("konan.version=0.3\n")
|
||||||
|
}
|
||||||
|
def results = buildTwice(project) { KonanInteropProject it ->
|
||||||
|
def newText = it.propertiesFile.text.replace('konan.version=0.3', 'konan.version=0.4')
|
||||||
|
it.propertiesFile.write(newText)
|
||||||
|
}
|
||||||
|
|
||||||
|
then:
|
||||||
|
recompilationAndInteropProcessingHappened(*results)
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreIf({ System.getProperty('os.name').contains('windows') })
|
||||||
|
def 'target change should cause recompilation and interop reprocessing'() {
|
||||||
|
when:
|
||||||
|
def newTarget
|
||||||
|
if (System.getProperty('os.name').toLowerCase().contains('linux')) {
|
||||||
|
newTarget = "raspberrypi"
|
||||||
|
} else if (System.getProperty('os.name').toLowerCase().contains('mac')) {
|
||||||
|
newTarget = "iphone"
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Unknown host platform")
|
||||||
|
}
|
||||||
|
|
||||||
|
def results = buildTwiceEmpty { KonanInteropProject project ->
|
||||||
|
project.buildFile.append("konanArtifacts['main'].target '$newTarget'\n")
|
||||||
|
project.buildFile.append("konanInterop['stdio'].target '$newTarget'\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
then:
|
||||||
|
recompilationAndInteropProcessingHappened(*results)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
+188
@@ -0,0 +1,188 @@
|
|||||||
|
package org.jetbrains.kotlin.gradle.plugin.test
|
||||||
|
|
||||||
|
import org.gradle.testkit.runner.GradleRunner
|
||||||
|
import org.junit.rules.TemporaryFolder
|
||||||
|
|
||||||
|
class KonanProject {
|
||||||
|
|
||||||
|
TemporaryFolder projectDir
|
||||||
|
|
||||||
|
File getProjectDirRoot() { return projectDir.root }
|
||||||
|
|
||||||
|
String konanHome = System.getProperty("konan.home") ?: { throw new IllegalStateException("konan.home isn't specified") }()
|
||||||
|
|
||||||
|
File buildFile
|
||||||
|
File propertiesFile
|
||||||
|
|
||||||
|
Set<File> srcFiles = []
|
||||||
|
|
||||||
|
List<String> compilationTasks = []
|
||||||
|
String downloadTask = ":downloadKonanCompiler"
|
||||||
|
|
||||||
|
List<String> getBuildingTasks() { return compilationTasks }
|
||||||
|
List<String> getKonanTasks() { return getBuildingTasks() + downloadTask }
|
||||||
|
|
||||||
|
GradleRunner createRunner() { return GradleRunner.create().withProjectDir(projectDirRoot).withPluginClasspath() }
|
||||||
|
|
||||||
|
protected KonanProject(TemporaryFolder projectDir) {
|
||||||
|
this.projectDir = projectDir
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateFolders() {
|
||||||
|
projectDir.newFolder("src", "main", "kotlin")
|
||||||
|
}
|
||||||
|
|
||||||
|
File generateBuildFile(String content) {
|
||||||
|
buildFile = projectDir.newFile("build.gradle")
|
||||||
|
buildFile.write(content)
|
||||||
|
return buildFile
|
||||||
|
}
|
||||||
|
|
||||||
|
File generateBuildFile() {
|
||||||
|
def result = generateBuildFile("""
|
||||||
|
plugins { id 'konan' }
|
||||||
|
|
||||||
|
konanArtifacts {
|
||||||
|
main { }
|
||||||
|
}
|
||||||
|
""".stripIndent()
|
||||||
|
)
|
||||||
|
compilationTasks = [":compileKonanMain", ":compileKonan", ":build"]
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
File generateSrcFile(String directoryPath, String fileName, String content) {
|
||||||
|
def result = projectDir.newFile("$directoryPath/$fileName")
|
||||||
|
result.write(content)
|
||||||
|
srcFiles.add(result)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
File generateSrcFile(String fileName, String content) {
|
||||||
|
return generateSrcFile("src/main/kotlin",fileName, content)
|
||||||
|
}
|
||||||
|
|
||||||
|
File generateSrcFile(String fileName) {
|
||||||
|
return generateSrcFile(fileName, """
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
println(42)
|
||||||
|
}
|
||||||
|
""".stripIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
File generatePropertiesFile(String konanHome) {
|
||||||
|
propertiesFile = projectDir.newFile("gradle.properties")
|
||||||
|
propertiesFile.write("konan.home=$konanHome\n")
|
||||||
|
return propertiesFile
|
||||||
|
}
|
||||||
|
|
||||||
|
File newFolder(String... path) { return projectDir.newFolder(path) }
|
||||||
|
|
||||||
|
static KonanProject create(TemporaryFolder projectDir) {
|
||||||
|
return createEmpty(projectDir) {
|
||||||
|
it.generateSrcFile("main.kt")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static KonanProject create(TemporaryFolder projectDir, Closure config) {
|
||||||
|
def result = create(projectDir)
|
||||||
|
config(result)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
static KonanProject createEmpty(TemporaryFolder projectDir) {
|
||||||
|
def result = new KonanProject(projectDir)
|
||||||
|
result.with {
|
||||||
|
generateFolders()
|
||||||
|
generateBuildFile()
|
||||||
|
generatePropertiesFile(konanHome)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
static KonanProject createEmpty(TemporaryFolder projectDir, Closure config) {
|
||||||
|
def result = createEmpty(projectDir)
|
||||||
|
config(result)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class KonanInteropProject extends KonanProject {
|
||||||
|
|
||||||
|
Set<File> defFiles = []
|
||||||
|
|
||||||
|
List<String> interopTasks = []
|
||||||
|
|
||||||
|
protected KonanInteropProject(TemporaryFolder projectDir) { super(projectDir) }
|
||||||
|
|
||||||
|
List<String> getBuildingTasks() { return interopTasks + compilationTasks }
|
||||||
|
|
||||||
|
void generateFolders() {
|
||||||
|
super.generateFolders()
|
||||||
|
projectDir.newFolder("src", "main", "c_interop")
|
||||||
|
}
|
||||||
|
|
||||||
|
File generateBuildFile() {
|
||||||
|
def result = generateBuildFile("""
|
||||||
|
plugins { id 'konan' }
|
||||||
|
|
||||||
|
konanInterop {
|
||||||
|
stdio { }
|
||||||
|
}
|
||||||
|
|
||||||
|
konanArtifacts {
|
||||||
|
main { useInterop 'stdio' }
|
||||||
|
}
|
||||||
|
""".stripIndent()
|
||||||
|
)
|
||||||
|
interopTasks = [":genStdioInteropStubs", ":compileStdioInteropStubs"]
|
||||||
|
compilationTasks = [":compileKonanMain", ":compileKonan", ":build"]
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
File generateDefFile(String fileName, String content) {
|
||||||
|
def result = projectDir.newFile("src/main/c_interop/$fileName")
|
||||||
|
result.write(content)
|
||||||
|
defFiles.add(result)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
File generateDefFile(String fileName) {
|
||||||
|
return generateDefFile(fileName, """
|
||||||
|
headers = stdio.h stdlib.h string.h
|
||||||
|
excludeDependentModules.osx = true
|
||||||
|
""".stripIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
static KonanInteropProject create(TemporaryFolder projectDir) {
|
||||||
|
return createEmpty(projectDir) {
|
||||||
|
it.generateSrcFile("main.kt")
|
||||||
|
it.generateDefFile("stdio.def")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static KonanInteropProject create(TemporaryFolder projectDir, Closure config) {
|
||||||
|
def result = create(projectDir)
|
||||||
|
config(result)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
static KonanInteropProject createEmpty(TemporaryFolder projectDir) {
|
||||||
|
def result = new KonanInteropProject(projectDir)
|
||||||
|
result.with {
|
||||||
|
generateFolders()
|
||||||
|
generateBuildFile()
|
||||||
|
generatePropertiesFile(konanHome)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
static KonanInteropProject createEmpty(TemporaryFolder projectDir, Closure config) {
|
||||||
|
def result = createEmpty(projectDir)
|
||||||
|
config(result)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user