Simple Makefile to build and run scala program I wrote this simple Makefile but it ended up like a spaghetti code. I used basename multiple times. I have a special case for first.spec.scala.run and follow.spec.scala.run and maybe more antipattern code that I am not aware of. I am not happy with my code and I appreciate any feedback or review. Thank you.
SPECS=First Follow
EXAMPLES_PATH=../..
ROOT_PATH=../${EXAMPLES_PATH}
SCALAV=2.12
APSLIB=${ROOT_PATH}/lib/aps-library-${SCALAV}.jar
SCALA_FLAGS=.:${APSLIB}
APS2SCALA=${ROOT_PATH}/bin/aps2scala

all: $(addsuffix Spec.compile, $(SPECS)) $(addsuffix Spec.run, $(SPECS))

%.generate:
    ${APS2SCALA} -DCOT -p ${EXAMPLES_PATH}:${ROOT_PATH}/base $*

%.run:
    @scala -cp ${SCALA_FLAGS} $(basename $@)

GrammarUtil.compile: grammar.generate
    scalac -cp ${SCALA_FLAGS} grammar.scala $(basename $@).scala

first.compile:
    scalac -cp ${SCALA_FLAGS} $(basename $@).scala

follow.compile:
    scalac -cp ${SCALA_FLAGS} $(basename $@).scala

Spec.compile:
    scalac -cp ${SCALA_FLAGS} $(basename $@).scala

FirstSpec.compile: Spec.compile grammar.generate GrammarUtil.compile first.generate first.compile
    scalac -cp ${SCALA_FLAGS} $(basename $@).scala

FollowSpec.compile: Spec.compile grammar.generate GrammarUtil.compile follow.generate follow.compile
    scalac -cp ${SCALA_FLAGS} $(basename $@).scala

clean:
    rm -f *.class grammar.scala first.scala follow.scala
I don't know Scala, but I do know Make, so I hope this helps.
Firstly, the makefile is missing .DELETE_ON_ERROR:, which pretty much every makefile needs, to avoid part-written output files appearing up-to-date when a compilation command fails (e.g. is interrupted).
We also want .PHONY: for those targets that don't produce files, such as all and clean.  (And clean should use $(RM) rather than rm -f, for increased portability.)
I think that we want a straightforward pattern rule that says that we can make a file called foo.compile given an input called foo.scala:
%.compile: %.scala
    scalac -cp ${SCALA_FLAGS} $&lt;

It looks to me that -cp is one of the flags to scalac, so that should probably be in ${SCALA_FLAGS} rather than in the command.
I'm not convinced that your rules actually create the files they claim to.  For example, GrammarUtil.compile depends on grammar.generate, but then actually uses grammar.scala - should grammar.generate actually be grammar.scala there?