A configurable zephyr board support.

This commit is contained in:
Alexander Gorshenev
2018-01-16 17:43:55 +03:00
committed by alexander-gorshenev
parent d968fafec0
commit 9789420ed3
63 changed files with 665 additions and 473 deletions
@@ -51,9 +51,6 @@ class CInteropArguments : CommonInteropArguments() {
@Argument(value = "-def", valueDescription = "<file>", description = "the library definition file")
var def: String? = null
@Argument(value = "-properties", valueDescription = "<file>", description = "an alternative location of konan.properties file")
var properties: String? = null
// TODO: the short -h for -header conflicts with -h for -help.
// The -header currently wins, but need to make it a little more sound.
@Argument(value = "-header", shortName = "-h", valueDescription = "<file>", description = "header file to produce kotlin bindings for")
@@ -16,29 +16,20 @@
package org.jetbrains.kotlin.native.interop.tool
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.properties.loadProperties
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.target.PlatformManager
import org.jetbrains.kotlin.konan.target.TargetManager
import org.jetbrains.kotlin.konan.util.DependencyProcessor
import org.jetbrains.kotlin.konan.target.*
import org.jetbrains.kotlin.konan.util.visibleName
import org.jetbrains.kotlin.native.interop.gen.jvm.KotlinPlatform
class ToolConfig(userProvidedTargetName: String?, userProvidedKonanProperties: String?,
runnerProvidedKonanHome: String, val flavor: KotlinPlatform) {
class ToolConfig(userProvidedTargetName: String?, flavor: KotlinPlatform) {
private val targetManager = TargetManager(userProvidedTargetName)
private val host = TargetManager.host
private val konanHome = System.getProperty("konan.home")
private val distribution = customerDistribution(konanHome)
private val platformManager = PlatformManager(distribution)
private val targetManager = platformManager.targetManager(userProvidedTargetName)
private val host = HostManager.host
private val target = targetManager.target
private val konanHome = File(runnerProvidedKonanHome).absolutePath
private val konanPropertiesFile = userProvidedKonanProperties?.File() ?: File(konanHome, "konan/konan.properties")
private val properties = konanPropertiesFile.loadProperties()
private val dependencies = DependencyProcessor.defaultDependenciesRoot
private val platform = PlatformManager(properties, dependencies.path).platform(target)
private val platform = platformManager.platform(target)
val substitutions = mapOf<String, String>(
"target" to target.detailedName,
@@ -249,8 +249,6 @@ private fun processCLib(args: Array<String>): Array<String>? {
val tool = ToolConfig(
arguments.target,
arguments.properties,
System.getProperty("konan.home"),
flavor
)
tool.downloadDependencies()
+3 -4
View File
@@ -168,11 +168,11 @@ task start(dependsOn: "${hostName}Start")
// These files are built before the 'dist' is complete,
// so we provide custom values for
// -runtime, -properties, -library and -Djava.library.path
// konan.home, --runtime, -Djava.library.path etc
targetList.each { target ->
def konanJvmArgs = ["-ea",
"-Dkonan.home=$distDir",
"-Dkonan.home=${rootProject.projectDir}",
"-Djava.library.path=${project.buildDir}/nativelibs/$hostName",
"-Dfile.encoding=UTF-8"]
@@ -180,8 +180,7 @@ targetList.each { target ->
if (target != "wasm32") defaultArgs += '-g'
def konanArgs = [*defaultArgs,
'-target', target,
'-runtime', project(':runtime').file("build/${target}/runtime.bc"),
'-properties', rootProject.konanPropertiesFile.canonicalPath,
'--runtime', project(':runtime').file("build/${target}/runtime.bc"),
*project.globalBuildArgs]
task("${target}Stdlib", type: JavaExec) {
@@ -124,7 +124,6 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
arguments.mainPackage ?.let{ put(ENTRY, it) }
arguments.manifestFile ?.let{ put(MANIFEST_FILE, it) }
arguments.runtimeFile ?.let{ put(RUNTIME_FILE, it) }
arguments.propertyFile ?.let{ put(PROPERTY_FILE, it) }
put(LIST_TARGETS, arguments.listTargets)
put(OPTIMIZATION, arguments.optimization)
@@ -78,15 +78,9 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
@Argument(value = "-produce", shortName = "-p", valueDescription = "{program|dynamic|framework|library|bitcode}", description = "Specify output file kind")
var produce: String? = null
@Argument(value = "-properties", valueDescription = "<path>", description = "Override standard 'konan.properties' location")
var propertyFile: String? = null
@Argument(value = "-repo", shortName = "-r", valueDescription = "<path>", description = "Library search path")
var repositories: Array<String>? = null
@Argument(value = "-runtime", valueDescription = "<path>", description = "Override standard 'runtime.bc' location")
var runtimeFile: String? = null
@Argument(value = "-target", valueDescription = "<target>", description = "Set hardware target")
var target: String? = null
@@ -124,6 +118,9 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
@Argument(value = "--purge_user_libs", description = "Don't link unused libraries even explicitly specified")
var purgeUserLibs: Boolean = false
@Argument(value = "--runtime", valueDescription = "<path>", description = "Override standard 'runtime.bc' location")
var runtimeFile: String? = null
@Argument(value = "--time", description = "Report execution time for compiler phases")
var timePhases: Boolean = false
@@ -829,7 +829,7 @@ internal class CAdapterGenerator(
output("RUNTIME_USED ${prefix}_ExportedSymbols* $exportedSymbol(void) { return &__konan_symbols;}")
outputStreamWriter.close()
if (context.config.targetManager.target.family == Family.WINDOWS) {
if (context.config.target.family == Family.WINDOWS) {
outputStreamWriter = context.config.tempFiles
.cAdapterDef
.printWriter()
@@ -73,7 +73,7 @@ internal fun produceOutput(context: Context) {
val neededLibraries
= context.llvm.librariesForLibraryManifest
val abiVersion = context.config.currentAbiVersion
val target = context.config.targetManager.target
val target = context.config.target
val nopack = config.getBoolean(KonanConfigKeys.NOPACK)
val manifest = config.get(KonanConfigKeys.MANIFEST_FILE)
@@ -1,49 +0,0 @@
/*
* Copyright 2010-2017 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.backend.konan
import org.jetbrains.kotlin.konan.file.*
import org.jetbrains.kotlin.konan.properties.*
import org.jetbrains.kotlin.konan.target.*
import org.jetbrains.kotlin.konan.util.visibleName
import org.jetbrains.kotlin.konan.util.DependencyProcessor
class Distribution(val target: KonanTarget,
propertyFileOverride: String? = null,
runtimeFileOverride: String? = null) {
val localKonanDir = "${File.userHome}/.konan"
private fun findKonanHome(): String {
val value = System.getProperty("konan.home", "dist")
val path = File(value).absolutePath
return path
}
val konanHome = findKonanHome()
val propertyFileName = propertyFileOverride ?: "$konanHome/konan/konan.properties"
val properties = File(propertyFileName).loadProperties()
val klib = "$konanHome/klib"
val stdlib = "$klib/common/stdlib"
val targetName = target.visibleName
val defaultNatives = "$konanHome/konan/targets/${targetName}/native"
val runtime = runtimeFileOverride ?: "$stdlib/targets/${targetName}/native/runtime.bc"
val dependenciesDir = DependencyProcessor.defaultDependenciesRoot.absolutePath
}
@@ -39,30 +39,29 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
val currentAbiVersion: Int = configuration.get(KonanConfigKeys.ABI_VERSION)!!
internal val targetManager = TargetManager(
configuration.get(KonanConfigKeys.TARGET))
internal val distribution = Distribution(
false,
null,
configuration.get(KonanConfigKeys.RUNTIME_FILE))
private val target = targetManager.target
internal val platformManager = PlatformManager(distribution)
internal val targetManager = platformManager.targetManager(configuration.get(KonanConfigKeys.TARGET))
internal val target = targetManager.target
init {
if (!target.enabled) {
error("Target $target is not available on the ${TargetManager.host} host")
if (!platformManager.isEnabled(target)) {
error("Target $target is not available on the ${HostManager.host} host")
}
}
val indirectBranchesAreAllowed = target != KonanTarget.WASM32
internal val distribution = Distribution(target,
configuration.get(KonanConfigKeys.PROPERTY_FILE),
configuration.get(KonanConfigKeys.RUNTIME_FILE))
internal val platform = PlatformManager(distribution.properties, distribution.dependenciesDir).platform(target).apply {
val platform = platformManager.platform(target).apply {
if (configuration.getBoolean(KonanConfigKeys.CHECK_DEPENDENCIES)) {
downloadDependencies()
}
}
internal val clang = platform.clang
val indirectBranchesAreAllowed = target != KonanTarget.WASM32
internal val produce get() = configuration.get(KonanConfigKeys.PRODUCE)!!
private val prefix = produce.prefix(target)
@@ -84,7 +83,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
get() = configuration.getList(KonanConfigKeys.LIBRARY_FILES)
private val repositories = configuration.getList(KonanConfigKeys.REPOSITORIES)
private val resolver = defaultResolver(repositories, distribution)
private val resolver = defaultResolver(repositories, target, distribution)
internal val immediateLibraries: List<LibraryReaderImpl> by lazy {
val result = resolver.resolveImmediateLibraries(
@@ -109,7 +108,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
internal val defaultNativeLibraries =
if (produce == CompilerOutputKind.PROGRAM)
File(distribution.defaultNatives).listFiles.map { it.absolutePath }
File(distribution.defaultNatives(target)).listFiles.map { it.absolutePath }
else emptyList()
internal val nativeLibraries: List<String> =
@@ -83,8 +83,6 @@ class KonanConfigKeys {
= CompilerConfigurationKey.create("print locations")
val PRODUCE: CompilerConfigurationKey<CompilerOutputKind>
= CompilerConfigurationKey.create("compiler output kind")
val PROPERTY_FILE: CompilerConfigurationKey<String?>
= CompilerConfigurationKey.create("override default property file path")
val PURGE_USER_LIBS: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("purge user-specified libs too")
val REPOSITORIES: CompilerConfigurationKey<List<String>>
@@ -18,7 +18,8 @@ package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.konan.KonanExternalToolFailure
import org.jetbrains.kotlin.konan.exec.Command
import org.jetbrains.kotlin.konan.file.*
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.file.createTempFile
import org.jetbrains.kotlin.konan.target.*
typealias BitcodeFile = String
@@ -28,7 +29,7 @@ typealias ExecutableFile = String
internal class LinkStage(val context: Context) {
private val config = context.config.configuration
private val target = context.config.targetManager.target
private val target = context.config.target
private val platform = context.config.platform
private val linker = platform.linker
@@ -117,6 +118,19 @@ internal class LinkStage(val context: Context) {
return combinedWasm
}
private fun llvmLinkAndLlc(bitcodeFiles: List<BitcodeFile>): String {
val combinedBc = temporary("combined", ".bc")
hostLlvmTool("llvm-link", "-o", combinedBc, *bitcodeFiles.toTypedArray())
val optimizedBc = temporary("optimized", ".bc")
hostLlvmTool("opt", combinedBc, "-o=$optimizedBc", "-O3")
val combinedO = temporary("combined", ".o")
hostLlvmTool("llc", combinedBc, "-filetype=obj", "-o", combinedO, "-function-sections", "-data-sections")
return combinedO
}
private fun asLinkerArgs(args: List<String>): List<String> {
if (linker.useCompilerDriverAsLinker) {
return args
@@ -201,15 +215,19 @@ internal class LinkStage(val context: Context) {
val libraryProvidedLinkerFlags =
libraries.map{it -> it.linkerOpts}.flatten()
var objectFiles: List<String> = listOf()
val objectFiles: MutableList<String> = mutableListOf()
val phaser = PhaseManager(context)
phaser.phase(KonanPhase.OBJECT_FILES) {
objectFiles = listOf(
if (target == KonanTarget.WASM32)
bitcodeToWasm(bitcodeFiles)
else
llvmLto(bitcodeFiles)
objectFiles.add(
when (platform.configurables) {
is WasmConfigurables
-> bitcodeToWasm(bitcodeFiles)
is ZephyrConfigurables
-> llvmLinkAndLlc(bitcodeFiles)
else
-> llvmLto(bitcodeFiles)
}
)
}
phaser.phase(KonanPhase.LINKER) {
@@ -16,14 +16,12 @@
package org.jetbrains.kotlin.backend.konan.library
import org.jetbrains.kotlin.backend.konan.Distribution
import org.jetbrains.kotlin.backend.konan.library.impl.LibraryReaderImpl
import org.jetbrains.kotlin.backend.konan.util.removeSuffixIfPresent
import org.jetbrains.kotlin.backend.konan.util.suffixIfNot
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.target.Distribution
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.target.TargetManager
import org.jetbrains.kotlin.konan.util.visibleName
interface SearchPathResolver {
val searchRoots: List<File>
@@ -32,12 +30,12 @@ interface SearchPathResolver {
}
fun defaultResolver(repositories: List<String>, target: KonanTarget): SearchPathResolver =
defaultResolver(repositories, Distribution(target))
defaultResolver(repositories, target, Distribution())
fun defaultResolver(repositories: List<String>, distribution: Distribution): SearchPathResolver =
fun defaultResolver(repositories: List<String>, target: KonanTarget, distribution: Distribution): SearchPathResolver =
KonanLibrarySearchPathResolver(
repositories,
distribution.target,
target,
distribution.klib,
distribution.localKonanDir
)
@@ -362,7 +362,9 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
val staticData = StaticData(context)
val runtimeFile = context.config.distribution.runtime
private val target = context.config.target
val runtimeFile = context.config.distribution.runtime(target)
val runtime = Runtime(runtimeFile) // TODO: dispose
init {
@@ -416,7 +418,17 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
null
}
private val personalityFunctionName = when (context.config.targetManager.target) {
val tlsMode by lazy {
when (target) {
KonanTarget.WASM32,
is KonanTarget.ZEPHYR
-> LLVMThreadLocalMode.LLVMNotThreadLocal
else
-> LLVMThreadLocalMode.LLVMGeneralDynamicTLSModel
}
}
private val personalityFunctionName = when (target) {
KonanTarget.MINGW -> "__gxx_personality_seh0"
else -> "__gxx_personality_v0"
}
@@ -2228,7 +2228,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
// On x86_64 it is the case if the return value takes more than 16 bytes or is the structure with
// unaligned fields (there are some complicated exceptions currently ignored). The latter condition
// is "encoded" by stub generator by emitting either `getMessenger` or `getMessengerLU` intrinsic call.
val isStret = when (context.config.targetManager.target) {
val isStret = when (context.config.target) {
KonanTarget.MACBOOK, KonanTarget.IPHONE_SIM -> isLU // x86_64
KonanTarget.IPHONE -> false // aarch64
else -> TODO()
@@ -205,7 +205,7 @@ internal fun ContextUtils.addGlobal(name: String, type: LLVMTypeRef, isExported:
assert(LLVMGetNamedGlobal(context.llvmModule, name) == null)
val result = LLVMAddGlobal(context.llvmModule, type, name)!!
if (threadLocal)
LLVMSetThreadLocalMode(result, runtime.tlsMode)
LLVMSetThreadLocalMode(result, context.llvm.tlsMode)
return result
}
@@ -219,12 +219,12 @@ internal fun ContextUtils.importGlobal(name: String, type: LLVMTypeRef, origin:
assert (getGlobalType(found) == type)
assert (LLVMGetInitializer(found) == null)
if (threadLocal)
assert(LLVMGetThreadLocalMode(found) == runtime.tlsMode)
assert(LLVMGetThreadLocalMode(found) == context.llvm.tlsMode)
return found
} else {
val result = LLVMAddGlobal(context.llvmModule, type, name)!!
if (threadLocal)
LLVMSetThreadLocalMode(result, runtime.tlsMode)
LLVMSetThreadLocalMode(result, context.llvm.tlsMode)
return result
}
}
@@ -46,11 +46,6 @@ class Runtime(bitcodeFile: String) {
val target = LLVMGetTarget(llvmModule)!!.toKString()
// TODO: deduce TLS model from explicit config parameter.
val tlsMode by lazy {
if (target.indexOf("wasm") != -1) LLVMThreadLocalMode.LLVMNotThreadLocal
else LLVMThreadLocalMode.LLVMGeneralDynamicTLSModel
}
val dataLayout = LLVMGetDataLayout(llvmModule)!!.toKString()
val targetData = LLVMCreateTargetData(dataLayout)!!
@@ -1007,4 +1007,4 @@ private val ReturnableTypeBridge.objCEncoding: String get() = when (this) {
HashCodeBridge -> "L" // NSUInteger = unsigned long; // TODO: `unsigned int` on watchOS
}
internal fun Context.is64Bit(): Boolean = this.config.targetManager.target.architecture.bitness == 64
internal fun Context.is64Bit(): Boolean = this.config.target.architecture.bitness == 64
@@ -31,7 +31,7 @@ import org.jetbrains.kotlin.name.isSubpackageOf
internal class ObjCExport(val context: Context) {
private val target get() = context.config.targetManager.target
private val target get() = context.config.target
internal fun produceObjCFramework() {
if (context.config.produce != CompilerOutputKind.FRAMEWORK) return
@@ -1,14 +1,14 @@
package org.jetbrains.kotlin.compiletest
import org.jetbrains.kotlin.konan.target.Family
import org.jetbrains.kotlin.konan.target.TargetManager
import org.jetbrains.kotlin.konan.target.HostManager
import java.nio.file.Path
import java.nio.file.Paths
object DistProperties {
private val dist: Path = Paths.get(requireProp("konan.home"))
private val konancDriver = if (TargetManager.host.family == Family.WINDOWS) "konanc.bat" else "konanc"
private val konancDriver = if (HostManager.host.family == Family.WINDOWS) "konanc.bat" else "konanc"
val konanc: Path = dist.resolve("bin/$konancDriver")
val lldb: Path = Paths.get("lldb")
val lldbPrettyPrinters: Path = dist.resolve("tools/konan_lldb.py")
+11 -24
View File
@@ -23,24 +23,10 @@ defaultTasks 'clean', 'dist'
convention.plugins.platformInfo = new PlatformInfo()
ext {
konanPropertiesFile = project(':backend.native').file('konan.properties')
konanProperties = PropertiesKt.loadProperties(konanPropertiesFile.absolutePath)
String DEPENDENCY_PROFILES_KEY = "dependencyProfiles"
def dependencyProfiles = konanProperties.getProperty(DEPENDENCY_PROFILES_KEY)
if (dependencyProfiles != "default alt")
throw new Error("unexpected $DEPENDENCY_PROFILES_KEY value: expected 'default alt', got '$dependencyProfiles'")
// Force build to use only 'default' profile:
konanProperties.setProperty(DEPENDENCY_PROFILES_KEY, "default")
// Force build to use fixed Xcode version:
konanProperties.setProperty("useFixedXcodeVersion", "9.2")
// TODO: it actually affects only resolution made in :dependencies,
// that's why we assume that 'default' profile comes first (and check this above).
distDir = file('dist')
dependenciesDir = DependencyProcessor.defaultDependenciesRoot
platformManager = new PlatformManager(konanProperties, dependenciesDir.absolutePath)
platformManager = new PlatformManager(DistributionKt.buildDistribution(projectDir.absolutePath))
kotlinCompilerModule="org.jetbrains.kotlin:kotlin-compiler:${kotlinCompilerVersion}"
kotlinStdLibModule="org.jetbrains.kotlin:kotlin-stdlib:${kotlinStdLibVersion}"
kotlinReflectModule="org.jetbrains.kotlin:kotlin-reflect:${kotlinReflectVersion}"
@@ -66,8 +52,9 @@ allprojects {
}
void setupHostAndTarget() {
ext.hostName = TargetManager.hostName
ext.targetList = TargetManager.enabled.collect { it.visibleName } as List
ext.hostName = platformManager.hostName
ext.targetList = platformManager.enabled.collect { it.visibleName } as List
ext.konanTargetList = platformManager.enabled as List
}
void setupClang(Project project) {
@@ -135,15 +122,15 @@ void loadCommandLineProperties() {
class PlatformInfo {
boolean isMac() {
return TargetManager.hostIsMac
return HostManager.hostIsMac
}
boolean isWindows() {
return TargetManager.hostIsMingw
return HostManager.hostIsMingw
}
boolean isLinux() {
return TargetManager.hostIsLinux
return HostManager.hostIsLinux
}
Throwable unsupportedPlatformException() {
@@ -243,7 +230,7 @@ task distCompiler(type: Copy) {
exclude('**/*.bat')
}
}
from(konanPropertiesFile) {
from(project.file('konan')) {
into('konan')
}
}
@@ -345,7 +332,7 @@ dependencies {
task bundle(type: (isWindows()) ? Zip : Tar) {
dependsOn('crossDistPlatformLibs')
dependsOn('crossDist')
def simpleOsName = TargetManager.simpleOsName()
def simpleOsName = HostManager.simpleOsName()
baseName = "kotlin-native-$simpleOsName-${project.konanVersion}"
from("$project.rootDir/dist") {
include '**'
@@ -399,7 +386,7 @@ task uploadBundle {
server: project.findProperty("cdnUrl") ?: System.getenv("CDN_URL"),
userid: project.findProperty("cdnUser") ?: System.getenv("CDN_USER"),
password: project.findProperty("cdnPass") ?: System.getenv("CDN_PASS"),
remoteDir: "/builds/$kind/$konanVersion/${TargetManager.simpleOsName()}"
remoteDir: "/builds/$kind/$konanVersion/${HostManager.simpleOsName()}"
]
ant {
taskdef(name: 'ftp',
@@ -32,12 +32,15 @@ class ExecClang {
this.project = project
}
private def platformManager = project.rootProject.platformManager
private List<String> konanArgs(KonanTarget target) {
return project.rootProject.platform(target).clang.clangArgsForKonanSources
return platformManager.platform(target).clang.clangArgsForKonanSources
}
private List<String> konanArgs(String target) {
return konanArgs(new TargetManager(target).target)
private List<String> konanArgs(String targetName) {
def target = platformManager.targetManager(targetName).target
return konanArgs(target)
}
// The bare ones invoke clang with system default sysroot.
@@ -30,15 +30,12 @@ abstract class KonanTest extends JavaExec {
public boolean inDevelopersRun = false
public String source
def targetManager = new TargetManager(project.testTarget)
def target = targetManager.target
def backendNative = project.project(":backend.native")
def runtimeProject = project.project(":runtime")
def platformManager = project.rootProject.platformManager
def target = platformManager.targetManager(project.testTarget).target
def dist = project.rootProject.file(project.findProperty("konan.home") ?: "dist")
def dependenciesDir = project.rootProject.dependenciesDir
def konancDriver = project.isWindows() ? "konanc.bat" : "konanc"
def konanc = new File("${dist.canonicalPath}/bin/$konancDriver").absolutePath
def mainC = 'main.c'
def outputSourceSetName = "testOutputLocal"
def enableKonanAssertions = true
String outputDirectory = null
@@ -227,7 +224,7 @@ fun handleExceptionContinuation(x: (Throwable) -> Unit): Continuation<Any?> = ob
createOutputDirectory()
def program = buildExePath()
def suffix = targetManager.target.family.exeSuffix
def suffix = target.family.exeSuffix
def exe = "$program.$suffix"
compileTest(buildCompileList(), program)
@@ -282,19 +279,17 @@ fun handleExceptionContinuation(x: (Throwable) -> Unit): Continuation<Any?> = ob
}
List<String> executionCommandLine(String exe) {
def properties = project.rootProject.konanProperties
def targetToolchain = TargetPropertiesKt.hostTargetString(properties, "targetToolchain", target)
def absoluteTargetToolchain = "$dependenciesDir/$targetToolchain"
if (target == KonanTarget.WASM32) {
def absoluteTargetToolchain = platformManager.platform(target).absoluteTargetToolchain
def absoluteTargetSysRoot = platformManager.platform(target).absoluteTargetSysRoot
if (target instanceof KonanTarget.WASM32) {
def d8 = "$absoluteTargetToolchain/bin/d8"
def launcherJs = "${exe}.js"
return [d8, '--expose-wasm', launcherJs, '--', exe]
} else if (target == KonanTarget.LINUX_MIPS32 || target == KonanTarget.LINUX_MIPSEL32) {
def targetSysroot = TargetPropertiesKt.targetString(properties, "targetSysRoot", target)
def absoluteTargetSysroot = "$dependenciesDir/$targetSysroot"
def qemu = target == KonanTarget.LINUX_MIPS32 ? "qemu-mips" : "qemu-mipsel"
} else if (target instanceof KonanTarget.LINUX_MIPS32 || target instanceof KonanTarget.LINUX_MIPSEL32) {
def qemu = target instanceof KonanTarget.LINUX_MIPS32 ? "qemu-mips" : "qemu-mipsel"
def absoluteQemu = "$absoluteTargetToolchain/bin/$qemu"
return [absoluteQemu, "-L", absoluteTargetSysroot, exe]
return [absoluteQemu, "-L", absoluteTargetSysRoot, exe]
} else {
return [exe]
}
@@ -548,7 +543,7 @@ class DynamicKonanTest extends KonanTest {
void compileTest(List<String> filesToCompile, String exe) {
def libname = "testlib"
def dylib = "$outputDirectory/$libname"
def realExe = "${exe}.${targetManager.target.family.exeSuffix}"
def realExe = "${exe}.${target.family.exeSuffix}"
runCompiler(filesToCompile, dylib, ['-produce', 'dynamic'] + ((flags != null) ? flags :[]))
runClang([cSource], realExe, ['-I', outputDirectory, '-L', outputDirectory, '-l', libname])
@@ -147,7 +147,6 @@ class NamedNativeInteropConfig implements Named {
}
File getNativeLibsDir() {
def target = new TargetManager(target).target.visibleName
return new File(project.buildDir, "nativelibs/$target")
}
@@ -158,9 +157,12 @@ class NamedNativeInteropConfig implements Named {
NamedNativeInteropConfig(Project project, String name, String target = null, String flavor = 'jvm') {
this.name = name
this.project = project
this.target = target
this.flavor = flavor
def platformManager = project.rootProject.ext.platformManager
def targetManager = platformManager.targetManager(target)
this.target = targetManager.targetName
this.headers = []
this.linkFiles = project.files()
@@ -197,7 +199,7 @@ class NamedNativeInteropConfig implements Named {
new File(project.findProject(":Interop:Indexer").buildDir, "nativelibs"),
new File(project.findProject(":Interop:Runtime").buildDir, "nativelibs")
).asPath
systemProperties "konan.home": project.rootProject.file("dist")
systemProperties "konan.home": project.rootProject.projectDir
environment "LIBCLANG_DISABLE_CRASH_RECOVERY": "1"
outputs.dir generatedSrcDir
@@ -213,7 +215,6 @@ class NamedNativeInteropConfig implements Named {
linkerOpts += linkFiles.files
args '-properties', project.findProject(":backend.native").file("konan.properties")
args '-generated', generatedSrcDir
args '-natives', nativeLibsDir
args '-flavor', this.flavor
@@ -7,7 +7,7 @@ import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.OutputDirectory
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.target.TargetManager
import org.jetbrains.kotlin.konan.target.HostManager
import java.io.File
// TODO: Implement as a part of the gradle plugin
@@ -24,12 +24,13 @@ open class KlibInstall: Exec() {
}
@Input
var target: String = TargetManager.hostName
var target: String = HostManager.hostName
override fun configure(config: Closure<*>): Task {
val result = super.configure(config)
val konanHome = project.rootProject.file(project.findProperty("konan.home") ?: "dist")
val suffix = if (TargetManager.host == KonanTarget.MINGW) ".bat" else ""
val konanHomePath = project.findProperty("konan.home") ?: "dist"
val konanHome = project.rootProject.file(konanHomePath)
val suffix = if (HostManager.host == KonanTarget.MINGW) ".bat" else ""
val klibProgram = "$konanHome/bin/klib$suffix"
doFirst {
+11 -15
View File
@@ -139,8 +139,7 @@ task update_kotlin_compiler(type: DefaultTask) {
}
abstract class NativeDep extends DefaultTask {
protected final String hostSystem = TargetManager.longerSystemName();
static final String baseUrl = "https://jetbrains.bintray.com/kotlin-native-dependencies"
static final String baseUrl = "https://download.jetbrains.com/kotlin/native"
@Input
abstract String getFileName()
@@ -198,11 +197,11 @@ class TgzNativeDep extends NativeDep {
class HelperNativeDep extends TgzNativeDep {
Properties konanProperties = new Properties()
KonanPropertiesLoader konanPropertiesLoader = null
@TaskAction
public void downloadAndExtract() {
def downloader = new DependencyProcessor(baseOutDir, konanProperties, [baseName], baseUrl, false)
def downloader = new DependencyProcessor(baseOutDir, konanPropertiesLoader, baseUrl, false)
downloader.showInfo = false
downloader.run()
}
@@ -237,18 +236,15 @@ enum DependencyKind {
String toString() { return name }
}
TargetManager.enabled.each { target ->
def konanProperties = ConfigurablesImplKt.loadConfigurables(
target,
rootProject.ext.konanProperties,
rootProject.ext.dependenciesDir.canonicalPath
)
def platformManager = rootProject.ext.platformManager
konanProperties.dependencies.each { dependency ->
platformManager.enabled.each { target ->
def loader = platformManager.loader(target)
loader.dependencies.each { dependency ->
if (tasks.findByName(dependency) == null) {
task "${dependency}"(type: HelperNativeDep) {
baseName = dependency
it.konanProperties = rootProject.ext.konanProperties
it.konanPropertiesLoader = loader
}
}
}
@@ -256,14 +252,14 @@ TargetManager.enabled.each { target ->
// Also resolves all dependencies:
final DependencyProcessor dependencyProcessor = new DependencyProcessor(
project.rootProject.ext.dependenciesDir,
rootProject.ext.konanProperties,
konanProperties.dependencies,
loader.properties,
loader.dependencies,
HelperNativeDep.baseUrl,
false
)
DependencyKind.values().each { kind ->
def dir = kind.getDirectory(konanProperties)
def dir = kind.getDirectory(loader)
if (dir != null) {
String path = dependencyProcessor.resolveRelative(dir).canonicalPath
rootProject.ext.set(kind.getPropertyName(target), path)
@@ -16,12 +16,15 @@
package org.jetbrains.kotlin.cli.klib
import kotlin.system.exitProcess
// TODO: Extract these as a shared jar?
import org.jetbrains.kotlin.backend.konan.library.impl.*
// TODO: Extract `library` package as a shared jar?
import org.jetbrains.kotlin.backend.konan.library.KonanLibrarySearchPathResolver
import org.jetbrains.kotlin.backend.konan.library.impl.LibraryReaderImpl
import org.jetbrains.kotlin.backend.konan.library.impl.UnzippedKonanLibrary
import org.jetbrains.kotlin.backend.konan.library.impl.ZippedKonanLibrary
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.target.TargetManager
import org.jetbrains.kotlin.konan.target.PlatformManager
import org.jetbrains.kotlin.konan.target.customerDistribution
import kotlin.system.exitProcess
fun printUsage() {
println("Usage: klib <command> <library> <options>")
@@ -167,7 +170,7 @@ fun libraryInRepoOrCurrentDir(repository: File, name: String): File {
fun main(args: Array<String>) {
val command = Command(args)
val targetManager = TargetManager(command.options["-target"]?.last())
val targetManager = PlatformManager().targetManager(command.options["-target"]?.last())
val target = targetManager.targetName
val repository = command.options["-repository"]?.last()
@@ -330,17 +330,4 @@ llcNooptFlags.wasm32 = -O1
llcOptFlags.wasm32 = -O3
llcDebugFlags.wasm32 = -O0
# The stack size is in bytes.
s2wasmFlags.wasm32 = --allocate-stack 1048576 --import-memory
# Zephyr RTOS.
targetToolchain.linux-zephyr = target-gcc-toolchain-6-2017q2-linux-armemb/arm-none-eabi
dependencies.linux-zephyr = \
clang-llvm-5.0.0-linux-x86-64 \
target-gcc-toolchain-6-2017q2-linux-armemb \
target-sysroot-2-wasm \
zephyr-host-tools-1-linux \
zephyr-zephyr-v1.10.0
quadruple.zephyr = armv7m-none-eabi
targetSysRoot.zephyr = target-sysroot-2-wasm
entrySelector.zephyr = --defsym main=Konan_main
s2wasmFlags.wasm32 = --allocate-stack 1048576 --import-memory
+36
View File
@@ -0,0 +1,36 @@
#
# 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.
#
# Zephyr RTOS.
# STM32 F4 Discovery
quadruple.zephyr_stm32f4_disco = armv7m-none-eabi
targetSysRoot.zephyr_stm32f4_disco = target-sysroot-2-wasm
entrySelector.zephyr_stm32f4_disco = --defsym main=Konan_main
boardSpecificClangFlags.zephyr_stm32f4_disco = -mabi=aapcs -mthumb -mcpu=cortex-m4
targetToolchain.linux-zephyr_stm32f4_disco = gcc-arm-none-eabi-7-2017-q4-major-linux/arm-none-eabi
dependencies.linux-zephyr_stm32f4_disco = \
clang-llvm-5.0.0-linux-x86-64 \
gcc-arm-none-eabi-7-2017-q4-major-linux \
target-sysroot-2-wasm
targetToolchain.osx-zephyr_stm32f4_disco = gcc-arm-none-eabi-7-2017-q4-major-mac/arm-none-eabi
dependencies.osx-zephyr_stm32f4_disco = \
gcc-arm-none-eabi-7-2017-q4-major-mac \
clang-llvm-5.0.0-darwin-macos \
target-sysroot-2-wasm
+22 -25
View File
@@ -1,5 +1,7 @@
import org.jetbrains.kotlin.KlibInstall
import org.jetbrains.kotlin.konan.target.TargetManager
import org.jetbrains.kotlin.konan.target.*
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.target.KonanTarget.*
import org.jetbrains.kotlin.konan.util.DefFile
import static org.jetbrains.kotlin.konan.util.VisibleNamedKt.getVisibleName
@@ -25,41 +27,36 @@ buildscript {
}
//#region Util functions.
private ArrayList<DefFile> targetDefFiles(String target) {
def platform = targetToPlatform(target)
def substitution = ['arch': target,
'os' : targetToOs(target)]
file("src/platform/$platform")
private ArrayList<DefFile> targetDefFiles(KonanTarget target) {
def substitution = ['arch': target.visibleName,
'os' : target.detailedName]
file("src/platform/${getVisibleName(target.family)}")
.listFiles()
.findAll { it.name.endsWith(".def") }
// The libz.a/libz.so and zlib.h are missing in raspberrypi and mips sysroots.
// Just workaround it until we have sysroots corrected.
.findAll { ! ((target == 'raspberrypi' || target == 'linux_mips32' || target == 'linux_mipsel32') && it.name == 'zlib.def') }
.findAll { ! ((target instanceof KonanTarget.RASPBERRYPI ||
target instanceof KonanTarget.LINUX_MIPS32 ||
target instanceof KonanTarget.LINUX_MIPSEL32) && it.name == 'zlib.def') }
.collect { new DefFile(it, substitution) }
}
private String targetToPlatform(String target) {
getVisibleName(new TargetManager(target).target.family)
}
private String targetToOs(String target) {
new TargetManager(target).target.detailedName
}
private String defFileToLibName(String target, String name) {
return "$target-$name".toString()
}
//#endregion
targetList.each { target ->
project.rootProject.ext.platformManager.enabled.each { target ->
def targetName = target.visibleName
ArrayList<Task> installTasks = []
targetDefFiles(target).each { df ->
def libName = defFileToLibName(target, df.name)
def libName = defFileToLibName(targetName, df.name)
konanArtifacts {
interop (libName, targets: [target]) {
interop (libName, targets: [targetName]) {
defFile df.file
artifactName df.name
noDefaultLibs true
@@ -70,21 +67,21 @@ targetList.each { target ->
}
}
def libTask = konanArtifacts."$libName"."$target"
libTask.dependsOn df.config.depends.collect{ defFileToLibName(target, it) }
libTask.dependsOn ":${target}CrossDist"
def libTask = konanArtifacts."$libName"."$targetName"
libTask.dependsOn df.config.depends.collect{ defFileToLibName(targetName, it) }
libTask.dependsOn ":${targetName}CrossDist"
task "$libName"(type: KlibInstall) {
klib = libTask.artifact
repo = file("$konanHome/klib/platform/$target")
it.target = target
repo = file("$konanHome/klib/platform/$targetName")
it.target = targetName
dependsOn libTask
}
installTasks.add(tasks[libName])
}
task "${target}Install" {
task "${targetName}Install" {
dependsOn installTasks
}
}
@@ -92,7 +89,7 @@ targetList.each { target ->
// TODO: Don't install libraries here - copy them in the distPlatformLibs task
task hostInstall {
dependsOn tasks.withType(KlibInstall.class).findAll {
new TargetManager(it.target).target == TargetManager.host
it.target == HostManager.hostName
}
}
+2 -9
View File
@@ -27,13 +27,6 @@
#define KONAN_NEED_ASINH_ACOSH 0
#endif
#if KONAN_WASM || __ZEPHYR__
#define KONAN_NO_MATH 1
#else
#define KONAN_NO_MATH 0
#endif
#ifdef KONAN_NEED_ASINH_ACOSH
namespace {
@@ -99,7 +92,7 @@ namespace {
extern "C" {
#if !KONAN_NO_MATH // There is a platform math library.
#ifndef KONAN_NO_MATH // There is a platform math library.
// region Double math.
@@ -357,6 +350,6 @@ KLong Kotlin_math_absl(KLong x) { NotImplemented(); }
KLong Kotlin_math_minl(KLong a, KLong b) { NotImplemented(); }
KLong Kotlin_math_maxl(KLong a, KLong b) { NotImplemented(); }
#endif // #if !KONAN_NO_MATH
#endif // #ifndef KONAN_NO_MATH
} // extern "C"
+46 -44
View File
@@ -32,12 +32,17 @@
#include <chrono>
#include "Common.h"
#include "Porting.h"
#if KONAN_WASM || __ZEPHYR__
#if KONAN_WASM || KONAN_ZEPHYR
extern "C" void Konan_abort(const char*);
extern "C" void Konan_exit(int32_t status);
#endif
#ifdef KONAN_ZEPHYR
// In Zephyr's Newlib strnlen(3) is not included from string.h by default.
extern "C" size_t strnlen(const char* buffer, size_t maxSize);
#endif
namespace konan {
@@ -70,9 +75,13 @@ void consoleErrorUtf8(const void* utf8, uint32_t sizeBytes) {
}
uint32_t consoleReadUtf8(void* utf8, uint32_t maxSizeBytes) {
#ifdef KONAN_ZEPHYR
return 0;
#else
char* result = ::fgets(reinterpret_cast<char*>(utf8), maxSizeBytes - 1, stdin);
if (result == nullptr) return 0;
return ::strlen(result);
#endif
}
#if KONAN_INTERNAL_SNPRINTF
@@ -124,7 +133,7 @@ static void onThreadExitInit() {
void onThreadExit(void (*destructor)()) {
#if KONAN_NO_THREADS
#if KONAN_WASM || __ZEPHYR__
#if KONAN_WASM || KONAN_ZEPHYR
// No way to do that.
#else
#error "How to do onThreadExit()?"
@@ -141,11 +150,11 @@ void onThreadExit(void (*destructor)()) {
}
// Process execution.
void abort() {
void abort(void) {
::abort();
}
#if KONAN_WASM || __ZEPHYR__
#if KONAN_WASM || KONAN_ZEPHYR
void exit(int32_t status) {
Konan_exit(status);
}
@@ -159,7 +168,7 @@ void exit(int32_t status) {
// memcpy/memmove are not here intentionally, as frequently implemented/optimized
// by C compiler.
void* memmem(const void *big, size_t bigLen, const void *little, size_t littleLen) {
#if KONAN_WINDOWS || KONAN_WASM || __ZEPHYR__
#if KONAN_NO_MEMMEM
for (size_t i = 0; i + littleLen <= bigLen; ++i) {
void* pos = ((char*)big) + i;
if (::memcmp(little, pos, littleLen) == 0) return pos;
@@ -180,11 +189,9 @@ int snprintf(char* buffer, size_t size, const char* format, ...) {
return rv;
}
#if !__ZEPHYR__
size_t strnlen(const char* buffer, size_t maxSize) {
return ::strnlen(buffer, maxSize);
}
#endif
// Memory operations.
#if KONAN_INTERNAL_DLMALLOC
@@ -207,7 +214,14 @@ void free(void* pointer) {
#if KONAN_INTERNAL_NOW
#ifdef KONAN_ZEPHYR
void Konan_date_now(uint64_t* arg) {
// TODO: so how will we support time for embedded?
*arg = 0LL;
}
#else
extern "C" void Konan_date_now(uint64_t*);
#endif
uint64_t getTimeMillis() {
uint64_t now;
@@ -243,7 +257,7 @@ uint64_t getTimeMicros() {
#if KONAN_INTERNAL_DLMALLOC
// This function is being called when memory allocator needs more RAM.
#if KONAN_WASM || __ZEPHYR__
#if KONAN_WASM
// This one is an interface to query module.env.memory.buffer.byteLength
extern "C" unsigned long Konan_heap_upper();
@@ -304,12 +318,17 @@ long getpagesize() {
} // namespace konan
extern "C" {
#if KONAN_WASM || __ZEPHYR__
// TODO: get rid of these.
// TODO: get rid of these.
#if (KONAN_WASM || KONAN_ZEPHYR)
void _ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv(void) {
Konan_abort("TODO: throw_length_error not implemented.");
}
void _ZNKSt3__220__vector_base_commonILb1EE20__throw_length_errorEv(void) {
Konan_abort("TODO: throw_length_error not implemented.");
}
void _ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv(void) {
Konan_abort("TODO: throw_length_error not implemented.");
}
void _ZNKSt3__221__basic_string_commonILb1EE20__throw_length_errorEv(void) {
Konan_abort("TODO: throw_length_error not implemented.");
}
@@ -336,6 +355,9 @@ extern "C" {
}
return prime;
}
int _ZNSt3__112__next_primeEj(unsigned long n) {
return _ZNSt3__212__next_primeEj(n);
}
void __assert_fail(const char * assertion, const char * file, unsigned int line, const char * function) {
char buf[1024];
konan::snprintf(buf, sizeof(buf), "%s:%d in %s: runtime assert: %s\n", file, line, function, assertion);
@@ -351,9 +373,10 @@ extern "C" {
double pow(double x, double y) {
return __builtin_pow(x, y);
}
#endif
#ifdef KONAN_WASM
// Some string.h functions.
void *memcpy(void *dst, const void *src, size_t n) {
for (long i = 0; i != n; ++i)
*((char*)dst + i) = *((char*)src + i);
@@ -401,60 +424,39 @@ extern "C" {
}
#endif
#if __ZEPHYR__
/* Support the alias for the __aeabi_memcpy which may
assume memory alignment. */
void __aeabi_memcpy4 (void *dest, const void *source, size_t n)
__attribute__ ((alias ("memcpy")));
void __aeabi_memcpy8 (void *dest, const void *source, size_t n)
__attribute__ ((alias ("memcpy")));
void __aeabi_memcpy (void *dest, const void *source, size_t n)
__attribute__ ((alias ("memcpy")));
/* Support the alias for the __aeabi_memmove which may
assume memory alignment. */
void __aeabi_memmove4 (void *dest, const void *source, size_t n)
__attribute__ ((alias ("memmove")));
void __aeabi_memmove8 (void *dest, const void *source, size_t n)
__attribute__ ((alias ("memmove")));
void __aeabi_memmove (void *dest, const void *source, size_t n)
__attribute__ ((alias ("memmove")));
#ifdef KONAN_ZEPHYR
RUNTIME_USED void Konan_abort(const char*) {
while(1) {}
}
/* Support the alias for the __aeabi_memset which may
assume memory alignment. */
void __aeabi_memset4 (void *dest, size_t n, int c)
RUNTIME_USED void __aeabi_memset4 (void *dest, size_t n, int c)
__attribute__ ((alias ("__aeabi_memset")));
void __aeabi_memset8 (void *dest, size_t n, int c)
RUNTIME_USED void __aeabi_memset8 (void *dest, size_t n, int c)
__attribute__ ((alias ("__aeabi_memset")));
/* Support the routine __aeabi_memset. Can't alias to memset
because it's not defined in the same translation unit. */
void __aeabi_memset (void *dest, size_t n, int c)
RUNTIME_USED void __aeabi_memset (void *dest, size_t n, int c)
{
/*Note that relative to ANSI memset, __aeabi_memset hase the order
of its second and third arguments reversed. */
memset (dest, c, n);
}
/* Support the alias for the __aeabi_memclr which may
assume memory alignment. */
void __aeabi_memclr4 (void *dest, size_t n)
RUNTIME_USED void __aeabi_memclr4 (void *dest, size_t n)
__attribute__ ((alias ("__aeabi_memclr")));
void __aeabi_memclr8 (void *dest, size_t n)
RUNTIME_USED void __aeabi_memclr8 (void *dest, size_t n)
__attribute__ ((alias ("__aeabi_memclr")));
/* Support the routine __aeabi_memclr. */
void __aeabi_memclr (void *dest, size_t n)
RUNTIME_USED void __aeabi_memclr (void *dest, size_t n)
{
__aeabi_memset (dest, n, 0);
}
#endif
#endif // KONAN_ZEPHYR
}
+1 -1
View File
@@ -32,7 +32,7 @@ void consoleErrorUtf8(const void* utf8, uint32_t sizeBytes);
uint32_t consoleReadUtf8(void* utf8, uint32_t maxSizeBytes);
// Process control.
void abort();
void abort(void);
void exit(int32_t status);
// Thread control.
+2 -2
View File
@@ -19,8 +19,8 @@
#include <stdlib.h>
#if (KONAN_WASM || __ZEPHYR__) && !defined(assert)
// assert() is needed by WASM STL.
#if (KONAN_WASM || KONAN_ZEPHYR) && !defined(assert)
// assert() is needed by STLport.
#define assert(cond) if (!(cond)) abort()
#endif
+1 -1
View File
@@ -525,7 +525,7 @@ MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP
/**** Start of Konan-specific dlmalloc configuration. ****/
#define USE_DL_PREFIX 1
#if KONAN_WASM || __ZEPHYR__
#if KONAN_WASM
#define USE_LOCKS 0
#define LACKS_TIME_H 1
#define NO_MALLOC_STATS 1
+4 -1
View File
@@ -4,4 +4,7 @@ if [ -z "$KONAN_HOME" ]; then
PATH="$DIR/../../dist/bin:$DIR/../../bin:$PATH"
else
PATH="$KONAN_HOME/bin:$PATH"
fi
fi
KONAN_USER_DIR="$HOME/.konan"
KONAN_DEPS="$KONAN_USER_DIR/dependencies"
+1 -1
View File
@@ -1,4 +1,4 @@
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(NONE)
target_sources(app PRIVATE build/program.o)
target_sources(app PRIVATE build/program.o src/main.c src/blinky.c)
+36 -7
View File
@@ -1,18 +1,47 @@
#!/usr/bin/env bash
BOARD=stm32f4_disco
#export ZEPHYR_BASE="PLEASE_SET_ZEPHYR_BASE"
export ZEPHYR_BASE=~/kotlin-native/zephyr
if [ "$ZEPHYR_BASE" == "PLEASE_SET_ZEPHYR_BASE" ] ; then
echo "Please set ZEPHYR_BASE in this build.sh."
exit 1
fi
DIR=$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$DIR/../konan.sh"
if [ x$TARGET == x ]; then
case "$OSTYPE" in
darwin*) TOOLCHAIN=gcc-arm-none-eabi-7-2017-q4-major-mac ;;
linux*) TOOLCHAIN=gcc-arm-none-eabi-7-2017-q4-major-linux ;;
*) echo "unknown: $OSTYPE" && exit 1;;
esac
fi
GCC_ARM="$KONAN_DEPS/$TOOLCHAIN"
mkdir -p $DIR/build && cd $DIR/build
konanc $DIR/src/main.kt -target zephyr
konanc $DIR/src/main.kt -target zephyr_$BOARD -linkerOpts -L$GCC_ARM/arm-none-eabi/lib/thumb -linkerOpts -lsupc++ -opt || exit 1
DEP="$HOME/.konan/dependencies"
export ZEPHYR_BASE="$DEP/zephyr-zephyr-v1.10.0"
export ZEPHYR_GCC_VARIANT=gccarmemb
export GCCARMEMB_TOOLCHAIN_PATH="$DEP/target-gcc-toolchain-6-2017q2-linux-armemb/"
export PATH="$DEP/zephyr-host-tools-1-linux/bin:$PATH"
export GCCARMEMB_TOOLCHAIN_PATH=$GCC_ARM
[ -f CMakeCache.txt ] || cmake -DBOARD=qemu_cortex_m3 ..
make run
[ -f CMakeCache.txt ] || cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DBOARD=$BOARD .. || exit 1
make || exit 1
# make flash
#
# For our STM32 boards the OpenOCD unable to flash the binary,
# so we go with the following alternative utility:
echo
echo "Now run 'make flash' to flash the .bin to the card."
echo
echo "Or, if that doesn't work, like, for example if you have an stm32f4-disco,"
echo "run the following command:"
echo "st-flash --reset write build/zephyr/zephyr.bin 0x08000000"
echo
+2 -1
View File
@@ -1,4 +1,5 @@
CONFIG_CPLUSPLUS=y
CONFIG_CPLUSPLUS=n
CONFIG_PRINTK=y
CONFIG_BOOT_BANNER=y
CONFIG_BUILD_OUTPUT_BIN=y
CONFIG_NEWLIB_LIBC=y
+36
View File
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <board.h>
#include <device.h>
#include <gpio.h>
/* Change this if you have an LED connected to a custom port */
#define PORT LED0_GPIO_PORT
/* Change this if you have an LED connected to a custom pin */
#define LED LED0_GPIO_PIN
/* 1000 msec = 1 sec */
#define SLEEP_TIME 1000
void blinky(int value)
{
int cnt = 0;
struct device *dev;
dev = device_get_binding(PORT);
/* Set LED pin as output */
gpio_pin_configure(dev, LED, GPIO_DIR_OUT);
while (1) {
/* Set pin to HIGH/LOW every 1 second */
gpio_pin_write(dev, LED, cnt % 2);
cnt++;
k_sleep(SLEEP_TIME * value);
}
}
+18
View File
@@ -0,0 +1,18 @@
/*
* 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.
*/
extern int Konan_main(int argc, const char** argv);
-13
View File
@@ -1,13 +0,0 @@
/*
* Copyright (c) 2012-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <misc/printk.h>
void main(void)
{
printk("Hello World! %s\n", CONFIG_ARCH);
}
+22 -1
View File
@@ -1,3 +1,24 @@
/*
* 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.
*/
@SymbolName("blinky")
external fun blinky(value: Int)
val x = 1
fun main(args: Array<String>) {
println("Hello World!")
blinky(x)
}
@@ -81,19 +81,20 @@ class ClangArgs(private val configurables: Configurables) : Configurables by con
"-nostdinc", "-Xclang", "-nobuiltininc", "-Xclang", "-nostdsysteminc",
"-Xclang", "-isystem$absoluteTargetSysRoot/include/libcxx", "-Xclang", "-isystem$absoluteTargetSysRoot/lib/libcxxabi/include",
"-Xclang", "-isystem$absoluteTargetSysRoot/include/compat", "-Xclang", "-isystem$absoluteTargetSysRoot/include/libc")
KonanTarget.ZEPHYR ->
listOf("-target", targetArg!!, "-mabi=aapcs", "-mthumb", "-mcpu=cortex-m3",
"-Os", "-g",
is KonanTarget.ZEPHYR ->
listOf("-target", targetArg!!,
"-fno-rtti",
"-fno-exceptions",
"-fno-asynchronous-unwind-tables",
"-fno-pie",
"-fno-pic",
"-nostdinc",
"-isystem$sysRoot/include/libcxx",
"-isystem$sysRoot/lib/libcxxabi/include",
"-isystem$sysRoot/include/compat",
"-isystem$sysRoot/include/libc")
"-isystem$absoluteTargetSysRoot/include/libcxx",
"-isystem$absoluteTargetSysRoot/lib/libcxxabi/include",
"-isystem$absoluteTargetSysRoot/include/compat",
"-isystem$absoluteTargetSysRoot/include/libc") +
(configurables as ZephyrConfigurables).boardSpecificClangFlags
}
return result
@@ -114,7 +115,7 @@ class ClangArgs(private val configurables: Configurables) : Configurables by con
listOf("-DUSE_GCC_UNWIND=1", "-DUSE_ELF_SYMBOLS=1", "-DELFSIZE=32")
KonanTarget.MINGW ->
listOf("-DUSE_GCC_UNWIND=1", "-DUSE_PE_COFF_SYMBOLS=1", "-DKONAN_WINDOWS=1")
listOf("-DUSE_GCC_UNWIND=1", "-DUSE_PE_COFF_SYMBOLS=1", "-DKONAN_WINDOWS=1", "-DKONAN_NO_MEMMEM=1")
KonanTarget.MACBOOK ->
listOf("-DKONAN_OSX=1", "-DKONAN_OBJC_INTEROP=1")
@@ -133,13 +134,16 @@ class ClangArgs(private val configurables: Configurables) : Configurables by con
KonanTarget.WASM32 ->
listOf("-DKONAN_WASM=1", "-DKONAN_NO_FFI=1", "-DKONAN_NO_THREADS=1", "-DKONAN_NO_EXCEPTIONS=1",
"-DKONAN_INTERNAL_DLMALLOC=1", "-DKONAN_INTERNAL_SNPRINTF=1", "-DKONAN_INTERNAL_NOW=1")
KonanTarget.ZEPHYR ->
listOf( "-D__ZEPHYR__=1", "-DKONAN_NO_FFI=1", "-DKONAN_NO_THREADS=1", "-DKONAN_NO_EXCEPTIONS=1",
"-DKONAN_INTERNAL_DLMALLOC=1", "-DKONAN_INTERNAL_SNPRINTF=1", "-DKONAN_INTERNAL_NOW=1")
"-DKONAN_NO_MATH=1", "-DKONAN_INTERNAL_DLMALLOC=1", "-DKONAN_INTERNAL_SNPRINTF=1",
"-DKONAN_INTERNAL_NOW=1", "-DKONAN_NO_MEMMEM")
is KonanTarget.ZEPHYR ->
listOf( "-DKONAN_ZEPHYR=1", "-DKONAN_NO_FFI=1", "-DKONAN_NO_THREADS=1", "-DKONAN_NO_EXCEPTIONS=1",
"-DKONAN_NO_MATH=1", "-DKONAN_INTERNAL_SNPRINTF=1", "-DKONAN_INTERNAL_NOW=1",
"-DKONAN_NO_MEMMEM=1")
}
private val host = TargetManager.host
private val host = HostManager.host
private val binDir = when (host) {
KonanTarget.LINUX -> "$absoluteTargetToolchain/bin"
@@ -167,7 +171,7 @@ class ClangArgs(private val configurables: Configurables) : Configurables by con
home.parentFile.absolutePath
}
val hostCompilerArgsForJni = listOf("", TargetManager.jniHostPlatformIncludeDir).map { "-I$jdkDir/include/$it" }.toTypedArray()
val hostCompilerArgsForJni = listOf("", HostManager.jniHostPlatformIncludeDir).map { "-I$jdkDir/include/$it" }.toTypedArray()
val clangArgs = (commonClangArgs + specificClangArgs).toTypedArray()
@@ -88,3 +88,8 @@ interface WasmConfigurables : NonAppleConfigurables {
val optOptFlags get() = targetList("optOptFlags")
val optDebugFlags get() = targetList("optDebugFlags")
}
interface ZephyrConfigurables : NonAppleConfigurables {
val boardSpecificClangFlags get() = targetList("boardSpecificClangFlags")
}
@@ -33,6 +33,9 @@ class MingwConfigurablesImpl(target: KonanTarget, properties: Properties, baseDi
class WasmConfigurablesImpl(target: KonanTarget, properties: Properties, baseDir: String?)
: WasmConfigurables, KonanPropertiesLoader(target, properties, baseDir)
class ZephyrConfigurablesImpl(target: KonanTarget, properties: Properties, baseDir: String?)
: ZephyrConfigurables, KonanPropertiesLoader(target, properties, baseDir)
fun loadConfigurables(target: KonanTarget, properties: Properties, baseDir: String?) = when (target) {
KonanTarget.LINUX, KonanTarget.RASPBERRYPI ->
@@ -47,5 +50,7 @@ fun loadConfigurables(target: KonanTarget, properties: Properties, baseDir: Stri
MingwConfigurablesImpl(target, properties, baseDir)
KonanTarget.WASM32 ->
WasmConfigurablesImpl(target, properties, baseDir)
is KonanTarget.ZEPHYR ->
ZephyrConfigurablesImpl(target, properties, baseDir)
}
@@ -0,0 +1,89 @@
/*
* Copyright 2010-2017 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.konan.target
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.properties.keepOnlyDefaultProfiles
import org.jetbrains.kotlin.konan.properties.loadProperties
import org.jetbrains.kotlin.konan.util.DependencyProcessor
class Distribution(
private val onlyDefaultProfiles: Boolean = false,
private val konanHomeOverride: String? = null,
private val runtimeFileOverride: String? = null) {
val localKonanDir = "${File.userHome}/.konan"
private fun findKonanHome(): String {
if (konanHomeOverride != null) return konanHomeOverride
val value = System.getProperty("konan.home", "dist")
val path = File(value).absolutePath
return path
}
val konanHome = findKonanHome()
val konanSubdir = "$konanHome/konan"
val mainPropertyFileName = "$konanSubdir/konan.properties"
private fun propertyFilesFromConfigDir(configDir: String, genericName: String): List<File> {
val directory = File(configDir, "platforms/$genericName")
return if (directory.exists && directory.isDirectory)
directory.listFiles
else
emptyList()
}
private fun preconfiguredPropertyFiles(genericName: String) =
propertyFilesFromConfigDir(konanSubdir, genericName)
private fun userPropertyFiles(genericName: String) =
propertyFilesFromConfigDir(localKonanDir, genericName)
fun additionalPropertyFiles(genericName: String) =
preconfiguredPropertyFiles(genericName) + userPropertyFiles(genericName)
val properties by lazy {
val loaded = File(mainPropertyFileName).loadProperties()
HostManager.knownTargetTemplates.forEach {
additionalPropertyFiles(it).forEach {
val additional = it.loadProperties()
loaded.putAll(additional)
}
}
if (onlyDefaultProfiles) {
loaded.keepOnlyDefaultProfiles()
}
loaded
}
val klib = "$konanHome/klib"
val stdlib = "$klib/common/stdlib"
fun defaultNatives(target: KonanTarget) = "$konanHome/konan/targets/${target.visibleName}/native"
fun runtime(target: KonanTarget) = runtimeFileOverride ?: "$stdlib/targets/${target.visibleName}/native/runtime.bc"
val dependenciesDir = DependencyProcessor.defaultDependenciesRoot.absolutePath
fun availableSubTarget(genericName: String) =
additionalPropertyFiles(genericName).map { it.name }
}
fun buildDistribution(konanHomeOverride: String? = null) = Distribution(true, konanHomeOverride, null)
fun customerDistribution(konanHomeOverride: String? = null) = Distribution(false, konanHomeOverride, null)
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.konan.util.DependencyProcessor
interface TargetableExternalStorage {
fun targetString(key: String): String?
fun targetList(key: String): List<String>
fun targetList(key: String): List<String>
fun hostString(key: String): String?
fun hostList(key: String): List<String>
fun hostTargetString(key: String): String?
@@ -50,6 +50,7 @@ abstract class KonanPropertiesLoader(override val target: KonanTarget, val prope
= properties.hostTargetString(key, target)
override fun hostTargetList(key: String): List<String>
= properties.hostTargetList(key, target)
override fun absolute(value: String?): String =
dependencyProcessor!!.resolveRelative(value!!).absolutePath
private val dependencyProcessor by lazy {
@@ -57,3 +58,16 @@ abstract class KonanPropertiesLoader(override val target: KonanTarget, val prope
}
}
fun Properties.keepOnlyDefaultProfiles() {
val DEPENDENCY_PROFILES_KEY = "dependencyProfiles"
val dependencyProfiles = this.getProperty(DEPENDENCY_PROFILES_KEY)
if (dependencyProfiles != "default alt")
error("unexpected $DEPENDENCY_PROFILES_KEY value: expected 'default alt', got '$dependencyProfiles'")
// Force build to use only 'default' profile:
this.setProperty(DEPENDENCY_PROFILES_KEY, "default")
// Force build to use fixed Xcode version:
this.setProperty("useFixedXcodeVersion", "9.2")
// TODO: it actually affects only resolution made in :dependencies,
// that's why we assume that 'default' profile comes first (and check this above).
}
@@ -16,9 +16,8 @@
package org.jetbrains.kotlin.konan.target
import org.jetbrains.kotlin.konan.util.visibleName
import org.jetbrains.kotlin.konan.util.Named
import org.jetbrains.kotlin.konan.target.KonanTarget.*
import org.jetbrains.kotlin.konan.util.Named
enum class Family(val exeSuffix:String, val dynamicPrefix: String, val dynamicSuffix: String) {
OSX ("kexe", "lib", "dylib"),
@@ -39,7 +38,7 @@ enum class Architecture(val bitness: Int) {
WASM32(32);
}
sealed class KonanTarget(override val name: String, val family: Family, val architecture: Architecture, val detailedName: String, var enabled: Boolean = false) : Named {
sealed class KonanTarget(override val name: String, val family: Family, val architecture: Architecture, val detailedName: String) : Named {
object ANDROID_ARM32 : KonanTarget( "android_arm32", Family.ANDROID, Architecture.ARM32, "android_arm32")
object ANDROID_ARM64 : KonanTarget( "android_arm64", Family.ANDROID, Architecture.ARM64, "android_arm64")
object IPHONE : KonanTarget( "iphone", Family.IOS, Architecture.ARM64, "ios")
@@ -51,23 +50,9 @@ sealed class KonanTarget(override val name: String, val family: Family, val arch
object LINUX_MIPS32 : KonanTarget( "linux_mips32", Family.LINUX, Architecture.MIPS32, "linux_mips32")
object LINUX_MIPSEL32 : KonanTarget( "linux_mipsel32", Family.LINUX, Architecture.MIPSEL32, "linux_mipsel32")
object WASM32 : KonanTarget( "wasm32", Family.WASM, Architecture.WASM32, "wasm32")
// Tunable targets
class ZEPHYR(val subName: String) : KonanTarget("$zephyr_$subName", Family.ZEPHYR, Architecture.ARM32, "$zephyr_$subName")
companion object {
protected val memberObjects = mutableListOf<KonanTarget>()
fun values() = memberObjects
}
init {
memberObjects.add(this)
}
fun generateZephyrTargets(subtargets: List<String>) {
subtargets.forEach {
object : ZEPHYR(it)
}
}
class ZEPHYR(val subName: String, val genericName: String = "zephyr") : KonanTarget("${genericName}_$subName", Family.ZEPHYR, Architecture.ARM32, "${genericName}_$subName")
}
fun hostTargetSuffix(host: KonanTarget, target: KonanTarget) =
@@ -95,12 +80,61 @@ enum class CompilerOutputKind {
open fun prefix(target: KonanTarget? = null): String = ""
}
class TargetManager(val userRequest: String? = null) {
val targets = KonanTarget.values().associate{ it.visibleName to it }
val target = determineCurrent()
val targetName
interface TargetManager {
val target: KonanTarget
val targetName : String
fun list() : Unit
val hostTargetSuffix: String
val targetSuffix: String
}
private class TargetManagerImpl(val userRequest: String?, val hostManager: HostManager): TargetManager {
override val target = determineCurrent()
override val targetName
get() = target.visibleName
override fun list() {
hostManager.enabled.forEach {
val isDefault = if (it == target) "(default)" else ""
println(String.format("%1$-30s%2$-10s", "${it.visibleName}:", "$isDefault"))
}
}
fun determineCurrent(): KonanTarget {
return if (userRequest == null || userRequest == "host") {
HostManager.host
} else {
hostManager.targets[hostManager.known(userRequest)]!!
}
}
override val hostTargetSuffix get() = hostTargetSuffix(HostManager.host, target)
override val targetSuffix get() = target.detailedName
}
open class HostManager internal constructor(protected val distribution: Distribution = Distribution()) {
fun targetManager(userRequest: String? = null): TargetManager = TargetManagerImpl(userRequest, this)
// TODO: need a better way to enumerated predefined targets.
private val predefinedTargets = listOf(ANDROID_ARM32, ANDROID_ARM64, IPHONE, IPHONE_SIM, LINUX, MINGW, MACBOOK, RASPBERRYPI, LINUX_MIPS32, LINUX_MIPSEL32, WASM32)
private val zephyrSubtargets = distribution.availableSubTarget("zephyr").map { ZEPHYR(it) }
private val configurableSubtargets = zephyrSubtargets
val targetValues: List<KonanTarget> by lazy {
predefinedTargets + configurableSubtargets
}
val targets = targetValues.associate{ it.visibleName to it }
fun toKonanTargets(names: Iterable<String>): List<KonanTarget> {
return names.map {
if (it == "host") HostManager.host
else targets[known(it)]!!
}
}
fun known(name: String): String {
if (targets[name] == null) {
@@ -109,28 +143,44 @@ class TargetManager(val userRequest: String? = null) {
return name
}
fun list() {
targets.forEach { key, it ->
if (it.enabled) {
val isDefault = if (it == target) "(default)" else ""
println(String.format("%1$-30s%2$-10s", "$key:", "$isDefault"))
}
}
fun targetByName(name: String): KonanTarget {
if (name == "host") return host
val target = targets[name]
if (target == null) throw TargetSupportException("Unknown target name: $name")
return target
}
fun determineCurrent(): KonanTarget {
return if (userRequest == null || userRequest == "host") {
host
} else {
targets[known(userRequest)]!!
}
val enabled: List<KonanTarget> by lazy {
when (host) {
KonanTarget.LINUX -> listOf(
KonanTarget.LINUX,
KonanTarget.RASPBERRYPI,
KonanTarget.LINUX_MIPS32,
KonanTarget.LINUX_MIPSEL32,
KonanTarget.ANDROID_ARM32,
KonanTarget.ANDROID_ARM64,
KonanTarget.WASM32
) + zephyrSubtargets
KonanTarget.MINGW -> listOf(
KonanTarget.MINGW,
KonanTarget.WASM32
)
KonanTarget.MACBOOK -> listOf(
KonanTarget.MACBOOK,
KonanTarget.IPHONE,
KonanTarget.IPHONE_SIM,
KonanTarget.ANDROID_ARM32,
KonanTarget.ANDROID_ARM64,
KonanTarget.WASM32
) + zephyrSubtargets
else ->
throw TargetSupportException("Unknown host platform: $host")
}
}
val hostTargetSuffix get() = hostTargetSuffix(host, target)
val targetSuffix get() = target.detailedName
fun isEnabled(target: KonanTarget) = enabled.contains(target)
companion object {
fun host_os(): String {
val javaOsName = System.getProperty("os.name")
return when {
@@ -180,46 +230,16 @@ class TargetManager(val userRequest: String? = null) {
else -> throw TargetSupportException("Unknown host target: ${host_os()} ${host_arch()}")
}
val hostIsMac = (host == KonanTarget.MACBOOK)
val hostIsLinux = (host == KonanTarget.LINUX)
val hostIsMingw = (host == KonanTarget.MINGW)
val hostSuffix get() = host.detailedName
@JvmStatic
val hostName get() = host.visibleName
init {
when (host) {
KonanTarget.LINUX -> {
KonanTarget.LINUX.enabled = true
/*KonanTarget.RASPBERRYPI.enabled = true
KonanTarget.LINUX_MIPS32.enabled = true
KonanTarget.LINUX_MIPSEL32.enabled = true
KonanTarget.ANDROID_ARM32.enabled = true
KonanTarget.ANDROID_ARM64.enabled = true
KonanTarget.WASM32.enabled = true*/
KonanTarget.ZEPHYR.enabled = true
}
KonanTarget.MINGW -> {
KonanTarget.MINGW.enabled = true
KonanTarget.WASM32.enabled = true
}
KonanTarget.MACBOOK -> {
KonanTarget.MACBOOK.enabled = true
KonanTarget.IPHONE.enabled = true
KonanTarget.IPHONE_SIM.enabled = true
KonanTarget.ANDROID_ARM32.enabled = true
KonanTarget.ANDROID_ARM64.enabled = true
KonanTarget.WASM32.enabled = true
}
else ->
throw TargetSupportException("Unknown host platform: $host")
}
}
val knownTargetTemplates = listOf("zephyr")
@JvmStatic
val enabled: List<KonanTarget>
get() = KonanTarget.values().filter { it.enabled }
val hostIsMac = (host == KonanTarget.MACBOOK)
val hostIsLinux = (host == KonanTarget.LINUX)
val hostIsMingw = (host == KonanTarget.MINGW)
}
}
@@ -33,7 +33,7 @@ abstract class LinkerFlags(val configurables: Configurables)
protected val llvmBin = "${configurables.absoluteLlvmHome}/bin"
protected val llvmLib = "${configurables.absoluteLlvmHome}/lib"
private val libLTODir = when (TargetManager.host) {
private val libLTODir = when (HostManager.host) {
KonanTarget.MACBOOK, KonanTarget.LINUX -> llvmLib
KonanTarget.MINGW -> llvmBin
else -> error("Don't know libLTO location for this platform.")
@@ -288,7 +288,7 @@ open class WasmLinker(targetProperties: WasmConfigurables)
open class ZephyrLinker(targetProperties: ZephyrConfigurables)
: LinkerFlags(targetProperties), ZephyrConfigurables by targetProperties {
private val linker = "$targetToolchain/bin/ld"
private val linker = "$absoluteTargetToolchain/bin/ld"
override val useCompilerDriverAsLinker: Boolean get() = false
@@ -318,5 +318,7 @@ fun linker(configurables: Configurables): LinkerFlags =
MingwLinker(configurables as MingwConfigurables)
KonanTarget.WASM32 ->
WasmLinker(configurables as WasmConfigurables)
is KonanTarget.ZEPHYR ->
ZephyrLinker(configurables as ZephyrConfigurables)
}
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.konan.target
import org.jetbrains.kotlin.konan.properties.*
import org.jetbrains.kotlin.konan.util.DependencyProcessor
class Platform(val configurables: Configurables)
: Configurables by configurables {
@@ -29,13 +29,19 @@ class Platform(val configurables: Configurables)
}
}
class PlatformManager(properties: Properties, baseDir: String) {
private val host = TargetManager.host
private val platforms = TargetManager.enabled.map {
it to Platform(loadConfigurables(it, properties, baseDir))
class PlatformManager(distribution: Distribution = Distribution()) : HostManager(distribution) {
private val loaders = enabled.map {
it to loadConfigurables(it, distribution.properties, DependencyProcessor.defaultDependenciesRoot.absolutePath)
}.toMap()
private val platforms = loaders.map {
it.key to Platform(it.value)
}.toMap()
fun platform(target: KonanTarget) = platforms[target]!!
val hostPlatform = platforms[host]!!
fun loader(target: KonanTarget) = loaders[target]!!
}
@@ -19,10 +19,10 @@ package org.jetbrains.kotlin.konan.properties
import org.jetbrains.kotlin.konan.target.*
fun Properties.hostString(name: String): String?
= this.propertyString(name, TargetManager.host.detailedName)
= this.propertyString(name, HostManager.host.detailedName)
fun Properties.hostList(name: String): List<String>
= this.propertyList(name, TargetManager.host.detailedName)
= this.propertyList(name, HostManager.host.detailedName)
fun Properties.targetString(name: String, target: KonanTarget): String?
= this.propertyString(name, target.detailedName)
@@ -31,7 +31,7 @@ fun Properties.targetList(name: String, target: KonanTarget): List<String>
= this.propertyList(name, target.detailedName)
fun Properties.hostTargetString(name: String, target: KonanTarget): String?
= this.propertyString(name, hostTargetSuffix(TargetManager.host, target))
= this.propertyString(name, hostTargetSuffix(HostManager.host, target))
fun Properties.hostTargetList(name: String, target: KonanTarget): List<String>
= this.propertyList(name, hostTargetSuffix(TargetManager.host, target))
= this.propertyList(name, hostTargetSuffix(HostManager.host, target))
@@ -27,9 +27,8 @@ import org.gradle.api.plugins.BasePlugin
import org.gradle.internal.reflect.Instantiator
import org.gradle.util.ConfigureUtil
import org.jetbrains.kotlin.gradle.plugin.tasks.KonanBuildingTask
import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.target.TargetManager
import org.jetbrains.kotlin.konan.util.visibleName
import java.io.File
/** Base class for all Kotlin/Native artifacts. */
@@ -47,11 +46,11 @@ abstract class KonanBuildingConfig<T: KonanBuildingTask>(private val name_: Stri
internal val aggregateBuildTask: Task
private val konanTargets: Iterable<KonanTarget>
get() = targets.map { TargetManager(it).target }.distinct()
get() = project.platformManager.toKonanTargets(targets).distinct()
init {
for (target in konanTargets) {
if (!target.enabled) {
if (!project.platformManager.isEnabled(target)) {
project.logger.warn("The target is not enabled on the current host: ${target.visibleName}")
continue
}
@@ -109,7 +108,7 @@ abstract class KonanBuildingConfig<T: KonanBuildingTask>(private val name_: Stri
}
protected fun createHostTaskIfDeclared(): Task? =
this[TargetManager.host]?.let { hostBuild ->
this[HostManager.host]?.let { hostBuild ->
project.tasks.create(generateHostTaskName()) {
it.group = BasePlugin.BUILD_GROUP
it.description = generateHostTaskDescription(it, hostBuild.konanTarget)
@@ -120,7 +119,7 @@ abstract class KonanBuildingConfig<T: KonanBuildingTask>(private val name_: Stri
internal operator fun get(target: KonanTarget) = targetToTask[target]
fun getByTarget(target: String) = findByTarget(target) ?: throw NoSuchElementException("No such target for artifact $name: ${target}")
fun findByTarget(target: String) = this[TargetManager(target).target]
fun findByTarget(target: String) = this[project.platformManager.targetByName(target)]
fun getArtifactByTarget(target: String) = getByTarget(target).artifact
fun findArtifactByTarget(target: String) = findByTarget(target)?.artifact
@@ -145,9 +144,9 @@ abstract class KonanBuildingConfig<T: KonanBuildingTask>(private val name_: Stri
fun dependsOn(vararg dependencies: Any?) = forEach { it.dependsOn(*dependencies) }
fun target(targetString: String, configureAction: T.() -> Unit) {
val target = TargetManager(targetString).target
val target = project.platformManager.targetByName(targetString)
if (!target.enabled) {
if (!project.platformManager.isEnabled(target)) {
project.logger.warn("Target '$targetString' of artifact '$name' is not supported on the current host")
return
}
@@ -24,8 +24,8 @@ import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import org.jetbrains.kotlin.gradle.plugin.KonanPlugin.Companion.COMPILE_ALL_TASK_NAME
import org.jetbrains.kotlin.gradle.plugin.tasks.*
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.target.TargetManager
import org.jetbrains.kotlin.konan.util.visibleName
import org.jetbrains.kotlin.konan.target.PlatformManager
import org.jetbrains.kotlin.konan.target.customerDistribution
import java.io.File
import java.util.*
import javax.inject.Inject
@@ -74,8 +74,14 @@ internal val Project.konanArtifactsContainer: NamedDomainObjectContainer<KonanBu
get() = extensions.getByName(KonanPlugin.ARTIFACTS_CONTAINER_NAME)
as NamedDomainObjectContainer<KonanBuildingConfig<*>>
internal val Project.platformManager: PlatformManager
get() = findProperty("platformManager") as PlatformManager? ?:
PlatformManager(customerDistribution(konanHome))
internal val Project.konanTargets: List<KonanTarget>
get() = konanExtension.konanTargets
get() = platformManager.toKonanTargets(konanExtension.targets)
.filter{ platformManager.isEnabled(it) }
.distinct()
@Suppress("UNCHECKED_CAST")
internal val Project.konanExtension: KonanExtension
@@ -227,11 +233,7 @@ open class KonanExtension {
var targets = mutableListOf("host")
var languageVersion: String? = null
var apiVersion: String? = null
val jvmArgs = mutableListOf<String>()
internal val konanTargets: List<KonanTarget>
get() = targets.map { TargetManager(it).target }.distinct()
}
class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderRegistry)
@@ -28,16 +28,16 @@ import org.gradle.util.ConfigureUtil
import org.jetbrains.kotlin.gradle.plugin.KonanArtifactSpec
import org.jetbrains.kotlin.gradle.plugin.KonanArtifactWithLibrariesSpec
import org.jetbrains.kotlin.gradle.plugin.KonanLibrariesSpec
import org.jetbrains.kotlin.gradle.plugin.konanTargets
import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.target.TargetManager
import org.jetbrains.kotlin.konan.util.visibleName
import java.io.File
internal val Project.host
get() = TargetManager.host.visibleName
get() = HostManager.host.visibleName
internal val Project.simpleOsName
get() = TargetManager.simpleOsName()
get() = HostManager.simpleOsName()
/** A task with a KonanTarget specified. */
abstract class KonanTargetableTask: DefaultTask() {
@@ -48,11 +48,8 @@ abstract class KonanTargetableTask: DefaultTask() {
this.konanTarget = target
}
val targetIsSupported: Boolean
@Internal get() = konanTarget.enabled
val isCrossCompile: Boolean
@Internal get() = (konanTarget != TargetManager.host)
@Internal get() = (konanTarget != HostManager.host)
val target: String
@Internal get() = konanTarget.visibleName
@@ -75,7 +75,7 @@ open class KonanCompilerDownloadTask : DefaultTask() {
// Download dependencies if a user said so.
if (downloadDependencies) {
val runner = KonanCompilerRunner(project)
project.konanExtension.konanTargets.forEach {
project.konanTargets.forEach {
runner.run("--check_dependencies", "-target", it.visibleName)
}
}
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.gradle.plugin.KonanLibrary
import org.jetbrains.kotlin.gradle.plugin.KonanProgram
import org.jetbrains.kotlin.gradle.plugin.konanArtifactsContainer
import org.jetbrains.kotlin.konan.target.Family
import org.jetbrains.kotlin.konan.target.TargetManager
import org.jetbrains.kotlin.konan.target.HostManager
import java.io.File
open class KonanGenerateCMakeTask : DefaultTask() {
@@ -48,6 +48,8 @@ open class KonanGenerateCMakeTask : DefaultTask() {
.mkdir()
}
private val host = HostManager.host
private fun generateCMakeLists(
projectName: String,
interops: List<KonanInteropLibrary>,
@@ -67,7 +69,7 @@ open class KonanGenerateCMakeTask : DefaultTask() {
appendln()
for (interop in interops) {
val task = interop[TargetManager.host] ?: continue
val task = interop[host] ?: continue
appendln(
Call("cinterop")
.arg("NAME", interop.name)
@@ -77,7 +79,7 @@ open class KonanGenerateCMakeTask : DefaultTask() {
}
for (library in libraries) {
val task = library[TargetManager.host] ?: continue
val task = library[host] ?: continue
appendln(
Call("konanc_library")
.arg("NAME", library.name)
@@ -87,7 +89,7 @@ open class KonanGenerateCMakeTask : DefaultTask() {
}
for (program in programs) {
val task = program[TargetManager.host] ?: continue
val task = program[host] ?: continue
appendln(
Call("konanc_executable")
.arg("NAME", program.name)
@@ -101,7 +103,7 @@ open class KonanGenerateCMakeTask : DefaultTask() {
private val File.relativePath get() = relativeTo(project.projectDir)
private val String.crossPlatformPath get() =
if (TargetManager.host.family == Family.WINDOWS) replace('\\', '/') else this
if (host.family == Family.WINDOWS) replace('\\', '/') else this
private val FileCollection.asCMakeSourceList: List<String>
get() = files.map { it.relativePath.toString().crossPlatformPath }
@@ -62,8 +62,6 @@ open class KonanInteropTask: KonanBuildingTask(), KonanInteropSpec {
@InputFiles val linkFiles = mutableSetOf<FileCollection>()
override fun buildArgs() = mutableListOf<String>().apply {
addArg("-properties", "${project.konanHome}/konan/konan.properties")
addArg("-o", artifact.canonicalPath)
addArgIfNotNull("-target", konanTarget.visibleName)
@@ -1,14 +1,14 @@
package org.jetbrains.kotlin.gradle.plugin.test
import org.jetbrains.kotlin.konan.target.Family
import org.jetbrains.kotlin.konan.target.TargetManager
import org.jetbrains.kotlin.konan.target.HostManager
class CMakeSpecification extends BaseKonanSpecification {
def 'Plugin should generate CMake from project without additional settings'() {
when:
def sdlIncludePath
def sdlLinkOptions
switch (TargetManager.host.family) {
switch (HostManager.host.family) {
case Family.WINDOWS:
sdlIncludePath = "C:/SDL2/include"
sdlLinkOptions = "C:/SDL2/lib"
@@ -22,7 +22,7 @@ class CMakeSpecification extends BaseKonanSpecification {
sdlLinkOptions = "-L/usr/lib/x86_64-linux-gnu"
break
default:
throw IllegalStateException("Unknown host: $TargetManager.host")
throw IllegalStateException("Unknown host: ${HostManager.hostName}")
break
}
@@ -1,7 +1,7 @@
package org.jetbrains.kotlin.gradle.plugin.test
import org.gradle.testkit.runner.GradleRunner
import org.jetbrains.kotlin.konan.target.TargetManager
import org.jetbrains.kotlin.konan.target.HostManager
import java.nio.file.Files
import java.nio.file.Path
@@ -25,7 +25,7 @@ class KonanProject {
static String DEFAULT_ARTIFACT_NAME = 'main'
static String DEFAULT_INTEROP_NAME = "stdio"
static String HOST = TargetManager.hostName
static String HOST = HostManager.hostName
File projectDir
Path projectPath
@@ -1,7 +1,7 @@
package org.jetbrains.kotlin.gradle.plugin.test
import org.gradle.testkit.runner.TaskOutcome
import org.jetbrains.kotlin.konan.target.TargetManager
import org.jetbrains.kotlin.konan.target.PlatformManager
class PathSpecification extends BaseKonanSpecification {
@@ -9,14 +9,13 @@ class PathSpecification extends BaseKonanSpecification {
project.konanBuildDir.toPath().resolve(path).toFile().exists()
}
def platformManager = new PlatformManager()
def 'Plugin should provide a correct path to the artifacts created'() {
expect:
def project = KonanProject.createEmpty(
projectDirectory,
new TargetManager('host')
.getTargets()
.findAll { k, v -> v.enabled }
.collect { k, v -> k }
platformManager.enabled.collect { t -> t.visibleName }
) { KonanProject it ->
it.generateSrcFile("main.kt")
it.generateDefFile("interop.def", "")
@@ -71,9 +70,10 @@ class PathSpecification extends BaseKonanSpecification {
def project = KonanProject.create(projectDirectory)
project.propertiesFile.write("konan.home=fakepath")
def result = project.createRunner().withArguments('build').buildAndFail()
def task = result.task(project.defaultCompilationTask())
then:
result.task(project.defaultCompilationTask()).outcome == TaskOutcome.FAILED
task == null || task.outcome == TaskOutcome.FAILED
}
def 'Plugin should stop building if the stub generator classpath is empty'() {
@@ -81,9 +81,10 @@ class PathSpecification extends BaseKonanSpecification {
def project = KonanProject.createWithInterop(projectDirectory)
project.propertiesFile.write("konan.home=fakepath")
def result = project.createRunner().withArguments('build').buildAndFail()
def task = result.task(project.compilationTask(KonanProject.DEFAULT_INTEROP_NAME))
then:
result.task(project.compilationTask(KonanProject.DEFAULT_INTEROP_NAME)).outcome == TaskOutcome.FAILED
task == null || task.outcome == TaskOutcome.FAILED
}
def 'Plugin should remove custom output directories'() {
@@ -3,7 +3,7 @@ package org.jetbrains.kotlin.gradle.plugin.test
import org.gradle.testkit.runner.BuildResult
import org.gradle.testkit.runner.TaskOutcome
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.target.TargetManager
import org.jetbrains.kotlin.konan.target.HostManager
import spock.lang.Requires
import spock.lang.Unroll
@@ -58,7 +58,7 @@ class TaskSpecification extends BaseKonanSpecification {
"includeDirs" | ""
}
@Requires({ TargetManager.host == KonanTarget.MACBOOK })
@Requires({ HostManager.host instanceof KonanTarget.MACBOOK })
def 'Plugin should create framework tasks only for Apple targets'() {
when:
def project = KonanProject.createEmpty(projectDirectory) { KonanProject it ->
@@ -91,7 +91,7 @@ class TaskSpecification extends BaseKonanSpecification {
""".stripIndent())
}
def result = project.createRunner().withArguments('tasks', '--all').build()
def hostName = TargetManager.getHostName()
def hostName = HostManager.hostName
then:
compilationTaskExists (result, 'defaultTarget', hostName)
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.backend.konan.library.impl.KonanLibrary
import org.jetbrains.kotlin.backend.konan.library.resolveLibrariesRecursive
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.properties.loadProperties
import org.jetbrains.kotlin.konan.target.TargetManager
import org.jetbrains.kotlin.konan.target.PlatformManager
import org.jetbrains.kotlin.native.interop.gen.jvm.interop
import org.jetbrains.kotlin.utils.addIfNotNull
@@ -35,7 +35,7 @@ fun invokeInterop(flavor: String, args: Array<String>): Array<String> {
val cinteropArgFilter = listOf(NODEFAULTLIBS, PURGE_USER_LIBS)
var outputFileName = "nativelib"
var target = "host"
var targetRequest = "host"
val libraries = mutableListOf<String>()
val repos = mutableListOf<String>()
var noDefaultLibs = false
@@ -46,7 +46,7 @@ fun invokeInterop(flavor: String, args: Array<String>): Array<String> {
if (arg.startsWith("-o"))
outputFileName = nextArg ?: outputFileName
if (arg == "-target")
target = nextArg ?: target
targetRequest = nextArg ?: targetRequest
if (arg == "-library")
libraries.addIfNotNull(nextArg)
if (arg == "-r" || arg == "-repo")
@@ -64,10 +64,10 @@ fun invokeInterop(flavor: String, args: Array<String>): Array<String> {
val cstubsName ="cstubs"
val manifest = File(buildDir, "manifest.properties")
val targetManager = TargetManager(target)
val resolver = defaultResolver(repos, targetManager.target)
val target = PlatformManager().targetManager(targetRequest).target
val resolver = defaultResolver(repos, target)
val allLibraries = resolver.resolveLibrariesRecursive(
libraries, targetManager.target, noStdLib = true, noDefaultLibs = noDefaultLibs
libraries, target, noStdLib = true, noDefaultLibs = noDefaultLibs
)
val importArgs = allLibraries.flatMap {
@@ -104,7 +104,7 @@ fun invokeInterop(flavor: String, args: Array<String>): Array<String> {
generatedDir.path,
"-produce", "library",
"-o", outputFileName,
"-target", target,
"-target", target.visibleName,
"-manifest", manifest.path) +
nativeStubs +
cinteropArgsToCompiler +