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:
Alexander Gorshenev
2017-03-22 17:57:40 +03:00
committed by alexander-gorshenev
parent 826b3fc3f2
commit 334d2f0ee6
11 changed files with 171 additions and 37 deletions
+16 -3
View File
@@ -2,9 +2,9 @@
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
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
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
+2 -2
View File
@@ -204,7 +204,7 @@ targetList.each { target ->
project(':runtime').file('src/main/kotlin'),
project(':Interop:Runtime').file('src/main/kotlin'),
project(':Interop:Runtime').file('src/native/kotlin'),
*project.globalArgs)
*project.globalBuildArgs)
inputs.dir(project(':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"),
'-properties', project(':backend.native').file('konan.properties'),
project(':runtime').file('src/launcher/kotlin'),
*project.globalArgs)
*project.globalBuildArgs)
inputs.dir(project(':runtime').file('src/launcher/kotlin'))
outputs.file(project(':runtime').file("build/${target}/start.kt.bc"))
+4 -1
View File
@@ -65,8 +65,11 @@ targetSysRoot.linux-raspberrypi = target-sysroot-1-raspberrypi
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/
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
entrySelector.linux-raspberrypi = --defsym main=Konan_main
dependencies.raspberrypi = clang+llvm-3.9.0-linux-x86-64 \
target-gcc-toolchain-3-linux-x86-64 \
target-sysroot-1-raspberrypi
+8
View File
@@ -29,6 +29,8 @@ ext.testOutputRoot = rootProject.file("test.output").absolutePath
ext.externalTestsDir = project.file("external")
externalTestsDir.mkdirs()
project.convention.plugins.remoteExec = new org.jetbrains.kotlin.ExecRemote(project)
allprojects {
// Root directories for test output (logs, compiled files, statistics etc). Only single path must be in each set.
sourceSets {
@@ -1604,6 +1606,12 @@ task interop2(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"
source = "interop/basics/3.kt"
interop = 'cstdlib'
+1 -1
View File
@@ -26,4 +26,4 @@ private fun comparator(a: COpaquePointer?, b: COpaquePointer?): Int {
val bValue = b!!.reinterpret<CInt32Var>().pointed.value
return (aValue - bValue)
}
}
+49 -26
View File
@@ -2,12 +2,6 @@
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()
allprojects {
@@ -19,6 +13,37 @@ allprojects {
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.clangArgs = []
ext.targetArgs = [:]
@@ -64,30 +89,28 @@ allprojects {
ext.clangPath << binDir
ext.jvmArgs = ["-ea"]
ext.globalArgs = project.hasProperty("konanc_flags") ? ext.konanc_flags.split(' ') : []
}
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 loadLocalProperties() {
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)}
}
}
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 {
private final String osName = System.properties['os.name']
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",
*filesToCompile,
*moreArgs,
*project.globalArgs]
*project.globalTestArgs]
if (project.testTarget) {
args "-target", project.testTarget
}
standardOutput = log
errorOutput = log
super.exec()
@@ -162,7 +165,7 @@ abstract class KonanTest extends JavaExec {
def out = null
//TODO Add test timeout
ExecResult execResult = project.exec {
ExecResult execResult = project.execRemote {
commandLine exe
if (arguments != null) {
args arguments
@@ -210,6 +213,7 @@ class RunInteropKonanTest extends KonanTest {
void setInterop(String value) {
this.interop = value
this.interopConf = project.kotlinNativeInterop[value]
this.interopConf.target = project.testTarget
this.dependsOn(this.interopConf.genTask)
}
@@ -27,7 +27,8 @@ class NamedNativeInteropConfig implements Named {
private String defFile
private String pkg;
private String pkg
private String target
private List<String> compilerOpts = []
private List<String> headers;
@@ -47,6 +48,10 @@ class NamedNativeInteropConfig implements Named {
genTask.inputs.file(project.file(defFile))
}
void target(String value) {
target = value
}
void pkg(String value) {
pkg = value
}
@@ -191,7 +196,7 @@ class NamedNativeInteropConfig implements Named {
args "-natives:" + nativeLibsDir
args "-flavor:" + this.flavor
// Uncomment to debug.
//args "-verbose:true"
// args "-verbose:true"
if (defFile != null) {
args "-def:" + project.file(defFile)
@@ -205,6 +210,10 @@ class NamedNativeInteropConfig implements Named {
args "-linker:" + linker
}
if (target != null) {
args "-target:" + target
}
// TODO: the interop plugin should probably be reworked to execute clang from build scripts directly
environment['PATH'] = project.files(project.clangPath).asPath +
File.pathSeparator + environment['PATH']
+1
View File
@@ -1,6 +1,7 @@
kotlin_version=1.1.0
llvmVersion = 3.9.0
minMacOsVersion = 10.10
remoteRoot=konan_tests
#kotlinCompilerModule=org.jetbrains.kotlin:kotlin-compiler:1.1-SNAPSHOT
# Download artifacts of https://teamcity.jetbrains.com/viewType.html?buildTypeId=bt345
testDataVersion=1009012:id
+4
View File
@@ -9,16 +9,20 @@ LINKER_ARGS_macbook="-F /Library/Frameworks -framework SDL2"
COMPILER_ARGS_macbook=
CFLAGS_macbook=-I/opt/local/include/SDL2
LINKER_ARGS_macbook="-L/opt/local/lib -lSDL2"
CFLAGS_linux=-I/usr/include/SDL2
LINKER_ARGS_linux="-L/usr/lib/x86_64-linux-gnu -lSDL2"
COMPILER_ARGS_linux=
CFLAGS_iphone=-I$DEPS/target-sysroot-2-darwin-ios/System/Library/Frameworks/SDL2.framework/Headers
LINKER_ARGS_iphone="-framework SDL2 \
-framework AVFoundation -framework CoreGraphics -framework CoreMotion -framework Foundation -framework GameController \
-framework AudioToolbox -framework OpenGLES -framework QuartzCore -framework UIKit"
COMPILER_ARGS_iphone=-nomain
CFLAGS_raspberrypi=-I$DEPS/target-sysroot-1-raspberrypi/usr/include/SDL2
LINKER_ARGS_raspberrypi="-lSDL2"
COMPILER_ARGS_raspberrypi=-nomain
if [ x$TARGET == x ]; then
case "$OSTYPE" in