2016-09-09 25 views
15

我有一个项目,我试图从Java源文件的树中包含单个文件到库项目中。无论我做什么,我都无法仅包含该文件。我在另一个项目中取得了成功,除了那个项目以外的所有文件,但只有在从库项目运行gradle时才有效。当它从应用程序目录运行时,所有文件都包含在内。在尝试创建一个复制问题的简单项目时,同样排除所有项也不起作用。Gradle从源码集排除文件不起作用

样本文件树很简单:

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 

的LIBRARY1的build.gradle看起来是这样的。包含或不包括下面的工作。

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') 
} 

而且library2的build.gradle。令人惊讶的是,下面的未注释排除确实有效。

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') 
      } 
     } 

只是要注意的,我从来没有看到 “的文件搜索,找到” 当LIBRARY1正在建设的文本。我不知道为什么。我确实在这个测试从较大的项目中看到它,这取决于构建的运行位置。

如果您想拉样本项目,并尝试一下,这里是一个链接:https://github.com/gbak/gradleTest

回答

6

我终于想出办法,包括单个文件,而不需要修改的路径srcDir路径:

main.java { 
    srcDir "../../java/src" 
    setIncludes(new HashSet(['com/company/product/pkg1/libraryoneonly/*.java'])) 
} 

'**/*.java'被自动包括作为该路径包括,添加任何更多包括,就像一个直接包括源文件不执行任何操作,因为它已经包含的路径的yway。

setIncludes()调用将替换任何现有的包含,包括'**/*.java',并将提供的路径设置为唯一包含路径。

阅读文档并在main.java帮助后添加建议的printf语句。

main.java.getIncludes().each { println "Added include: $it" } 
main.java.sourceFiles.each { println "File in source set: " + it } 

感谢所有帮助过我的人。

3

您的代码似乎是正确的对我来说,这只是FileCollectionssourceFiles懒洋洋地评估,也就是你的println声明不会执行,直到源集的内容实际上被请求。

添加类似

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

main.java {...}关闭后应实际上使println工作。

6

Gradle'e SourceDirectorySet似乎缺少功能。 docs有一个很能说明注:

TODO - 配置包含/排除个别源显示目录,并与CopySpec TODO同步上涨 - 允许添加文件树

缺乏与CopySpec相提并论功能意味着是不是一个合乎逻辑的方式去做你所要求的。 include模式首先将一个文件列表添加到sourceSet,然后您可以从该组中的几个文件中找到exclude。除此之外,

  1. main.java sourceset隐式添加**\*.java
  2. 没有排除一切不是

意味着你SOL。

你可以声明一个单独的main.somethingElse源代码集并使用包含那一个文件,但我无法弄清楚如何将新的源代码集添加到编译路径中。黑客建议here,使用编译器参数不工作了,java抱怨无效的标志。

我能想到的唯一的解决方法就是使用排除你不想在main.java.srcDir文件LIBRARY1

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

感谢您的回应,我已经尝试过srcDir方法,但我记得有一些缺点,不允许我使用它。我记得甚至将源文件分成单独的包来做到这一点。我将不得不再次尝试刷新我的记忆。排除一切工作在另一个项目中。 –

+0

您有没有机会重试srcDir方法? – RaGe

+1

请注意,Android Gradle插件不会*使用Gradle的默认源(目录)集,但它自己的[AndroidSource(目录)集](https://google.github.io/android-gradle-dsl/current/ com.android.build.gradle.api.AndroidSourceSet.html)实现。因此,引用Gradle源代码在这里可能无效。 – sschuberth