kotlin
kotlin copied to clipboard
add resources to klib
problem
If we publish a Kotlin Native library. It will take the klib file outputed by compileKotlinNative task.
the klib file's layout like this:

It has a resources directory which is empty, even I put some file in common resources directory.

reason
the ${target}ProcessResources task will merge common resources directory and target resources directory into build/processedResources/native/main directory.

And Kotlin gradle plugin create a ${target}Jar task for some target, like js and jvm target. for example:
jstarget's jar task isjsJar.jvmtarget's jar task isjvmJar.
and ${target}Jar task will archive:
- Kotlin compile output directory
- Kotlin resources directory
so ${target}Jar task depends on these two output. for example:
-
jsJardepends on:compileKotlinJsjsMainClasseswhich depends onjsProcessResources
-
jvmJardepends on:compileKotlinJvmjvmMainClasseswhich depends onjvmProcessResources
compileKotlinJvm and jvmMainClasses are two separate task. they don't depends on each other.
js target or jvm target will publish the jar outputed by ${target}Jar task.
Kotlin Native problem
Kotlin Native publishes the klib file outputed by compileKotlinNative task, which does not depend on nativeProcessResources task, and compileKotlinNative task has not resources input property.
the solution
- make
compileKotlinNativetask depends onnativeProcessResourcestask. - pass the resources directory to
compileKotlinNativetask, and copy the resources directory toklibresources directory.
result

TODO
when create a binary contains resources(like iOS framework), merge all dependencies klib resources directory into framework.
@abelkov hello, can you add a reviewer for my push?
Hey, thanks a lot for the contribution!
We need to discuss it with the team. Unfortunately, some relevant folks are absent on this week. I'll follow-up somewhere around the next week (17th of May -- 21st of May)
Hey, thanks a lot for the contribution!
We need to discuss it with the team. Unfortunately, some relevant folks are absent on this week. I'll follow-up somewhere around the next week (17th of May -- 21st of May)
ok, thanks. Kotlin JS has the sample problem. I have mentioned in https://github.com/JetBrains/kotlin/pull/4385.
Hey, thanks a lot for the contribution!
We need to discuss it with the team. Unfortunately, some relevant folks are absent on this week. I'll follow-up somewhere around the next week (17th of May -- 21st of May)
hello, what's the progress of this issue.
We need some more time to discuss it, sorry.
To give you some context: the design of resources in MPP and in klibs in particular is still work-in-progress. Therefore, we need to make sure that the proposed changes align nicely at least with possible future work in that area, least we'll have to deprecate and phase out those changes in like half a year. We're evaluating other possible options and workarounds, as well as the amount of pain they will cause compared to out-of-the-box solution vs. the probability of those solutions to need deprecation in future.
@jiqimaogou could you please describe a bit your use case of resources in klib? The PR adds some logic to put resources into zipped klib without using them. Seems like at least that kind of work could be done on the build script level (produce unzipped klib, copy resource folder into compiler output dir, zip it using corresponding zip task).
@jiqimaogou could you please describe a bit your use case of resources in klib? The PR adds some logic to put resources into zipped klib without using them. Seems like at least that kind of work could be done on the build script level (produce unzipped klib, copy resource folder into compiler output dir, zip it using corresponding zip task).
In the TODO, I will put klib resources into iOS framework. I will do it this week. the use case is that I make a home module as a klib, and I will put some resources(like international strings) into klib, and read it in platform native code.
in Android, AAR contains code and resources. in iOS, the framework contains code and resources. in Java, the jar contains code and resources.
I think as a Kotlin module, it may be reasonable to contain resources.
@jiqimaogou Thank you for your response.
and read it in platform native code.
Why do you think those resources going to be accessible in your application? There is some extra that has to be done either on the compiler side or build side to make that possible. I would prefer the build side TBH.
I think as a Kotlin module, it may be reasonable to contain resources.
I agree with that.
@jiqimaogou Thank you for your response.
and read it in platform native code.
Why do you think those resources going to be accessible in your application? There is some extra that has to be done either on the compiler side or build side to make that possible. I would prefer the build side TBH.
I think as a Kotlin module, it may be reasonable to contain resources.
I agree with that.
yes, we can do it on the build side. I put it on the compiler side, because compile and Link are the same task with different compile options. If I do it on the build side, I must create a new task depends on the Link framework, and merge resources with the framework in the new place. If I put it on the compiler side, it will be less complicated.
I want to know is, does the Kotlin team has a plan to support contains resources in the Kotlin module? If you have a plan, I think the official team's implementation is more suitable. My push request purpose is just to take my push request as a reference. It may be more convincing to write code than submit an issue.
I want to know is, does the Kotlin team has a plan to support contains resources in the Kotlin module?
Yes, we have such plan.
Anyway, it would be great if you create an issue in YT with a short description of your use-case, even with reference to this PR.
Do you need any help with build script code?
I want to know is, does the Kotlin team has a plan to support contains resources in the Kotlin module?
Yes, we have such plan.
Anyway, it would be great if you create an issue in YT with a short description of your use-case, even with reference to this PR.
Do you need any help with build script code?
I have create a issue: https://youtrack.jetbrains.com/issues?q=project:%20%7BKT%7D&preview=KT-46956
@jiqimaogou Thank you for issue.
So do you need any help with build script?
@jiqimaogou Thank you for issue.
So do you need any help with build script?
sorry, I don't know the context of the build script. Is it the feature of packaging the klib resources into the framework I will do later?
I don't know if I must continue, I don't know the Kotlin team's plan, maybe you have a different implementation?
@jiqimaogou Thank you for issue. So do you need any help with build script?
sorry, I don't know the context of the build script. Is it the feature of packaging the klib resources into the framework I will do later?
I don't know if I must continue, I don't know the Kotlin team's plan, maybe you have a different implementation?
I mean do you need any help with how to put resources into klib using gradle?
I don't know the Kotlin team's plan, maybe you have a different implementation?
We don't actually. The implementation should naturally come from design which is led by use cases. So now we have the first use case. I believe your implementation is completely correct but to be accepted first requires some extra work from Kotlin team.
@jiqimaogou Thank you for issue. So do you need any help with build script?
sorry, I don't know the context of the build script. Is it the feature of packaging the klib resources into the framework I will do later? I don't know if I must continue, I don't know the Kotlin team's plan, maybe you have a different implementation?
I mean do you need any help with how to put resources into klib using gradle?
I don't know the Kotlin team's plan, maybe you have a different implementation?
We don't actually. The implementation should naturally come from design which is led by use cases. So now we have the first use case. I believe your implementation is completely correct but to be accepted first requires some extra work from Kotlin team.
yes, I need some help.
val shouldAddCompileOutputsToElements = compilation.owner is KotlinGradleVariant || compilation.isMainCompilationData()
when compilation.owner is KotlinGradleVariant is true and compilation.isMainCompilationData() is false?
I found it may publish multiple klib files at once.
when
compilation.owner is KotlinGradleVariantis true andcompilation.isMainCompilationData()is false?
For now, compilation.owner is KotlinGradleVariant is true only in our experimental (not officially released) plugins. In those plugins, not just the main parts of a project might be exposed to project-to-project dependencies, but other parts as well. If you only aim to work with the org.jetbrains.kotlin.multiplatform plugin, you can safely assume that compilation.owner is KotlinGradleVariant is always false.
@romanart I have updated my commit, put the resources file into klib with at build script side instead of compiler side.
the solution
In Java, it creates a task named ${target}Jar packages main(only) compilation outputs.

