- # GNUMake snippet for java compilation and execution
- #
- # SPDX-License-Identifier: GPL-3.0-or-later
- # SPDX-FileCopyrightText: 2024-2025 Jonas Smedegaard <dr@jones.dk>
- #
- # Setup:
- # In main Makefile...
- # * set variable JAVA_PROJECTMODULES, or PROJECT for one simply named
- # * set variable JAVA_MAINCLASSES with at least one main()-method class,
- # where the first one listed will be used by default
- # * set variables JAVA_CLASSPATHS JAVA_MODULEPATHS JAVA_MODULESOURCEPATH
- # JAVA_ROOT JAVA_EXTRACLASSES JAVA_MODULES JAR_FILE
- # if needed,
- # * include this make snippet
- #
- # Variables may add suffix _$(PROJECTMODULE), in full or "host-only",
- # e.g. JAVA_MODULES_org.example.mydemo or JAVA_MODULES_mydemo.
- # defaults overridable at make invocation
- JAVA_ROOT ?= src/main/java
- JAVAC ?= javac
- JAVA ?= java
- JAR ?= jar
- # account for one annoyingly popular class of non-POSIX system
- _java_path_separator := $(if $(filter Windows%,$($(shell uname))),;,:)
- _java_module_separator = ,
- # expansions optionally stem- or last-word-of-stem-based
- # first try fully suffixed, then "host"-suffixed, then bare variable
- _java_projvar = $(strip $(foreach v,$1,$(or \
- $(if $(or $2,$*),$(or \
- $(value $v_$(or $2,$*)),\
- $(value $v_$(lastword $(subst ., $(),$(or $2,$*)))))),\
- $(value $v))))
- _java_root = $(call _java_projvar,JAVA_ROOT)
- _java_flag = $(eval x = $(call _java_projvar,$2))$(strip $(if $4$x$5,\
- --$1 $(subst $() ,$(value _java_$3_separator),$(strip $4 $x $5))))
- _java_common_flags = $(strip \
- $(call _java_flag,class-path,JAVA_CLASSPATHS,path) \
- $(call _java_flag,module-path,JAVA_MODULEPATHS,path) \
- $(call _java_flag,add-modules,JAVA_MODULES,module))
- # projectmodules with default main function
- _java_mainclassmodules = $(strip \
- $(foreach p,$(JAVA_PROJECTMODULES),\
- $(if $(call _java_projvar,JAVA_MAINCLASSES,$p),$p)))
- # projectmodules with non-default main function expanded, dot-appended
- _java_extramainclassmodules = $(strip \
- $(foreach p,$(JAVA_PROJECTMODULES),\
- $(eval classes = $(call _java_projvar,JAVA_MAINCLASSES,$p))\
- $(foreach c,$(filter-out $(firstword $(classes)),$(classes)),\
- $p.$(subst /,.,$c))))
- # TODO: formally define a builddir, and drop that on clean
- #clean::
- # rm -f $(CLASSES)
- $(JAVA_PROJECTMODULES:%=build-%): build-%:
- rm -rf mods/$*
- $(JAVAC) $(strip \
- $(call _java_flag,module-source-path,JAVA_MODULESOURCEPATH) \
- $(_java_common_flags) -Xlint -Xdoclint -implicit:none \
- $(call _java_projvar,JAVACFLAGS) \
- -d mods/$* \
- $(wildcard $(_java_root)/module-info.java) \
- $(foreach c,\
- $(call _java_projvar,JAVA_MAINCLASSES JAVA_EXTRACLASSES),\
- $(_java_root)/$(subst .,/,$*)/$c.java))
- $(JAVA_PROJECTMODULES:%=check-%): check-%:
- checkstyle -c _checkstyle/checks.xml $(strip \
- $(foreach c,\
- $(call _java_projvar,JAVA_MAINCLASSES JAVA_EXTRACLASSES),\
- $(_java_root)/$(subst .,/,$*)/$c.java))
- $(JAVA_PROJECTMODULES:%=jar-%): jar-%: build-%
- $(JAR) --create $(strip \
- --file $(or $(call _java_projvar,JAR_FILE),$*.jar) \
- $(addprefix --main-class $*.,\
- $(firstword $(call _java_projvar,JAVA_MAINCLASSES))) \
- $(call _java_projvar,JARFLAGS) \
- -C mods/$* .)
- $(addprefix runsrc-,$(_java_mainclassmodules)): runsrc-%:
- $(strip \
- $(call _java_projvar,JAVA_RUNTIME_ENV) \
- $(JAVA) \
- $(_java_common_flags) \
- $(call _java_projvar,JAVAFLAGS) \
- $(patsubst %,$(_java_root)/%.java,\
- $(subst .,/,$(or \
- $(_java_main_class),\
- $*/$(firstword $(call _java_projvar,JAVA_MAINCLASSES))))) \
- $(call _java_projvar,JAVA_RUNTIME_ARGS))
- $(addprefix runclass-,$(_java_mainclassmodules)): runclass-%: build-%
- $(strip \
- $(eval JAVA_MODULEPATHS_$* = mods/$* $(call _java_projvar,JAVA_MODULEPATHS))\
- $(call _java_projvar,JAVA_RUNTIME_ENV) \
- $(JAVA) \
- --module-path mods/$* \
- $(_java_common_flags) \
- $(call _java_projvar,JAVAFLAGS) \
- -m $*/$(or $(_java_main_class),\
- $*.$(firstword $(call _java_projvar,JAVA_MAINCLASSES))) \
- $(call _java_projvar,JAVA_RUNTIME_ARGS))
- $(addprefix runjar-,$(_java_mainclassmodules)): runjar-%: jar-%
- $(strip \
- $(call _java_projvar,JAVA_RUNTIME_ENV) \
- $(JAVA) \
- $(call _java_flag,class-path,JAVA_CLASSPATHS,path) \
- $(call _java_flag,module-path,JAVA_MODULEPATHS,path,\
- $(or $(call _java_projvar,JAR_FILE),$*.jar)) \
- $(call _java_projvar,JAVAFLAGS) \
- --module $*$(_java_main_class:%=/%) \
- $(call _java_projvar,JAVA_RUNTIME_ARGS))
- $(addprefix runsrc-,$(_java_extramainclassmodules)): runsrc-%:
- $(strip _java_main_class=$(*) \
- $(MAKE) runsrc-$(strip $(foreach p,$(JAVA_PROJECTMODULES),\
- $(if $(filter $p%,$*),$p))))
- $(addprefix runclass-,$(_java_extramainclassmodules)): runclass-%:
- $(strip _java_main_class=$(*) \
- $(MAKE) runclass-$(strip $(foreach p,$(JAVA_PROJECTMODULES),\
- $(if $(filter $p%,$*),$p))))
- $(addprefix runjar-,$(_java_extramainclassmodules)): runjar-%:
- $(strip _java_main_class=$(*) \
- $(MAKE) runjar-$(strip $(foreach p,$(JAVA_PROJECTMODULES),\
- $(if $(filter $p%,$*),$p))))
- .PHONY: \
- $(foreach p,$(JAVA_PROJECTMODULES),build-$p check-$p) \
- $(foreach p,$(_java_mainclassmodules) $(_java_extramainclassmodules),\
- runclass-$p runsrc-$p runjar-$p)
|