javac忽略sourcepath文件的第一行,不编译类

cwxwcias  于 2021-07-08  发布在  Java
关注(0)|答案(2)|浏览(602)

我有一个这样结构的项目(为简单起见缩短了):

我试着用终端来编译它。
我加入了 src 目录并首先执行以下操作:

find * -name "*.java" > sources.txt

在第一个命令之后 sources.txt 生成文件:

aircraft/Baloon.java
aircraft/Aircraft.java
aircraft/JetPlane.java
aircraft/AircraftFactory.java
aircraft/Coordinates.java
aircraft/Flyable.java
aircraft/Helicopter.java
exception/WrongNumberArgsException.java
simulator/Simulator.java

此外,我正在做:

javac -sourcepath @sources.txt

它产生了所有 .class 文件,除了第一个- Baloon.java 完全被javac忽略。
如果我这样做了:

javac -sourcepath @sources.txt src/aircraft/Baloon.java

Baloon.class 文件也与其他文件一起生成 .class 文件夹。
如果我手动更改 sources.txt ,例如切换第一行和第二行,然后当我重新编译第一行时 .java 文件输入 sources.txt 被javac和相应的 .class 未创建文件。
或者,如果我用intellij idea编译-一切正常,没有问题发生。
不管我是在project的根目录下编译,还是在 src 目录,结果相同-第一行 sources.txt 被忽略。
所以问题是-我用上面两个终端命令做了什么错误?或者可能是javac的一个bug?
javac版本-1.8.0\u 221
项目文件本身:https://github.com/dman-89/42_avaj_launcher

zlhcx6iw

zlhcx6iw1#

听起来您的目标是创建一个源文件列表,然后将它们全部传递给javac进行编译。如果这是你的目标, -sourcepath 不是你想要的。
你想要两件事中的一件:

做所有真正的java程序员都做的事情

“真实”的定义是:他们这样做是为了钱和/或眼球,而不是作为一种学术活动。
使用构建系统;gradle或maven是常见的选择。他们将为您处理所有这些,比草率地将一些bash脚本拼凑在一起要好得多。

只需传递java源文件

只需移除 -sourcepath 部分。 javac @sources.txt 是你想要的。

怎么回事?

第一个“论点”(你的第一行) sources.txt 文件)是 -sourcepath 参数,javac不会编译这个,因为 -sourcepath 并不意味着“编译这些东西”(见下文)。其余的(第2行和更进一步的)只是参数,这实际上是javac将编译的。

那么什么是sourcepath?

要用javac编译源文件 javac foo/A.java bar/B.java . 但是,如果, A.java 包含: import lombok.Value; ? javac现在不能编译这个文件,除非javac知道 lombok.Value . 通常这种依赖关系已经编译好了(在目录或jar文件中有类文件),在这种情况下,您可以使用 -classpath 选择 javac 告诉javac在哪里可以找到这些东西。 -sourcepath 类似,只是,它是为尚未编译的东西。这意味着javac将意识到sourcepath中存在任何东西,以防出现任何需要首先编译的东西,并且仅当您为编译指定的任何实际文件需要它时才会这样做。
像任何人一样 -xpath 选择 javac 或者 java ,如果要指定多个条目,请使用冒号(windows上的分号)作为分隔符,而不是空格。此外,这个想法是传递目录而不是实际的文件。就像 -classpath ,传递无效(例如不存在)路径是可以的。然后他们就被忽略了。

示例

javac -sourcepath deps:deps2 src/com/mypkg/Main.java src/com/mypkg/Extra.java

这将告诉javac编译main和extra(而不是 deps 或者 deps2 或者里面的任何文件)。但是,如果, Main.java 包含行: Object o = new bar.baz.Hello(); ,以及文件 deps/bar/baz/Hello.java 存在,则此命令也将结束编译 Hello.java . 如果 deps/bar/baz/Whatever.java 也存在,除非 Whatever 是在某个地方提到的 Hello.java , Main.java ,或 Extra.java . 不是在注解中,也不是在import语句中( import 如果java ese用于 alias ,它实际上不导入任何内容)。

egmofgnx

egmofgnx2#

javac 将编译指定的源文件,例如 Baloon.java 对你来说。
此外,如果编译器能够找到源文件,那么从那些显式命名的源文件引用的任何类也将被编译。它在sourcepath上查找它们,如果未指定,则默认为与类路径相同。
假设 Simulator 这个班有学生吗 main() 方法(如图标的绿色“play”三角形所示),它将直接或间接引用所有其他源文件,因此要指定的文件如下:

cd src
javac simulator/Simulator.java

或:

javac -cp src src/simulator/Simulator.java

相关问题