A configurable zephyr board support.
This commit is contained in:
committed by
alexander-gorshenev
parent
d968fafec0
commit
9789420ed3
-3
@@ -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")
|
||||
|
||||
+8
-17
@@ -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,
|
||||
|
||||
-2
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
+1
-1
@@ -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()
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
|
||||
-49
@@ -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
|
||||
}
|
||||
+13
-14
@@ -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> =
|
||||
|
||||
-2
@@ -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>>
|
||||
|
||||
+26
-8
@@ -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) {
|
||||
|
||||
+4
-6
@@ -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
|
||||
)
|
||||
|
||||
+14
-2
@@ -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"
|
||||
}
|
||||
|
||||
+1
-1
@@ -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()
|
||||
|
||||
+3
-3
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
-5
@@ -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)!!
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+2
-2
@@ -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
@@ -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 {
|
||||
|
||||
Vendored
+11
-15
@@ -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
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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,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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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))
|
||||
+7
-8
@@ -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
|
||||
}
|
||||
|
||||
+9
-7
@@ -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)
|
||||
|
||||
+5
-8
@@ -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
|
||||
|
||||
+1
-1
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+7
-5
@@ -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 }
|
||||
|
||||
-2
@@ -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)
|
||||
|
||||
+3
-3
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
+8
-7
@@ -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
-3
@@ -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 +
|
||||
|
||||
Reference in New Issue
Block a user