[K/N] Add option to omit generation of binary when producing framework
`-Xomit-framework-binary` is useful when the user does not care about generated machine code, but only about its public interface. Current use-case is for development purposes only: to iterate faster on ObjCExport. But potentially it can be turned into user-facing feature
This commit is contained in:
+3
@@ -387,6 +387,9 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
|
|||||||
@Argument(value = "-Xpartial-linkage", description = "Allow unlinked symbols")
|
@Argument(value = "-Xpartial-linkage", description = "Allow unlinked symbols")
|
||||||
var partialLinkage: Boolean = false
|
var partialLinkage: Boolean = false
|
||||||
|
|
||||||
|
@Argument(value = "-Xomit-framework-binary", description = "Omit binary when compiling framework")
|
||||||
|
var omitFrameworkBinary: Boolean = false
|
||||||
|
|
||||||
override fun configureAnalysisFlags(collector: MessageCollector, languageVersion: LanguageVersion): MutableMap<AnalysisFlag<*>, Any> =
|
override fun configureAnalysisFlags(collector: MessageCollector, languageVersion: LanguageVersion): MutableMap<AnalysisFlag<*>, Any> =
|
||||||
super.configureAnalysisFlags(collector, languageVersion).also {
|
super.configureAnalysisFlags(collector, languageVersion).also {
|
||||||
val optInList = it[AnalysisFlags.optIn] as List<*>
|
val optInList = it[AnalysisFlags.optIn] as List<*>
|
||||||
|
|||||||
@@ -386,6 +386,7 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
|
|||||||
putIfNotNull(BUNDLE_ID, parseBundleId(arguments, outputKind, configuration))
|
putIfNotNull(BUNDLE_ID, parseBundleId(arguments, outputKind, configuration))
|
||||||
arguments.testDumpOutputPath?.let { put(TEST_DUMP_OUTPUT_PATH, it) }
|
arguments.testDumpOutputPath?.let { put(TEST_DUMP_OUTPUT_PATH, it) }
|
||||||
put(PARTIAL_LINKAGE, arguments.partialLinkage)
|
put(PARTIAL_LINKAGE, arguments.partialLinkage)
|
||||||
|
put(OMIT_FRAMEWORK_BINARY, arguments.omitFrameworkBinary)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-2
@@ -30,9 +30,10 @@ import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
|
|||||||
*/
|
*/
|
||||||
val KonanConfig.isFinalBinary: Boolean get() = when (this.produce) {
|
val KonanConfig.isFinalBinary: Boolean get() = when (this.produce) {
|
||||||
CompilerOutputKind.PROGRAM, CompilerOutputKind.DYNAMIC,
|
CompilerOutputKind.PROGRAM, CompilerOutputKind.DYNAMIC,
|
||||||
CompilerOutputKind.STATIC, CompilerOutputKind.FRAMEWORK -> true
|
CompilerOutputKind.STATIC -> true
|
||||||
CompilerOutputKind.DYNAMIC_CACHE, CompilerOutputKind.STATIC_CACHE,
|
CompilerOutputKind.DYNAMIC_CACHE, CompilerOutputKind.STATIC_CACHE,
|
||||||
CompilerOutputKind.LIBRARY, CompilerOutputKind.BITCODE -> false
|
CompilerOutputKind.LIBRARY, CompilerOutputKind.BITCODE -> false
|
||||||
|
CompilerOutputKind.FRAMEWORK -> !omitFrameworkBinary
|
||||||
}
|
}
|
||||||
|
|
||||||
val CompilerOutputKind.involvesBitcodeGeneration: Boolean
|
val CompilerOutputKind.involvesBitcodeGeneration: Boolean
|
||||||
@@ -45,8 +46,9 @@ val KonanConfig.involvesLinkStage: Boolean
|
|||||||
get() = when (this.produce) {
|
get() = when (this.produce) {
|
||||||
CompilerOutputKind.PROGRAM, CompilerOutputKind.DYNAMIC,
|
CompilerOutputKind.PROGRAM, CompilerOutputKind.DYNAMIC,
|
||||||
CompilerOutputKind.DYNAMIC_CACHE, CompilerOutputKind.STATIC_CACHE,
|
CompilerOutputKind.DYNAMIC_CACHE, CompilerOutputKind.STATIC_CACHE,
|
||||||
CompilerOutputKind.STATIC, CompilerOutputKind.FRAMEWORK -> true
|
CompilerOutputKind.STATIC-> true
|
||||||
CompilerOutputKind.LIBRARY, CompilerOutputKind.BITCODE -> false
|
CompilerOutputKind.LIBRARY, CompilerOutputKind.BITCODE -> false
|
||||||
|
CompilerOutputKind.FRAMEWORK -> !omitFrameworkBinary
|
||||||
}
|
}
|
||||||
|
|
||||||
val CompilerOutputKind.isCache: Boolean
|
val CompilerOutputKind.isCache: Boolean
|
||||||
@@ -183,6 +185,10 @@ internal fun produceOutput(context: Context) {
|
|||||||
val produce = config.get(KonanConfigKeys.PRODUCE)
|
val produce = config.get(KonanConfigKeys.PRODUCE)
|
||||||
if (produce == CompilerOutputKind.FRAMEWORK) {
|
if (produce == CompilerOutputKind.FRAMEWORK) {
|
||||||
context.objCExport.produceFrameworkInterface()
|
context.objCExport.produceFrameworkInterface()
|
||||||
|
if (context.config.omitFrameworkBinary) {
|
||||||
|
// Compiler does not compile anything in this mode, so return early.
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
when (produce) {
|
when (produce) {
|
||||||
CompilerOutputKind.STATIC,
|
CompilerOutputKind.STATIC,
|
||||||
|
|||||||
+12
@@ -397,6 +397,18 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
|||||||
&& librariesToCache.isEmpty()
|
&& librariesToCache.isEmpty()
|
||||||
&& configuration[KonanConfigKeys.EXPORTED_LIBRARIES].isNullOrEmpty()
|
&& configuration[KonanConfigKeys.EXPORTED_LIBRARIES].isNullOrEmpty()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not compile binary when compiling framework.
|
||||||
|
* This is useful when user care only about framework's interface.
|
||||||
|
*/
|
||||||
|
internal val omitFrameworkBinary: Boolean by lazy {
|
||||||
|
configuration.getBoolean(KonanConfigKeys.OMIT_FRAMEWORK_BINARY).also {
|
||||||
|
if (it && produce != CompilerOutputKind.FRAMEWORK) {
|
||||||
|
configuration.report(CompilerMessageSeverity.STRONG_WARNING,
|
||||||
|
"Trying to disable framework binary compilation when producing ${produce.name.lowercase()} is meaningless.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun CompilerConfiguration.report(priority: CompilerMessageSeverity, message: String)
|
fun CompilerConfiguration.report(priority: CompilerMessageSeverity, message: String)
|
||||||
|
|||||||
+1
-1
@@ -172,7 +172,7 @@ class KonanConfigKeys {
|
|||||||
val LAZY_IR_FOR_CACHES: CompilerConfigurationKey<Boolean> = CompilerConfigurationKey.create("use lazy IR for cached libraries")
|
val LAZY_IR_FOR_CACHES: CompilerConfigurationKey<Boolean> = CompilerConfigurationKey.create("use lazy IR for cached libraries")
|
||||||
val PARTIAL_LINKAGE: CompilerConfigurationKey<Boolean> = CompilerConfigurationKey.create("allows some symbols in klibs be missed")
|
val PARTIAL_LINKAGE: CompilerConfigurationKey<Boolean> = CompilerConfigurationKey.create("allows some symbols in klibs be missed")
|
||||||
val TEST_DUMP_OUTPUT_PATH: CompilerConfigurationKey<String?> = CompilerConfigurationKey.create("path to a file to dump the list of all available tests")
|
val TEST_DUMP_OUTPUT_PATH: CompilerConfigurationKey<String?> = CompilerConfigurationKey.create("path to a file to dump the list of all available tests")
|
||||||
|
val OMIT_FRAMEWORK_BINARY: CompilerConfigurationKey<Boolean> = CompilerConfigurationKey.create("do not generate binary in framework")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -622,7 +622,7 @@ internal fun PhaseConfig.konanPhasesConfig(config: KonanConfig) {
|
|||||||
disableUnless(entryPointPhase, config.produce == CompilerOutputKind.PROGRAM)
|
disableUnless(entryPointPhase, config.produce == CompilerOutputKind.PROGRAM)
|
||||||
disableUnless(buildAdditionalCacheInfoPhase, config.produce.isCache && config.lazyIrForCaches)
|
disableUnless(buildAdditionalCacheInfoPhase, config.produce.isCache && config.lazyIrForCaches)
|
||||||
disableUnless(exportInternalAbiPhase, config.produce.isCache)
|
disableUnless(exportInternalAbiPhase, config.produce.isCache)
|
||||||
disableIf(backendCodegen, config.produce == CompilerOutputKind.LIBRARY)
|
disableIf(backendCodegen, config.produce == CompilerOutputKind.LIBRARY || config.omitFrameworkBinary)
|
||||||
disableUnless(checkExternalCallsPhase, getBoolean(KonanConfigKeys.CHECK_EXTERNAL_CALLS))
|
disableUnless(checkExternalCallsPhase, getBoolean(KonanConfigKeys.CHECK_EXTERNAL_CALLS))
|
||||||
disableUnless(rewriteExternalCallsCheckerGlobals, getBoolean(KonanConfigKeys.CHECK_EXTERNAL_CALLS))
|
disableUnless(rewriteExternalCallsCheckerGlobals, getBoolean(KonanConfigKeys.CHECK_EXTERNAL_CALLS))
|
||||||
disableUnless(stringConcatenationTypeNarrowingPhase, config.optimizationsEnabled)
|
disableUnless(stringConcatenationTypeNarrowingPhase, config.optimizationsEnabled)
|
||||||
@@ -655,7 +655,7 @@ internal fun PhaseConfig.konanPhasesConfig(config: KonanConfig) {
|
|||||||
|
|
||||||
disableUnless(removeRedundantSafepointsPhase, config.memoryModel == MemoryModel.EXPERIMENTAL)
|
disableUnless(removeRedundantSafepointsPhase, config.memoryModel == MemoryModel.EXPERIMENTAL)
|
||||||
|
|
||||||
if (config.metadataKlib) {
|
if (config.metadataKlib || config.omitFrameworkBinary) {
|
||||||
disable(psiToIrPhase)
|
disable(psiToIrPhase)
|
||||||
disable(copyDefaultValuesToActualPhase)
|
disable(copyDefaultValuesToActualPhase)
|
||||||
disable(specialBackendChecksPhase)
|
disable(specialBackendChecksPhase)
|
||||||
|
|||||||
Reference in New Issue
Block a user