如何让IntelliJ识别gradle生成的源文件目录?

14

我有一个 XJC javaExec,它像陀螺一样旋转,但 IntelliJ 却无法识别生成的输出,尽管已将 generated-src/java 标记为这样。我需要调整 Idea 插件或其他什么吗?

注:该插件本身是从根目录下的子项目 build.gradle 中加载的。

XJC 项目:

description = "Generates sources and compiles them into a Jar for $project"

configurations { xjc }
dependencies {
    xjc 'org.glassfish.jaxb:jaxb-xjc:2.2.11'
    xjc 'org.glassfish.jaxb:jaxb-runtime:2.2.11'
}

task xjc (type:JavaExec) {

    doFirst{
        File generatedSrcDir = file("$buildDir/generated-src/java")
        if (!generatedSrcDir.exists()) {
            generatedSrcDir.mkdirs()
        }
    }

    main = "com.sun.tools.xjc.XJCFacade"
    classpath configurations.xjc

    def argsList = [
            "-mark-generated",
            "-no-header",
            "-verbose", // or -quiet or nothing for default.
            "-target", "2.1",
            "-encoding", "UTF-8",
            "-d", "$buildDir/generated-src/java",
            "-catalog","$projectDir/src/main/resources/commons-gradle.cat",
            file("$projectDir/src/main/resources/v1/") ]

    args argsList
    inputs.files files(file("$projectDir/src/main/resources/v1/"))
    outputs.files files(file("$buildDir/generated-src/java"),file("$buildDir/classes"))

}

compileJava {
    dependsOn xjc
    source "${buildDir}/generated-src"
}

在依赖于此项目的项目中,我只需:

compile project(":path:to:schemas:the-test-schema")

我已经尝试过:

idea {
    module {

        def buildDir = file("$buildDir")
        def generatedDir = file("$buildDir/generated-src")
        def listOfDirs = []

        buildDir.eachDir { file ->
            if (file.name != buildDir.name && file.name != generatedDir.name)
            listOfDirs.add(file)
        }

        excludeDirs = listOfDirs.toArray()

        generatedSourceDirs += file("$buildDir/generated-src/java")
        scopes.COMPILE.plus += [ configurations.xjc ]
    }
}

你可以尝试添加Gradle插件,然后可能会操纵Idea使用的项目类路径? - RaGe
我的错。这是添加在子项目中的。 - user447607
我闻到了一个 bug,或许不只一个。原因在于,在生成的文档中,我可以找到对其他项目的引用,但却找不到 generatedSourceDirs 的引用。如果我使用 sourceDirs += ... 就能正常工作。怀疑是由于某种原因导致 generatedSourceDirs 没有被包含在构建中。 - user447607
暂时的解决方法是:在Idea插件的主sourceSet或sourceDirs中添加该目录。 - user447607
6个回答

21
我将指出Daniel Dekany提供的解决方案,这个Gradle讨论帖实际上链接到了这个问题。引用一下他的话:
apply plugin: "idea"
...
sourceSets.main.java.srcDir new File(buildDir, 'generated/javacc')
idea {
    module {
        // Marks the already(!) added srcDir as "generated"
        generatedSourceDirs += file('build/generated/javacc')
    }
}

这对我来说很有效。


对我来说,仅将其添加到sourceSets是不够的,我需要在模块配置中添加sourceDirs += theDir - romnempire
1
更简洁的写法:File genSrc = file('build/generated/javacc'); sourceSets.main.java.srcDir genSrc; idea.module.generatedSourceDirs += genSrc - ThomasR
1
文档提示您需要将其添加到sourceDirsgeneratedSourceDirs两个目录中-> https://docs.gradle.org/current/dsl/org.gradle.plugins.ide.idea.model.IdeaModule.html - BoD
如果你不想硬编码路径,可以使用以下代码:sourceSets.main.output.getGeneratedSourcesDirs()。 https://github.com/gradle/gradle/blob/13e6c035c374aa6e5dc4a2e947591d237550d7a4/subprojects/plugins/src/main/java/org/gradle/api/tasks/SourceSetOutput.java#L162 - Steven Gerdes

14

使用Kotlin DSL重写后,这个答案的代码如下:

plugins {
    idea
}

val generatedSourcesPath = file("out/production/classes/generated")

java.sourceSets["main"].java.srcDir(generatedSourcesPath)

idea {
    module {
        generatedSourceDirs.add(generatedSourcesPath)
    }
}

什么是 Kotlin?开个玩笑——有点儿。很多人不知道 Kotlin。 - user447607
@user447607 嗯,它是一种编程语言 :) (https://kotlinlang.org/)。自版本3.0起,Gradle提供了一个基于Kotlin的DSL,与Groovy相当:https://github.com/gradle/kotlin-dsl - jihor
@user447607和很多人都使用Kotlin而不是Groovy来进行Gradle编程,因此这非常有用。 - Captain Man

5
在我的情况下,除非我将生成源目录添加到 sourceDirs generatedSourceDirs 中,否则它不起作用:
def generatedSourcesDir = file('src/generated/main/java')
idea {
  module {
    sourceDirs += generatedSourcesDir
    generatedSourceDirs += generatedSourcesDir
  }
}

2

在2020年,您可能不需要在IDEA中刷新项目

因为它实际上可以直接使用。

不用再花费30分钟阅读过时的解决方案了 :(


1
这在某些版本中发生。我们可以仔细查看和阅读一些问题。但是对于我自己来说,从IntelliJ IDEA 2019开始,以下解决方案不再适用: 在Gradle论坛上讨论此问题:https://discuss.gradle.org/t/how-do-i-get-intellij-to-recognize-gradle-generated-sources-dir/16847 根据@Daniel Dekany的说法,这在IDEA 2017.1.2中有效,并且在我使用2019版本之前也有效。
plugins {
    id 'idea'
}

idea {
    module {
        generatedSourceDirs += file('build/generated/sources/annotationProcessor')
    }
}

但是从2019年到2022年,对我有效的解决方案是:
def generatedDir = "${buildDir}/generated/sources"

sourceSets {
    main {
        java {
            srcDir generatedDir
        }
    }
}

idea {
    module {
        generatedSourceDirs.addAll(file(generatedDir))
    }
}

0
ext {
    // path to IDEA generated sources directory
    ideaGeneratedSourcesDir = "$projectDir/src/main/generated"
}
compileJava {
    //……
    options.annotationProcessorGeneratedSourcesDirectory = file(ideaGeneratedSourcesDir)
    //options.headerOutputDirectory.set(file(ideaGeneratedSourcesDir)) (tested no effect)
    //……
}
// above work for me, and i try all method this question mentioned it's not work! env: idea2019.3, wrapped gradle6.3-all, zh-CN, JDK8, [x] annotation processing is disabled(no effect, in global settings ), no idea plugin([x]plugins {id idea}), [x]sourceSets no need to set(genereated srcDir)

我的代码生成示例:

task vertxCodeGen(type: JavaCompile) {
    group 'build'
    source = sourceSets.main.java
    destinationDir = file(ideaGeneratedSourcesDir)
    classpath = configurations.compileClasspath
    options.annotationProcessorPath = configurations.annotationProcessor
    options.debugOptions.debugLevel = "source,lines,vars"
    options.compilerArgs = [
            "-proc:only",
            "-processor", "io.vertx.codegen.CodeGenProcessor",
            // where the non Java classes / non resources are stored (mandatory) - the processors requires this option to know where to place them
            "-Acodegen.output=$destinationDir.absolutePath",
    ]
}

刷新Gradle,持续存在


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接