Monday, September 19, 2016

Gradle exclude file from sourceSet not working

Leave a Comment

I've got a project where I'm trying to include a single file from a tree of java source files into a library project. Whatever I do I am not able to include only that file. I have had success in another project excluding all files except the one, but that only worked when running gradle from the library project only. When it was run from the application directory, all files were included. While trying to create a simple project that reproduces the issue, that same exclude all does not work either.

The sample file tree is simple:

application - android app that includes the two libraries library1/   build.gradle   src/main/AndroidManifest.xml library2/   build.gradle   src/main/AndroidManifest.xml java/src/com/company/product/   /pkg1     Source1.java, Source2.java, Source3.java     libraryoneonly/Library1Source.java   /pkg2     Source1.java, Source2.java, Source3.java 

The library1 build.gradle looks like this. Neither of the includes or excludes work below.

library1/build.gradle

apply plugin: 'com.android.library' android {     sourceSets {         main.jni.srcDirs = []         main.jniLibs.srcDir 'src/main/libs'         main.java {             srcDir "../../java/src"             exclude  {  FileTreeElement elem ->                 println "Searching for files, found: " + elem.relativePath                 !(elem.isDirectory() || elem.name.equals('Library1Source.java'))             }             //include ("**/libraryoneonly/**")             //include ('com/company/product/pkg1/libraryoneonly/Library1Source.java')         }     } dependencies {     compile project(':library2') } 

And library2 build.gradle. Surprisingly, the uncommented exclude below does work.

library2/build.gradle

apply plugin: 'com.android.library'  android {         sourceSets {             main.jni.srcDirs = []             main.jniLibs.srcDir 'src/main/libs'             main.java {                 srcDir "../../java/src"                 //exclude  {  FileTreeElement elem -> ((elem.path.contains('/libraryoneonly/')) ) }                 exclude ('com/company/product/pkg1/libraryoneonly/Library1Source.java')             }         } 

Just to note, I never see the "Searching for files, found" text when library1 is building. I'm not sure why. I do see it in the larger project this test was modeled from, depending on where the build was run from.

If you'd like to pull the sample project and try it out, here is a link: https://github.com/gbak/gradleTest

2 Answers

Answers 1

Gradle'e SourceDirectorySet seems to be missing features. docs has a very telling note:

TODO - configure includes/excludes for individual source dirs, and sync up with CopySpec TODO - allow add FileTree

The lack of features on par with CopySpec means there isn't a logical way to do what you're asking. The include pattern first adds a list of files to the sourceSet and then you can exclude a few files from that set. Except,

  1. The main.java sourceset implicitly adds **\*.java
  2. There is no exclude everything that is not

means you are SOL.

You can declare a separate main.somethingElse source set and use include just that one file, but I wasn't able to figure out how to add the new sourceset to the compile path. The hack suggested here, using compiler args doesn't work anymore, java complains about invalid flags.

The only workaround I can think of is to use a path that excludes that files you do not want in main.java.srcDir for library1

    main.java {         srcDir '../../java/src/com/company/product/pkg1/libraryoneonly'     } 

Answers 2

Your code seems to be correct to me, it's just that FileCollections like sourceFiles are lazily evaluated, i.e. your println statement is not executed until the contents of the source set are actually being requested.

Adding something like

main.java.sourceFiles.each { println "File in source set: " + it } 

after the main.java {...} closure should actually make the println work.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment