java 多个源文件夹:避免使用 Ant 进行隐式编译

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4627913/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 07:17:05  来源:igfitidea点击:

Multiple source folders: Avoid implicit compilation with Ant

javaantbuild-process

提问by Michael Piefel

Consider the following project layout (assuming A and B depend on each other):

考虑以下项目布局(假设 A 和 B 相互依赖):

.
|-- bin1
|-- bin2
|-- src1
|   `-- A.java
`-- src2
    `-- B.java

After compilation, I want the classes to reside in their respective folders liike this:

编译后,我希望类像这样驻留在各自的文件夹中:

.
|-- bin1
|   `-- A.class
|-- bin2
|   `-- B.class
|-- src1
|   `-- A.java
`-- src2
    `-- B.java

This is quite simple from the command line:

这在命令行中非常简单:

 $ javac -implicit:none -sourcepath src1:src2 -d bin1 src1/*
 $ javac -implicit:none -sourcepath src1:src2 -d bin2 src2/*

Eclipse also does it that way if so configured. But I cannot figure out how to do it with Ant.

如果这样配置,Eclipse 也会这样做。但我不知道如何用 Ant 做到这一点。

Appendix:My current javactasks:

附录:我目前的javac任务:

    <javac destdir="${classes.1.dir}">
        <src path="${src.1.dir}" />
        <src path="${src.2.dir}" />
    </javac>
    <javac destdir="${classes.2.dir}">
        <classpath path="${classes.1.dir}" />
        <src path="${src.2.dir}" />
    </javac>

Note the circular dependency. The secondtask works well, it only compiles what's in src2as it has a classpathdependency on the other build. The firsttask, however, cannot take a classpath, since nothing is yet compiled, and with srcit of course compiles too much.

注意循环依赖。在第二个任务的效果很好,它只是编译什么的src2,因为它有一个classpath在其他构建依赖。在第一个任务,但是,不能坐classpath,因为没有什么是尚未编制,并与src它当然编译的太多了。

采纳答案by Kurt Kaylor

This is extremely ugly and needs some cleaning, but it should do what your looking for

这非常丑陋,需要一些清洁,但它应该可以满足您的需求

<target name="compile" depends="clean,init" description="Compiles all source files.">
    <mkdir dir="temp"/>
    <javac srcdir="src1" sourcepath="src2" destdir="temp">
        <classpath>
            <fileset dir="lib">
                <include name="**/*.jar"/>
            </fileset>
        </classpath>
    </javac>
    <javac srcdir="src2" sourcepath="src1" destdir="temp">
        <classpath>
            <fileset dir="lib">
                <include name="**/*.jar"/>
            </fileset>
        </classpath>
    </javac>
    <javac srcdir="src1" destdir="bin1">
        <classpath>
            <fileset dir="lib">
                <include name="**/*.jar"/>
            </fileset>
            <pathelement location="temp"/>
        </classpath>
    </javac>
    <javac srcdir="src2" destdir="bin2">
        <classpath>
            <fileset dir="lib">
                <include name="**/*.jar"/>
            </fileset>
            <pathelement location="temp"/>
        </classpath>
    </javac>
    <delete dir="temp"/>
</target>

回答by Vitali Olshevski

I had the same problem. And i found some pretty easy solution.

我有同样的问题。我找到了一些非常简单的解决方案。

You just need to specify several source foulders in srcdirattribute in javactask. And you should not specify destdirattribute.

您只需要在 task.properties 中的srcdir属性中指定几个源文件夹javac。你不应该指定destdir属性。

Something like this:

像这样的东西:

    <javac srcdir="src1:src2" />

All the binaries (.class files) will be placed in the same places as sources. So the structure of the class files will be exactly the same. Then you can move all *.class to the separate place, so they won't be stored in the source foulders.

所有二进制文件(.class 文件)都将放置在与源相同的位置。所以类文件的结构将完全相同。然后您可以将所有 *.class 移动到单独的位置,这样它们就不会存储在源文件夹中。

And no double compilation as in Kurt Kaylor's example.

并且没有像 Kurt Kaylor 的例子那样的双重编译。

回答by aphahn

Here is what works for me when dealing with complex source trees with no duplicate compilation. The key is how you build and reference the paths.

这是在处理没有重复编译的复杂源树时对我有用的方法。关键是您如何构建和引用路径。

<path id="src.separate.java.path">
    <pathelement path="separate-src1/java" />
    <pathelement path="separate-src2/java" />
</path>

<property name="src.separate.java.path" refid="src.separate.java.path" />

<path id="src.java.path">
    <pathelement path="src1/java" />
    <pathelement path="src2/java" />
    <pathelement path="src3/java" />
</path>

<property name="src.java.path" refid="src.java.path" />

<path id="src.java.all.path">
    <path refid="src.separate.java.path" />
    <path refid="src.java.path" />
</path>

<property name="src.java.all.path" refid="src.java.all.path" />

<target name="compile-java">
    <mkdir dir="${separate.classes.dir}" />
    <javac srcdir="${src.separate.java.path}" sourcepath="${src.java.all.path}" destdir="${separate.classes.dir}">
        <classpath refid="project.class.path" />
        <compilerarg value="-implicit:none"/>
    </javac>

    <mkdir dir="${build.classes.dir}" />
    <javac srcdir="${src.java.path}" sourcepath="${src.java.all.path}" destdir="${build.classes.dir}">
        <classpath refid="project.class.path"/>
        <compilerarg value="-implicit:none"/>
    </javac>
</target>

In order for this to work the source paths need to be made up of <pathelement>s. If you use <fileset>s the srcdirattribute for javac will choke on the path. You also need to expand the path into a property for srcdirand sourcepathto be able to use it.

为了使其工作,源路径需要由<pathelement>s 组成。如果您使用<fileset>s srcdir,则 javac的属性将在路径上阻塞。您还需要将路径扩展为属性srcdirsourcepath能够使用它。

So srcdiris the path to the source to compile and sourcepathis the path to all source the compiler needs to do resolve references. <compilerarg value="-implicit:none"/>tells the compiler to not generate class files for implicitly loaded source.

所以srcdir是路径源代码编译,并sourcepath是通向所有的源编译器需要做的决心引用。<compilerarg value="-implicit:none"/>告诉编译器不要为隐式加载的源生成类文件。

Of course you can do the same thing using nested <src>elements in javac instead of the <path>s and <property>s, but that will force you to list your source paths twice.

当然,您可以使用<src>javac 中的嵌套元素而不是<path>s 和<property>s来执行相同的操作,但这将迫使您将源路径列出两次。