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

发布于 2024-10-10 13:15:42 字数 1045 浏览 5 评论 0原文

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

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

编译后,我希望这些类驻留在各自的文件夹中,如下所示:

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

这在命令行中非常简单:

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

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

附录:我当前的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>

注意循环依赖。 第二任务运行良好,它只编译src2中的内容,因为它对其他构建有classpath依赖。然而,第一个任务不能采用类路径,因为尚未编译任何内容,并且使用 src 当然会编译太多内容。

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

.
|-- 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.

Appendix: My current javac tasks:

    <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 second task works well, it only compiles what’s in src2 as it has a classpath dependency on the other build. The first task, however, cannot take a classpath, since nothing is yet compiled, and with src it of course compiles too much.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

清音悠歌 2024-10-17 13:15:42

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

您只需要在javac任务中的srcdir属性中指定几个源文件夹即可。并且您不应指定 destdir 属性。

像这样的事情:

    <javac srcdir="src1:src2" />

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

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

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

You just need to specify several source foulders in srcdir attribute in javac task. And you should not specify destdir attribute.

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.

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

酒与心事 2024-10-17 13:15:42

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

<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>

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>
故事未完 2024-10-17 13:15:42

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

<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>

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

因此,srcdir 是要编译的源的路径,sourcepath 是编译器解析引用所需的所有源的路径。 告诉编译器不要为隐式加载的源代码生成类文件。

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

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 srcdir attribute for javac will choke on the path. You also need to expand the path into a property for srcdir and sourcepath to be able to use it.

So srcdir is the path to the source to compile and sourcepath is 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.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文