@@ -11,6 +11,7 @@ import org.gradle.api.logging.Logger
1111import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink
1212import org.jetbrains.kotlin.library.KotlinLibraryLayout
1313import org.jetbrains.kotlin.library.impl.KotlinLibraryLayoutImpl
14+ import org.jetbrains.kotlin.library.impl.javaFile
1415import java.io.File
1516
1617internal abstract class CopyResourcesFromKLibsAction : Action <Task > {
@@ -19,50 +20,69 @@ internal abstract class CopyResourcesFromKLibsAction : Action<Task> {
1920 linkTask : KotlinNativeLink ,
2021 outputDir : File
2122 ) {
22- val packedKlibs: List <File > = linkTask.klibs
23- .filter { it.exists() }
24- .filter { it.extension == " klib" }
25- .map { it }
26- val unpackedKlibs: List <File > = linkTask.klibs
27- .filter { it.exists() }
28- // we need only unpacked klibs
29- .filter { it.name == " manifest" && it.parentFile.name == " default" }
30- // manifest stored in klib inside directory default
31- .map { it.parentFile.parentFile }
23+ val logger: Logger = linkTask.logger
3224
33- (packedKlibs + unpackedKlibs)
34- .forEach { inputFile ->
35- linkTask.logger.info(" found dependency $inputFile , try to copy resources" )
36-
37- val layout: KotlinLibraryLayout = getKotlinLibraryLayout(inputFile)
38-
39- copyResourcesFromKlib(
40- logger = linkTask.logger,
41- layout = layout,
42- outputDir = outputDir,
43- )
25+ linkTask.klibs
26+ .onEach { logger.debug(" found klib dependency {}" , it) }
27+ .flatMap { getBundlesFromSources(sourceFile = it, logger = logger) }
28+ .forEach { bundle ->
29+ logger.info(" copy $bundle to $outputDir " )
30+ bundle.copyRecursively(File (outputDir, bundle.name), overwrite = true )
4431 }
4532 }
4633
47- private fun copyResourcesFromKlib (logger : Logger , layout : KotlinLibraryLayout , outputDir : File ) {
48- logger.info(" copy resources from $layout into $outputDir " )
34+ /* *
35+ * Search bundles in klib different types.
36+ *
37+ * We know about 3 types of klib in filesystem:
38+ * 1. packed klib - single file with .klib extension
39+ * 2. unpacked klib directory - root directory with klib content (used for local project
40+ * dependencies)
41+ * 3. unpacked klib content - all files inside klib directory (used for current project
42+ * compilation results)
43+ *
44+ * @param sourceFile file from linking task dependencies and sources list
45+ * @param logger gradle logger
46+ *
47+ * @return list of .bundle directories founded in klibs
48+ */
49+ private fun getBundlesFromSources (sourceFile : File , logger : Logger ): List <File > {
50+ val isPackedKlib = sourceFile.isFile && sourceFile.extension == " klib"
51+ val isUnpackedKlib = sourceFile.isDirectory
4952
50- try {
51- File (layout.resourcesDir.path).copyRecursively(
52- target = outputDir,
53- overwrite = true
54- )
55- } catch (@Suppress(" SwallowedException" ) exc: NoSuchFileException ) {
56- logger.info(" resources in $layout not found" )
57- } catch (@Suppress(" SwallowedException" ) exc: java.nio.file.NoSuchFileException ) {
58- logger.info(" resources in $layout not found (empty lib)" )
53+ return if (isPackedKlib || isUnpackedKlib) {
54+ logger.info(" found klib {}" , sourceFile)
55+ getBundlesFromKotlinLibrary(sourceFile)
56+ } else if (sourceFile.name == " manifest" && sourceFile.parentFile.name == " default" ) {
57+ // for unpacked klibs we can see content files instead of klib directory.
58+ // try to check this case
59+ logger.info(" found manifest of klib {}" , sourceFile)
60+ val unpackedKlibRoot: File = sourceFile.parentFile.parentFile
61+ getBundlesFromKotlinLibrary(unpackedKlibRoot)
62+ } else {
63+ logger.debug(" found some file {}" , sourceFile)
64+ emptyList()
5965 }
6066 }
6167
68+ private fun getBundlesFromKotlinLibrary (
69+ klibFile : File
70+ ): List <File > {
71+ val layout: KotlinLibraryLayout = getKotlinLibraryLayout(klibFile)
72+ return layout.resourcesDir.listFilesOrEmpty
73+ .filter { it.isDirectory && it.extension == " bundle" }
74+ .map { it.javaFile() }
75+ }
76+
6277 private fun getKotlinLibraryLayout (file : File ): KotlinLibraryLayout {
6378 val klibKonan = org.jetbrains.kotlin.konan.file.File (file.path)
6479 val klib = KotlinLibraryLayoutImpl (klib = klibKonan, component = " default" )
6580
81+ // while klib zipped we can't check resources directory, so we should unpack all klibs :(
82+ // maybe will be better if we will write some state in cache as build result file with
83+ // klib path, hash, resources count. to not extract klibs that we already know that not
84+ // contains any resources. BUT maybe extraction will be faster then hashing for this logic.
85+ // so this improvement should be checked in future
6686 return if (klib.isZipped) klib.extractingToTemp else klib
6787 }
6888}
0 commit comments