Remote test execution for cross compiled tests. Run it like:
$ ./gradlew backend.native:tests:run \
-Premote=user@111.22.33.444 -Ptest_target=raspberrypi
The new gradle command line options:
-Pbuild_flags renamed -Pkonanc_flags.
-Ptest_flags provides compiler flags to the test builds.
-Ptest_target properly sets up compiler as well as interop
to cross compile tests.
-Premote specifies remote host and login.
This commit is contained in:
committed by
alexander-gorshenev
parent
826b3fc3f2
commit
334d2f0ee6
+16
-3
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
There are several gradle flags one can use for Konan build.
|
There are several gradle flags one can use for Konan build.
|
||||||
|
|
||||||
* **-Pkonanc_flags** passes flags to the compiler used to build stdlib
|
* **-Pbuild_flags** passes flags to the compiler used to build stdlib
|
||||||
|
|
||||||
./gradlew -Pkonanc_flags="--disable lower_inline --print_ir" stdlib
|
./gradlew -Pbuild_flags="--disable lower_inline --print_ir" stdlib
|
||||||
|
|
||||||
* **-Pshims** compiles LLVM interface with tracing "shims". Allowing one
|
* **-Pshims** compiles LLVM interface with tracing "shims". Allowing one
|
||||||
to trace the LLVM calls from the compiler.
|
to trace the LLVM calls from the compiler.
|
||||||
@@ -31,4 +31,17 @@ To update the blackbox compiler tests set TeamCity build number in `gradle.prope
|
|||||||
|
|
||||||
testDataVersion=<build number>:id
|
testDataVersion=<build number>:id
|
||||||
|
|
||||||
and run `./gradlew update_external_tests`
|
and run `./gradlew update_external_tests`
|
||||||
|
|
||||||
|
* **-Ptest_flags** passes flags to the compiler used to compile tests
|
||||||
|
|
||||||
|
./gradlew -Ptest_flags="--time" backend.native:tests:array0
|
||||||
|
|
||||||
|
* **-Ptest_target** specifies cross target for a test run.
|
||||||
|
|
||||||
|
./gradlew -Ptest_target=raspberrypi backend.native:tests:array0
|
||||||
|
|
||||||
|
* **-Premote=user@host** sets remote test execution login/hostname. Good for cross compiled tests.
|
||||||
|
|
||||||
|
./gradles -Premote=kotlin@111.22.33.444 backend.native:tests:run
|
||||||
|
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ targetList.each { target ->
|
|||||||
project(':runtime').file('src/main/kotlin'),
|
project(':runtime').file('src/main/kotlin'),
|
||||||
project(':Interop:Runtime').file('src/main/kotlin'),
|
project(':Interop:Runtime').file('src/main/kotlin'),
|
||||||
project(':Interop:Runtime').file('src/native/kotlin'),
|
project(':Interop:Runtime').file('src/native/kotlin'),
|
||||||
*project.globalArgs)
|
*project.globalBuildArgs)
|
||||||
|
|
||||||
inputs.dir(project(':runtime').file('src/main/kotlin'))
|
inputs.dir(project(':runtime').file('src/main/kotlin'))
|
||||||
inputs.dir(project(':Interop:Runtime').file('src/main/kotlin'))
|
inputs.dir(project(':Interop:Runtime').file('src/main/kotlin'))
|
||||||
@@ -230,7 +230,7 @@ targetList.each { target ->
|
|||||||
'-runtime', project(':runtime').file("build/${target}/runtime.bc"),
|
'-runtime', project(':runtime').file("build/${target}/runtime.bc"),
|
||||||
'-properties', project(':backend.native').file('konan.properties'),
|
'-properties', project(':backend.native').file('konan.properties'),
|
||||||
project(':runtime').file('src/launcher/kotlin'),
|
project(':runtime').file('src/launcher/kotlin'),
|
||||||
*project.globalArgs)
|
*project.globalBuildArgs)
|
||||||
|
|
||||||
inputs.dir(project(':runtime').file('src/launcher/kotlin'))
|
inputs.dir(project(':runtime').file('src/launcher/kotlin'))
|
||||||
outputs.file(project(':runtime').file("build/${target}/start.kt.bc"))
|
outputs.file(project(':runtime').file("build/${target}/start.kt.bc"))
|
||||||
|
|||||||
@@ -65,8 +65,11 @@ targetSysRoot.linux-raspberrypi = target-sysroot-1-raspberrypi
|
|||||||
llvmHome.linux-raspberrypi = clang+llvm-3.9.0-linux-x86-64
|
llvmHome.linux-raspberrypi = clang+llvm-3.9.0-linux-x86-64
|
||||||
libGcc.linux-raspberrypi = target-sysroot-1-raspberrypi/lib/gcc/arm-linux-gnueabihf/4.8.3/
|
libGcc.linux-raspberrypi = target-sysroot-1-raspberrypi/lib/gcc/arm-linux-gnueabihf/4.8.3/
|
||||||
gccToolChain.linux-raspberrypi = target-gcc-toolchain-3-linux-x86-64
|
gccToolChain.linux-raspberrypi = target-gcc-toolchain-3-linux-x86-64
|
||||||
llvmLlcFlags.linux-raspberrypi = -mtriple=armv7-unknown-linux-gnueabihf --disable-fp-elim -mfloat-abi=hard
|
llvmLtoFlags.linux-raspberrypi = -O3 -function-sections -exported-symbol=Konan_main
|
||||||
|
llvmLlcFlags.linux-raspberrypi = -mtriple=armv7-unknown-linux-gnueabihf --disable-fp-elim -float-abi=hard
|
||||||
linkerKonanFlags.linux-raspberrypi = -Bstatic -lstdc++ -Bdynamic -ldl -lm -lc -lpthread -fuse-ld=gold
|
linkerKonanFlags.linux-raspberrypi = -Bstatic -lstdc++ -Bdynamic -ldl -lm -lc -lpthread -fuse-ld=gold
|
||||||
|
entrySelector.linux-raspberrypi = --defsym main=Konan_main
|
||||||
dependencies.raspberrypi = clang+llvm-3.9.0-linux-x86-64 \
|
dependencies.raspberrypi = clang+llvm-3.9.0-linux-x86-64 \
|
||||||
target-gcc-toolchain-3-linux-x86-64 \
|
target-gcc-toolchain-3-linux-x86-64 \
|
||||||
target-sysroot-1-raspberrypi
|
target-sysroot-1-raspberrypi
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ ext.testOutputRoot = rootProject.file("test.output").absolutePath
|
|||||||
ext.externalTestsDir = project.file("external")
|
ext.externalTestsDir = project.file("external")
|
||||||
externalTestsDir.mkdirs()
|
externalTestsDir.mkdirs()
|
||||||
|
|
||||||
|
project.convention.plugins.remoteExec = new org.jetbrains.kotlin.ExecRemote(project)
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
// Root directories for test output (logs, compiled files, statistics etc). Only single path must be in each set.
|
// Root directories for test output (logs, compiled files, statistics etc). Only single path must be in each set.
|
||||||
sourceSets {
|
sourceSets {
|
||||||
@@ -1604,6 +1606,12 @@ task interop2(type: RunInteropKonanTest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
task interop3(type: RunInteropKonanTest) {
|
task interop3(type: RunInteropKonanTest) {
|
||||||
|
// We disable this test on Raspberry Pi because
|
||||||
|
// qsort accepts size_t args. So the .kt file
|
||||||
|
// should be different depending on the bitness of the target.
|
||||||
|
// There are plans to provide a solution and turn this
|
||||||
|
// test back on.
|
||||||
|
disabled = (project.testTarget == 'raspberrypi')
|
||||||
goldValue = "8 9 12 13 14 \n"
|
goldValue = "8 9 12 13 14 \n"
|
||||||
source = "interop/basics/3.kt"
|
source = "interop/basics/3.kt"
|
||||||
interop = 'cstdlib'
|
interop = 'cstdlib'
|
||||||
|
|||||||
@@ -26,4 +26,4 @@ private fun comparator(a: COpaquePointer?, b: COpaquePointer?): Int {
|
|||||||
val bValue = b!!.reinterpret<CInt32Var>().pointed.value
|
val bValue = b!!.reinterpret<CInt32Var>().pointed.value
|
||||||
|
|
||||||
return (aValue - bValue)
|
return (aValue - bValue)
|
||||||
}
|
}
|
||||||
|
|||||||
+49
-26
@@ -2,12 +2,6 @@
|
|||||||
|
|
||||||
defaultTasks 'clean', 'demo'
|
defaultTasks 'clean', 'demo'
|
||||||
|
|
||||||
if (new File("$project.rootDir/local.properties").exists()) {
|
|
||||||
Properties props = new Properties()
|
|
||||||
props.load(new FileInputStream("$project.rootDir/local.properties"))
|
|
||||||
props.each {prop -> project.ext.set(prop.key, prop.value)}
|
|
||||||
}
|
|
||||||
|
|
||||||
convention.plugins.platformInfo = new PlatformInfo()
|
convention.plugins.platformInfo = new PlatformInfo()
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
@@ -19,6 +13,37 @@ allprojects {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadCommandLineProperties()
|
||||||
|
loadLocalProperties()
|
||||||
|
setupCompilationFlags()
|
||||||
|
setupClang()
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupClang() {
|
||||||
|
|
||||||
|
convention.plugins.execClang = new org.jetbrains.kotlin.ExecClang(project)
|
||||||
|
|
||||||
|
plugins.withType(NativeComponentPlugin) {
|
||||||
|
model {
|
||||||
|
toolChains {
|
||||||
|
clang(Clang) {
|
||||||
|
clangPath.each {
|
||||||
|
path it
|
||||||
|
}
|
||||||
|
|
||||||
|
eachPlatform { // TODO: will not work when cross-compiling
|
||||||
|
[cCompiler, cppCompiler, linker].each {
|
||||||
|
it.withArguments { it.addAll(hostClangArgs) }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupCompilationFlags() {
|
||||||
ext.clangPath = ["$llvmDir/bin"]
|
ext.clangPath = ["$llvmDir/bin"]
|
||||||
ext.clangArgs = []
|
ext.clangArgs = []
|
||||||
ext.targetArgs = [:]
|
ext.targetArgs = [:]
|
||||||
@@ -64,30 +89,28 @@ allprojects {
|
|||||||
|
|
||||||
ext.clangPath << binDir
|
ext.clangPath << binDir
|
||||||
ext.jvmArgs = ["-ea"]
|
ext.jvmArgs = ["-ea"]
|
||||||
ext.globalArgs = project.hasProperty("konanc_flags") ? ext.konanc_flags.split(' ') : []
|
}
|
||||||
|
|
||||||
convention.plugins.execClang = new org.jetbrains.kotlin.ExecClang(project)
|
void loadLocalProperties() {
|
||||||
|
if (new File("$project.rootDir/local.properties").exists()) {
|
||||||
plugins.withType(NativeComponentPlugin) {
|
Properties props = new Properties()
|
||||||
model {
|
props.load(new FileInputStream("$project.rootDir/local.properties"))
|
||||||
toolChains {
|
props.each {prop -> project.ext.set(prop.key, prop.value)}
|
||||||
clang(Clang) {
|
|
||||||
clangPath.each {
|
|
||||||
path it
|
|
||||||
}
|
|
||||||
|
|
||||||
eachPlatform { // TODO: will not work when cross-compiling
|
|
||||||
[cCompiler, cppCompiler, linker].each {
|
|
||||||
it.withArguments { it.addAll(hostClangArgs) }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void loadCommandLineProperties() {
|
||||||
|
if (project.hasProperty("konanc_flags")) {
|
||||||
|
throw new Error("Specify either -Ptest_flags or -Pbuild_flags.")
|
||||||
|
}
|
||||||
|
ext.globalBuildArgs = project.hasProperty("build_flags")
|
||||||
|
? ext.build_flags.split(' ') : []
|
||||||
|
ext.globalTestArgs = project.hasProperty("test_flags")
|
||||||
|
? ext.test_flags.split(' ') : []
|
||||||
|
ext.testTarget = project.hasProperty("test_target")
|
||||||
|
? ext.test_target : null
|
||||||
|
}
|
||||||
|
|
||||||
class PlatformInfo {
|
class PlatformInfo {
|
||||||
private final String osName = System.properties['os.name']
|
private final String osName = System.properties['os.name']
|
||||||
private final String osArch = System.properties['os.arch']
|
private final String osArch = System.properties['os.arch']
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package org.jetbrains.kotlin
|
||||||
|
|
||||||
|
import org.gradle.api.Action
|
||||||
|
import org.gradle.api.GradleException
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.process.ExecResult
|
||||||
|
import org.gradle.process.ExecSpec
|
||||||
|
import org.gradle.util.ConfigureUtil
|
||||||
|
|
||||||
|
// This class provides process.execRemote -- a drop-in replacement for process.exec .
|
||||||
|
// If we provide -Premote=user@host the binaries are executed on a remote host
|
||||||
|
// If we omit -Premote then the binary is executed locally as usual.
|
||||||
|
|
||||||
|
class ExecRemote {
|
||||||
|
|
||||||
|
private final Project project
|
||||||
|
private final String remote = null
|
||||||
|
private final String remoteDir = null
|
||||||
|
|
||||||
|
ExecRemote(Project project) {
|
||||||
|
this.project = project
|
||||||
|
if (project.hasProperty('remote')) {
|
||||||
|
remote = project.ext.remote
|
||||||
|
remoteDir = uniqSessionName()
|
||||||
|
createRemoteDir()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String uniqSessionName() {
|
||||||
|
def date = new Date().format('yyyyMMddHHmmss')
|
||||||
|
return project.ext.remoteRoot + File.createTempFile(System.properties['user.name'], "_" + date)
|
||||||
|
}
|
||||||
|
|
||||||
|
private createRemoteDir() {
|
||||||
|
project.exec {
|
||||||
|
commandLine('ssh', remote, 'mkdir', '-p', remoteDir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private upload(String fileName) {
|
||||||
|
project.exec {
|
||||||
|
commandLine('scp', fileName, "${remote}:${remoteDir}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecResult execRemote(Action<? super ExecSpec> action) {
|
||||||
|
Action<? super ExecSpec> extendedAction = new Action<ExecSpec>() {
|
||||||
|
@Override
|
||||||
|
void execute(ExecSpec execSpec) {
|
||||||
|
action.execute(execSpec)
|
||||||
|
|
||||||
|
if (remote == null) return
|
||||||
|
|
||||||
|
execSpec.with {
|
||||||
|
upload(getExecutable())
|
||||||
|
executable = "$remoteDir/${new File(executable).name}"
|
||||||
|
if (project.hasProperty('remote')) {
|
||||||
|
commandLine = ['/usr/bin/ssh', remote] + commandLine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return project.exec(extendedAction)
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecResult execRemote(Closure closure) {
|
||||||
|
return this.execRemote(ConfigureUtil.configureUsing(closure));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -82,7 +82,10 @@ abstract class KonanTest extends JavaExec {
|
|||||||
"-ea",
|
"-ea",
|
||||||
*filesToCompile,
|
*filesToCompile,
|
||||||
*moreArgs,
|
*moreArgs,
|
||||||
*project.globalArgs]
|
*project.globalTestArgs]
|
||||||
|
if (project.testTarget) {
|
||||||
|
args "-target", project.testTarget
|
||||||
|
}
|
||||||
standardOutput = log
|
standardOutput = log
|
||||||
errorOutput = log
|
errorOutput = log
|
||||||
super.exec()
|
super.exec()
|
||||||
@@ -162,7 +165,7 @@ abstract class KonanTest extends JavaExec {
|
|||||||
|
|
||||||
def out = null
|
def out = null
|
||||||
//TODO Add test timeout
|
//TODO Add test timeout
|
||||||
ExecResult execResult = project.exec {
|
ExecResult execResult = project.execRemote {
|
||||||
commandLine exe
|
commandLine exe
|
||||||
if (arguments != null) {
|
if (arguments != null) {
|
||||||
args arguments
|
args arguments
|
||||||
@@ -210,6 +213,7 @@ class RunInteropKonanTest extends KonanTest {
|
|||||||
void setInterop(String value) {
|
void setInterop(String value) {
|
||||||
this.interop = value
|
this.interop = value
|
||||||
this.interopConf = project.kotlinNativeInterop[value]
|
this.interopConf = project.kotlinNativeInterop[value]
|
||||||
|
this.interopConf.target = project.testTarget
|
||||||
this.dependsOn(this.interopConf.genTask)
|
this.dependsOn(this.interopConf.genTask)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ class NamedNativeInteropConfig implements Named {
|
|||||||
|
|
||||||
private String defFile
|
private String defFile
|
||||||
|
|
||||||
private String pkg;
|
private String pkg
|
||||||
|
private String target
|
||||||
|
|
||||||
private List<String> compilerOpts = []
|
private List<String> compilerOpts = []
|
||||||
private List<String> headers;
|
private List<String> headers;
|
||||||
@@ -47,6 +48,10 @@ class NamedNativeInteropConfig implements Named {
|
|||||||
genTask.inputs.file(project.file(defFile))
|
genTask.inputs.file(project.file(defFile))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void target(String value) {
|
||||||
|
target = value
|
||||||
|
}
|
||||||
|
|
||||||
void pkg(String value) {
|
void pkg(String value) {
|
||||||
pkg = value
|
pkg = value
|
||||||
}
|
}
|
||||||
@@ -191,7 +196,7 @@ class NamedNativeInteropConfig implements Named {
|
|||||||
args "-natives:" + nativeLibsDir
|
args "-natives:" + nativeLibsDir
|
||||||
args "-flavor:" + this.flavor
|
args "-flavor:" + this.flavor
|
||||||
// Uncomment to debug.
|
// Uncomment to debug.
|
||||||
//args "-verbose:true"
|
// args "-verbose:true"
|
||||||
|
|
||||||
if (defFile != null) {
|
if (defFile != null) {
|
||||||
args "-def:" + project.file(defFile)
|
args "-def:" + project.file(defFile)
|
||||||
@@ -205,6 +210,10 @@ class NamedNativeInteropConfig implements Named {
|
|||||||
args "-linker:" + linker
|
args "-linker:" + linker
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (target != null) {
|
||||||
|
args "-target:" + target
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: the interop plugin should probably be reworked to execute clang from build scripts directly
|
// TODO: the interop plugin should probably be reworked to execute clang from build scripts directly
|
||||||
environment['PATH'] = project.files(project.clangPath).asPath +
|
environment['PATH'] = project.files(project.clangPath).asPath +
|
||||||
File.pathSeparator + environment['PATH']
|
File.pathSeparator + environment['PATH']
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
kotlin_version=1.1.0
|
kotlin_version=1.1.0
|
||||||
llvmVersion = 3.9.0
|
llvmVersion = 3.9.0
|
||||||
minMacOsVersion = 10.10
|
minMacOsVersion = 10.10
|
||||||
|
remoteRoot=konan_tests
|
||||||
#kotlinCompilerModule=org.jetbrains.kotlin:kotlin-compiler:1.1-SNAPSHOT
|
#kotlinCompilerModule=org.jetbrains.kotlin:kotlin-compiler:1.1-SNAPSHOT
|
||||||
# Download artifacts of https://teamcity.jetbrains.com/viewType.html?buildTypeId=bt345
|
# Download artifacts of https://teamcity.jetbrains.com/viewType.html?buildTypeId=bt345
|
||||||
testDataVersion=1009012:id
|
testDataVersion=1009012:id
|
||||||
|
|||||||
@@ -9,16 +9,20 @@ LINKER_ARGS_macbook="-F /Library/Frameworks -framework SDL2"
|
|||||||
COMPILER_ARGS_macbook=
|
COMPILER_ARGS_macbook=
|
||||||
CFLAGS_macbook=-I/opt/local/include/SDL2
|
CFLAGS_macbook=-I/opt/local/include/SDL2
|
||||||
LINKER_ARGS_macbook="-L/opt/local/lib -lSDL2"
|
LINKER_ARGS_macbook="-L/opt/local/lib -lSDL2"
|
||||||
|
|
||||||
CFLAGS_linux=-I/usr/include/SDL2
|
CFLAGS_linux=-I/usr/include/SDL2
|
||||||
LINKER_ARGS_linux="-L/usr/lib/x86_64-linux-gnu -lSDL2"
|
LINKER_ARGS_linux="-L/usr/lib/x86_64-linux-gnu -lSDL2"
|
||||||
COMPILER_ARGS_linux=
|
COMPILER_ARGS_linux=
|
||||||
|
|
||||||
CFLAGS_iphone=-I$DEPS/target-sysroot-2-darwin-ios/System/Library/Frameworks/SDL2.framework/Headers
|
CFLAGS_iphone=-I$DEPS/target-sysroot-2-darwin-ios/System/Library/Frameworks/SDL2.framework/Headers
|
||||||
LINKER_ARGS_iphone="-framework SDL2 \
|
LINKER_ARGS_iphone="-framework SDL2 \
|
||||||
-framework AVFoundation -framework CoreGraphics -framework CoreMotion -framework Foundation -framework GameController \
|
-framework AVFoundation -framework CoreGraphics -framework CoreMotion -framework Foundation -framework GameController \
|
||||||
-framework AudioToolbox -framework OpenGLES -framework QuartzCore -framework UIKit"
|
-framework AudioToolbox -framework OpenGLES -framework QuartzCore -framework UIKit"
|
||||||
COMPILER_ARGS_iphone=-nomain
|
COMPILER_ARGS_iphone=-nomain
|
||||||
|
|
||||||
CFLAGS_raspberrypi=-I$DEPS/target-sysroot-1-raspberrypi/usr/include/SDL2
|
CFLAGS_raspberrypi=-I$DEPS/target-sysroot-1-raspberrypi/usr/include/SDL2
|
||||||
LINKER_ARGS_raspberrypi="-lSDL2"
|
LINKER_ARGS_raspberrypi="-lSDL2"
|
||||||
|
COMPILER_ARGS_raspberrypi=-nomain
|
||||||
|
|
||||||
if [ x$TARGET == x ]; then
|
if [ x$TARGET == x ]; then
|
||||||
case "$OSTYPE" in
|
case "$OSTYPE" in
|
||||||
|
|||||||
Reference in New Issue
Block a user