Несколько исходных папок: избегайте неявной компиляции с помощью Ant - PullRequest
5 голосов
/ 07 января 2011

Рассмотрим следующую схему проекта (при условии, что 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>

Обратите внимание на циклическую зависимость.Задача second работает хорошо, она компилирует только то, что в src2, так как имеет зависимость classpath от другой сборки.Задача first , однако, не может занять classpath, поскольку ничего еще не скомпилировано, а с src она, конечно, компилируется слишком много.

Ответы [ 3 ]

9 голосов
/ 15 января 2012

У меня была такая же проблема. И я нашел довольно простое решение.

Вам просто нужно указать несколько исходных фулеров в атрибуте srcdir в задаче javac. И вы не должны указывать destdir атрибут.

Примерно так:

    <javac srcdir="src1:src2" />

Все двоичные файлы (файлы .class) будут размещены в тех же местах, что и исходные коды. Таким образом, структура файлов классов будет точно такой же. Затем вы можете переместить все * .class в отдельное место, чтобы они не сохранялись в исходных полях.

И никакой двойной компиляции, как в примере с Куртом Кейлором.

2 голосов
/ 07 января 2011

Это очень уродливо и нуждается в некоторой чистке, но оно должно делать то, что вы ищете

<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>
1 голос
/ 13 августа 2013

Вот что мне подходит, когда приходится работать со сложными исходными деревьями без дублирования компиляции.Ключ в том, как вы строите и ссылаетесь на пути.

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

Чтобы это работало, исходные пути должны состоять из <pathelement> с.Если вы используете <fileset> s, атрибут srcdir для javac захлебнется на пути.Вам также нужно расширить путь в свойство для srcdir и sourcepath, чтобы иметь возможность его использовать.

Так что srcdir - это путь к источнику для компиляции, а sourcepath - это путь.ко всему источнику компилятор должен делать ссылки на разрешения.<compilerarg value="-implicit:none"/> указывает компилятору не создавать файлы классов для неявно загруженного источника.

Конечно, вы можете сделать то же самое, используя вложенные элементы <src> в javac вместо <path> s и <property> s, но это заставит вас дважды перечислить исходные пути.

...