From 55c4966203d998a4e52e004e99b8591c98bf6a16 Mon Sep 17 00:00:00 2001 From: Alexander Gorshenev Date: Thu, 6 Jul 2017 12:39:02 +0300 Subject: [PATCH] Moved clang flags out of the root build.gardle. Collected clang args in ClangArgs.kt Switched dependencies/build.gradle to KonanTarget. Introduced KonanProperties to take care of target specific properties. --- Interop/Runtime/build.gradle | 3 +- backend.native/build.gradle | 6 +- .../kotlin/backend/konan/Distribution.kt | 28 +-- .../kotlin/backend/konan/KonanConfig.kt | 2 +- .../kotlin/backend/konan/LinkStage.kt | 67 ++++---- .../kotlin/backend/konan/ir/KonanIr.kt | 4 +- .../backend/konan/library/KonanLibrary.kt | 2 +- .../konan/library/SearchPathResolver.kt | 2 +- .../konan/library/impl/KonanLibrary.kt | 3 +- .../library/impl/KonanLibraryReaderImpl.kt | 6 +- .../library/impl/KonanLibraryWriterImpl.kt | 3 +- .../konan/library/impl/MetadataWriterImpl.kt | 2 +- .../kotlin/backend/konan/llvm/DebugUtils.kt | 2 +- backend.native/konan.properties | 1 + build.gradle | 161 +++--------------- .../jetbrains/kotlin/CompileToBitcode.groovy | 57 ++----- .../org/jetbrains/kotlin/ExecClang.groovy | 5 +- .../kotlin/NativeInteropPlugin.groovy | 2 +- common/build.gradle | 3 +- dependencies/build.gradle | 78 +++------ .../org/jetbrains/kotlin/cli/klib/main.kt | 2 +- runtime/build.gradle | 4 +- .../kotlin/konan/target/ClangArgs.kt | 103 +++++++++++ .../kotlin/konan/target/ClangCross.kt | 43 +++++ .../kotlin/konan/target/KonanProperties.kt | 72 ++++++++ .../kotlin/konan/target/KonanTarget.kt | 93 ++++++---- .../kotlin/konan/target}/Properties.kt | 6 +- .../kotlin/konan/target}/TargetProperties.kt | 8 +- .../kotlin}/konan/util/NoJavaUtil.kt | 5 +- .../jetbrains/kotlin/cli/utilities/main.kt | 2 +- 30 files changed, 432 insertions(+), 343 deletions(-) create mode 100644 shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/ClangArgs.kt create mode 100644 shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/ClangCross.kt create mode 100644 shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/KonanProperties.kt rename {backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/util => shared/src/main/kotlin/org/jetbrains/kotlin/konan/target}/Properties.kt (91%) rename {backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/util => shared/src/main/kotlin/org/jetbrains/kotlin/konan/target}/TargetProperties.kt (75%) rename {backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend => shared/src/main/kotlin/org/jetbrains/kotlin}/konan/util/NoJavaUtil.kt (98%) diff --git a/Interop/Runtime/build.gradle b/Interop/Runtime/build.gradle index 1169039959a..d21435bddb3 100644 --- a/Interop/Runtime/build.gradle +++ b/Interop/Runtime/build.gradle @@ -35,7 +35,8 @@ model { include '**/*.c' } binaries.all { - def host = rootProject.ext.host + def host = rootProject.ext.hostName + def hostLibffiDir = rootProject.ext.get("${host}LibffiDir") cCompiler.args hostCompilerArgsForJni diff --git a/backend.native/build.gradle b/backend.native/build.gradle index 1ce8f5cfef0..978696fdadd 100644 --- a/backend.native/build.gradle +++ b/backend.native/build.gradle @@ -106,7 +106,7 @@ kotlinNativeInterop { compilerOpts '-fPIC' linkerOpts '-fPIC' linker 'clang++' - linkOutputs ":common:${host}Hash" + linkOutputs ":common:${hostName}Hash" headers fileTree('../common/src/hash/headers') { include '**/*.h' @@ -148,8 +148,8 @@ build.dependsOn 'compilerClasses','cli_bcClasses','bc_frontendClasses' // These are just a couple of aliases -task stdlib(dependsOn: "${host}Stdlib") -task start(dependsOn: "${host}Start") +task stdlib(dependsOn: "${hostName}Stdlib") +task start(dependsOn: "${hostName}Start") // These files are built before the 'dist' is complete, // so we provide custom values for diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Distribution.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Distribution.kt index a1ddb3e1f85..c1628ddb8ba 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Distribution.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Distribution.kt @@ -17,7 +17,8 @@ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.konan.target.* -import org.jetbrains.kotlin.backend.konan.util.* +import org.jetbrains.kotlin.konan.file.* +import org.jetbrains.kotlin.konan.properties.* class Distribution(val targetManager: TargetManager, val propertyFileOverride: String? = null, @@ -25,7 +26,8 @@ class Distribution(val targetManager: TargetManager, val target = targetManager.target val targetName = targetManager.targetName - val hostSuffix = targetManager.hostSuffix + val host = TargetManager.host + val hostSuffix = TargetManager.hostSuffix val hostTargetSuffix = targetManager.hostTargetSuffix val targetSuffix = targetManager.targetSuffix @@ -42,23 +44,23 @@ class Distribution(val targetManager: TargetManager, val properties = File(propertyFileName).loadProperties() val klib = "$konanHome/klib" - - val dependenciesDir = "$konanHome/dependencies" - val dependencies = properties.propertyList("dependencies.$hostTargetSuffix") - val stdlib = "$klib/stdlib" val runtime = runtimeFileOverride ?: "$stdlib/targets/${targetName}/native/runtime.bc" - val llvmHome = "$dependenciesDir/${properties.propertyString("llvmHome.$hostSuffix")}" - val hostSysRoot = "$dependenciesDir/${properties.propertyString("targetSysRoot.$hostSuffix")}" - val targetSysRoot = "$dependenciesDir/${properties.propertyString("targetSysRoot.$targetSuffix")}" - val targetToolchain = "$dependenciesDir/${properties.propertyString("targetToolchain.$hostTargetSuffix")}" - val libffi = - "$dependenciesDir/${properties.propertyString("libffiDir.$targetSuffix")}/lib/libffi.a" + val dependenciesDir = "$konanHome/dependencies" + val targetProperties = KonanProperties(target, properties, dependenciesDir) + val hostProperties = if (target == host) { + targetProperties + } else { + KonanProperties(host, properties, dependenciesDir) + } + val dependencies = targetProperties.hostTargetList("dependencies") + + val llvmHome = hostProperties.absoluteLlvmHome + val hostSysRoot = hostProperties.absoluteTargetSysRoot val llvmBin = "$llvmHome/bin" val llvmLib = "$llvmHome/lib" - val llvmLto = "$llvmBin/llvm-lto" private val libLTODir = when (TargetManager.host) { diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt index ef8f96c85cf..512954e5523 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt @@ -20,7 +20,6 @@ import com.intellij.openapi.project.Project import org.jetbrains.kotlin.backend.konan.library.KonanLibraryReader import org.jetbrains.kotlin.backend.konan.library.KonanLibrarySearchPathResolver import org.jetbrains.kotlin.backend.konan.library.impl.LibraryReaderImpl -import org.jetbrains.kotlin.backend.konan.util.File import org.jetbrains.kotlin.backend.konan.util.profile import org.jetbrains.kotlin.backend.konan.util.removeSuffixIfPresent import org.jetbrains.kotlin.backend.konan.util.suffixIfNot @@ -30,6 +29,7 @@ import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.* import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl +import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.target.* import org.jetbrains.kotlin.konan.target.TargetManager.* import org.jetbrains.kotlin.konan.target.CompilerOutputKind.* diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LinkStage.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LinkStage.kt index 681561e7809..07bca9fd8be 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LinkStage.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LinkStage.kt @@ -16,11 +16,11 @@ package org.jetbrains.kotlin.backend.konan -import org.jetbrains.kotlin.backend.konan.util.bufferedReader import java.lang.ProcessBuilder import java.lang.ProcessBuilder.Redirect +import org.jetbrains.kotlin.konan.file.* +import org.jetbrains.kotlin.konan.properties.* import org.jetbrains.kotlin.konan.target.* -import org.jetbrains.kotlin.backend.konan.util.* typealias BitcodeFile = String typealias ObjectFile = String @@ -28,46 +28,39 @@ typealias ExecutableFile = String // Use "clang -v -save-temps" to write linkCommand() method // for another implementation of this class. -internal abstract class PlatformFlags(val distribution: Distribution) { - val properties = distribution.properties - - val target = distribution.target - - open val llvmLtoNooptFlags - = propertyTargetList("llvmLtoNooptFlags") - open val llvmLtoOptFlags - = propertyTargetList("llvmLtoOptFlags") - open val llvmLtoFlags - = propertyTargetList("llvmLtoFlags") - open val entrySelector - = propertyTargetList("entrySelector") - open val linkerOptimizationFlags - = propertyTargetList("linkerOptimizationFlags") - open val linkerKonanFlags - = propertyTargetList("linkerKonanFlags") - open val linkerDebugFlags - = propertyTargetList("linkerDebugFlags") - open val llvmDebugOptFlags - = propertyTargetList("llvmDebugOptFlags") +internal abstract class PlatformFlags(val properties: KonanProperties) { + val llvmLtoNooptFlags = properties.llvmLtoNooptFlags + val llvmLtoOptFlags = properties.llvmLtoOptFlags + val llvmLtoFlags = properties.llvmLtoFlags + val entrySelector = properties.entrySelector + val linkerOptimizationFlags = properties.linkerOptimizationFlags + val linkerKonanFlags = properties.linkerKonanFlags + val linkerDebugFlags = properties.linkerDebugFlags + val llvmDebugOptFlags = properties.llvmDebugOptFlags open val useCompilerDriverAsLinker: Boolean get() = false // TODO: refactor. abstract fun linkCommand(objectFiles: List, executable: ExecutableFile, optimize: Boolean, debug: Boolean): List + val targetLibffiDir = properties.absoluteLibffiDir + val targetLibffi = "$targetLibffiDir/lib/libffi.a" + val targetToolchain = properties.absoluteTargetToolchain + val targetSysRoot = properties.absoluteTargetSysRoot + open fun linkCommandSuffix(): List = emptyList() protected fun propertyTargetString(name: String) - = properties.targetString(name, target)!! - protected fun propertyTargetList(name: String) - = properties.targetList(name, target) + = properties.targetString(name)!! + protected fun propertyTargetList(name: String) + = properties.targetList(name) } internal open class AndroidPlatform(distribution: Distribution) - : PlatformFlags(distribution) { + : PlatformFlags(distribution.targetProperties) { - private val prefix = "${distribution.targetToolchain}/bin/" + private val prefix = "$targetToolchain/bin/" private val clang = "$prefix/clang" override val useCompilerDriverAsLinker: Boolean get() = true @@ -87,11 +80,12 @@ internal open class AndroidPlatform(distribution: Distribution) } internal open class MacOSBasedPlatform(distribution: Distribution) - : PlatformFlags(distribution) { + : PlatformFlags(distribution.targetProperties) { // TODO: move 'ld' out of the host sysroot, as it doesn't belong here. private val linker = "${distribution.hostSysRoot}/usr/bin/ld" internal val dsymutil = "${distribution.llvmBin}/llvm-dsymutil" + internal val libLTO = distribution.libLTO open val osVersionMin by lazy { listOf( @@ -102,10 +96,10 @@ internal open class MacOSBasedPlatform(distribution: Distribution) override fun linkCommand(objectFiles: List, executable: ExecutableFile, optimize: Boolean, debug: Boolean): List { return mutableListOf(linker).apply { add("-demangle") - addAll(listOf("-object_path_lto", "temporary.o", "-lto_library", distribution.libLTO)) + addAll(listOf("-object_path_lto", "temporary.o", "-lto_library", libLTO)) addAll(listOf("-dynamic", "-arch", propertyTargetString("arch"))) addAll(osVersionMin) - addAll(listOf("-syslibroot", distribution.targetSysRoot, "-o", executable)) + addAll(listOf("-syslibroot", targetSysRoot, "-o", executable)) addAll(objectFiles) if (optimize) addAll(linkerOptimizationFlags) if (!debug) addAll(linkerDebugFlags) @@ -121,12 +115,11 @@ internal open class MacOSBasedPlatform(distribution: Distribution) } internal open class LinuxBasedPlatform(distribution: Distribution) - : PlatformFlags(distribution) { + : PlatformFlags(distribution.targetProperties) { - private val targetSysRoot = distribution.targetSysRoot private val llvmLib = distribution.llvmLib private val libGcc = "$targetSysRoot/${propertyTargetString("libGcc")!!}" - private val linker = "${distribution.targetToolchain}/bin/ld.gold" + private val linker = "$targetToolchain/bin/ld.gold" private val pluginOptimizationFlags = propertyTargetList("pluginOptimizationFlags") private val specificLibs = propertyTargetList("abiSpecificLibraries").map{it -> "-L${targetSysRoot}/$it"} @@ -158,9 +151,9 @@ internal open class LinuxBasedPlatform(distribution: Distribution) } internal open class MingwPlatform(distribution: Distribution) - : PlatformFlags(distribution) { + : PlatformFlags(distribution.targetProperties) { - private val linker = "${distribution.targetToolchain}/bin/clang++" + private val linker = "$targetToolchain/bin/clang++" override val useCompilerDriverAsLinker: Boolean get() = true @@ -250,7 +243,7 @@ internal class LinkStage(val context: Context) { private fun link(objectFiles: List, libraryProvidedLinkerFlags: List): ExecutableFile { val executable = context.config.outputFile val linkCommand = platform.linkCommand(objectFiles, executable, optimize, debug) + - distribution.libffi + + platform.targetLibffi + asLinkerArgs(config.getNotNull(KonanConfigKeys.LINKER_ARGS)) + entryPointSelector + platform.linkCommandSuffix() + diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/KonanIr.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/KonanIr.kt index ed6fcebc348..a80cd44336f 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/KonanIr.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/KonanIr.kt @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.backend.konan.ir -import org.jetbrains.kotlin.backend.konan.util.File import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor @@ -38,6 +37,7 @@ import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrBindableSymbolBase import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor +import org.jetbrains.kotlin.konan.file.* import org.jetbrains.kotlin.types.KotlinType //-----------------------------------------------------------------------------// @@ -235,4 +235,4 @@ class IrSuspendableExpressionImpl(startOffset: Int, endOffset: Int, type: Kotlin suspensionPointId = suspensionPointId.transform(transformer, data) result = result.transform(transformer, data) } -} \ No newline at end of file +} diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/KonanLibrary.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/KonanLibrary.kt index e6777d50447..2941b177dbc 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/KonanLibrary.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/KonanLibrary.kt @@ -17,7 +17,7 @@ package org.jetbrains.kotlin.backend.konan.library import org.jetbrains.kotlin.konan.target.KonanTarget -import org.jetbrains.kotlin.backend.konan.util.File +import org.jetbrains.kotlin.konan.file.File // This scheme describes the Konan Library (klib) layout. interface KonanLibraryLayout { diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/SearchPathResolver.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/SearchPathResolver.kt index 83cf7d9432a..7bd4b283ce7 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/SearchPathResolver.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/SearchPathResolver.kt @@ -16,9 +16,9 @@ package org.jetbrains.kotlin.backend.konan.library -import org.jetbrains.kotlin.backend.konan.util.File import org.jetbrains.kotlin.backend.konan.util.removeSuffixIfPresent import org.jetbrains.kotlin.backend.konan.util.suffixIfNot +import org.jetbrains.kotlin.konan.file.File interface SearchPathResolver { val searchRoots: List diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/KonanLibrary.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/KonanLibrary.kt index 1338a882a08..f270db3da74 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/KonanLibrary.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/KonanLibrary.kt @@ -17,7 +17,8 @@ package org.jetbrains.kotlin.backend.konan.library.impl import org.jetbrains.kotlin.backend.konan.library.KonanLibrary -import org.jetbrains.kotlin.backend.konan.util.* +import org.jetbrains.kotlin.backend.konan.util.removeSuffixIfPresent +import org.jetbrains.kotlin.konan.file.* import org.jetbrains.kotlin.konan.target.KonanTarget open class ZippedKonanLibrary(val klibFile: File, override val target: KonanTarget? = null): KonanLibrary { diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/KonanLibraryReaderImpl.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/KonanLibraryReaderImpl.kt index d02fccbe225..885dc51e971 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/KonanLibraryReaderImpl.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/KonanLibraryReaderImpl.kt @@ -18,10 +18,8 @@ package org.jetbrains.kotlin.backend.konan.library.impl import org.jetbrains.kotlin.backend.konan.library.KonanLibraryReader import org.jetbrains.kotlin.backend.konan.serialization.deserializeModule -import org.jetbrains.kotlin.backend.konan.util.File -import org.jetbrains.kotlin.backend.konan.util.Properties -import org.jetbrains.kotlin.backend.konan.util.loadProperties -import org.jetbrains.kotlin.backend.konan.util.propertyList +import org.jetbrains.kotlin.konan.file.File +import org.jetbrains.kotlin.konan.properties.* import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.konan.target.KonanTarget diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/KonanLibraryWriterImpl.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/KonanLibraryWriterImpl.kt index 2f2f7aae4ee..273551b3b10 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/KonanLibraryWriterImpl.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/KonanLibraryWriterImpl.kt @@ -21,7 +21,8 @@ import llvm.LLVMWriteBitcodeToFile import org.jetbrains.kotlin.backend.konan.library.KonanLibrary import org.jetbrains.kotlin.backend.konan.library.KonanLibraryWriter import org.jetbrains.kotlin.backend.konan.library.LinkData -import org.jetbrains.kotlin.backend.konan.util.* +import org.jetbrains.kotlin.konan.file.* +import org.jetbrains.kotlin.konan.properties.* import org.jetbrains.kotlin.konan.target.KonanTarget abstract class FileBasedLibraryWriter ( diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/MetadataWriterImpl.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/MetadataWriterImpl.kt index 13a7297a8f1..b9d973c232f 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/MetadataWriterImpl.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/MetadataWriterImpl.kt @@ -18,7 +18,7 @@ package org.jetbrains.kotlin.backend.konan.library.impl import org.jetbrains.kotlin.backend.konan.library.KonanLibrary import org.jetbrains.kotlin.backend.konan.library.LinkData -import org.jetbrains.kotlin.backend.konan.util.File +import org.jetbrains.kotlin.konan.file.File internal class MetadataWriterImpl(library: KonanLibrary): KonanLibrary by library { diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DebugUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DebugUtils.kt index 5ff3ee37d38..cb73a5c45f8 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DebugUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DebugUtils.kt @@ -22,13 +22,13 @@ import llvm.* import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.KonanConfigKeys import org.jetbrains.kotlin.backend.konan.KonanVersion -import org.jetbrains.kotlin.backend.konan.util.File import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.ir.SourceManager.FileEntry import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe +import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils diff --git a/backend.native/konan.properties b/backend.native/konan.properties index 8d2df05cb87..aab15273da5 100644 --- a/backend.native/konan.properties +++ b/backend.native/konan.properties @@ -89,6 +89,7 @@ osVersionMin.ios_sim = 8.0 # Linux x86-64. llvmVersion.linux = 3.9.0 llvmHome.linux = clang-llvm-3.9.0-linux-x86-64 +gccToolchain.linux = target-gcc-toolchain-3-linux-x86-64 targetToolchain.linux = target-gcc-toolchain-3-linux-x86-64/x86_64-unknown-linux-gnu quadruple.linux = x86_64-unknown-linux-gnu diff --git a/build.gradle b/build.gradle index f55c7738a10..0e2f1bf87a2 100644 --- a/build.gradle +++ b/build.gradle @@ -14,13 +14,21 @@ * limitations under the License. */ import groovy.io.FileType - -//ant.importBuild 'backend.native/kotlin-ir/build.xml' +import org.jetbrains.kotlin.konan.target.* +import org.jetbrains.kotlin.konan.properties.* defaultTasks 'clean', 'dist' convention.plugins.platformInfo = new PlatformInfo() +ext { + konanPropertiesFile = project(':backend.native').file('konan.properties') + konanProperties = PropertiesKt.loadProperties(konanPropertiesFile.absolutePath) + + dependenciesDir = rootProject.file("dist/dependencies") + clangManager = new ClangManager(konanProperties, dependenciesDir.absolutePath) +} + allprojects { if (path != ":dependencies") { evaluationDependsOn(":dependencies") @@ -33,14 +41,20 @@ allprojects { } } + setupHostAndTarget() loadCommandLineProperties() loadLocalProperties() - setupCompilationFlags() setupClang(project) } +void setupHostAndTarget() { + ext.hostName = TargetManager.hostName + ext.targetList = TargetManager.enabled*.userName as List +} + void setupClang(Project project) { + project.convention.plugins.clangManager = project.rootProject.ext.clangManager project.convention.plugins.execClang = new org.jetbrains.kotlin.ExecClang(project) project.plugins.withType(NativeComponentPlugin) { @@ -67,13 +81,13 @@ void setupClang(Project project) { toolChains { clang(Clang) { - clangPath.each { + hostClang.hostClangPath.each { path it } eachPlatform { // TODO: will not work when cross-compiling [cCompiler, cppCompiler, linker].each { - it.withArguments { it.addAll(hostClangArgs) } + it.withArguments { it.addAll(project.hostClangArgs) } } } @@ -84,98 +98,6 @@ void setupClang(Project project) { } } -String getTargetArg(String target) { - def result = konanProperties.getProperty("quadruple.$target") - if (result == null) { - throw IllegalArgumentException("konan.properties has no LLVM target args for target: $target") - } - return result -} - -void setupCompilationFlags() { - ext.clangPath = ["$llvmDir/bin"] - ext.clangArgs = [] - ext.targetArgs = [:] - final String binDir - - if (isLinux()) { - ext.host = "linux" - ext.targetArgs << - [(ext.host): - ["--sysroot=${gccToolchainDir}/${gnuTriplet}/sysroot", - "-DUSE_GCC_UNWIND=1", "-DUSE_ELF_SYMBOLS=1", "-DELFSIZE=64"], - "raspberrypi": - ["-target", getTargetArg("raspberrypi"), - "-mfpu=vfp", "-mfloat-abi=hard", - "-DUSE_GCC_UNWIND=1", "-DUSE_ELF_SYMBOLS=1", "-DELFSIZE=32", - "--sysroot=$raspberrypiSysrootDir", - // TODO: those two are hacks. - "-I$raspberrypiSysrootDir/usr/include/c++/4.8.3", - "-I$raspberrypiSysrootDir/usr/include/c++/4.8.3/arm-linux-gnueabihf"] - ] - } else if (isWindows()) { - ext.host = "mingw" - ext.targetArgs << - [(ext.host): - ["-target", "x86_64-w64-mingw32", "--sysroot=${mingwWithLlvmDir}", - "-DUSE_GCC_UNWIND=1", "-DUSE_PE_COFF_SYMBOLS=1", "-DKONAN_WINDOWS=1"]] - } else { - ext.host = "macbook" - ext.targetArgs << - [(ext.host): - ["--sysroot=$macbookSysrootDir", "-mmacosx-version-min=10.11"], - "iphone": - ["-stdlib=libc++", "-arch", "arm64", "-isysroot", "$iphoneSysrootDir", - "-miphoneos-version-min=8.0.0"] -// TODO: re-enable after simulator sysroot is available in the dependencies -// "iphone_sim": -// ["-stdlib=libc++", "-isysroot", "$iphoneSimSysrootDir", "-miphoneos-version-min=8.0.0"], - ] - } - - if (isLinux() || isMac()) { - ext.targetArgs << [ - "android_arm32": - ["-target", getTargetArg("android_arm32"), - "--sysroot=$android_arm32SysrootDir", - "-D__ANDROID__", "-DUSE_GCC_UNWIND=1", "-DUSE_ELF_SYMBOLS=1", "-DELFSIZE=32", "-DKONAN_ANDROID", - // HACKS! - "-I$android_arm32SysrootDir/usr/include/c++/4.9.x", - "-I$android_arm32SysrootDir/usr/include/c++/4.9.x/arm-linux-androideabi"], - "android_arm64": - ["-target", getTargetArg("android_arm64"), - "--sysroot=$android_arm64SysrootDir", - "-D__ANDROID__", "-DUSE_GCC_UNWIND=1", "-DUSE_ELF_SYMBOLS=1", "-DELFSIZE=64", "-DKONAN_ANDROID", - // HACKS! - "-I$android_arm64SysrootDir/usr/include/c++/4.9.x", - "-I$android_arm64SysrootDir/usr/include/c++/4.9.x/aarch64-linux-android"] - - ] - } - - ext.targetList = ext.targetArgs.keySet() as List - - if (isLinux()) { - binDir = "$gccToolchainDir/$gnuTriplet/bin" - ext.clangArgs.addAll([ - "--gcc-toolchain=$gccToolchainDir" - ]) - } else if (isWindows()) { - binDir = "$mingwWithLlvmDir/bin" - } else { - binDir = "$macbookSysrootDir/usr/bin" - } - ext.clangArgs << "-B$binDir" - ext.hostClangArgs = ext.clangArgs.clone() - ext.hostClangArgs.addAll(ext.targetArgs[host]) - - ext.clangPath << binDir - ext.jvmArgs = ["-ea"] - - File jdkHome = new File(System.getProperty('java.home')).absoluteFile.parentFile - ext.hostCompilerArgsForJni = ["", jniHostPlatformIncludeDir()].collect { "-I$jdkHome/include/$it" } as String[] -} - void loadLocalProperties() { if (new File("$project.rootDir/local.properties").exists()) { Properties props = new Properties() @@ -197,50 +119,20 @@ void loadCommandLineProperties() { } class PlatformInfo { - private final String osName = System.properties['os.name'] - private final String osArch = System.properties['os.arch'] - boolean isMac() { - return osName == 'Mac OS X' + return TargetManager.host == KonanTarget.MACBOOK } boolean isWindows() { - return osName.startsWith('Windows'); + return TargetManager.host == KonanTarget.MINGW } boolean isLinux() { - return osName == 'Linux' - } - - boolean isAmd64() { - return osArch in ['x86_64', 'amd64'] - } - - String getGnuTriplet() { - if (isLinux() && isAmd64()) { - return "x86_64-unknown-linux-gnu" - } else { - throw unsupportedPlatformException() - } - } - - String simpleOsName() { - if (isMac()) return 'macos' - if (isLinux()) return 'linux' - if (isWindows()) return 'windows' - throw unsupportedPlatformException() - } - - String jniHostPlatformIncludeDir() { - if (isMac()) return "darwin" - if (isLinux()) return "linux" - if (isWindows()) return "win32" - - throw unsupportedPlatformException() + return TargetManager.host == KonanTarget.LINUX } Throwable unsupportedPlatformException() { - return new Error("unsupported platform: $osName/$osArch") + return new TargetSupportException() } } @@ -323,7 +215,7 @@ task listDist(type: Exec) { } task distRuntime(type: Copy) { - dependsOn "${host}CrossDistRuntime" + dependsOn "${hostName}CrossDistRuntime" dependsOn('commonDistRuntime') } @@ -331,7 +223,7 @@ task commonDistRuntime(type: Copy) { destinationDir file('dist') // Target independant common part. - from(project(':runtime').file("build/${host}Stdlib")) { + from(project(':runtime').file("build/${hostName}Stdlib")) { include('**') into('klib/stdlib') } @@ -375,7 +267,8 @@ task crossDist { task bundle(type: (isWindows()) ? Zip : Tar) { dependsOn('crossDist') - baseName = "kotlin-native-${simpleOsName()}-${project.konanVersion}" + def simpleOsName = TargetManager.simpleOsName() + baseName = "kotlin-native-$simpleOsName-${project.konanVersion}" from("$project.rootDir/dist") { include '**' exclude 'dependencies' diff --git a/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/CompileToBitcode.groovy b/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/CompileToBitcode.groovy index fdd3e987474..67fc0b567ce 100644 --- a/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/CompileToBitcode.groovy +++ b/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/CompileToBitcode.groovy @@ -22,52 +22,7 @@ import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction -class CompilePerTarget extends CompileCppToBitcode { - private List targetList = [] - private Map> targetArgs = null - private Map> targetLinkerArgs = null - - void targetList(List list) { - targetList.addAll(list) - } - - void targetArgs(Map> map) { - targetArgs = map - } - - private Map> getTargetArgs() { - return targetArgs - } - - void targetLinkerArgs(Map> map) { - targetLinkerArgs = map - } - - private Map> getTargetLinkerArgs() { - return targetLinkerArgs - } - - @TaskAction - void compile() { - def targetList = this.targetList - def targetArgs = getTargetArgs() - def targetLinkerArgs = getTargetLinkerArgs() - def commonCompilerArgs = getCompilerArgs().clone() - def commonLinkerArgs = getLinkerArgs().clone() - targetList.each { - this.compilerArgs = [] - this.linkerArgs = [] - target(it) - compilerArgs(commonCompilerArgs) - if (targetArgs != null) - compilerArgs(targetArgs[it]) - linkerArgs(commonLinkerArgs) - if (targetLinkerArgs != null) - linkerArgs(targetLinkerArgs[it]) - super.compile() - } - } -} +import org.jetbrains.kotlin.konan.target.KonanTarget class CompileCppToBitcode extends DefaultTask { private String name = "main" @@ -123,6 +78,10 @@ class CompileCppToBitcode extends DefaultTask { return linkerArgs } + protected String getTarget() { + return target + } + void compilerArgs(String... args) { compilerArgs.addAll(args) } @@ -139,6 +98,11 @@ class CompileCppToBitcode extends DefaultTask { linkerArgs.addAll(args) } + List targetArgs(String target) { + def result = project.rootProject.targetClangArgs(KonanTarget.valueOf(target.toUpperCase())) + return result + } + @TaskAction void compile() { // the strange code below seems to be required due to some Gradle (Groovy?) behaviour @@ -154,6 +118,7 @@ class CompileCppToBitcode extends DefaultTask { executable "clang++" args '-std=c++11' + args targetArgs(this.target) args compilerArgs args "-I$headersDir" diff --git a/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/ExecClang.groovy b/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/ExecClang.groovy index 7303097f2ff..784937706d0 100644 --- a/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/ExecClang.groovy +++ b/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/ExecClang.groovy @@ -53,12 +53,9 @@ class ExecClang { throw new GradleException("unsupported clang executable: $executable") } - environment["PATH"] = project.files(project.clangPath).asPath + + environment["PATH"] = project.files(project.hostClang.hostClangPath).asPath + File.pathSeparator + environment["PATH"] - - args project.clangArgs } - } } return project.exec(extendedAction) diff --git a/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/NativeInteropPlugin.groovy b/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/NativeInteropPlugin.groovy index 508b48de795..bbf6934349e 100644 --- a/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/NativeInteropPlugin.groovy +++ b/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/NativeInteropPlugin.groovy @@ -228,7 +228,7 @@ class NamedNativeInteropConfig implements Named { } // TODO: the interop plugin should probably be reworked to execute clang from build scripts directly - environment['PATH'] = project.files(project.clangPath).asPath + + environment['PATH'] = project.files(project.hostClang.hostClangPath).asPath + File.pathSeparator + environment['PATH'] args compilerOpts.collectMany { ['-copt', it] } diff --git a/common/build.gradle b/common/build.gradle index 2b590ab6ec6..626d3686163 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -22,12 +22,11 @@ targetList.each { targetName -> task ("${targetName}Hash", type: CompileCppToBitcode) { name 'hash' target targetName - compilerArgs targetArgs[targetName] } } task build { - dependsOn "${host}Hash" + dependsOn "${hostName}Hash" } task clean { diff --git a/dependencies/build.gradle b/dependencies/build.gradle index 813cb2e2276..d3a215f90f9 100644 --- a/dependencies/build.gradle +++ b/dependencies/build.gradle @@ -15,6 +15,10 @@ */ import static DependencyTaskKind.* +import org.jetbrains.kotlin.konan.target.* +import static org.jetbrains.kotlin.konan.target.KonanTarget.* +import org.jetbrains.kotlin.konan.properties.KonanProperties +import org.jetbrains.kotlin.konan.properties.* buildscript { repositories { @@ -30,10 +34,6 @@ buildscript { apply plugin: 'com.jfrog.bintray' -rootProject.ext.konanPropertiesFile = project(':backend.native').file('konan.properties') -rootProject.ext.konanProperties = new Properties() -rootProject.konanProperties.load(new FileInputStream(rootProject.konanPropertiesFile)) - configurations { kotlin_compiler_jar kotlin_compiler_pom @@ -106,20 +106,7 @@ task update_kotlin_compiler(type: DefaultTask) { } abstract class NativeDep extends DefaultTask { - - private String getCurrentHostTarget() { - if (project.isMac() && project.isAmd64()) { - return 'darwin-macos' - } else if (project.isLinux() && project.isAmd64()) { - return 'linux-x86-64' - } else if (project.isWindows() && project.isAmd64()) { - return 'windows-x86-64' - } else { - throw project.unsupportedPlatformException() - } - } - - protected final String host = getCurrentHostTarget(); + protected final String hostSystem = TargetManager.longerSystemName(); String baseUrl = "https://jetbrains.bintray.com/kotlin-native-dependencies" @Input @@ -130,7 +117,7 @@ abstract class NativeDep extends DefaultTask { } protected File getBaseOutDir() { - final File res = project.rootProject.file("dist/dependencies") + final File res = project.rootProject.ext.dependenciesDir res.mkdirs() return res } @@ -193,15 +180,6 @@ class HelperNativeDep extends TgzNativeDep { } } -static String substituteName(String name) { - switch (name) { - case "macbook": return "osx" - case "iphone": return "ios" - case "iphoneSim": return "ios_sim" - } - return name -} - enum DependencyTaskKind { LIBFFI("Libffi"), SYSROOT("Sysroot") @@ -213,22 +191,23 @@ enum DependencyTaskKind { String toString() { return name } } -void dependencyTask(String target, DependencyTaskKind kind) { +void dependencyTask(KonanTarget target, DependencyTaskKind kind) { String dependencyBaseName - def properties = rootProject.konanProperties + def properties = rootProject.ext.konanProperties + def dirs = new KonanProperties(target, properties, null) switch (kind) { case LIBFFI: - dependencyBaseName = properties.getProperty("libffiDir.${substituteName(target)}") + dependencyBaseName = dirs.libffiDir break case SYSROOT: - dependencyBaseName = properties.getProperty("targetSysRoot.${substituteName(target)}") + dependencyBaseName = dirs.targetSysRoot break } if (dependencyBaseName == null) { throw project.unsupportedPlatformException() } - task "${target}${kind}"(type: HelperNativeDep) { + task "${target.userName}${kind}"(type: HelperNativeDep) { baseName = dependencyBaseName } } @@ -236,37 +215,36 @@ void dependencyTask(String target, DependencyTaskKind kind) { if (isLinux()) { // The gcc toolchain contains the sysroot for linux platform. task gccToolchain(type: HelperNativeDep) { - baseName = "target-gcc-toolchain-3-$host" + baseName = "target-gcc-toolchain-3-$hostSystem" } - dependencyTask("linux", LIBFFI) - dependencyTask("raspberrypi", SYSROOT) - dependencyTask("raspberrypi", LIBFFI) + dependencyTask(LINUX, LIBFFI) + dependencyTask(RASPBERRYPI, SYSROOT) + dependencyTask(RASPBERRYPI, LIBFFI) } else if (isWindows()) { task mingwWithLlvm(type: HelperNativeDep) { - baseName = "msys2-mingw-w64-x86_64-gcc-6.3.0-clang-llvm-3.9.1-$host" + baseName = "msys2-mingw-w64-x86_64-gcc-6.3.0-clang-llvm-3.9.1-$hostSystem" } - dependencyTask("mingw", LIBFFI) + dependencyTask(MINGW, LIBFFI) } else { - dependencyTask("macbook", SYSROOT) - dependencyTask("macbook", LIBFFI) - dependencyTask("iphone", SYSROOT) - dependencyTask("iphone", LIBFFI) - + dependencyTask(MACBOOK, SYSROOT) + dependencyTask(MACBOOK, LIBFFI) + dependencyTask(IPHONE, SYSROOT) + dependencyTask(IPHONE, LIBFFI) // TODO: re-enable when we known how to bring the simulator sysroot to dependencies. - // dependencyTask("iphoneSim", SYSROOT) + // dependencyTask(IPHONE_SIM, SYSROOT) } if (isLinux() || isMac()) { task llvm(type: HelperNativeDep) { - baseName = "clang-llvm-$llvmVersion-$host" + baseName = "clang-llvm-$llvmVersion-$hostSystem" } - dependencyTask("android_arm32", SYSROOT) - dependencyTask("android_arm32", LIBFFI) - dependencyTask("android_arm64", SYSROOT) - dependencyTask("android_arm64", LIBFFI) + dependencyTask(ANDROID_ARM32, SYSROOT) + dependencyTask(ANDROID_ARM32, LIBFFI) + dependencyTask(ANDROID_ARM64, SYSROOT) + dependencyTask(ANDROID_ARM64, LIBFFI) } task update(type: Copy) { diff --git a/klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/main.kt b/klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/main.kt index bea62bb4a0c..cb1f7d87078 100644 --- a/klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/main.kt +++ b/klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/main.kt @@ -22,7 +22,7 @@ import java.util.Properties import org.jetbrains.kotlin.backend.konan.library.impl.* import org.jetbrains.kotlin.backend.konan.library.KonanLibrary import org.jetbrains.kotlin.backend.konan.library.KonanLibrarySearchPathResolver -import org.jetbrains.kotlin.backend.konan.util.File +import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.target.TargetManager fun printUsage() { diff --git a/runtime/build.gradle b/runtime/build.gradle index 9b98b09ef04..6e893ff4228 100644 --- a/runtime/build.gradle +++ b/runtime/build.gradle @@ -25,7 +25,6 @@ targetList.each { targetName -> dependsOn ":common:${targetName}Hash" dependsOn "${targetName}Launcher" target targetName - compilerArgs targetArgs[targetName] compilerArgs '-g' compilerArgs '-I' + project.file('../common/src/hash/headers') compilerArgs '-I' + project.file(rootProject.ext.get("${targetName}LibffiDir") + "/include") @@ -38,14 +37,13 @@ targetList.each { targetName -> name "launcher" srcRoot file('src/launcher') target targetName - compilerArgs targetArgs[targetName] compilerArgs '-g' compilerArgs '-I' + project.file('../common/src/hash/headers') compilerArgs '-I' + project.file('src/main/cpp') } } -task hostRuntime(dependsOn: "${rootProject.ext.host}Runtime") +task hostRuntime(dependsOn: "${hostName}Runtime") task clean { doLast { diff --git a/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/ClangArgs.kt b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/ClangArgs.kt new file mode 100644 index 00000000000..134b63126fa --- /dev/null +++ b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/ClangArgs.kt @@ -0,0 +1,103 @@ +/* + * 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 -> 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.properties.KonanProperties +import org.jetbrains.kotlin.konan.file.File + +class ClangTarget(val target: KonanTarget, val konanProperties: KonanProperties) { + + val sysRoot = konanProperties.absoluteTargetSysRoot!! + val targetArg = konanProperties.targetArg + + val specificClangArgs: List get() { + return when (target) { + + KonanTarget.LINUX -> + listOf("--sysroot=$sysRoot", + "-DUSE_GCC_UNWIND=1", "-DUSE_ELF_SYMBOLS=1", "-DELFSIZE=64") + KonanTarget.RASPBERRYPI -> + listOf("-target", targetArg!!, + "-mfpu=vfp", "-mfloat-abi=hard", + "-DUSE_GCC_UNWIND=1", "-DUSE_ELF_SYMBOLS=1", "-DELFSIZE=32", + "--sysroot=$sysRoot", + // TODO: those two are hacks. + "-I$sysRoot/usr/include/c++/4.8.3", + "-I$sysRoot/usr/include/c++/4.8.3/arm-linux-gnueabihf") + + KonanTarget.MINGW -> + listOf("-target", targetArg!!, "--sysroot=$sysRoot", + "-DUSE_GCC_UNWIND=1", "-DUSE_PE_COFF_SYMBOLS=1", "-DKONAN_WINDOWS=1") + + KonanTarget.MACBOOK -> + listOf("--sysroot=$sysRoot", "-mmacosx-version-min=10.11") + + KonanTarget.IPHONE -> + listOf("-stdlib=libc++", "-arch", "arm64", "-isysroot", "$sysRoot", "-miphoneos-version-min=8.0.0") + + KonanTarget.IPHONE_SIM -> + listOf("-stdlib=libc++", "-isysroot", "$sysRoot", "-miphoneos-version-min=8.0.0") + + KonanTarget.ANDROID_ARM32 -> + listOf("-target", targetArg!!, + "--sysroot=$sysRoot", + "-D__ANDROID__", "-DUSE_GCC_UNWIND=1", "-DUSE_ELF_SYMBOLS=1", "-DELFSIZE=32", "-DKONAN_ANDROID", + // HACKS! + "-I$sysRoot/usr/include/c++/4.9.x", + "-I$sysRoot/usr/include/c++/4.9.x/arm-linux-androideabi") + + KonanTarget.ANDROID_ARM64 -> + listOf("-target", targetArg!!, + "--sysroot=$sysRoot", + "-D__ANDROID__", "-DUSE_GCC_UNWIND=1", "-DUSE_ELF_SYMBOLS=1", "-DELFSIZE=64", "-DKONAN_ANDROID", + // HACKS! + "-I$sysRoot/usr/include/c++/4.9.x", + "-I$sysRoot/usr/include/c++/4.9.x/aarch64-linux-android") + } + } +} + +class ClangHost(val hostProperties: KonanProperties) { + + val targetToolchain get() = hostProperties.absoluteTargetToolchain + val gccToolchain get() = hostProperties.absoluteGccToolchain + val sysRoot get() = hostProperties.absoluteTargetSysRoot + val llvmDir get() = hostProperties.absoluteLlvmHome + + val binDir = when(TargetManager.host) { + KonanTarget.LINUX -> "$targetToolchain/bin" + KonanTarget.MINGW -> "$sysRoot/bin" + KonanTarget.MACBOOK -> "$sysRoot/usr/bin" + else -> throw TargetSupportException("Unexpected host platform") + } + + private val extraHostClangArgs = + if (TargetManager.host == KonanTarget.LINUX) { + listOf("--gcc-toolchain=$gccToolchain") + } else { + emptyList() + } + + val commonClangArgs = listOf("-B$binDir") + extraHostClangArgs + + val hostClangPath = listOf("$llvmDir/bin", binDir) + + private val jdkHome = File.jdkHome.absoluteFile.parent + + val hostCompilerArgsForJni = listOf("", TargetManager.jniHostPlatformIncludeDir).map { "-I$jdkHome/include/$it" } +} + diff --git a/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/ClangCross.kt b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/ClangCross.kt new file mode 100644 index 00000000000..45fe86e8d80 --- /dev/null +++ b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/ClangCross.kt @@ -0,0 +1,43 @@ +/* + * 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 -> 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.properties.* + +class ClangManager(val properties: Properties, val baseDir: String) { + private val host = TargetManager.host + private val enabledTargets = TargetManager.enabled + private val konanProperties = enabledTargets.map { + it to KonanProperties(it, properties, baseDir) + }.toMap() + + private val targetClangs = enabledTargets.map { + it to ClangTarget(it, konanProperties[it]!!) + }.toMap() + + private val hostClang = ClangHost(konanProperties[host]!!) + + // These are converted to arrays to be convenient + // in groovy plugins. + val hostClangArgs = (hostClang.commonClangArgs + targetClangs[host]!!.specificClangArgs).toTypedArray() + + fun targetClangArgs(target: KonanTarget) + = (hostClang.commonClangArgs + targetClangs[target]!!.specificClangArgs).toTypedArray() + + val hostCompilerArgsForJni = hostClang.hostCompilerArgsForJni.toTypedArray() +} + diff --git a/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/KonanProperties.kt b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/KonanProperties.kt new file mode 100644 index 00000000000..d8bd17baedb --- /dev/null +++ b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/KonanProperties.kt @@ -0,0 +1,72 @@ +/* + * 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 -> 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.properties + +import org.jetbrains.kotlin.konan.file.* +import org.jetbrains.kotlin.konan.target.* + +class KonanProperties(val target: KonanTarget, val properties: Properties, val baseDir: String? = null) { + + fun targetString(key: String): String? + = properties.targetString(key, target) + fun targetList(key: String): List + = properties.targetList(key, target) + fun hostString(key: String): String? + = properties.hostString(key) + fun hostList(key: String): List + = properties.hostList(key) + fun hostTargetString(key: String): String? + = properties.hostTargetString(key, target) + fun hostTargetList(key: String): List + = properties.hostTargetList(key, target) + + // TODO: Delegate to a map? + val llvmLtoNooptFlags get() = targetList("llvmLtoNooptFlags") + val llvmLtoOptFlags get() = targetList("llvmLtoOptFlags") + val llvmLtoFlags get() = targetList("llvmLtoFlags") + val entrySelector get() = targetList("entrySelector") + val linkerOptimizationFlags get() = targetList("linkerOptimizationFlags") + val linkerKonanFlags get() = targetList("linkerKonanFlags") + val linkerDebugFlags get() = targetList("linkerDebugFlags") + val llvmDebugOptFlags get() = targetList("llvmDebugOptFlags") + + val targetSysRoot get() = targetString("targetSysRoot") + val libffiDir get() = targetString("libffiDir") + val gccToolchain get() = targetString("gccToolchain") + val targetArg get() = targetString("quadruple") + val llvmHome get() = targetString("llvmHome") + // Notice: this one is host-target. + val targetToolchain get() = hostTargetString("targetToolchain") + + fun absolute(value: String?) = "${baseDir!!}/${value!!}" + + val absoluteTargetSysRoot get() = absolute(targetSysRoot) + val absoluteTargetToolchain get() = absolute(targetToolchain) + val absoluteGccToolchain get() = absolute(gccToolchain) + val absoluteLlvmHome get() = absolute(llvmHome) + val absoluteLibffiDir get() = absolute(libffiDir) + + val mingwWithLlvm: String? + get() { + if (target != KonanTarget.MINGW) { + error("Only mingw target can have '.mingwWithLlvm' property") + } + // TODO: make it a property in the konan.properties. + // Use (equal) llvmHome fow now. + return targetString("llvmHome") + } +} diff --git a/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/KonanTarget.kt b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/KonanTarget.kt index ea473189f5d..fafead82f30 100644 --- a/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/KonanTarget.kt +++ b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/KonanTarget.kt @@ -24,9 +24,13 @@ enum class KonanTarget(val targetSuffix: String, val programSuffix: String, var LINUX("linux", "kexe"), MINGW("mingw", "exe"), MACBOOK("osx", "kexe"), - RASPBERRYPI("raspberrypi", "kexe") + RASPBERRYPI("raspberrypi", "kexe"); + val userName get() = name.toLowerCase() } +fun hostTargetSuffix(host: KonanTarget, target: KonanTarget) = + if (target == host) host.targetSuffix else "${host.targetSuffix}-${target.targetSuffix}" + enum class CompilerOutputKind { PROGRAM { override fun suffix(target: KonanTarget?) = ".${target!!.programSuffix}" @@ -42,37 +46,15 @@ enum class CompilerOutputKind { } class TargetManager(val userRequest: String? = null) { - val targets = KonanTarget.values().associate{ it.name.toLowerCase() to it } + val targets = KonanTarget.values().associate{ it.userName to it } val target = determineCurrent() val targetName get() = target.name.toLowerCase() - init { - when (host) { - KonanTarget.LINUX -> { - KonanTarget.LINUX.enabled = true - KonanTarget.RASPBERRYPI.enabled = true - KonanTarget.ANDROID_ARM32.enabled = true - KonanTarget.ANDROID_ARM64.enabled = true - } - KonanTarget.MINGW -> { - KonanTarget.MINGW.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 - } - else -> - error("Unknown host platform: $host") - } - } fun known(name: String): String { if (targets[name] == null) { - error("Unknown target: $name. Use -list_targets to see the list of available targets") + throw TargetSupportException("Unknown target: $name. Use -list_targets to see the list of available targets") } return name } @@ -94,36 +76,52 @@ class TargetManager(val userRequest: String? = null) { } } - val hostSuffix get() = host.targetSuffix - val hostTargetSuffix get() = - if (target == host) host.targetSuffix else "${host.targetSuffix}-${target.targetSuffix}" + val hostTargetSuffix get() = hostTargetSuffix(host, target) val targetSuffix get() = target.targetSuffix val programSuffix get() = CompilerOutputKind.PROGRAM.suffix(target) companion object { + fun host_os(): String { val javaOsName = System.getProperty("os.name") return when { javaOsName == "Mac OS X" -> "osx" javaOsName == "Linux" -> "linux" javaOsName.startsWith("Windows") -> "windows" - else -> error("Unknown operating system: ${javaOsName}") + else -> throw TargetSupportException("Unknown operating system: ${javaOsName}") } } + @JvmStatic fun simpleOsName(): String { val hostOs = host_os() return if (hostOs == "osx") "macos" else hostOs } + @JvmStatic + fun longerSystemName(): String = when (host) { + KonanTarget.MACBOOK -> "darwin-macos" + KonanTarget.LINUX -> "linux-x86-64" + KonanTarget.MINGW -> "windows-x86-64" + else -> throw TargetSupportException("Unknown host: $host") + } + + val jniHostPlatformIncludeDir: String + get() = when(host) { + KonanTarget.MACBOOK -> "darwin" + KonanTarget.LINUX -> "linux" + KonanTarget.MINGW ->"win32" + else -> throw TargetSupportException("Unknown host: $host.") + } + fun host_arch(): String { val javaArch = System.getProperty("os.arch") return when (javaArch) { "x86_64" -> "x86_64" "amd64" -> "x86_64" "arm64" -> "arm64" - else -> error("Unknown hardware platform: ${javaArch}") + else -> throw TargetSupportException("Unknown hardware platform: ${javaArch}") } } @@ -131,8 +129,41 @@ class TargetManager(val userRequest: String? = null) { "osx" -> KonanTarget.MACBOOK "linux" -> KonanTarget.LINUX "windows" -> KonanTarget.MINGW - else -> error("Unknown host target: ${host_os()} ${host_arch()}") + else -> throw TargetSupportException("Unknown host target: ${host_os()} ${host_arch()}") } + + val hostSuffix get() = host.targetSuffix + @JvmStatic + val hostName get() = host.name.toLowerCase() + + init { + when (host) { + KonanTarget.LINUX -> { + KonanTarget.LINUX.enabled = true + KonanTarget.RASPBERRYPI.enabled = true + KonanTarget.ANDROID_ARM32.enabled = true + KonanTarget.ANDROID_ARM64.enabled = true + } + KonanTarget.MINGW -> { + KonanTarget.MINGW.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 + } + else -> + throw TargetSupportException("Unknown host platform: $host") + } + } + + @JvmStatic + val enabled: List + get() = KonanTarget.values().asList().filter { it.enabled } } } +class TargetSupportException (message: String = "", cause: Throwable? = null) : Exception(message, cause) + diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/util/Properties.kt b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/Properties.kt similarity index 91% rename from backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/util/Properties.kt rename to shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/Properties.kt index 21f36b47751..9dea8a652ce 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/util/Properties.kt +++ b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/Properties.kt @@ -14,7 +14,9 @@ * limitations under the License. */ -package org.jetbrains.kotlin.backend.konan.util +package org.jetbrains.kotlin.konan.properties + +import org.jetbrains.kotlin.konan.file.* typealias Properties = java.util.Properties @@ -26,6 +28,8 @@ fun File.loadProperties(): Properties { return properties } +fun loadProperties(path: String): Properties = File(path).loadProperties() + fun File.saveProperties(properties: Properties) { this.outputStream().use { properties.store(it, null) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/util/TargetProperties.kt b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/TargetProperties.kt similarity index 75% rename from backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/util/TargetProperties.kt rename to shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/TargetProperties.kt index 7409dbce2c2..b86f9ad4a93 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/util/TargetProperties.kt +++ b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/TargetProperties.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.kotlin.backend.konan.util +package org.jetbrains.kotlin.konan.properties import org.jetbrains.kotlin.konan.target.* @@ -29,3 +29,9 @@ fun Properties.targetString(name: String, target: KonanTarget): String? fun Properties.targetList(name: String, target: KonanTarget): List = this.propertyList(name, target.targetSuffix) + +fun Properties.hostTargetString(name: String, target: KonanTarget): String? + = this.propertyString(name, hostTargetSuffix(TargetManager.host, target)) + +fun Properties.hostTargetList(name: String, target: KonanTarget): List + = this.propertyList(name, hostTargetSuffix(TargetManager.host, target)) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/util/NoJavaUtil.kt b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/util/NoJavaUtil.kt similarity index 98% rename from backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/util/NoJavaUtil.kt rename to shared/src/main/kotlin/org/jetbrains/kotlin/konan/util/NoJavaUtil.kt index ed76dbff3f8..ec2085217de 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/util/NoJavaUtil.kt +++ b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/util/NoJavaUtil.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.kotlin.backend.konan.util +package org.jetbrains.kotlin.konan.file import java.io.BufferedReader import java.io.InputStream @@ -128,6 +128,9 @@ class File constructor(internal val javaPath: Path) { val userHome get() = File(System.getProperty("user.home")) + val jdkHome + get() = File(System.getProperty("java.home")) + } } diff --git a/utilities/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/main.kt b/utilities/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/main.kt index 987ce722c26..aebe2f81636 100644 --- a/utilities/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/main.kt +++ b/utilities/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/main.kt @@ -1,6 +1,6 @@ package org.jetbrains.kotlin.cli.utilities -import org.jetbrains.kotlin.backend.konan.util.File +import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.cli.bc.main as konancMain import org.jetbrains.kotlin.native.interop.gen.jvm.main as cinteropMain import org.jetbrains.kotlin.cli.klib.main as klibMain