[caches] Make output for cache a directory
(cherry picked from commit 9850bb322bee2bc98fc453a440e41af0dac0b0f2)
This commit is contained in:
committed by
Vasily Levchenko
parent
57621d12c5
commit
90044108e0
+21
-16
@@ -23,34 +23,39 @@ class CachedLibraries(
|
||||
enum class Kind { DYNAMIC, STATIC }
|
||||
}
|
||||
|
||||
private fun selectCache(library: KotlinLibrary, cacheDir: File): Cache? {
|
||||
// See Linker.renameOutput why is it ok to have an empty cache directory.
|
||||
if (cacheDir.listFilesOrEmpty.isEmpty()) return null
|
||||
val baseName = getCachedLibraryName(library)
|
||||
val dynamicFile = cacheDir.child(getArtifactName(baseName, CompilerOutputKind.DYNAMIC_CACHE))
|
||||
val staticFile = cacheDir.child(getArtifactName(baseName, CompilerOutputKind.STATIC_CACHE))
|
||||
|
||||
if (dynamicFile.exists && staticFile.exists)
|
||||
error("Both dynamic and static caches files cannot be in the same directory." +
|
||||
" Library: ${library.libraryName}, path to cache: ${cacheDir.absolutePath}")
|
||||
return when {
|
||||
dynamicFile.exists -> Cache(Cache.Kind.DYNAMIC, dynamicFile.absolutePath)
|
||||
staticFile.exists -> Cache(Cache.Kind.STATIC, staticFile.absolutePath)
|
||||
else -> error("No cache found for library ${library.libraryName} at ${cacheDir.absolutePath}")
|
||||
}
|
||||
}
|
||||
|
||||
private val allCaches: Map<KotlinLibrary, Cache> = allLibraries.mapNotNull { library ->
|
||||
val explicitPath = explicitCaches[library]
|
||||
|
||||
val cache = if (explicitPath != null) {
|
||||
val kind = when {
|
||||
explicitPath.endsWith(target.family.dynamicSuffix) -> Cache.Kind.DYNAMIC
|
||||
explicitPath.endsWith(target.family.staticSuffix) -> Cache.Kind.STATIC
|
||||
else -> error("unexpected cache: $explicitPath")
|
||||
}
|
||||
Cache(kind, explicitPath)
|
||||
selectCache(library, File(explicitPath))
|
||||
?: error("No cache found for library ${library.libraryName} at $explicitPath")
|
||||
} else {
|
||||
implicitCacheDirectories.firstNotNullResult { dir ->
|
||||
val baseName = getCachedLibraryName(library)
|
||||
val dynamicFile = dir.child(getArtifactName(baseName, CompilerOutputKind.DYNAMIC_CACHE))
|
||||
val staticFile = dir.child(getArtifactName(baseName, CompilerOutputKind.STATIC_CACHE))
|
||||
|
||||
when {
|
||||
dynamicFile.exists -> Cache(Cache.Kind.DYNAMIC, dynamicFile.absolutePath)
|
||||
staticFile.exists -> Cache(Cache.Kind.STATIC, staticFile.absolutePath)
|
||||
else -> null
|
||||
}
|
||||
selectCache(library, dir.child(getCachedLibraryName(library)))
|
||||
}
|
||||
}
|
||||
|
||||
cache?.let { library to it }
|
||||
}.toMap()
|
||||
|
||||
fun getArtifactName(baseName: String, kind: CompilerOutputKind) =
|
||||
private fun getArtifactName(baseName: String, kind: CompilerOutputKind) =
|
||||
"${kind.prefix(target)}$baseName${kind.suffix(target)}"
|
||||
|
||||
fun isLibraryCached(library: KotlinLibrary): Boolean =
|
||||
|
||||
+10
-11
@@ -5,7 +5,6 @@ import org.jetbrains.kotlin.konan.file.File
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
import org.jetbrains.kotlin.konan.target.Family
|
||||
import org.jetbrains.kotlin.konan.target.LinkerOutputKind
|
||||
import org.jetbrains.kotlin.backend.konan.files.renameAtomic
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
||||
|
||||
internal fun determineLinkerOutput(context: Context): LinkerOutputKind =
|
||||
@@ -45,21 +44,21 @@ internal class Linker(val context: Context) {
|
||||
|
||||
val libraryProvidedLinkerFlags = context.llvm.allNativeDependencies.map { it.linkerOpts }.flatten()
|
||||
|
||||
if (context.config.produce.isCache)
|
||||
context.config.outputFiles.tempCacheDirectory!!.mkdirs()
|
||||
runLinker(objectFiles, includedBinaries, libraryProvidedLinkerFlags)
|
||||
|
||||
renameOutput()
|
||||
}
|
||||
|
||||
private fun renameOutput() {
|
||||
if (context.config.produce.isCache) {
|
||||
val outputFiles = context.config.outputFiles
|
||||
val outputFile = java.io.File(outputFiles.mainFileMangled)
|
||||
val outputDsymBundle = java.io.File(outputFiles.mainFileMangled + ".dSYM")
|
||||
if (renameAtomic(outputFile.absolutePath, outputFiles.mainFile, /* replaceExisting = */ false))
|
||||
outputDsymBundle.renameTo(java.io.File(outputFiles.mainFile + ".dSYM"))
|
||||
else {
|
||||
outputFile.delete()
|
||||
outputDsymBundle.deleteRecursively()
|
||||
}
|
||||
// For caches the output file is a directory. It might be created by someone else,
|
||||
// We have to delete it in order to the next renaming operation to succeed.
|
||||
java.io.File(outputFiles.mainFile).delete()
|
||||
if (!java.io.File(outputFiles.tempCacheDirectory!!.absolutePath).renameTo(java.io.File(outputFiles.mainFile)))
|
||||
outputFiles.tempCacheDirectory.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +95,7 @@ internal class Linker(val context: Context) {
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
executable = context.config.outputFiles.mainFileMangled
|
||||
executable = context.config.outputFiles.nativeBinaryFile
|
||||
} else {
|
||||
val framework = File(context.config.outputFile)
|
||||
val dylibName = framework.name.removeSuffix(".framework")
|
||||
@@ -127,7 +126,7 @@ internal class Linker(val context: Context) {
|
||||
caches.dynamic +
|
||||
libraryProvidedLinkerFlags + additionalLinkerArgs,
|
||||
optimize = optimize, debug = debug, kind = linkerOutput,
|
||||
outputDsymBundle = context.config.outputFiles.mainFileMangled + ".dSYM",
|
||||
outputDsymBundle = context.config.outputFiles.symbolicInfoFile,
|
||||
needsProfileLibrary = needsProfileLibrary).forEach {
|
||||
it.logWith(context::log)
|
||||
it.execute()
|
||||
|
||||
+28
-20
@@ -27,33 +27,41 @@ class OutputFiles(outputPath: String?, target: KonanTarget, val produce: Compile
|
||||
/**
|
||||
* Header file for dynamic library.
|
||||
*/
|
||||
val cAdapterHeader by lazy { File("${outputName}_api.h") }
|
||||
val cAdapterDef by lazy { File("${outputName}.def") }
|
||||
val cAdapterHeader by lazy { File("${outputName}_api.h") }
|
||||
val cAdapterDef by lazy { File("${outputName}.def") }
|
||||
|
||||
/**
|
||||
* Main compiler's output file.
|
||||
*/
|
||||
val mainFile = outputName
|
||||
.prefixBaseNameIfNeeded(prefix)
|
||||
.suffixIfNeeded(suffix)
|
||||
val mainFile =
|
||||
if (produce.isCache)
|
||||
outputName
|
||||
else
|
||||
outputName.fullOutputName()
|
||||
|
||||
val mainFileMangled = if (!produce.isCache) mainFile else {
|
||||
(outputName + Random.nextLong().toString())
|
||||
.prefixBaseNameIfNeeded(prefix)
|
||||
.suffixIfNeeded(suffix)
|
||||
}
|
||||
val tempCacheDirectory =
|
||||
if (produce.isCache)
|
||||
File(outputName + Random.nextLong().toString())
|
||||
else null
|
||||
|
||||
private fun String.prefixBaseNameIfNeeded(prefix: String): String {
|
||||
return if (produce.isCache)
|
||||
prefixBaseNameAlways(prefix)
|
||||
else prefixBaseNameIfNot(prefix)
|
||||
}
|
||||
val nativeBinaryFile =
|
||||
if (produce.isCache)
|
||||
tempCacheDirectory!!.child(File(outputName.fullOutputName()).absoluteFile.name).absolutePath
|
||||
else mainFile
|
||||
|
||||
private fun String.suffixIfNeeded(prefix: String): String {
|
||||
return if (produce.isCache)
|
||||
suffixAlways(prefix)
|
||||
else suffixIfNot(prefix)
|
||||
}
|
||||
val symbolicInfoFile = "$nativeBinaryFile.dSYM"
|
||||
|
||||
private fun String.fullOutputName() = prefixBaseNameIfNeeded(prefix).suffixIfNeeded(suffix)
|
||||
|
||||
private fun String.prefixBaseNameIfNeeded(prefix: String) =
|
||||
if (produce.isCache)
|
||||
prefixBaseNameAlways(prefix)
|
||||
else prefixBaseNameIfNot(prefix)
|
||||
|
||||
private fun String.suffixIfNeeded(prefix: String) =
|
||||
if (produce.isCache)
|
||||
suffixAlways(prefix)
|
||||
else suffixIfNot(prefix)
|
||||
|
||||
private fun String.prefixBaseNameAlways(prefix: String): String {
|
||||
val file = File(this).absoluteFile
|
||||
|
||||
@@ -25,7 +25,7 @@ fun configureCacheTesting(project: Project): CacheTesting? {
|
||||
val target = project.testTarget
|
||||
|
||||
val cacheDir = project.file("${project.buildDir}/cache")
|
||||
val cacheFile = "$cacheDir/${cacheKind.prefix(target)}stdlib-cache${cacheKind.suffix(target)}"
|
||||
val cacheFile = "$cacheDir/stdlib-cache"
|
||||
val dist = project.kotlinNativeDist
|
||||
val stdlib = "$dist/klib/common/stdlib"
|
||||
val compilerArgs = listOf("-Xcached-library=$stdlib,$cacheFile")
|
||||
|
||||
+2
-6
@@ -31,15 +31,11 @@ open class KonanCacheTask: DefaultTask() {
|
||||
val cacheDirectory: File
|
||||
get() = cacheRoot.resolve("$target-g$cacheKind")
|
||||
|
||||
@get:OutputFile
|
||||
@get:OutputDirectory
|
||||
protected val cacheFile: File
|
||||
get() {
|
||||
val konanTarget = HostManager().targetByName(target)
|
||||
val klibName = originalKlib.nameWithoutExtension
|
||||
val cachePrefix = cacheKind.outputKind.prefix(konanTarget)
|
||||
val cacheSuffix = cacheKind.outputKind.suffix(konanTarget)
|
||||
val cacheName = "${cachePrefix}${klibName}-cache${cacheSuffix}"
|
||||
return cacheDirectory.resolve(cacheName)
|
||||
return cacheDirectory.resolve("${klibName}-cache")
|
||||
}
|
||||
|
||||
@Input
|
||||
|
||||
+5
-5
@@ -260,7 +260,7 @@ private fun generateLibrary(
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCacheFile(
|
||||
private fun getLibraryCacheDir(
|
||||
libraryName: String,
|
||||
target: KonanTarget,
|
||||
cacheDirectory: File,
|
||||
@@ -279,14 +279,14 @@ private fun buildCache(
|
||||
rebuild: Boolean,
|
||||
logger: Logger
|
||||
) = with(cacheInfo) {
|
||||
val cacheFile = getCacheFile(def.name, target, cacheDirectory, cacheKind)
|
||||
if (cacheFile.exists && !rebuild) {
|
||||
val libraryCacheDir = getLibraryCacheDir(def.name, target, cacheDirectory, cacheKind)
|
||||
if (libraryCacheDir.listFilesOrEmpty.isNotEmpty() && !rebuild) {
|
||||
logger.verbose("Skip precompiling ${def.name} as it's already precompiled")
|
||||
return
|
||||
}
|
||||
|
||||
if (rebuild) {
|
||||
cacheFile.delete()
|
||||
libraryCacheDir.deleteRecursively()
|
||||
}
|
||||
|
||||
val compilerArgs = arrayOf(
|
||||
@@ -307,7 +307,7 @@ private fun buildStdlibCache(
|
||||
cacheInfo: CacheInfo,
|
||||
logger: Logger
|
||||
) = with(cacheInfo) {
|
||||
val stdlibCacheFile = getCacheFile("stdlib", target, cacheDirectory, cacheKind)
|
||||
val stdlibCacheFile = getLibraryCacheDir("stdlib", target, cacheDirectory, cacheKind)
|
||||
if (stdlibCacheFile.exists) {
|
||||
logger.verbose("Skip precompiling standard library as it's already precompiled")
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user