In my solution for Kotlin native:

I create a task named ${compilation}Klib(maybe the task name is not well) packages every compilation output and publishes the output.
if the commit is OK, I will do the next step to package all klib resources into the ios framework.
@jiqimaogou Thanks! It's good to have your PR as a reference for a future implementation once we have a proper design for resources in Kotlin/Native KLIBs and binaries!
As you can see, our current implementation of KLIB generation is somewhat inconsistent in that some tasks (for platform-specific compilations) pack a KLIB directly as an archive, and some tasks (those for common/intermediate source sets) produce an unpacked KLIB. So if you want to package resources into the outputs without the changes in this PR, using just the build script, probably the easiest way would be to add some code to the tasks using doLast and write the resources to the output directory or the KLIB, depending on what the task produces.
@jiqimaogou Thanks! It's good to have your PR as a reference for a future implementation once we have a proper design for resources in Kotlin/Native KLIBs and binaries!
As you can see, our current implementation of KLIB generation is somewhat inconsistent in that some tasks (for platform-specific compilations) pack a KLIB directly as an archive, and some tasks (those for common/intermediate source sets) produce an unpacked KLIB. So if you want to package resources into the outputs without the changes in this PR, using just the build script, probably the easiest way would be to add some code to the tasks using
doLastand write the resources to the output directory or the KLIB, depending on what the task produces.
OK, I know, the Kotlin team has not the proper design yet. So at current, it's recommended to implement the feature in my own build.gradle file instead of in the Kotlin repository.