2 # Copyright (C) 2019 Michael Zucchi
4 # This is the copyright for java.make
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.
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.
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/>.
20 # General purpose modular java makefile that supports native library
21 # compilation directly. Non-recrusve implementation.
23 # Uses metamake programming with some file conventions to implement
24 # auto-make-like features.
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.
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.
42 # JMODFLAGS jmod flags.
44 # Module specific variables
46 # <module>_JDEPMOD Lists modules which this one depends on.
48 # <module>_JAVACFLAGS Extra module-specific flags for each command.
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.
56 # Variables for use in fragments
58 # gen.make and jni.make can additionally make use of these variables
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.
71 # Each module can define one or more native libraries.
73 # These are compiled after the java sources have been compiled as that
74 # process also generates any native binding headers.
76 # <module>_JNI_LIBRARIES list of libraries to build.
77 # library names match System.loadLibrary().
85 # SO shared library suffix
86 # LIB shared library prefix
90 # $(call library-path,<module>,<libname>) will resolve to the library file name.
92 # Per library variables.
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
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
104 # <library>_DEPENDENCIES A list of other objects on which this library depends before linking.
106 # <library>_DEFS A list of .def files for nativez-gen.
107 # <library>_DEFSFLAGS Flags for nativez-gen invocation.
109 # .c files have dependencies automatically generated
114 # make gen only generate java sources
115 # make clean rm -rf bin
116 # make dist create dist tar in bin/
117 # make | make jar make all jars and jmods
118 # make bin make everything but jars and mods
123 # All intermediate and output files are written to bin/
125 # This layout is enforced by javac
126 # bin/include/<module>/ .h files from javac -h
127 # bin/modules/<module>/ .class files from javac
129 # This layout is convenient for netbeans
130 # bin/gen/<module>/gen/ .c, exe files for generator free use
131 # bin/gen/<module>/classes/ .java files from generator <module>_JAVA_GENERATED
134 # bin/status/ marker files for makefile
136 # bin/<module>/<target>/lib .so librareies for jmod <module>_LIBRARIES = libname
137 # bin/<module>/<target>/obj .o, .d files for library <libname>_SOURCES
138 # bin/<module>/<target>/include .h files for jmod <libname>_HEADERS
139 # bin/<module>/<target>/<module>.jmod .jmod module
142 # bin/<target>/lib/ modular jar files and shared libraries for GNU/linux dev
143 # bin/<target>/include/ header files for exported shared libraries
144 # bin/<target>/bin/ shared libraries for microsoft dev
145 # bin/<target>/jmods/ jmod files for 'jlink' use.
147 # ######################################################################
152 # All modules with native code
153 java_JMODS=$(foreach module,$(java_MODULES),$(if $(wildcard src/$(module)/jni/jni.make),$(module)))
154 # Only modules with no native code
155 java_JARS=$(foreach module,$(java_MODULES),$(if $(wildcard src/$(module)/jni/jni.make),,$(module)))
156 # Modules with generated java source
157 java_JGEN=$(foreach module,$(java_MODULES),$(if $(wildcard src/$(module)/gen/gen.make),$(module)))
159 # Define some useful variables before including fragments
160 define java_variables=
161 $(1)_gendir:=bin/gen/$(1)/gen
162 $(1)_genjavadir:=bin/gen/$(1)/classes
163 $(1)_jnidir:=bin/$(1)/$(TARGET)/jni
164 $(1)_objdir:=bin/$(1)/$(TARGET)/obj
165 $(1)_incdir:=bin/$(1)/$(TARGET)/include
166 $(1)_libdir:=$$(if $$(filter windows-%,$(TARGET)),bin/$(1)/$(TARGET)/bin,bin/$(1)/$(TARGET)/lib)
167 $(1)_bindir:=bin/$(1)/$(TARGET)/bin
169 $(1)_JAVA := $$(shell find src/$(1)/classes -type f -name '*.java')
171 ifndef $(1)_RESOURCES
172 $(1)_RESOURCES := $$(shell find src/$(1)/classes -type f \! -name '*.java')
176 java_libdir:=$(if $(filter windows-%,$(TARGET)),bin/$(TARGET)/bin,bin/$(TARGET)/lib)
177 java_bindir:=bin/$(TARGET)/bin
178 java_jardir:=bin/$(TARGET)/lib
179 java_incdir:=bin/$(TARGET)/include
180 java_jmoddir:=bin/$(TARGET)/jmods
182 $(foreach module,$(java_MODULES),$(eval $(call java_variables,$(module))))
184 # ######################################################################
190 .PHONY: all clean jar bin gen
194 include $(patsubst %,src/%/gen/gen.make,$(java_JGEN))
195 include $(patsubst %,src/%/jni/jni.make,$(java_JMODS))
197 # ######################################################################
199 # ######################################################################
202 # Rules for module $(1)
203 $(1)_JAVA_generated = $$(addprefix $$($(1)_genjavadir)/,$$($(1)_JAVA_GENERATED))
205 bin/status/$(1).data: $$($(1)_RESOURCES)
206 bin/status/$(1).classes: $(patsubst %,bin/status/%.classes,$($(1)_JDEPMOD)) $$($(1)_JAVA) $$($(1)_JAVA_generated)
207 jar $(1): $(java_jardir)/$(1).jar $(java_jmoddir)/$(1).jmod
208 bin: bin/status/$(1).classes bin/status/$(1).data
209 sources: $(java_jardir)/$(1)-sources.zip
210 gen: $$($(1)_JAVA_generated)
213 $(java_jardir)/$(1).jar: bin/status/$(1).classes bin/status/$(1).data
216 $(JARFLAGS) $$($(1)_JARFLAGS) \
217 -C bin/modules/$(1) .
220 $(java_jmoddir)/$(1).jmod: bin/status/$(1).classes bin/status/$(1).data
224 $$(JMODFLAGS) $$($(1)_JMODFLAGS) \
225 --target-platform $(TARGET) \
226 --class-path bin/modules/$(1) \
227 $$(if $$(wildcard bin/$(1)/$(TARGET)/include),--header-files bin/$(1)/$(TARGET)/include) \
228 $$(if $$(wildcard src/$(1)/legal),--legal-notices src/$(1)/legal) \
229 $$(if $$(wildcard bin/$(1)/$(TARGET)/bin),--cmds bin/$(1)/$(TARGET)/bin) \
230 $$(if $$(wildcard bin/$(1)/$(TARGET)/lib),--libs bin/$(1)/$(TARGET)/lib) \
233 # Create an IDE source zip, paths have to match --module-source-path
234 $(java_jardir)/$(1)-sources.zip: bin/status/$(1).classes
237 $$(patsubst src/$(1)/classes/%,-C src/$(1)/classes %,$$(filter src/$(1)/classes/%,$$($(1)_JAVA))) \
238 $$(patsubst bin/gen/$(1)/classes/%,-C bin/gen/$(1)/classes %,$$(filter bin/gen/$(1)/classes/%,$$($(1)_JAVA)))
242 #$(foreach module,$(java_MODULES),$(info $(call java_targets,$(module))))
243 $(foreach module,$(java_MODULES),$(eval $(call java_targets,$(module))))
245 # ######################################################################
246 # Global pattern rules
251 for data in $(patsubst src/$*/classes/%,"%",$($*_RESOURCES)) ; do \
252 install -vDC "src/$*/classes/$$data" "bin/modules/$*/$$data" || exit 1 ; \
256 # Compile one module. This only updates (javac -h) headers if they changed.
257 bin/status/%.classes:
260 --module-source-path "src/*/classes:bin/gen/*/classes" \
261 $(if $(JAVAMODPATH) $($*_JAVAMODPATH),--module-path $(subst $(S),:,$(JAVAMODPATH) $($*_JAVAMODPATH))) \
262 $(JAVACFLAGS) $($*_JAVACFLAGS) \
266 $($*_JAVA) $($*_JAVA_generated)
267 if [ -d bin/inc/$* ] ; then \
268 install -DC -t bin/include/$* bin/inc/$*/*.h ; \
272 # ######################################################################
274 # ######################################################################
280 # functions to find cross-module stuff $(call library-path,modname,libname)
281 library-path=$($(1)_libdir)/$(LIB)$(2)$(SO)
282 library-dir=$($(1)_libdir)/
285 # Rule for library $(2) in module $(1)
286 $(2)_OBJS = $(foreach sx,$(SUFFIXES),$(patsubst %$(sx), $($(1)_objdir)/%.o, $(filter %$(sx),$($(2)_SOURCES))))
287 $(2)_SRCS = $(addprefix src/$(1)/jni/,$($(2)_SOURCES))
288 $(2)_SO = $($(1)_libdir)/$(LIB)$(2)$(SO)
290 $($(1)_libdir)/$(LIB)$(2)$(SO): $$($(2)_OBJS) $($(2)_LIBADD) $($(2)_DEPENDENCIES)
292 $($(TARGET)_CC) -o $$@ -shared \
293 $($(TARGET)_LDFLAGS) $($(2)_LDFLAGS) $$($(2)_OBJS) $($(2)_LIBADD) $($(TARGET)_LDLIBS) $($(2)_LDLIBS)
295 $(java_libdir)/%: $($(1)_libdir)/%
297 $(java_bindir)/%: $($(1)_bindir)/%
299 $(java_incdir)/%: $($(1)_incdir)/%
302 $($(1)_objdir)/%.o: src/$(1)/jni/%.c
304 $($(TARGET)_CC) -Isrc/$(1)/jni -Ibin/include/$(1) -I$($(1)_jnidir) \
305 $($(TARGET)_CPPFLAGS) $($(2)_CPPFLAGS) \
306 $($(TARGET)_CFLAGS) $($(2)_CFLAGS) -c -o $$@ $$<
308 $($(1)_incdir)/%.h: src/$(1)/jni/%.h
311 # auto-dependencies for c files
312 $($(1)_objdir)/%.d: src/$(1)/jni/%.c bin/status/$(1).classes
315 @$($(TARGET)_CC) -MM -MT "bin/$(1)/$(TARGET)/obj/$$*.o" -Isrc/$(1)/jni -Ibin/include/$(1) \
316 $($(TARGET)_CPPFLAGS) $($(2)_CPPFLAGS) $$< -o $$@.d 2>/dev/null
317 @sed 's,\($$*\.o\) *:,\1 $$@ : ,g' $$@.d > $$@ ; rm $$@.d
319 # .def files for nativez mapping
320 $($(1)_jnidir)/%.h: src/$(1)/jni/%.def
322 $(NATIVEZ_HOME)/bin/nativez-gen -J $($(2)_DEFSFLAGS) $$< > $$@ || ( rm $$@ ; exit 1)
324 bin jni $(1) $(java_jmoddir)/$(1).jmod: \
325 $($(1)_libdir)/$(LIB)$(2)$(SO) \
326 $(java_libdir)/$(LIB)$(2)$(SO) \
327 $(addprefix $($(1)_incdir)/,$($(2)_HEADERS)) \
328 $(addprefix $(java_incdir)/,$($(2)_HEADERS)) \
329 $(addprefix $($(1)_bindir)/,$($(2)_COMMANDS)) \
330 $(addprefix $(java_bindir)/,$($(2)_COMMANDS)) \
331 $(addprefix $($(1)_libdir)/,$($(2)_LIBRARIES))
333 $(if $(filter clean dist gen,$(MAKECMDGOALS)),,-include $$($(2)_OBJS:.o=.d))
336 #$(foreach module,$(java_JMODS),$(foreach library,$($(module)_JNI_LIBRARIES),$(info $(call jni_library,$(module),$(library)))))
337 $(foreach module,$(java_JMODS),$(foreach library,$($(module)_JNI_LIBRARIES),$(eval $(call jni_library,$(module),$(library)))))
339 #$(foreach module,$(java_JMODS),$(foreach library,$($(module)_JNI_LIBRARIES),$(foreach def,$($(library)_DEFS),$(info $($(module)_objdir)/$(def:.def=.o): $($(module)_jnidir)/$(def:.def=.h)))))
340 $(foreach module,$(java_JMODS),$(foreach library,$($(module)_JNI_LIBRARIES),$(foreach def,$($(library)_DEFS),$(eval $($(module)_objdir)/$(def:.def=.o): $($(module)_jnidir)/$(def:.def=.h)))))
342 # ######################################################################
346 tar cfz bin/$(dist_NAME)-$(dist_VERSION).tar.gz \
347 --transform=s,^,$(dist_NAME)-$(dist_VERSION)/, \
348 config.make java.make Makefile src \