KT-39670: -Xdebug-prefix-map for path remapping
This introduces a new `-Xdebug-prefix-map` flag. When compiling files with directories prefixed by the map key, the prefix will be changed to the map value. This allows for reproducable builds by replacing absolute paths with relative ones. (cherry picked from commit bba4ce1c2c5ee06b9f5f65148ac8ef883715474a)
This commit is contained in:
committed by
Vasily Levchenko
parent
f135220444
commit
c1f0a6048b
@@ -235,6 +235,7 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
|
||||
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<String, String> = arguments.debugPrefixMap?.asList().orEmpty().mapNotNull {
|
||||
val libraryAndCache = it.split("=")
|
||||
if (libraryAndCache.size != 2) {
|
||||
configuration.report(
|
||||
ERROR,
|
||||
"incorrect debug prefix map format: expected '<old>=<new>', got '$it'"
|
||||
)
|
||||
null
|
||||
} else {
|
||||
libraryAndCache[0] to libraryAndCache[1]
|
||||
}
|
||||
}.toMap()
|
||||
|
||||
|
||||
fun main(args: Array<String>) = K2Native.main(args)
|
||||
fun mainNoExitWithGradleRenderer(args: Array<String>) = K2Native.mainNoExitWithGradleRenderer(args)
|
||||
|
||||
@@ -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 = "<old1=new1,old2=new2,...>", description = "Remap file source directory paths in debug info")
|
||||
var debugPrefixMap: Array<String>? = null
|
||||
|
||||
override fun configureAnalysisFlags(collector: MessageCollector): MutableMap<AnalysisFlag<*>, Any> =
|
||||
super.configureAnalysisFlags(collector).also {
|
||||
val useExperimental = it[AnalysisFlags.useExperimental] as List<*>
|
||||
|
||||
+2
@@ -138,6 +138,8 @@ class KonanConfigKeys {
|
||||
= CompilerConfigurationKey.create("path to *.profraw coverage output")
|
||||
val OBJC_GENERICS: CompilerConfigurationKey<Boolean>
|
||||
= CompilerConfigurationKey.create("write objc header with generics support")
|
||||
val DEBUG_PREFIX_MAP: CompilerConfigurationKey<Map<String, String>>
|
||||
= CompilerConfigurationKey.create("remap file source paths in debug info")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -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 = "",
|
||||
|
||||
+11
-3
@@ -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,
|
||||
|
||||
+1
-1
@@ -1896,7 +1896,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
//-------------------------------------------------------------------------//
|
||||
private fun IrFile.file(): DIFileRef {
|
||||
return context.debugInfo.files.getOrPut(this.fileEntry.name) {
|
||||
val path = this.fileEntry.name.toFileAndFolder()
|
||||
val path = this.fileEntry.name.toFileAndFolder(context)
|
||||
DICreateFile(context.debugInfo.builder, path.file, path.folder)!!
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user