2 # Copyright (C) 2019,2022 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.
34 # native_MODULES list of native-only "modules".
39 # JAVA_HOME location of jdk.
40 # JAVAC java compiler to use. Default is 'javac' on the path.
41 # JAVACFLAGS javac flags applied to all invocations.
45 # JMODFLAGS jmod flags.
46 # JAVAFLAGS java flags for run targets
48 # Module specific variables
50 # <module>_JDEPMOD Lists modules which this one depends on.
52 # <module>_JAVACFLAGS Extra module-specific flags for each command.
56 # <module>_JAVA Java sources. If not set it is found from src/<module>/classes/(*.java)
57 # <module>_RESOURCES .jar resources. If not set it is found from src/<module>/classes/(not *.java)
58 # <module>_JAVA_GENERATED Java generated sources. These must be relative to the package name.
60 # Variables for use in fragments
62 # gen.make and jni.make can additionally make use of these variables
64 # <module>_gendir Location for files used in Java generation process (per project).
65 # <module>_genjavadir Location where _JAVA_GENERATED .java files will be created (per project).
66 # <module>_objdir Location for c objects (per target).
67 # <module>_incdir Location for output includes, .jmod staging.
68 # <module>_libdir Location for output libraries, .jmod staging. May point to _bindir.
69 # <module>_bindir Location for output commands, .jmod staging.
74 # Each module can define one or more native libraries.
76 # These are compiled after the java sources have been compiled as that
77 # process also generates any native binding headers.
79 # <module>_NATIVE_LIBRARIES list of libraries to build.
80 # library names match System.loadLibrary().
91 # SO shared library suffix
92 # LIB shared library prefix
96 # $(call library-path,<module>,<libname>) will resolve to the library file name.
98 # Per library variables.
100 # <library>_SOURCES .c source files for library. Paths are relative to src/<module>/native.
101 # <library>_CXXSOURCES .c source files for library. Paths are relative to src/<module>/native.
102 # <library>_HEADERS header files for install/jmod
103 # <library>_COMMANDS commands/bin/scripts for install/jmod
105 # <library>_LDFLAGS link flags
106 # <library>_LIBADD extra objects to add to link line
107 # <library>_LDLIBS link libraries
108 # <library>_CPPFLAGS c and c++ pre-processor flags. "-Isrc/<module>/jni -Ibin/include/<module>" is implicit.
109 # <library>_CCFLAGS c compiler flags
110 # <library>_CXXFLAGS c++ compiler flags
112 # <library>_DEPENDENCIES A list of other objects on which this library depends before linking.
114 # .c and .cc files have dependencies automatically generated
119 # make gen only generate java sources
120 # make clean rm -rf bin
121 # make dist create dist tar in bin/
122 # make | make jar make all jars and jmods
127 # All intermediate and output files are written to bin/
129 # This layout is enforced by javac
130 # bin/include/<module>/ .h files from javac -h
131 # bin/modules/<module>/ .class files from javac
133 # This layout is convenient for netbeans
134 # bin/gen/<module>/gen/ .c, exe files for generator free use
135 # bin/gen/<module>/classes/ .java files from generator <module>_JAVA_GENERATED
138 # bin/status/ marker files for makefile
140 # bin/<module>/<target>/lib .so librareies for jmod <module>_LIBRARIES = libname
141 # bin/<module>/<target>/obj .o, .d files for library <libname>_SOURCES
142 # bin/<module>/<target>/include .h files for jmod <libname>_HEADERS
143 # bin/<module>/<target>/<module>.jmod .jmod module
146 # bin/<target>/lib/ modular jar files and shared libraries for GNU/linux dev
147 # bin/<target>/include/ header files for exported shared libraries
148 # bin/<target>/bin/ shared libraries for microsoft dev
149 # bin/<target>/jmods/ jmod files for 'jlink' use.
151 # ######################################################################
156 # All modules with native code
157 java_JMODS=$(foreach module,$(java_MODULES),$(if $(wildcard src/$(module)/jni/jni.make),$(module)))
158 # Only modules with no native code
159 java_JARS=$(foreach module,$(java_MODULES),$(if $(wildcard src/$(module)/jni/jni.make),,$(module)))
160 # Modules with generated java source
161 java_JGEN=$(foreach module,$(java_MODULES),$(if $(wildcard src/$(module)/gen/gen.make),$(module)))
163 # Define some useful variables before including fragments
164 define common_variables=
165 $(1)_gendir:=bin/gen/$(1)/gen
166 $(1)_genjavadir:=bin/gen/$(1)/classes
167 $(1)_objdir:=bin/$(1)/$(TARGET)/obj
168 $(1)_incdir:=bin/$(1)/$(TARGET)/include
169 $(1)_libdir:=$$(if $$(filter windows-%,$(TARGET)),bin/$(1)/$(TARGET)/bin,bin/$(1)/$(TARGET)/lib)
170 $(1)_bindir:=bin/$(1)/$(TARGET)/bin
172 $(1)_SCRIPTS := $$(shell find src/$(1)/bin src/$(1)/$(TARGET)/bin -type f 2>/dev/null)
175 $(1)_DATA := $$(shell find src/$(1)/lib src/$(1)/$(TARGET)/lib -type f 2>/dev/null)
179 define java_variables=
181 $(1)_JAVA := $$(shell find src/$(1)/classes -type f -name '*.java')
183 ifndef $(1)_RESOURCES
184 $(1)_RESOURCES := $$(shell find src/$(1)/classes -type f \! -name '*.java')
188 java_libdir:=$(if $(filter windows-%,$(TARGET)),bin/$(TARGET)/bin,bin/$(TARGET)/lib)
189 java_bindir:=bin/$(TARGET)/bin
190 java_jardir:=bin/$(TARGET)/lib
191 java_incdir:=bin/$(TARGET)/include
192 java_jmoddir:=bin/$(TARGET)/jmods
194 $(foreach module,$(java_MODULES),$(eval $(call java_variables,$(module))))
195 $(foreach module,$(java_MODULES) $(native_MODULES),$(eval $(call common_variables,$(module))))
197 # ######################################################################
203 .PHONY: all clean jar gen $(java_MODULES)
207 include $(foreach module,$(java_MODULES),$(wildcard src/$(module)/gen/gen.make))
208 include $(foreach module,$(java_MODULES) $(native_MODULES),$(wildcard src/$(module)/native/native.make))
210 # staging only, not for modules, not sure here?
211 define bin_files_targets=
212 bin/status/$1.classes: $(patsubst src/$1/bin/%,bin/$(TARGET)/bin/%,$($1_SCRIPTS))
213 bin/$(TARGET)/bin/%: src/$1/bin/%
214 install -vD -m 0755 $$< $$@
216 define lib_files_targets=
217 bin/status/$1.classes: $(patsubst src/$1/lib/%,bin/$(TARGET)/lib/%,$($1_DATA))
218 bin/$(TARGET)/lib/%: src/$1/lib/%
219 install -vD -m 0644 $$< $$@
222 #$(foreach module,$(java_MODULES),$(if $($(module)_SCRIPTS),$(info $(call bin_files_targets,$(module)))))
223 #$(foreach module,$(java_MODULES),$(if $($(module)_DATA),$(info $(call lib_files_targets,$(module)))))
225 $(foreach module,$(java_MODULES),$(if $($(module)_SCRIPTS),$(eval $(call bin_files_targets,$(module)))))
226 $(foreach module,$(java_MODULES),$(if $($(module)_DATA),$(eval $(call lib_files_targets,$(module)))))
230 # ######################################################################
232 # ######################################################################
234 # Targets used to manage dependencies:
236 # bin/status/<module>.classes Source compilation target. Depends on dependent jars, sources, generated sources.
237 # $(java_jardir)/<module>.jar Binary compilation target. Depends on compiled classes and resources.
238 # $(java_jardir)/<module>.jmod Binary compilation target. Depends on compiled classes, resources, and native libraries.
241 # Rules for module $(1)
242 $(1)_JAVA_generated = $$(addprefix $$($1_genjavadir)/,$$($1_JAVA_GENERATED))
244 #$(java_jardir)/$1.jar: $(patsubst %,$(java_jardir)/%.jar,$(filter $($1_JDEPMOD), $(java_MODULES)))
245 $(java_jardir)/$1.jar: $(patsubst %,$(java_jardir)/%.jar,$($1_JDEPMOD))
247 #bin/status/$1.classes: $(patsubst %,bin/status/%.classes,$(filter $($1_JDEPMOD), $(java_MODULES))) $$($1_JAVA) $$($1_JAVA_generated)
248 bin/status/$1.classes: $(patsubst %,$(java_jardir)/%.jar,$(filter $($1_JDEPMOD), $(java_MODULES))) $$($1_JAVA) $$($1_JAVA_generated)
250 jar $1: $(java_jardir)/$1.jar $(java_jmoddir)/$1.jmod
251 $1: $(filter $($1_JDEPMOD), $(native_MODULES))
252 sources: $(java_jardir)/$(1)-sources.zip
253 gen: $$($(1)_JAVA_generated)
255 $(java_jardir)/$1.jar $(java_jmoddir)/$1.jmod: bin/status/$1.classes $(patsubst src/$1/classes/%,%,$($1_RESOURCES))
258 $(java_jardir)/$1.jar:
261 $(JARFLAGS) $$($(1)_JARFLAGS) \
262 -C bin/modules/$(1) .
265 $(java_jmoddir)/$1.jmod:
269 $$(JMODFLAGS) $$($(1)_JMODFLAGS) \
270 --target-platform $(TARGET) \
271 --class-path bin/modules/$(1) \
272 $$(if $$(wildcard bin/$(1)/$(TARGET)/include),--header-files bin/$(1)/$(TARGET)/include) \
273 $$(if $$(wildcard src/$(1)/legal),--legal-notices src/$(1)/legal) \
274 $$(if $$(wildcard bin/$(1)/$(TARGET)/bin),--cmds bin/$(1)/$(TARGET)/bin) \
275 $$(if $$(wildcard bin/$(1)/$(TARGET)/lib),--libs bin/$(1)/$(TARGET)/lib) \
278 # Create an IDE source zip, paths have to match --module-source-path
279 $(java_jardir)/$1-sources.zip: bin/status/$1.classes
282 $$(patsubst src/$1/classes/%,-C src/$1/classes %,$$(filter src/$1/classes/%,$$($1_JAVA))) \
283 $$(patsubst bin/gen/$1/classes/%,-C bin/gen/$1/classes %,$$(filter bin/gen/$1/classes/%,$$($1_JAVA)))
286 bin/modules/$1/%: src/$1/classes/%
290 bin/status/$1.classes:
293 --module-source-path "src/*/classes:bin/gen/*/classes" \
294 $(if $(JAVAMODPATH),--module-path $(subst $(S),:,$(JAVAMODPATH))) \
295 $(JAVACFLAGS) $($1_JAVACFLAGS) \
298 $($1_JAVA) $($1_JAVA_generated)
302 #$(foreach module,$(java_MODULES),$(info $(call java_targets,$(module))))
303 $(foreach module,$(java_MODULES),$(eval $(call java_targets,$(module))))
305 # setup run-* targets
307 run-$1/$2: $(java_jardir)/$1.jar
308 LD_LIBRARY_PATH=$(FFMPEG_HOME)/lib \
310 $(if $(JAVAMODPATH) $($1_JAVAMODPATH),--module-path $(subst $(S),:,$(JAVAMODPATH) $($1_JAVAMODPATH))) \
311 $(JMAINFLAGS) $($1_JMAINFLAGS) \
317 #$(foreach module,$(java_MODULES),$(foreach main,$($(module)_JMAIN),$(info $(call run_targets,$(module),$(main)))))
318 $(foreach module,$(java_MODULES),$(foreach main,$($(module)_JMAIN),$(eval $(call run_targets,$(module),$(main)))))
320 # ######################################################################
321 # notzed.nativez jdk.foreign export tool via _API variables
322 # ######################################################################
324 # <module>_API List of api's to include
325 # <module>_APIFLAGS Extra flags to pass to export-api for every api in module
326 # <module>_<api>_APIFLAGS Extra flags to pass to export-api for each api
328 define export_targets=
329 bin/status/$2.export: $(NATIVEZ_HOME)/lib/notzed.nativez.jar # hack for in-tree notzed.nativez?
330 bin/status/$1.classes: bin/status/$2.export
331 bin/status/$2.export:
332 mkdir -p bin/gen/$1/gen bin/status
333 $(NATIVEZ_HOME)/bin/export-api \
334 -w bin/gen/$1/gen -d bin/gen/$1/classes $($1_APIFLAGS) $($1_$2_APIFLAGS) src/$1/gen/$2.api
337 bin/status/$2.export.d:
338 @$(NATIVEZ_HOME)/bin/export-api -M -MT "$$(@:.d=) $$@" -MF $$@ \
339 -w bin/gen/$1/gen -d bin/gen/$1/classes $($1_APIFLAGS) $($1_$2_APIFLAGS) src/$1/gen/$2.api 2>/dev/null
341 $(if $(filter clean dist gen,$(MAKECMDGOALS)),,-include bin/status/$2.export.d)
344 #$(foreach module,$(java_MODULES),$(if $($(module)_API),$(foreach api,$($(module)_API),$(info $(call export_targets,$(module),$(api))))))
345 $(foreach module,$(java_MODULES),$(foreach api,$($(module)_API),$(eval $(call export_targets,$(module),$(api)))))
347 # ######################################################################
348 # C and c++ native library support
349 # ######################################################################
355 # functions to find cross-module stuff $(call library-path,modname,libname)
356 library-path=$($(1)_libdir)/$(LIB)$(2)$(SO)
357 library-dir=$($(1)_libdir)/
359 define native_library=
360 # Rule for library $(2) in module $(1)
361 $(2)_OBJS = $(patsubst %.c, $($(1)_objdir)/%.o, $($(2)_SOURCES)) \
362 $(patsubst %.cc, $($(1)_objdir)/%.o, $($(2)_CXXSOURCES))
363 $(2)_SRCS = $(addprefix src/$(1)/native/,$($(2)_SOURCES))
364 $(2)_SO = $($(1)_libdir)/$(LIB)$(2)$(SO)
366 $($(1)_libdir)/$(LIB)$(2)$(SO): $$($(2)_OBJS) $($(2)_LIBADD) $($(2)_DEPENDENCIES)
368 $($(TARGET)_CC) -o $$@ -shared \
369 $($(TARGET)_LDFLAGS) $($(2)_LDFLAGS) $$($(2)_OBJS) $($(2)_LIBADD) $($(TARGET)_LDLIBS) $($(2)_LDLIBS)
371 $(java_libdir)/%: $($(1)_libdir)/%
373 $(java_bindir)/%: $($(1)_bindir)/%
375 $(java_incdir)/%: $($(1)_incdir)/%
378 $($(1)_objdir)/%.o: src/$(1)/native/%.c
380 $($(TARGET)_CC) -Isrc/$(1)/native -Ibin/include/$(1) \
381 $($(TARGET)_CPPFLAGS) $($(2)_CPPFLAGS) \
382 $($(TARGET)_CFLAGS) $($(2)_CFLAGS) -c -o $$@ $$<
384 $($(1)_objdir)/%.o: src/$(1)/native/%.cc
386 $($(TARGET)_CXX) -Isrc/$(1)/native -Ibin/include/$(1) \
387 $($(TARGET)_CPPFLAGS) $($(2)_CPPFLAGS) \
388 $($(TARGET)_CXXFLAGS) $($(2)_CXXFLAGS) -c -o $$@ $$<
390 $($(1)_incdir)/%: src/$(1)/native/%
392 $($(1)_libdir)/%: src/$(1)/native/%
395 # auto-dependencies for c files
396 $($(1)_objdir)/%.d: src/$(1)/native/%.c
399 @$($(TARGET)_CC) -MM -MT "$$(@:.d=.o) $$@" -Isrc/$(1)/jni -Ibin/include/$(1) \
400 $($(TARGET)_CPPFLAGS) $($(2)_CPPFLAGS) $$< -o $$@ 2>/dev/null
402 # auto-dependencies for c++ files
403 $($(1)_objdir)/%.d: src/$(1)/native/%.cc
406 @$($(TARGET)_CXX) -MM -MT "$$(@:.d=.o) $$@" -Isrc/$(1)/jni -Ibin/include/$(1) \
407 $($(TARGET)_CPPFLAGS) $($(2)_CPPFLAGS) $$< -o $$@ 2>/dev/null
409 $(java_jardir)/$(1).jar: \
410 $($(1)_libdir)/$(LIB)$(2)$(SO) \
411 $(java_libdir)/$(LIB)$(2)$(SO) \
412 $(addprefix $($(1)_incdir)/,$($(2)_HEADERS)) \
413 $(addprefix $(java_incdir)/,$($(2)_HEADERS)) \
414 $(addprefix $($(1)_bindir)/,$($(2)_COMMANDS)) \
415 $(addprefix $(java_bindir)/,$($(2)_COMMANDS)) \
416 $(addprefix $($(1)_libdir)/,$($(2)_LIBRARIES))
418 $(if $(filter clean dist gen,$(MAKECMDGOALS)),,-include $$($(2)_OBJS:.o=.d))
421 #$(foreach module,$(java_MODULES) $(native_MODULES),$(foreach library,$($(module)_NATIVE_LIBRARIES),$(info $(call native_library,$(module),$(library)))))
422 $(foreach module,$(java_MODULES) $(native_MODULES),$(foreach library,$($(module)_NATIVE_LIBRARIES),$(eval $(call native_library,$(module),$(library)))))
424 # small hack: native-only modules have a phony jar target
425 define native_targets=
426 .PHONY: $(java_jardir)/$(1).jar
427 $1 jar: $(java_jardir)/$(1).jar
429 #$(foreach module,$(native_MODULES),$(info $(call native_targets,$(module))))
430 $(foreach module,$(native_MODULES),$(eval $(call native_targets,$(module))))
432 # ######################################################################
436 tar cfz bin/$(dist_NAME)-$(dist_VERSION).tar.gz \
437 --transform=s,^,$(dist_NAME)-$(dist_VERSION)/, \
438 config.make.in java.make Makefile src \