How to achieve the same functionality as running `javac sim.java` followed by `java sim (commands)`, but using a Makefile instead

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!