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 da8011d5ebe..ec682e03bdf 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 @@ -235,6 +235,7 @@ class K2Native : CLICompiler() { put(LIBRARIES_TO_COVER, arguments.coveredLibraries.toNonNullList()) arguments.coverageFile?.let { put(PROFRAW_PATH, it) } put(OBJC_GENERICS, !arguments.noObjcGenerics) + put(DEBUG_PREFIX_MAP, parseDebugPrefixMap(arguments, configuration)) put(LIBRARIES_TO_CACHE, parseLibrariesToCache(arguments, configuration, outputKind)) val libraryToAddToCache = parseLibraryToAddToCache(arguments, configuration, outputKind) @@ -422,5 +423,22 @@ private fun parseShortModuleName( } } +private fun parseDebugPrefixMap( + arguments: K2NativeCompilerArguments, + configuration: CompilerConfiguration +): Map = arguments.debugPrefixMap?.asList().orEmpty().mapNotNull { + val libraryAndCache = it.split("=") + if (libraryAndCache.size != 2) { + configuration.report( + ERROR, + "incorrect debug prefix map format: expected '=', got '$it'" + ) + null + } else { + libraryAndCache[0] to libraryAndCache[1] + } +}.toMap() + + fun main(args: Array) = K2Native.main(args) fun mainNoExitWithGradleRenderer(args: Array) = K2Native.mainNoExitWithGradleRenderer(args) 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 b3ad1c1be4d..ae28e68cb7f 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 @@ -265,6 +265,9 @@ class K2NativeCompilerArguments : CommonCompilerArguments() { @Argument(value = "-Xmetadata-klib", description = "Produce a klib that only contains the declarations metadata") var metadataKlib: Boolean = false + @Argument(value = "-Xdebug-prefix-map", valueDescription = "", description = "Remap file source directory paths in debug info") + var debugPrefixMap: Array? = null + override fun configureAnalysisFlags(collector: MessageCollector): MutableMap, Any> = super.configureAnalysisFlags(collector).also { val useExperimental = it[AnalysisFlags.useExperimental] as List<*> 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 db2e3df553e..3e4634e088d 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 @@ -138,6 +138,8 @@ class KonanConfigKeys { = CompilerConfigurationKey.create("path to *.profraw coverage output") val OBJC_GENERICS: CompilerConfigurationKey = CompilerConfigurationKey.create("write objc header with generics support") + val DEBUG_PREFIX_MAP: CompilerConfigurationKey> + = CompilerConfigurationKey.create("remap file source paths in debug info") } } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BitcodePhases.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BitcodePhases.kt index 033141e2919..cd53f42df41 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BitcodePhases.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BitcodePhases.kt @@ -38,11 +38,13 @@ internal val contextLLVMSetupPhase = makeKonanModuleOpPhase( // we don't split path to filename and directory to provide enough level uniquely for dsymutil to avoid symbol // clashing, which happens on linking with libraries produced from intercepting sources. + val filePath = context.config.outputFile.toFileAndFolder(context).path() + context.debugInfo.compilationUnit = if (context.shouldContainLocationDebugInfo()) DICreateCompilationUnit( builder = context.debugInfo.builder, lang = DWARF.language(context.config), - File = File(context.config.outputFile).absolutePath, - dir = "-", + File = filePath, + dir = "", producer = DWARF.producer, isOptimized = 0, flags = "", 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 f19a8c6e4eb..11c96bee67b 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 @@ -117,16 +117,24 @@ internal data class FileAndFolder(val file: String, val folder: String) { fun path() = if (this == NOFILE) file else "$folder/$file" } -internal fun String?.toFileAndFolder():FileAndFolder { +internal fun String?.toFileAndFolder(context: Context):FileAndFolder { this ?: return FileAndFolder.NOFILE val file = File(this).absoluteFile - return FileAndFolder(file.name, file.parent) + var parent = file.parent + context.configuration.get(KonanConfigKeys.DEBUG_PREFIX_MAP)?.let { debugPrefixMap -> + for ((key, value) in debugPrefixMap) { + if (parent.startsWith(key)) { + parent = value + parent.removePrefix(key) + } + } + } + return FileAndFolder(file.name, parent) } internal fun generateDebugInfoHeader(context: Context) { if (context.shouldContainAnyDebugInfo()) { val path = context.config.outputFile - .toFileAndFolder() + .toFileAndFolder(context) @Suppress("UNCHECKED_CAST") context.debugInfo.module = DICreateModule( builder = context.debugInfo.builder, diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index d70aa43c3ef..64ea98e9be0 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -1896,7 +1896,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map