Bump to jdk 13.
[nativez] / java.make
1 #
2 # Copyright (C) 2019 Michael Zucchi
3 #
4 # This is the copyright for java.make
5 #
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 #
19
20 # General purpose modular java makefile that supports native library
21 # compilation directly.  Non-recrusve implementation.
22 #
23 # Uses metamake programming with some file conventions to implement
24 # auto-make-like features.
25
26 # Define modules
27 # --------------
28 # java_MODULES list of java modules to compile.  The sources must
29 #               exist in src/<module>/classes.  Resource files are
30 #               stored in src/<module>/classes.  Source-code
31 #               generators must exist in src/<module>/gen.  Native
32 #               libraries must exist in src/<module>/jni.
33
34 # Global variables
35
36 # JAVA_HOME             location of jdk.
37 # JAVAC                 java compiler to use.  Default is 'javac' on the path.
38 # JAVACFLAGS            javac flags applied to all invocations.
39 # JAR                   jar command.
40 # JARFLAGS              jar flags
41 # JMOD                  jmod command.
42 # JMODFLAGS             jmod flags.
43
44 # Module specific variables
45
46 # <module>_JDEPMOD      Lists modules which this one depends on.
47
48 # <module>_JAVACFLAGS   Extra module-specific flags for each command.
49 # <module>_JARFLAGS
50 # <module>_JMODFLAGS
51
52 # <module>_JAVA                 Java sources.  If not set it is found from src/<module>/classes/(*.java)
53 # <module>_RESOURCES            .jar resources.  If not set it is found from src/<module>/classes/(not *.java)
54 # <module>_JAVA_GENERATED       Java generated sources.  These must be relative to the package name.
55
56 # Variables for use in fragments
57
58 # gen.make and jni.make can additionally make use of these variables
59
60 # <module>_gendir       Location for files used in Java generation process (per project).
61 # <module>_genjavadir   Location where _JAVA_GENERATED .java files will be created (per project).
62 # <module>_jnidir       Location for jni generated files (per target).
63 # <module>_objdir       Location for c objects (per target).
64 # <module>_incdir       Location for output includes, .jmod staging.
65 # <module>_libdir       Location for output libraries, .jmod staging.  May point to _bindir.
66 # <module>_bindir       Location for output commands, .jmod staging.
67
68 # Define libraries
69 # ----------------
70
71 # Each module can define one or more native libraries.
72
73 # These are compiled after the java sources have been compiled as that
74 # process also generates any native binding headers.
75
76 # <module>_JNI_LIBRARIES        list of libraries to build.
77 # library names match System.loadLibrary().
78
79 # Global variables
80
81 # <target>_LDFLAGS
82 # <target>_LDLIBS
83 # <target>_CPPFLAGS
84 # <target>_CFLAGS
85 # SO            shared library suffix
86 # LIB           shared library prefix
87
88 # Utility functions
89 #
90 # $(call library-path,<module>,<libname>) will resolve to the library file name.
91
92 # Per library variables.
93
94 # <library>_SOURCES     .c, .cc, .C - source files for library.  Paths are relative to src/<module>/jni.
95 # <library>_HEADERS     header files for jmod
96 # <library>_COMMANDS    commands/bin/scripts for jmod
97
98 # <library>_LDFLAGS     link flags
99 # <library>_LIBADD      extra objects to add to link line
100 # <library>_LDLIBS      link libraries
101 # <library>_CPPFLAGS    c pre-processor flags.  "-Isrc/<module>/jni -Ibin/include/<module>" is implicit.
102 # <library>_CCFLAGS     c compiler flags
103
104 # <library>_DEPENDENCIES        A list of other objects on which this library depends before linking.
105
106 # .c files have dependencies automatically generated
107
108 # Targets
109 # -------
110
111 # make gen              only generate java sources
112 # make clean            rm -rf bin
113 # make dist             create dist tar in bin/
114 # make | make jar       make all jars and jmods
115 # make bin              make everything but jars and mods
116
117 # Outputs
118 # -------
119
120 # All intermediate and output files are written to bin/
121
122 # This layout is enforced by javac
123 #  bin/include/<module>/        .h files from javac -h
124 #  bin/modules/<module>/        .class files from javac
125
126 # This layout is convenient for netbeans
127 #  bin/gen/<module>/gen/        .c, exe files for generator     free use
128 #  bin/gen/<module>/classes/    .java files from generator      <module>_JAVA_GENERATED
129
130 # Working files
131 #  bin/status/                  marker files for makefile
132
133 #  bin/<module>/<target>/lib    .so librareies for jmod         <module>_LIBRARIES = libname
134 #  bin/<module>/<target>/obj    .o, .d files for library        <libname>_SOURCES
135 #  bin/<module>/<target>/include .h files for jmod              <libname>_HEADERS
136 #  bin/<module>/<target>/<module>.jmod  .jmod module
137
138 # Output files
139 #  bin/<target>/lib/            modular jar files and shared libraries for GNU/linux dev
140 #  bin/<target>/include/        header files for exported shared libraries
141 #  bin/<target>/bin/            shared libraries for microsoft dev
142 #  bin/<target>/jmods/          jmod files for 'jlink' use.
143
144 # ######################################################################
145
146 E:=
147 S:=$(E) $(E)
148
149 # All modules with native code
150 java_JMODS=$(foreach module,$(java_MODULES),$(if $(wildcard src/$(module)/jni/jni.make),$(module)))
151 # Only modules with no native code
152 java_JARS=$(foreach module,$(java_MODULES),$(if $(wildcard src/$(module)/jni/jni.make),,$(module)))
153 # Modules with generated java source
154 java_JGEN=$(foreach module,$(java_MODULES),$(if $(wildcard src/$(module)/gen/gen.make),$(module)))
155
156 # Define some useful variables before including fragments
157 define java_variables=
158 $(1)_gendir:=bin/gen/$(1)/gen
159 $(1)_genjavadir:=bin/gen/$(1)/classes
160 $(1)_jnidir:=bin/$(1)/$(TARGET)/jni
161 $(1)_objdir:=bin/$(1)/$(TARGET)/obj
162 $(1)_incdir:=bin/$(1)/$(TARGET)/include
163 $(1)_libdir:=$$(if $$(filter windows-%,$(TARGET)),bin/$(1)/$(TARGET)/bin,bin/$(1)/$(TARGET)/lib)
164 $(1)_bindir:=bin/$(1)/$(TARGET)/bin
165 ifndef $(1)_JAVA
166 $(1)_JAVA := $$(shell find src/$(1)/classes -type f -name '*.java')
167 endif
168 ifndef $(1)_RESOURCES
169 $(1)_RESOURCES := $$(shell find src/$(1)/classes -type f \! -name '*.java')
170 endif
171 endef
172
173 java_libdir:=$(if $(filter windows-%,$(TARGET)),bin/$(TARGET)/bin,bin/$(TARGET)/lib)
174 java_bindir:=bin/$(TARGET)/bin
175 java_jardir:=bin/$(TARGET)/lib
176 java_incdir:=bin/$(TARGET)/include
177 java_jmoddir:=bin/$(TARGET)/jmods
178
179 $(foreach module,$(java_MODULES),$(eval $(call java_variables,$(module))))
180
181 # ######################################################################
182
183 all: jar
184 bin:
185 gen:
186
187 .PHONY: all clean jar bin gen
188 clean:
189         rm -rf bin
190
191 include $(patsubst %,src/%/gen/gen.make,$(java_JGEN))
192 include $(patsubst %,src/%/jni/jni.make,$(java_JMODS))
193
194 # ######################################################################
195 # Java
196 # ######################################################################
197
198 define java_targets=
199 # Rules for module $(1)
200 $(1)_JAVA_generated = $$(addprefix $$($(1)_genjavadir)/,$$($(1)_JAVA_GENERATED))
201
202 bin/status/$(1).data: $$($(1)_RESOURCES)
203 bin/status/$(1).classes: $(patsubst %,bin/status/%.classes,$($(1)_JDEPMOD)) $$($(1)_JAVA) $$($(1)_JAVA_generated)
204 jar $(1): $(java_jardir)/$(1).jar $(java_jmoddir)/$(1).jmod
205 bin: bin/status/$(1).classes bin/status/$(1).data
206 sources: $(java_jardir)/$(1)-sources.zip
207 gen: $$($(1)_JAVA_generated)
208
209 # Create modular jar
210 $(java_jardir)/$(1).jar: bin/status/$(1).classes bin/status/$(1).data
211         @install -d $$(@D)
212         $(JAR) cf $$@ \
213           $(JARFLAGS) $$($(1)_JARFLAGS) \
214           -C bin/modules/$(1) .
215
216 # Create a jmod
217 $(java_jmoddir)/$(1).jmod: bin/status/$(1).classes bin/status/$(1).data
218         rm -f $$@
219         @install -d $$(@D)
220         $$(JMOD) create \
221           $$(JMODFLAGS) $$($(1)_JMODFLAGS) \
222           --target-platform $(TARGET) \
223           --class-path bin/modules/$(1) \
224           $$(if $$(wildcard bin/$(1)/$(TARGET)/include),--header-files bin/$(1)/$(TARGET)/include) \
225           $$(if $$(wildcard src/$(1)/legal),--legal-notices src/$(1)/legal) \
226           $$(if $$(wildcard bin/$(1)/$(TARGET)/bin),--cmds bin/$(1)/$(TARGET)/bin) \
227           $$(if $$(wildcard bin/$(1)/$(TARGET)/lib),--libs bin/$(1)/$(TARGET)/lib) \
228           $$@
229
230 # Create an IDE source zip, paths have to match --module-source-path
231 $(java_jardir)/$(1)-sources.zip: bin/status/$(1).classes
232         @install -d $$(@D)
233         jar -c -f $$@ -M \
234                 $$(patsubst src/$(1)/classes/%,-C src/$(1)/classes %,$$(filter src/$(1)/classes/%,$$($(1)_JAVA))) \
235                 $$(patsubst bin/gen/$(1)/classes/%,-C bin/gen/$(1)/classes %,$$(filter bin/gen/$(1)/classes/%,$$($(1)_JAVA)))
236
237 endef
238
239 #$(foreach module,$(java_MODULES),$(info $(call java_targets,$(module))))
240 $(foreach module,$(java_MODULES),$(eval $(call java_targets,$(module))))
241
242 # ######################################################################
243 # Global pattern rules
244
245 # Stage resources
246 bin/status/%.data:
247         @install -d $(@D)
248         for data in $(patsubst src/$*/classes/%,"%",$($*_RESOURCES)) ; do \
249                 install -vDC "src/$*/classes/$$data" "bin/modules/$*/$$data" || exit 1 ; \
250         done
251         touch $@
252
253 # Compile one module.  This only updates (javac -h) headers if they changed.
254 bin/status/%.classes:
255         @install -d $(@D)
256         $(JAVAC) \
257                 --module-source-path "src/*/classes:bin/gen/*/classes" \
258                 $(if $(JAVAMODPATH),--module-path $(subst $(S),:,$(JAVAMODPATH))) \
259                 $(JAVACFLAGS) $($*_JAVACFLAGS) \
260                 -h bin/inc \
261                 -d bin/modules \
262                 -m $* \
263                 $($*_JAVA) $($*_JAVA_generated)
264         if [ -d bin/inc/$* ] ; then \
265                 install -DC -t bin/include/$* bin/inc/$*/*.h ; \
266         fi
267         touch $@
268
269 # ######################################################################
270 # C stuff
271 # ######################################################################
272
273 SUFFIXES=.c .C .cc
274 SO=$($(TARGET)_SO)
275 LIB=$($(TARGET)_LIB)
276
277 # functions to find cross-module stuff $(call library-path,modname,libname)
278 library-path=$($(1)_libdir)/$(LIB)$(2)$(SO)
279 library-dir=$($(1)_libdir)/
280
281 define jni_library=
282 # Rule for library $(2) in module $(1)
283 $(2)_OBJS = $(foreach sx,$(SUFFIXES),$(patsubst %$(sx), $($(1)_objdir)/%.o, $(filter %$(sx),$($(2)_SOURCES))))
284 $(2)_SRCS = $(addprefix src/$(1)/jni/,$($(2)_SOURCES))
285 $(2)_SO = $($(1)_libdir)/$(LIB)$(2)$(SO)
286
287 $($(1)_libdir)/$(LIB)$(2)$(SO): $$($(2)_OBJS) $($(2)_LIBADD) $($(2)_DEPENDENCIES)
288         @install -d $$(@D)
289         $($(TARGET)_CC) -o $$@ -shared \
290                 $($(TARGET)_LDFLAGS) $($(2)_LDFLAGS) $$($(2)_OBJS) $($(2)_LIBADD) $($(TARGET)_LDLIBS) $($(2)_LDLIBS)
291
292 $(java_libdir)/%: $($(1)_libdir)/%
293         install -DC $$< $$@
294 $(java_bindir)/%: $($(1)_bindir)/%
295         install -DC $$< $$@
296 $(java_incdir)/%: $($(1)_incdir)/%
297         install -DC $$< $$@
298
299 $($(1)_objdir)/%.o: src/$(1)/jni/%.c bin/status/$(1).classes
300         @install -d $$(@D)
301         $($(TARGET)_CC) -Isrc/$(1)/jni -Ibin/include/$(1) -I$($(1)_jnidir) \
302                 $($(TARGET)_CPPFLAGS) $($(2)_CPPFLAGS) \
303                 $($(TARGET)_CFLAGS) $($(2)_CFLAGS) -c -o $$@ $$<
304
305 $($(1)_incdir)/%.h: src/$(1)/jni/%.h
306         install -DC $$< $$@
307
308 $($(1)_objdir)/%.d: src/$(1)/jni/%.c bin/status/$(1).classes
309         @install -d $$(@D)
310         @rm -f $$@
311         @$($(TARGET)_CC) -MM -MT "bin/$(1)/$(TARGET)/obj/$$*.o" -Isrc/$(1)/jni -Ibin/include/$(1) \
312                 $($(TARGET)_CPPFLAGS) $($(2)_CPPFLAGS) $$< -o $$@.d 2>/dev/null
313         @sed 's,\($$*\.o\) *:,\1 $$@ : ,g' $$@.d > $$@ ; rm $$@.d
314
315 bin jni $(1) $(java_jmoddir)/$(1).jmod: \
316         $($(1)_libdir)/$(LIB)$(2)$(SO) \
317         $(java_libdir)/$(LIB)$(2)$(SO) \
318         $(addprefix $($(1)_incdir)/,$($(2)_HEADERS)) \
319         $(addprefix $(java_incdir)/,$($(2)_HEADERS)) \
320         $(addprefix $($(1)_bindir)/,$($(2)_COMMANDS)) \
321         $(addprefix $(java_bindir)/,$($(2)_COMMANDS)) \
322         $$(addprefix $($(1)_libdir)/,$$($(2)_LIBRARIES))
323
324 $(if $(filter clean dist gen,$(MAKECMDGOALS)),,-include $$($(2)_OBJS:.o=.d))
325 endef
326
327 #$(foreach module,$(java_JMODS),$(foreach library,$($(module)_JNI_LIBRARIES),$(info $(call jni_library,$(module),$(library)))))
328 $(foreach module,$(java_JMODS),$(foreach library,$($(module)_JNI_LIBRARIES),$(eval $(call jni_library,$(module),$(library)))))
329
330 # ######################################################################
331
332 dist:
333         @install -d bin
334         tar cfz bin/$(dist_NAME)-$(dist_VERSION).tar.gz \
335          --transform=s,^,$(dist_NAME)-$(dist_VERSION)/, \
336          config.make java.make Makefile src             \
337          $(dist_EXTRA)
338