How to exclude Kotlin files from compiling with Gradle - android

With Java, we are excluding like this:
java {
srcDir 'src'
exclude '**/myTests/**'
}
I want to make the same thing with Kotlin.
I am trying to find some documentation on this in official documentation configuring Kotlin, but without any success.
What I've expected and already tried (and of course without any success):
kotlin {
srcDir 'src'
exclude '**/myTests/*.kt'
}

java {
srcDir 'src'
exclude '**/myTests/*.kt'
}
There isn't any Kotlin related configuration.
Why I am saying this: I have all the Kotlin files into the kotlin directory and Java files into java directory. But while configuring, I have added:
sourceSets {
main.java.srcDirs += "src/main/kotlin"
}
This means that with src/main/java, add source files from src/main/kotlin also while compiling.
This should solve your issue.

Android (likely need improvement, seems flaky):
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile.class).configureEach {
it.exclude('**/TestExcludeKotlinClass.kt')
}

If you use a Kotlin Gradle project, try this:
tasks.withType<KotlinCompile> {
exclude("**/packageToExlude/**")}
In my case, a non-Android project.

I came across a way to make this work specifically for Android unit tests (but I'm assuming it's adaptable) using a combination of other solutions here:
def filesToExclude = [
'**/*TestOne*.kt',
'**/*TestTwo*.kt',
...
]
tasks.withType(org.gradle.api.tasks.SourceTask.class).configureEach {
it.exclude(filesToExclude)
}
android.sourceSets.test.kotlin.exclude(filesToExclude)
In my particular case, the extra wildcards around the test name were needed due to other generation occurring (specifically, Dagger with kapt).
This seems to be a bit hacky way to approach it, but it works by ensuring the test target is excluded from all tasks that it could actually be excluded from (including both build & kapt tasks). The sourceSets exclusion is still necessary for the file not to be picked up for compilation (I think this is the Kotlin Gradle Plugin doing it, but it might also be the Android Gradle Plugin).

Related

How to exclude a Kotlin file? [duplicate]

With Java, we are excluding like this:
java {
srcDir 'src'
exclude '**/myTests/**'
}
I want to make the same thing with Kotlin.
I am trying to find some documentation on this in official documentation configuring Kotlin, but without any success.
What I've expected and already tried (and of course without any success):
kotlin {
srcDir 'src'
exclude '**/myTests/*.kt'
}
java {
srcDir 'src'
exclude '**/myTests/*.kt'
}
There isn't any Kotlin related configuration.
Why I am saying this: I have all the Kotlin files into the kotlin directory and Java files into java directory. But while configuring, I have added:
sourceSets {
main.java.srcDirs += "src/main/kotlin"
}
This means that with src/main/java, add source files from src/main/kotlin also while compiling.
This should solve your issue.
Android (likely need improvement, seems flaky):
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile.class).configureEach {
it.exclude('**/TestExcludeKotlinClass.kt')
}
If you use a Kotlin Gradle project, try this:
tasks.withType<KotlinCompile> {
exclude("**/packageToExlude/**")}
In my case, a non-Android project.
I came across a way to make this work specifically for Android unit tests (but I'm assuming it's adaptable) using a combination of other solutions here:
def filesToExclude = [
'**/*TestOne*.kt',
'**/*TestTwo*.kt',
...
]
tasks.withType(org.gradle.api.tasks.SourceTask.class).configureEach {
it.exclude(filesToExclude)
}
android.sourceSets.test.kotlin.exclude(filesToExclude)
In my particular case, the extra wildcards around the test name were needed due to other generation occurring (specifically, Dagger with kapt).
This seems to be a bit hacky way to approach it, but it works by ensuring the test target is excluded from all tasks that it could actually be excluded from (including both build & kapt tasks). The sourceSets exclusion is still necessary for the file not to be picked up for compilation (I think this is the Kotlin Gradle Plugin doing it, but it might also be the Android Gradle Plugin).

