[gradle-plugin] Add a konan.useEnvironmentVariables property
This commit is contained in:
+44
-4
@@ -1,13 +1,53 @@
|
|||||||
package org.jetbrains.kotlin.gradle.plugin
|
package org.jetbrains.kotlin.gradle.plugin
|
||||||
|
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KonanPlugin.ProjectProperty
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
object EnvironmentVariables {
|
/**
|
||||||
|
* The plugin allows an IDE to specify some building parameters. These parameters
|
||||||
|
* are passed to the plugin via environment variables. Two variables are supported:
|
||||||
|
* - CONFIGURATION_BUILD_DIR - an absolute path to a destination directory for all compilation tasks.
|
||||||
|
* The IDE should take care about specifying different directories
|
||||||
|
* for different targets. This setting has less priority than
|
||||||
|
* an explicitly specified destination directory in the build script.
|
||||||
|
* - DEBUGGING_SYMBOLS - If YES, the debug support will be enabled for all artifacts. This option has less
|
||||||
|
* priority than explicitly specified enableDebug option in the build script and
|
||||||
|
* enableDebug project property.
|
||||||
|
*
|
||||||
|
* Support for environment variables should be explicitly enabled by setting a project property:
|
||||||
|
* konan.useEnvironmentVariables = true.
|
||||||
|
*/
|
||||||
|
|
||||||
|
internal interface EnvironmentVariables {
|
||||||
val configurationBuildDir: File?
|
val configurationBuildDir: File?
|
||||||
|
val debuggingSymbols: Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class EnvironmentVariablesUnused: EnvironmentVariables {
|
||||||
|
override val configurationBuildDir: File?
|
||||||
|
get() = null
|
||||||
|
|
||||||
|
override val debuggingSymbols: Boolean
|
||||||
|
get() = false
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class EnvironmentVariablesImpl: EnvironmentVariables {
|
||||||
|
override val configurationBuildDir: File?
|
||||||
get() = System.getenv("CONFIGURATION_BUILD_DIR")?.let {
|
get() = System.getenv("CONFIGURATION_BUILD_DIR")?.let {
|
||||||
File(it).apply {check(isAbsolute) { "A path passed using CONFIGURATION_BUILD_DIR should be absolute" } }
|
File(it).apply { check(isAbsolute) { "A path passed using CONFIGURATION_BUILD_DIR should be absolute" } }
|
||||||
}
|
}
|
||||||
|
|
||||||
val debuggingSymbols: Boolean
|
override val debuggingSymbols: Boolean
|
||||||
get() = System.getenv("DEBUGGING_SYMBOLS")?.toUpperCase() == "YES"
|
get() = System.getenv("DEBUGGING_SYMBOLS")?.toUpperCase() == "YES"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal val Project.useEnvironmentVariables: Boolean
|
||||||
|
get() = findProperty(ProjectProperty.KONAN_USE_ENVIRONMENT_VARIABLES)?.toString()?.toBoolean() ?: false
|
||||||
|
|
||||||
|
internal val Project.environmentVariables: EnvironmentVariables
|
||||||
|
get() = if (useEnvironmentVariables) {
|
||||||
|
EnvironmentVariablesImpl()
|
||||||
|
} else {
|
||||||
|
EnvironmentVariablesUnused()
|
||||||
|
}
|
||||||
|
|||||||
+4
-4
@@ -100,12 +100,12 @@ abstract class KonanBuildingConfig<T: KonanBuildingTask>(private val name_: Stri
|
|||||||
// In this case all produced files has the same name but are placed in different directories
|
// In this case all produced files has the same name but are placed in different directories
|
||||||
// depending on their targets (e.g. linux/foo.kexe and macbook/foo.kexe).
|
// depending on their targets (e.g. linux/foo.kexe and macbook/foo.kexe).
|
||||||
// 2. Custom path provided by IDE. In this case CONFIGURATION_BUILD_DIR environment variable should
|
// 2. Custom path provided by IDE. In this case CONFIGURATION_BUILD_DIR environment variable should
|
||||||
// contain a path to a destination directory. All produced files are placed in this directory and have
|
// contain a path to a destination directory. All produced files are placed in this directory so IDE
|
||||||
// different names depending on their target (e.g. foo/bar/baz_linux.kexe and foo/bar/baz_macbook.kexe).
|
// should take care about setting different CONFIGURATION_BUILD_DIR for different targets.
|
||||||
protected fun determineOutputPlacement(target: KonanTarget): OutputPlacement {
|
protected fun determineOutputPlacement(target: KonanTarget): OutputPlacement {
|
||||||
val configurationBuildDir = EnvironmentVariables.configurationBuildDir
|
val configurationBuildDir = project.environmentVariables.configurationBuildDir
|
||||||
return if (configurationBuildDir != null) {
|
return if (configurationBuildDir != null) {
|
||||||
OutputPlacement(configurationBuildDir, "${name}_${target.visibleName}")
|
OutputPlacement(configurationBuildDir, name)
|
||||||
} else {
|
} else {
|
||||||
OutputPlacement(defaultBaseDir.targetSubdir(target), name)
|
OutputPlacement(defaultBaseDir.targetSubdir(target), name)
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-5
@@ -245,11 +245,12 @@ class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderR
|
|||||||
: Plugin<ProjectInternal> {
|
: Plugin<ProjectInternal> {
|
||||||
|
|
||||||
enum class ProjectProperty(val propertyName: String) {
|
enum class ProjectProperty(val propertyName: String) {
|
||||||
KONAN_HOME ("konan.home"),
|
KONAN_HOME ("konan.home"),
|
||||||
KONAN_VERSION ("konan.version"),
|
KONAN_VERSION ("konan.version"),
|
||||||
KONAN_BUILD_TARGETS ("konan.build.targets"),
|
KONAN_BUILD_TARGETS ("konan.build.targets"),
|
||||||
KONAN_JVM_ARGS ("konan.jvmArgs"),
|
KONAN_JVM_ARGS ("konan.jvmArgs"),
|
||||||
DOWNLOAD_COMPILER ("download.compiler")
|
KONAN_USE_ENVIRONMENT_VARIABLES("konan.useEnvironmentVariables"),
|
||||||
|
DOWNLOAD_COMPILER ("download.compiler")
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
+1
-1
@@ -70,7 +70,7 @@ abstract class KonanCompileTask: KonanBuildingTask(), KonanCompileSpec {
|
|||||||
@Input val linkerOpts = mutableListOf<String>()
|
@Input val linkerOpts = mutableListOf<String>()
|
||||||
|
|
||||||
@Input var enableDebug = project.findProperty("enableDebug")?.toString()?.toBoolean()
|
@Input var enableDebug = project.findProperty("enableDebug")?.toString()?.toBoolean()
|
||||||
?: EnvironmentVariables.debuggingSymbols
|
?: project.environmentVariables.debuggingSymbols
|
||||||
|
|
||||||
@Input var noStdLib = false
|
@Input var noStdLib = false
|
||||||
@Input var noMain = false
|
@Input var noMain = false
|
||||||
|
|||||||
+124
-4
@@ -1,3 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.plugin.test
|
package org.jetbrains.kotlin.gradle.plugin.test
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.target.Family
|
import org.jetbrains.kotlin.konan.target.Family
|
||||||
@@ -7,6 +23,8 @@ import spock.lang.Unroll
|
|||||||
|
|
||||||
import static org.jetbrains.kotlin.gradle.plugin.test.KonanProject.escapeBackSlashes
|
import static org.jetbrains.kotlin.gradle.plugin.test.KonanProject.escapeBackSlashes
|
||||||
|
|
||||||
|
// TODO: Rewrite tests using Kotlin.
|
||||||
|
|
||||||
class EnvVariableSpecification extends BaseKonanSpecification {
|
class EnvVariableSpecification extends BaseKonanSpecification {
|
||||||
|
|
||||||
class WrapperResult {
|
class WrapperResult {
|
||||||
@@ -49,10 +67,14 @@ class EnvVariableSpecification extends BaseKonanSpecification {
|
|||||||
return project
|
return project
|
||||||
}
|
}
|
||||||
|
|
||||||
private WrapperResult runWrapper(KonanProject project, List<String> tasks, Map<String, String> environment = [:]) {
|
private WrapperResult runWrapper(KonanProject project,
|
||||||
|
List<String> tasks,
|
||||||
|
Map<String, String> environment = [:],
|
||||||
|
Map<String, String> properties = ["konan.useEnvironmentVariables": 'true']) {
|
||||||
def wrapper = (HostManager.host.family == Family.WINDOWS) ? "gradlew.bat" : "gradlew"
|
def wrapper = (HostManager.host.family == Family.WINDOWS) ? "gradlew.bat" : "gradlew"
|
||||||
def command = ["$project.projectDir.absolutePath/$wrapper".toString()]
|
def command = ["$project.projectDir.absolutePath/$wrapper".toString()]
|
||||||
command.addAll(tasks)
|
command.addAll(tasks)
|
||||||
|
command.addAll(properties.collect { "-P${it.key}=${it.value}".toString() })
|
||||||
def projectBuilder = new ProcessBuilder()
|
def projectBuilder = new ProcessBuilder()
|
||||||
.directory(project.projectDir)
|
.directory(project.projectDir)
|
||||||
.command(command)
|
.command(command)
|
||||||
@@ -62,8 +84,11 @@ class EnvVariableSpecification extends BaseKonanSpecification {
|
|||||||
return new WrapperResult(process)
|
return new WrapperResult(process)
|
||||||
}
|
}
|
||||||
|
|
||||||
private WrapperResult runWrapper(KonanProject project, String task, Map<String, String> environment = [:]) {
|
private WrapperResult runWrapper(KonanProject project,
|
||||||
return runWrapper(project, [task], environment)
|
String task,
|
||||||
|
Map<String, String> environment = [:],
|
||||||
|
Map<String, String> properties = ["konan.useEnvironmentVariables": 'true']) {
|
||||||
|
return runWrapper(project, [task], environment, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
private String artifactFileName(String baseName, ArtifactType type, KonanTarget target = HostManager.host) {
|
private String artifactFileName(String baseName, ArtifactType type, KonanTarget target = HostManager.host) {
|
||||||
@@ -85,7 +110,7 @@ class EnvVariableSpecification extends BaseKonanSpecification {
|
|||||||
suffix = target.family.dynamicSuffix
|
suffix = target.family.dynamicSuffix
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return "$prefix${baseName}_${target.visibleName}.$suffix"
|
return "$prefix${baseName}.$suffix"
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unroll("Plugin should support #action debug via an env variable")
|
@Unroll("Plugin should support #action debug via an env variable")
|
||||||
@@ -214,4 +239,99 @@ class EnvVariableSpecification extends BaseKonanSpecification {
|
|||||||
files2.contains(artifactFileName("main", ArtifactType.LIBRARY))
|
files2.contains(artifactFileName("main", ArtifactType.LIBRARY))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def 'Plugin should ignore environmentVariables if konan.useEnvironmentVariables is false or is not set'() {
|
||||||
|
when:
|
||||||
|
def project = createProjectWithWrapper()
|
||||||
|
def newDestinationDir = project.createSubDir("newDestination")
|
||||||
|
def newDestinationPath = newDestinationDir.absolutePath
|
||||||
|
project.buildFile.append("""\
|
||||||
|
apply plugin: 'konan'
|
||||||
|
konanArtifacts {
|
||||||
|
program('program')
|
||||||
|
library('library')
|
||||||
|
dynamic('dynamic')
|
||||||
|
framework('framework')
|
||||||
|
}
|
||||||
|
|
||||||
|
task assertNoOverrides {
|
||||||
|
doLast {
|
||||||
|
konanArtifacts.forEach { artifact ->
|
||||||
|
artifact.forEach {
|
||||||
|
if (it.destinationDir.absolutePath == '${escapeBackSlashes(newDestinationPath)}'){
|
||||||
|
throw new AssertionError("CONFIGURATION_BUILD_DIR overrides a default output path " +
|
||||||
|
"when it shouldn't.\\n" +
|
||||||
|
"Task: \${it.name}, Path: \${it.destinationDir}")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (it.enableDebug) {
|
||||||
|
throw new AssertionError("DEBUGGING_SYMBOLS overrides a default value " +
|
||||||
|
"when it shouldn't\\n" +
|
||||||
|
"Task: \${it.name}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""".stripIndent())
|
||||||
|
def resultNoProp = runWrapper(project,
|
||||||
|
"assertNoOverrides",
|
||||||
|
["DEBUGGING_SYMBOLS": "true", "CONFIGURATION_BUILD_DIR": newDestinationPath], [:])
|
||||||
|
.printStderr()
|
||||||
|
.getExitValue()
|
||||||
|
def resultFalseValue = runWrapper(project,
|
||||||
|
"assertNoOverrides",
|
||||||
|
["DEBUGGING_SYMBOLS": "true", "CONFIGURATION_BUILD_DIR": newDestinationPath],
|
||||||
|
["konan.useEnvironmentVariables": "false"])
|
||||||
|
.printStderr()
|
||||||
|
.getExitValue()
|
||||||
|
|
||||||
|
then:
|
||||||
|
resultNoProp == 0
|
||||||
|
resultFalseValue == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
def 'Up-to-date checks should work with different directories for different targets'() {
|
||||||
|
when:
|
||||||
|
def project = createProjectWithWrapper()
|
||||||
|
def fooDir = project.createSubDir("foo")
|
||||||
|
def barDir = project.createSubDir("bar")
|
||||||
|
project.buildFile.append("""\
|
||||||
|
apply plugin: 'konan'
|
||||||
|
|
||||||
|
konanArtifacts {
|
||||||
|
library('foo')
|
||||||
|
library('bar')
|
||||||
|
}
|
||||||
|
|
||||||
|
task assertUpToDate {
|
||||||
|
dependsOn 'compileKonanFoo'
|
||||||
|
doLast {
|
||||||
|
if (!konanArtifacts.foo.getByTarget('host').state.upToDate) {
|
||||||
|
throw new AssertionError("Compilation task is not up-to-date")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""".stripIndent())
|
||||||
|
project.generateSrcFile("main.kt")
|
||||||
|
|
||||||
|
def buildResult1 = runWrapper(project, "compileKonanFoo",
|
||||||
|
["CONFIGURATION_BUILD_DIR": fooDir.absolutePath])
|
||||||
|
.printStderr()
|
||||||
|
.getExitValue()
|
||||||
|
def buildResult2 = runWrapper(project, "compileKonanBar",
|
||||||
|
["CONFIGURATION_BUILD_DIR": barDir.absolutePath])
|
||||||
|
.printStderr()
|
||||||
|
.getExitValue()
|
||||||
|
def buildResult3 = runWrapper(project,
|
||||||
|
"assertUpToDate",
|
||||||
|
["CONFIGURATION_BUILD_DIR": fooDir.absolutePath])
|
||||||
|
.printStderr()
|
||||||
|
.getExitValue()
|
||||||
|
|
||||||
|
then:
|
||||||
|
buildResult1 == 0
|
||||||
|
buildResult2 == 0
|
||||||
|
buildResult3 == 0
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user