views:

46

answers:

2

I've got a quick and dirty little make file that does out-of-source builds for a relatively small java project:

default: bin/classes/EntryPoint.class bin/classes/manifest
    jar cvfm ./bin/output.jar ./bin/classes/manifest -C ./bin/classes EntryPoint.class

bin/classes/EntryPoint.class: ./src/EntryPoint.java bin
    javac -sourcepath ./src -d ./bin/classes ./src/EntryPoint.java

bin/classes/manifest: src/manifest
    cp bin/classes/manifest src/manifest

bin:
    mkdir ./bin; mkdir ./bin/classes;

clean:
    rm -rf bin

The downside here is that if I want to add a new java file, I need to add a target for it, and add dependencies to the jar packaging step, and the path to the jar packaging step's command line. Adding the same thing in 3 places is going to result in unmaintainable mess for anything more than 4-5 files.

What I would like to do is simply add a "SOURCEFILES= files here" definition and list the files, and not have to mess with the commands and such. Can this be done?

NOTE: I know there are probably better tools for this (such as ant), but this is something I'm turning in as a homework assignment, and I cannot require the grader to have anything but the jdk amd make installed.

+1  A: 

Doesn't wild card character help?

javac ./blah/*.java  

Updated: To recurse through sub directories add

**/*.java  

Example:

javac -sourcepath src src/**/*.java -d classes -verbose  
Ck-
It helps, but it won't help for subdirectories.
Billy ONeal
Try **/*.java that should recurse. Updated the answer above.
Ck-
@Ck-: I fixed the formatting for you. Use four spaces before a line to get `monospaced` text. This also ignores other markup like asterisks. It doesn't trigger unless there's a blank line after the previous paragraph, though.
Jack Kelly
Thanks for the tip Jack.
Ck-
+1  A: 

If you can expect GNUMake:

SOURCES := $(wildcard src/**/*.java)
CLASSES := $(patsubst src/%.java,bin/classes/%.class,$(SOURCES))

default: $(CLASSES) bin/classes/manifest
    jar cvfm ./bin/output.jar ./bin/classes/manifest -C ./bin/classes EntryPoint.class

bin/classes/%.class: src/%.java bin/.dirstamp
    javac -sourcepath ./src -d ./bin/classes $<

bin/classes/manifest: src/manifest
    cp bin/classes/manifest src/manifest

clean:
    rm -rf bin

bin/.dirstamp
    mkdir -p bin/classes
    touch $@

I explain in this answer why it's better to use a stamp file for directories rather than depending on the directory itself.

Note that if you have classes that depend on each other, you won't be able to compile with this Makefile. To compile those, javac has to be given both of the source files at once, if I remember correctly.

Jack Kelly