Reputation: 3225
I have a project with such structure (shortened for simplicity):
and I'm trying to compile it with terminal.
I'm in src
directory and firstly doing this:
find * -name "*.java" > sources.txt
After the first command a sources.txt
file is generated:
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
Further I'm doing:
javac -sourcepath @sources.txt
And it generates all .class
files, EXCEPT the first one - Baloon.java
is totally ignored by javac.
If I do:
javac -sourcepath @sources.txt src/aircraft/Baloon.java
a Baloon.class
file is generated as well with other .class
files.
If I manually change first row of sources.txt
, for example switch first and second rows, then when I recompile again first .java
file in sources.txt
is ignored by javac and respective .class
file is not created.
Alternatively if I compile with Intellij Idea - everything is fine, no problems occur.
It doesn't matter if I compile in the root directory of project, or in src
directory, result is the same - first line of sources.txt
is ignored.
So the question is - what I'm doing wrong with above 2 terminal commands? or maybe it's a bug of javac?
javac version - 1.8.0_221
project files themself: https://github.com/Dman-89/42_avaj_launcher
Upvotes: 0
Views: 477
Reputation: 102978
It sounds like your aim is to create a list of source files, and then pass them all to javac to compile. If that is your aim, -sourcepath
is not what you want.
You want one of two things:
'real' defined as: They do it for money and/or eyeballs, and not as an academic exercise.
Use a build system; gradle or maven are the common choices. They will take care of all this for you far better than a slapdash effort to hack some bash scripts together.
Just remove the -sourcepath
part. javac @sources.txt
is what you want.
The first 'argument' (first line in your sources.txt
file) is the 'value' for the -sourcepath
argument, and javac doesn't compile this, because -sourcepath
doesn't mean 'compile this stuff' (see later). The rest (lines 2 and further) are just arguments, which is actually what javac will compile.
To compile source files with javac, you'd write javac foo/A.java bar/B.java
. However, what if, say, A.java
contains: import lombok.Value;
? Javac is now not capable of compiling this file unless javac knows about lombok.Value
. Usually such dependencies are already compiled (you have class files in a directory or a jar file), in which case you'd use the -classpath
option of javac
to tell javac about where to find this stuff.
-sourcepath
is similar, except, it's for not-yet-compiled stuff. That means javac will gain awareness of the existence of anything in the sourcepath, in case it comes up that any of that needs to be compiled first, and will only do so if it is needed by any of the actual files you specified for compilation.
Like any -xpath
option to javac
or java
, if you want to specify more than 1 entry, use colons (semicolons on windows) as a separator, not space. Furthermore, the idea is to pass directories and not actual files. And just like -classpath
, passing invalid (e.g. non-existing) paths is fine. Then they are just ignored.
javac -sourcepath deps:deps2 src/com/mypkg/Main.java src/com/mypkg/Extra.java
This will tell javac to compile Main and Extra (not deps
or deps2
or any files inside). However, if, say, Main.java
contains the line: Object o = new bar.baz.Hello();
, and the file deps/bar/baz/Hello.java
exists, then this command will end up also compiling Hello.java
. If deps/bar/baz/Whatever.java
also exists, that won't be compiled, unless Whatever
is mentioned somewhere in Hello.java
, Main.java
, or Extra.java
. And not in either a comment or just an import statement (import
if java-ese for alias
, it doesn't actually import anything).
Upvotes: 4
Reputation: 159106
javac
will compile the source files specified, e.g. just Baloon.java
in your case.
In addition, any classes referenced from those explicitly named source files will also be compiled, if the compiler can find the source files for them. It looks for them on the sourcepath, which defaults to the same as the classpath if not specified.
Assuming Simulator
is the class with the main()
method (as indicated by the green "play" triangle of the icon), it will directly or indirectly reference all the other source files, so that's the file to specify:
cd src
javac simulator/Simulator.java
Or:
javac -cp src src/simulator/Simulator.java
Upvotes: 1