Creating a Makefile for a Java Project
My goal is to achieve the same functionality as running javac sim.java
followed by java sim (commands)
, but using a Makefile instead. Is there a way to accomplish this?
I’ve gone through several examples online and attempted modifications, but none have worked as expected. The project requirement is that my teacher should be able to compile and run my code simply by typing make
in the terminal. Ideally, I want to be able to execute sim
followed by the necessary commands as defined in my code.
Although the program runs correctly in Eclipse, I am unable to execute it using terminal commands. While the Makefile successfully compiles the code, when I try to run sim ...(arguments)
, I get a “command not found” error.
Since Makefiles haven’t been covered in our coursework, and I have no prior experience with them, I’m unsure what I’m doing wrong. Below is the Makefile I am currently using:
JFLAGS = -g
JC = javac
OPT = -O3
#OPT = -g
WARN = -Wall
sim: sim.class
sim.class: sim.java
$(JC) $(JFLAGS) sim.java
clean:
$(RM) sim.class
clobber:
$(RM) sim.class
How can I modify this Makefile to ensure my project compiles and runs correctly from the terminal?
Hey! Your Makefile is mostly fine for compilation, but the issue is that sim is a Java class, not an executable binary. When you try to run sim …arguments, the shell expects an actual executable named sim, which doesn’t exist.
A simple fix is to add a run target that explicitly calls java sim. Try this:
JFLAGS = -g
JC = javac
RM = rm -f
sim: sim.class
sim.class: sim.java
$(JC) $(JFLAGS) sim.java
run: sim
java sim
clean:
$(RM) sim.class
Now, after make, you can run make run to execute your program. If you need to pass arguments, you can modify the run target like this:
runargs: sim
java sim $(ARGS)
Then use:
make runargs ARGS="arg1 arg2"
Hope that helps!
@Ambikayache solution is great!
But let me suggest a small improvement: instead of writing explicit run and runargs targets, we can make it more flexible by using a single run target that automatically accepts arguments.
If you want an approach that simulates an executable sim command, you can create a shell script wrapper.
Modify your Makefile like this:
JFLAGS = -g
JC = javac
RM = rm -f
sim: sim.class
echo '#!/bin/sh' > sim
echo 'java sim $$@' >> sim
chmod +x sim
sim.class: sim.java
$(JC) $(JFLAGS) sim.java
clean:
$(RM) sim.class sim
Now, after running make, you can simply execute your program like a normal shell command:
./sim arg1 arg2
This avoids using make run entirely and makes it feel more like a compiled binary. Let me know if you need more tweaks!