aboutsummaryrefslogtreecommitdiff
path: root/_make/java.mk
blob: 38fc4b07c274b4d982799de87820bff3b9c2cd7e (plain)
  1. # GNUMake snippet for java compilation and execution
  2. #
  3. # SPDX-License-Identifier: GPL-3.0-or-later
  4. # SPDX-FileCopyrightText: 2024-2025 Jonas Smedegaard <dr@jones.dk>
  5. #
  6. # Setup:
  7. # In main Makefile...
  8. # * set variable JAVA_PROJECTMODULES, or PROJECT for one simply named
  9. # * set variable JAVA_MAINCLASSES with at least one main()-method class,
  10. # where the first one listed will be used by default
  11. # * set variables JAVA_CLASSPATHS JAVA_MODULEPATHS JAVA_MODULESOURCEPATH
  12. # JAVA_ROOT JAVA_EXTRACLASSES JAVA_MODULES JAR_FILE
  13. # if needed,
  14. # * include this make snippet
  15. #
  16. # Variables may add suffix _$(PROJECTMODULE), in full or "host-only",
  17. # e.g. JAVA_MODULES_org.example.mydemo or JAVA_MODULES_mydemo.
  18. # resolve Java version
  19. JAVA_MAJOR_VERSION = $(shell $(JAVA) -version 2>&1 \
  20. | grep -Pom1 '"\K\d+' )
  21. # defaults overridable at make invocation
  22. JAVA_ROOT ?= src/main/java
  23. JAVAC ?= javac
  24. JAVA ?= java
  25. JAR ?= jar
  26. # check javadoc only with JDK 23+ supporting Markdown-flavored javadoc
  27. ifeq ($(shell expr $(JAVA_MAJOR_VERSION) \>= 23), 1)
  28. JAVACFLAGS ?= -Xlint -Xdoclint -implicit:none
  29. else
  30. JAVACFLAGS ?= -Xlint -implicit:none
  31. endif
  32. # account for one annoyingly popular class of non-POSIX system
  33. _java_path_separator := $(if $(filter Windows%,$($(shell uname))),;,:)
  34. _java_module_separator = ,
  35. # expansions optionally stem- or last-word-of-stem-based
  36. # first try fully suffixed, then "host"-suffixed, then bare variable
  37. _java_projvar = $(strip $(foreach v,$1,$(or \
  38. $(if $(or $2,$*),$(or \
  39. $(value $v_$(or $2,$*)),\
  40. $(value $v_$(lastword $(subst ., $(),$(or $2,$*)))))),\
  41. $(value $v))))
  42. _java_root = $(call _java_projvar,JAVA_ROOT)
  43. _java_flag = $(eval x = $(call _java_projvar,$2))$(strip $(if $4$x$5,\
  44. --$1 $(subst $() ,$(value _java_$3_separator),$(strip $4 $x $5))))
  45. _java_common_flags = $(strip \
  46. $(call _java_flag,class-path,JAVA_CLASSPATHS,path) \
  47. $(call _java_flag,module-path,JAVA_MODULEPATHS,path) \
  48. $(call _java_flag,add-modules,JAVA_MODULES,module))
  49. # projectmodules with default main function
  50. _java_mainclassmodules = $(strip \
  51. $(foreach p,$(JAVA_PROJECTMODULES),\
  52. $(if $(call _java_projvar,JAVA_MAINCLASSES,$p),$p)))
  53. # projectmodules with non-default main function expanded, dot-appended
  54. _java_extramainclassmodules = $(strip \
  55. $(foreach p,$(JAVA_PROJECTMODULES),\
  56. $(eval classes = $(call _java_projvar,JAVA_MAINCLASSES,$p))\
  57. $(foreach c,$(filter-out $(firstword $(classes)),$(classes)),\
  58. $p.$(subst /,.,$c))))
  59. # TODO: formally define a builddir, and drop that on clean
  60. #clean::
  61. # rm -f $(CLASSES)
  62. $(JAVA_PROJECTMODULES:%=build-%): build-%:
  63. rm -rf mods/$*
  64. $(JAVAC) $(strip \
  65. $(call _java_flag,module-source-path,JAVA_MODULESOURCEPATH) \
  66. $(_java_common_flags) $(JAVACFLAGS) \
  67. $(call _java_projvar,JAVACFLAGS) \
  68. -d mods/$* \
  69. $(wildcard $(_java_root)/module-info.java) \
  70. $(foreach c,\
  71. $(call _java_projvar,JAVA_MAINCLASSES JAVA_EXTRACLASSES),\
  72. $(patsubst %,$(_java_root)/%.java,\
  73. $(subst .,/,\
  74. $(if $(wildcard $(_java_root)/module-info.java),$*/))$c)))
  75. $(JAVA_PROJECTMODULES:%=check-%): check-%:
  76. checkstyle -c _checkstyle/checks.xml $(strip \
  77. $(foreach c,\
  78. $(call _java_projvar,JAVA_MAINCLASSES JAVA_EXTRACLASSES),\
  79. $(_java_root)/$(subst .,/,$*)/$c.java))
  80. $(JAVA_PROJECTMODULES:%=jar-%): jar-%: build-%
  81. $(JAR) --create $(strip \
  82. --file $(or $(call _java_projvar,JAR_FILE),$*.jar) \
  83. $(addprefix --main-class $*.,\
  84. $(firstword $(call _java_projvar,JAVA_MAINCLASSES))) \
  85. $(call _java_projvar,JARFLAGS) \
  86. -C mods/$* .)
  87. $(addprefix runsrc-,$(_java_mainclassmodules)): runsrc-%:
  88. $(strip \
  89. $(call _java_projvar,JAVA_RUNTIME_ENV) \
  90. $(JAVA) \
  91. $(_java_common_flags) \
  92. $(call _java_projvar,JAVAFLAGS) \
  93. $(patsubst %,$(_java_root)/%.java,\
  94. $(subst .,/,$(or \
  95. $(_java_main_class),\
  96. $(strip $(if $(wildcard $(_java_root)/module-info.java),$*/)\
  97. )$(firstword $(call _java_projvar,JAVA_MAINCLASSES))))) \
  98. $(call _java_projvar,JAVA_RUNTIME_ARGS))
  99. $(addprefix runclass-,$(_java_mainclassmodules)): runclass-%: build-%
  100. $(strip \
  101. $(eval JAVA_MODULEPATHS_$* = $(strip \
  102. mods/$* $(call _java_projvar,JAVA_MODULEPATHS)))\
  103. $(call _java_projvar,JAVA_RUNTIME_ENV) \
  104. $(JAVA) \
  105. $(_java_common_flags) \
  106. $(call _java_projvar,JAVAFLAGS) \
  107. -m $*/$(or $(_java_main_class),\
  108. $*.$(firstword $(call _java_projvar,JAVA_MAINCLASSES))) \
  109. $(call _java_projvar,JAVA_RUNTIME_ARGS))
  110. $(addprefix runjar-,$(_java_mainclassmodules)): runjar-%: jar-%
  111. $(strip \
  112. $(call _java_projvar,JAVA_RUNTIME_ENV) \
  113. $(JAVA) \
  114. $(call _java_flag,class-path,JAVA_CLASSPATHS,path) \
  115. $(call _java_flag,module-path,JAVA_MODULEPATHS,path,\
  116. $(or $(call _java_projvar,JAR_FILE),$*.jar)) \
  117. $(call _java_projvar,JAVAFLAGS) \
  118. --module $*$(_java_main_class:%=/%) \
  119. $(call _java_projvar,JAVA_RUNTIME_ARGS))
  120. $(addprefix runsrc-,$(_java_extramainclassmodules)): runsrc-%:
  121. $(strip _java_main_class=$* \
  122. $(MAKE) runsrc-$(strip $(foreach p,$(JAVA_PROJECTMODULES),\
  123. $(if $(filter $p%,$*),$p))))
  124. $(addprefix runclass-,$(_java_extramainclassmodules)): runclass-%:
  125. $(strip _java_main_class=$* \
  126. $(MAKE) runclass-$(strip $(foreach p,$(JAVA_PROJECTMODULES),\
  127. $(if $(filter $p%,$*),$p))))
  128. $(addprefix runjar-,$(_java_extramainclassmodules)): runjar-%:
  129. $(strip _java_main_class=$* \
  130. $(MAKE) runjar-$(strip $(foreach p,$(JAVA_PROJECTMODULES),\
  131. $(if $(filter $p%,$*),$p))))
  132. .PHONY: \
  133. $(foreach p,$(JAVA_PROJECTMODULES),build-$p check-$p) \
  134. $(foreach p,$(_java_mainclassmodules) $(_java_extramainclassmodules),\
  135. runclass-$p runsrc-$p runjar-$p)