is it possible to use kotlin on the JVM or Android without a dependency on kotlin-stdlib?

I have an android library that I distribute as a jar file; Currently it has zero dependencies (other than the things built into Java itself). I like the idea of porting it to kotlin, however I haven't been able to figure out how to do this without forcing a dependency on kotlin-stdlib (or kotlin-stdlib-jre7, etc)
I'm somewhat wary about doing this, because kotlin-stdlib gets updates very frequently (multiple times per month sometimes) and I don't want to cause a future compatibility problem.
Obviously if I use any of the kotlin specific functions or types (e.g. listOf, mapOf, etc) then of course I'd need the stdlib, but if I stick to pure java types and functions, then is this possible? And if so, how?
I am not sure this is what you are looking for but I was able to build and run run this simple program using IntelliJ Idea 2018.3
fun main() {
System.out.println("hello world")
}
and the following build.gradle file
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.3.11'
}
apply plugin: 'application'
mainClassName = "MainKt"
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
The only thing I saw in the jar file, other than a META-INF folder was my MainKt.class
I was able to run this on the jvm using
java -classpath simple.jar MainKt
I think if you don't include the standard library you cant even use Kotlin's println function, so you have to resort to java's System.out.println method

How to exclude a cpp file in experimental gradle?

I'm trying to use Android Studio 1.3.1 to compile an NDK project using the experimental gradle syntax.
My build.gradle looks very much like the one from the Teapot example
With the exception that my source tree has some files which I don't want to include in the build. I can't remove these files so I need gradle to ignore them.
I tried adding an exclude definition:
android.sources {
main {
jni {
source {
srcDirs 'src/main/jni'
excludes += "src/main/jni/FileToExclude.cpp"
}
}
}
}
but that did not affect the outcome. gradle still tries to compile this file.
I tried excludes, exclude with =, += and with nothing at all but no permutation works.
From what I've found, the correct directive to exclude the file from the build is exclude, not excludes. Check your build.gradle to make sure you didn't make a mistake here (you've used excludes in the provided sample).
Upd: ok, after some research I found this thread on the AOSP issue tracker. The topic starter says the following:
The java/resources components of the sourcesets allow for include/exclude patterns.
We should do this for aidl/rs/jni/assets.
The issue is still open so I suppose this functionality has to be implemented in the Android Gradle plugin or Android Studio or in both of them (and isn't implemented yet). It'll be implemented in Android Studio 1.5, at least this is what the tags are saying.
I think you are giving path of the file in wrong manner.
It should be:
srcDir 'src/main/jni'
exclude 'FileToExclude.cpp'
You can follow this link.
https://discuss.gradle.org/t/how-can-i-exclude-certain-java-files-from-being-compiled/5287/2
Also note that you should use exclude instead of excludes and srcDir instead of srcDirs.
I looked into the android source, it looks like you could update the filter to exclude your file. I don't know what version of the gradle plugin you are using, so I can't be sure what the underlying api is. You could try setting the PatternFilterable manually to exclude the file.
android.sources {
main {
jni {
source {
srcDirs 'src/main/jni'
getFilter().exclude('**/FileToExclude.cpp')
}
}
}
}
I looked at Gradle Code Review, and saw that LanguageSourceSet was being used. Looking at the Gradle documentation for LanguageSourceSet, which you can access a SourceDirectorySet, which has a PatternFilterable that you can set the exclude on.
As it's still experimental there's not a much of documentation on Gradle Experimental. But with some experimentation I was able to dig a way on how to exclude some files, i.e.:
model {
//...
android.sources {
//...
jni {
//...
source {
excludes.add("<FILE PATH>") // You can have multiple excludes.add(...)
}
}
}
}
Note: the solution works on gradle-experimental 0.7.0
The easiest way is to set the properties in build.gradle:
sourceSets.main.jni.srcDirs = [] // now, AS will not try to compile your source files
sourceSets.main.jniLibs.srcDirs = ['libs'] // now, AS will pick up the compiled SO files from libs (where ndk-build will normally put them)
You can also define a "buildNative" task, to run ndk-build as part of compileTask, as defined in this answer.

Exclude class from resulting dex file

I have a problem. I have a structure of project looking like this:
P
|-SubP1
|-SubP2
There are two stub classes android.media.IRemoteDisplay in both packages. They differ in implementation, but that's not the matter - they will be replaced by system classes when I'll run the app on Android.
However, there is a problem - I can't build the project because dexMerger fails - it says there are two conflicting classes. I can understand that error - after all, there are really two conflicting classes :)
But when I try to exclude these files in build.gradle like this:
sourceSets {
main {
java {
srcDir 'src'
exclude '**/android/media/**'
}
}
}
The compilation fails because it can't find android.media.IRemoteControlDisplay class(and it's nested classes).
How can I still use these classes, but exclude them from resulting DEX file?
Please DON'T question if it's right to exclude the class from compiled project - it's the right thing to do, I already did it, but manually - by pre-compiling SubP1 and SubP2 to jars and then manually removing IRemoteController.class from these jar files and then including those jars in P.
I'll also be satisfied with that solution:
1. Build SubP1
2. Remove IRemoteControlDisplay.class from SubP1.jar
3. Build SubP2
4. Remove IRemoteControlDisplay.class from SubP2.jar
5. Add SubP1.jar and SubP2.jar as dependencies to P
6. Build P
If that's possible, please let me know.
Finally, I've been able to do it.
What I needed was a runtime dependency instead of compilation-time dependency. So, I've created submodule for SubP1 called SubSubP1(for example) moved the android.media.IRemoteDisplay into the SubSubP1, and created submodule SubSubP2 for SubP2, and did the same with stub class. Then I've declared the dependency as following for SubP1 and SubP2:
dependencies {
provided project(':SubP1:SubSubP1')
}
and
dependencies {
provided project(':SubP2:SubSubP2')
}
And that did the trick! Instead of compiling the classes, Gradle assumed that they will be loaded at runtime.

Exclude aidl files from Javadoc task with Gradle

I'm currently discovering Android Studio and Gradle and migrating all the build chain of my project from bash scripts to Gradle configurations. It's probably going to be awesome in the end, but meanwhile I'm struggling.
What I want to do now is quite simple. I have a standard rule to generate Javadoc from my source (I took this snippet from http://snowdream.github.io/blog/android/2013/11/01/how-to-generate-javadocs-with-android-gradle-plugin/):
android.libraryVariants.all { variant ->
task("generate${variant.name.capitalize()}Javadoc", type: Javadoc) {
source = variant.javaCompile.source
def androidJar = "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar"
classpath = files(variant.javaCompile.classpath.files, androidJar)
options {
links "http://docs.oracle.com/javase/7/docs/api/"
linksOffline "http://d.android.com/reference","${android.sdkDirectory}/docs/reference"
}
exclude '**/BuildConfig.java'
exclude '**/R.java'
}
}
But my project also contains AIDL files and I don't want these aidl files (nor the .java files generated from them) to be included to the Javadoc.
I tried the rule:
exclude "**/$buildDir/**"
... and I tried a thousand others, but none works and my interfaces and Stub are processed into HTML files.
I beg for your help! Thanks a lot.
After hours of research about how Gradle and Groovy work, the best way I found is:
exclude {
it.file.path.contains('aidl')
}
However, I'm still unsatisfied. I do feel something less brutal could be done using variant.aidlCompile.sourceOutputDir that points to the Java files generated by AIDL. But I could not compare the iterated elements in the Closure to this File, or FileTree, or whatever shape I give it...
EDIT:
After further research, another method is to hide the interfaces defined in AIDL using a custom Doclet that supports #hide tag (like Doclava). I preferred this method because it doesn't cause errors during Javadoc generation.

Categories

Resources