Using a Makefile for Java

89 views Asked by At

For college, I have to use Java. However, I do not want to use an IDE. I like vim.

So I'm trying to create a Makefile to build my java projects. My requirements are :

  1. No hardcoding of classes. The Makefile shall find all .java files in the src directory and any subdirectories, and compile the resulting classes to the classes directory.

  2. Multiple mains : Files containing main functions shall have an executable .jar file built with a corresponding MANIFEST.MF. Listing them explicitly is acceptable, although I'm pretty sure something could be done with grep here to find them automatically (but I suck at grep)

  3. A source jar for the whole project shall be created, containing unaltered .java files and no MANIFEST.MF or other extraneous files.

My best attempt so far (currently broken) follows :

include gmsl

targets := Client Server

# Folders 

binDir  := ./bin
clsDir  := ./classes
srcDir  := ./src
testDir := ./test

# Flags

version := 11

# Files

mainSrc := $(targets:%=$(srcDir)/tp1/%.java)
src  := $(shell find $(srcDir) -name *\.java -type f)
cls  := $(src:%.java=%.class)

# Rules

# Base
all     : $(targets)
again   : clean all
classes : $(cls)

# For debug
info:
    $(info mainSrc : $(mainSrc))
    $(info srcJar  : $(srcJar))
    $(info exeJar  : $(exeJar))
    $(info src     : $(src))
    $(info cls     : $(cls))

# Executables
$(targets): $(cls)
    $(shell cd $(srcDir))
    $(eval mainCls := $(shell find . -name *$@\.java -type f) )
    $(info mainCls = $(mainCls))
    jar --verbose --create --file=$(call lc,$@)-exe.jar --main-class=tp1/$@ -C $(clsDir) .

# Source
$(srcJar) : $(cls)
    jar --verbose --create --file=$@ --no-manifest -C $(srcDir) .

# Classes
$(cls):
    javac --release $(version) --source-path $(srcDir) -d $(clsDir) $(mainSrc)

# Cleanup
clean:
    -rm $(targets)
    -cd $(clsDir) && rm -rf ./*

1

There are 1 answers

0
dash-o On

Short Answer: It's OK to prefer non-IDE solution. However, limiting yourself to "make" as your ONLY build tool will mostly like lead to one of two outcome for any non-trivial project:

  1. Inefficient build(s), where each build will (re-)compile/(re-)package much more than what's needed (one of Make strength is incremental building, based on timestamp), OR
  2. Unreliable build, which will at time not rebuilt required targets because it will fail to understand dependencies.

What's the alternative ? use a tool that is "understand" Java, and has proper built in actions for building Java artifacts:

  • Maven: if you want modern solution, OR
  • Ant: if you want bare-bone, "manual gear" solution.

Technically, your can build a Makefile that will execute ant/build for you.

compile:
    mvn build

clean:
    mvn clean

...