diff --git a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt index cc24a464913..2de4860a640 100644 --- a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt +++ b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt @@ -149,6 +149,7 @@ class K2Native : CLICompiler() { put(LIST_TARGETS, arguments.listTargets) put(OPTIMIZATION, arguments.optimization) put(DEBUG, arguments.debug) + put(STATIC_FRAMEWORK, selectFrameworkType(configuration, arguments, outputKind)) put(PRINT_IR, arguments.printIr) put(PRINT_IR_WITH_DESCRIPTORS, arguments.printIrWithDescriptors) @@ -219,6 +220,23 @@ class K2Native : CLICompiler() { } } +private fun selectFrameworkType( + configuration: CompilerConfiguration, + arguments: K2NativeCompilerArguments, + outputKind: CompilerOutputKind +): Boolean { + return if (outputKind != CompilerOutputKind.FRAMEWORK && arguments.staticFramework) { + configuration.report( + STRONG_WARNING, + "'$STATIC_FRAMEWORK_FLAG' is only supported when producing frameworks, " + + "but the compiler is producing ${outputKind.name.toLowerCase()}" + ) + false + } else { + arguments.staticFramework + } +} + private fun selectBitcodeEmbeddingMode( configuration: CompilerConfiguration, arguments: K2NativeCompilerArguments, diff --git a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt index 4a07bf8b431..9043303587b 100644 --- a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt +++ b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt @@ -134,6 +134,9 @@ class K2NativeCompilerArguments : CommonCompilerArguments() { @Argument(value = "-Xruntime", deprecatedName = "--runtime", valueDescription = "", description = "Override standard 'runtime.bc' location") var runtimeFile: String? = null + @Argument(value = STATIC_FRAMEWORK_FLAG, description = "Create a framework with a static library instead of a dynamic one") + var staticFramework: Boolean = false + @Argument(value = "-Xtemporary-files-dir", deprecatedName = "--temporary_files_dir", valueDescription = "", description = "Save temporary files to the given directory") var temporaryFilesDir: String? = null @@ -168,3 +171,4 @@ class K2NativeCompilerArguments : CommonCompilerArguments() { const val EMBED_BITCODE_FLAG = "-Xembed-bitcode" const val EMBED_BITCODE_MARKER_FLAG = "-Xembed-bitcode-marker" +const val STATIC_FRAMEWORK_FLAG = "-Xstatic-framework" diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt index bbaf67ef4d4..3be8d039e87 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt @@ -88,6 +88,8 @@ class KonanConfigKeys { = CompilerConfigurationKey.create("override default runtime file path") val SOURCE_MAP: CompilerConfigurationKey> = CompilerConfigurationKey.create("generate source map") + val STATIC_FRAMEWORK: CompilerConfigurationKey + = CompilerConfigurationKey.create("Produce a static library for a framework") val TARGET: CompilerConfigurationKey = CompilerConfigurationKey.create("target we compile for") val TEMPORARY_FILES_DIR: CompilerConfigurationKey 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 ef913c489b1..03f5f1d3c79 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 @@ -15,6 +15,18 @@ typealias BitcodeFile = String typealias ObjectFile = String typealias ExecutableFile = String +private fun determineLinkerOutput(context: Context): LinkerOutputKind = + when (context.config.produce) { + CompilerOutputKind.FRAMEWORK -> { + val staticFramework = context.config.configuration.getBoolean(KonanConfigKeys.STATIC_FRAMEWORK) + if (staticFramework) LinkerOutputKind.STATIC_LIBRARY else LinkerOutputKind.DYNAMIC_LIBRARY + } + CompilerOutputKind.DYNAMIC -> LinkerOutputKind.DYNAMIC_LIBRARY + CompilerOutputKind.STATIC -> LinkerOutputKind.STATIC_LIBRARY + CompilerOutputKind.PROGRAM -> LinkerOutputKind.EXECUTABLE + else -> TODO("${context.config.produce} should not reach native linker stage") + } + internal class LinkStage(val context: Context) { private val config = context.config.configuration @@ -24,12 +36,8 @@ internal class LinkStage(val context: Context) { private val optimize = context.shouldOptimize() private val debug = context.config.debug - private val linkerOutput = when (context.config.produce) { - CompilerOutputKind.DYNAMIC, CompilerOutputKind.FRAMEWORK -> LinkerOutputKind.DYNAMIC_LIBRARY - CompilerOutputKind.STATIC -> LinkerOutputKind.STATIC_LIBRARY - CompilerOutputKind.PROGRAM -> LinkerOutputKind.EXECUTABLE - else -> TODO("${context.config.produce} should not reach native linker stage") - } + private val linkerOutput = determineLinkerOutput(context) + private val nomain = config.get(KonanConfigKeys.NOMAIN) ?: false private val emitted = context.bitcodeFileName private val libraries = context.llvm.librariesToLink