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 # all paths are relative to the root package name
58 # <module>_JAVA Java sources. If not set it is found from src/<module>/classes/(*.java)
59 # <module>_RESOURCES .jar resources. If not set it is found from src/<module>/classes/(not *.java)
60 # <module>_JAVA_GENERATED Java generated sources.
61 # <module>_RESOURCES_GENERATED Java generated sources.
63 # Variables for use in fragments
65 # gen.make and jni.make can additionally make use of these variables
67 # <module>_gendir Location for files used in Java generation process (per project).
68 # <module>_genjavadir Location where _JAVA_GENERATED .java files will be created (per project).
69 # <module>_objdir Location for c objects (per target).
70 # <module>_incdir Location for output includes, .jmod staging.
71 # <module>_libdir Location for output libraries, .jmod staging. May point to _bindir.
72 # <module>_bindir Location for output commands, .jmod staging.
77 # Each module can define one or more native libraries.
79 # These are compiled after the java sources have been compiled as that
80 # process also generates any native binding headers.
82 # <module>_NATIVE_LIBRARIES list of libraries to build.
83 # library names match System.loadLibrary().
94 # SO shared library suffix
95 # LIB shared library prefix
99 # $(call library-path,<module>,<libname>) will resolve to the library file name.
101 # Per library variables.
103 # <library>_SOURCES .c source files for library. Paths are relative to src/<module>/native.
104 # <library>_CXXSOURCES .c source files for library. Paths are relative to src/<module>/native.
105 # <library>_HEADERS header files for install/jmod
106 # <library>_COMMANDS commands/bin/scripts for install/jmod
108 # <library>_LDFLAGS link flags
109 # <library>_LIBADD extra objects to add to link line
110 # <library>_LDLIBS link libraries
111 # <library>_CPPFLAGS c and c++ pre-processor flags. "-Isrc/<module>/jni -Ibin/include/<module>" is implicit.
112 # <library>_CCFLAGS c compiler flags
113 # <library>_CXXFLAGS c++ compiler flags
115 # <library>_DEPENDENCIES A list of other objects on which this library depends before linking.
117 # .c and .cc files have dependencies automatically generated
122 # make gen only generate java sources
123 # make clean rm -rf bin
124 # make dist create dist tar in bin/
125 # make | make jar make all jars and jmods
130 # All intermediate and output files are written to bin/
132 # This layout is enforced by javac
133 # bin/include/<module>/ .h files from javac -h
134 # bin/modules/<module>/ .class files from javac
136 # This layout is convenient for netbeans
137 # bin/gen/<module>/gen/ .c, exe files for generator free use
138 # bin/gen/<module>/classes/ .java files from generator <module>_JAVA_GENERATED
141 # bin/status/ marker files for makefile
143 # bin/<module>/<target>/lib .so librareies for jmod <module>_LIBRARIES = libname
144 # bin/<module>/<target>/obj .o, .d files for library <libname>_SOURCES
145 # bin/<module>/<target>/include .h files for jmod <libname>_HEADERS
146 # bin/<module>/<target>/<module>.jmod .jmod module
149 # bin/<target>/lib/ modular jar files and shared libraries for GNU/linux dev
150 # bin/<target>/include/ header files for exported shared libraries
151 # bin/<target>/bin/ shared libraries for microsoft dev
152 # bin/<target>/jmods/ jmod files for 'jlink' use.
154 # ######################################################################
156 all_MODULES = $(java_MODULES) $(native_MODULES)
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
173 define java_variables=
175 $1_JAVA := $$(shell cd src/$1/classes && find * -type f -name '*.java')
178 $1_RESOURCES := $$(shell cd src/$1/classes && find * -type f \! -name '*.java')
182 java_libdir:=$(if $(filter windows-%,$(TARGET)),bin/$(TARGET)/bin,bin/$(TARGET)/lib)
183 java_bindir:=bin/$(TARGET)/bin
184 java_jardir:=bin/$(TARGET)/lib
185 java_incdir:=bin/$(TARGET)/include
186 java_jmoddir:=bin/$(TARGET)/jmods
188 $(foreach module,$(java_MODULES) $(native_MODULES),$(eval $(call common_variables,$(module))))
189 $(foreach module,$(java_MODULES),$(eval $(call java_variables,$(module))))
191 # ######################################################################
197 .PHONY: all clean jar gen $(java_MODULES) dist
202 dist_TAR = bin/$(dist_NAME)-$(dist_VERSION).tar.gz
203 dist_FILES = config.make.in java.make Makefile src $(dist_EXTRA)
205 # Gen is things that go into the jar (sources and resources)
206 include $(wildcard $(all_MODULES:%=src/%/gen/gen.make))
207 # Native is things that go into the sdk/jmod
208 include $(wildcard $(all_MODULES:%=src/%/native/native.make))
210 # ######################################################################
212 # create module depencies
214 # <module>_sdk is the target location of an expanded 'sdk' for this module
215 # it resides in a common location bin/<target>/
216 # <module>_jmod is the target location of a staging area for jmod files
217 # is resides in a per-module lcoation bin/<module>/<target>/
218 # <module>_java is all the targets that will cause the invocation of javac
219 # it includes the module source, generated sources, and sentinals for generated sources
222 # bin/status/<module>.depjava marks all source/generated sources are ready/updated
223 # bin/status/<module>.depjar all compiled class files and resources are ready/updated
224 # bin/status/<module>.sdk all files are available in bin/<target> as if it was an installed image
227 $1_sdk := $(addprefix $(java_bindir)/,$($1_COMMANDS)) $(addprefix $(java_libdir)/,$($1_LIBRARIES)) $($1_NATIVE_LIBRARIES:%=$(java_libdir)/lib%.so)
228 $1_jmod := $(addprefix $($1_bindir)/,$($1_COMMANDS)) $(addprefix $($1_libdir)/,$($1_LIBRARIES)) $($1_NATIVE_LIBRARIES:%=$($1_libdir)/lib%.so)
229 $1_java :=$($1_JAVA:%=src/$1/classes/%) $($1_JAVA_GENERATED:%=$($1_genjavadir)/%)
230 $1_resources:= $($1_RESOURCES:%=bin/modules/$1/%) $($1_RESOURCES_GENERATED:%=bin/modules/$1/%)
231 $1_depjava := $($1_API:%=bin/status/$1-%.export) $(patsubst %,bin/status/%.classes, $(filter $($1_JDEPMOD),$(java_MODULES)))
233 #ifneq ("$$(strip $$($1_java) $$($1_depjava))", "")
234 bin/status/$1.depjava: $$($1_java) $$($1_depjava)
237 bin/status/$1.depjar: bin/status/$1.classes $$($1_resources)
240 bin/status/$1.depmod: bin/status/$1.classes $$($1_resources) $$($1_jmod)
243 bin/status/$1.sdk: $(java_jardir)/$1.jar
244 jar: $(java_jardir)/$1.jar
245 gen: bin/status/$1.depjava
246 $1 all: $(java_jardir)/$1.jar $(java_jmoddir)/$1.jmod
248 # acutally not sure here?
249 #$1 all: bin/status/$1.sdk
252 $1-sdk sdk: bin/status/$1.sdk
254 bin/status/$1.sdk: $$($1_sdk) $$($1_jmod)
260 #$(foreach m,$(all_MODULES),$(info $(call module_vars,$m)))
261 $(foreach m,$(all_MODULES),$(eval $(call module_vars,$m)))
263 # ######################################################################
264 # notzed.nativez export-api
265 # ######################################################################
268 bin/status/$1-$2.export: src/$1/gen/$2.api src/$1/gen/$2.h
269 bin/status/$1-$2.export:
270 mkdir -p bin/gen/$1/gen bin/status
271 $(NATIVEZ_HOME)/bin/export-api \
272 -w bin/gen/$1/gen -d bin/gen/$1/classes $($1_APIFLAGS) $($1_$2_APIFLAGS) src/$1/gen/$2.api
275 bin/status/$1-$2.export.d:
276 @$(NATIVEZ_HOME)/bin/export-api -M -MT "$$(@:.d=) $$@" -MF $$@ \
277 -w bin/gen/$1/gen -d bin/gen/$1/classes $($1_APIFLAGS) $($1_$2_APIFLAGS) src/$1/gen/$2.api 2>/dev/null
279 $(if $(filter clean dist gen,$(MAKECMDGOALS)),,-include bin/status/$1-$2.export.d)
282 $(foreach m,$(all_MODULES),$(foreach a,$($m_API),$(eval $(call api_targets,$m,$a))))
284 # ######################################################################
286 # ######################################################################
288 # Build targets for java modules
292 # Create (modular) jar
293 $(java_jardir)/$1.jar: bin/status/$1.depjar
296 $(JARFLAGS) $$($(1)_JARFLAGS) \
297 -C bin/modules/$(1) .
300 $(java_jmoddir)/$1.jmod: bin/status/$1.depmod
304 $$(JMODFLAGS) $$($(1)_JMODFLAGS) \
305 --target-platform $(TARGET) \
306 --class-path bin/modules/$(1) \
307 $$(if $$(wildcard bin/$(1)/$(TARGET)/include),--header-files bin/$(1)/$(TARGET)/include) \
308 $$(if $$(wildcard src/$(1)/legal),--legal-notices src/$(1)/legal) \
309 $$(if $$(wildcard bin/$(1)/$(TARGET)/bin),--cmds bin/$(1)/$(TARGET)/bin) \
310 $$(if $$(wildcard bin/$(1)/$(TARGET)/lib),--libs bin/$(1)/$(TARGET)/lib) \
313 # Create an IDE source zip, paths have to match --module-source-path
314 $(java_jardir)/$1-sources.zip: bin/status/$1.depjar
316 $(JAR) -c -f $$@ -M \
317 $$($1_JAVA:%=-C src/$1/classes %) \
318 $$($1_JAVA_GENERATED:%=-C bin/gen/$1/classes %)
321 bin/modules/$1/%: src/$1/classes/%
323 bin/modules/$1/%: $($1_gejavadir)/%
327 bin/status/$1.classes: bin/status/$1.depjava
330 --module-source-path "src/*/classes:bin/gen/*/classes" \
331 $(if $(JAVAMODPATH),--module-path $(subst $(S),:,$(JAVAMODPATH))) \
332 $(JAVACFLAGS) $($1_JAVACFLAGS) \
335 $$($1_JAVA:%=src/$1/classes/%) \
336 $$($1_JAVA_GENERATED:%=bin/gen/$1/classes/%)
340 #$(foreach module,$(java_MODULES),$(info $(call java_targets,$(module))))
341 $(foreach module,$(java_MODULES),$(eval $(call java_targets,$(module))))
343 # ######################################################################
345 # setup run-* targets
347 run-$1/$2: bin/status/$1.sdk $($1_JDEPMOD:%=bin/status/%.sdk)
348 LD_LIBRARY_PATH=$(FFMPEG_HOME)/lib \
350 $(if $(strip $(JAVAMODPATH) $($1_JAVAMODPATH)),--module-path $(subst $(S),:,$(strip $(JAVAMODPATH) $($1_JAVAMODPATH)))) \
351 $(JMAINFLAGS) $($1_JMAINFLAGS) \
357 #$(foreach module,$(java_MODULES),$(foreach main,$($(module)_JMAIN),$(info $(call run_targets,$(module),$(main)))))
358 $(foreach module,$(java_MODULES),$(foreach main,$($(module)_JMAIN),$(eval $(call run_targets,$(module),$(main)))))
360 # ######################################################################
361 # C and c++ native library support
362 # ######################################################################
364 define native_library=
365 # Rule for library $$2 in module $$1
366 $2_OBJS = $(patsubst %.c, $($1_objdir)/%.o, $($2_SOURCES)) \
367 $(patsubst %.cc, $($1_objdir)/%.o, $($2_CXXSOURCES))
368 $2_SRCS = $(addprefix src/$1/native/,$($2_SOURCES))
369 $2_SO = $($1_libdir)/$(LIB)$2$(SO)
371 # Copy anything from staging area for jmods bin/module/<target>/* to sdk area bin/<target>/*
372 $(java_libdir)/%: $($(1)_libdir)/%
374 ln -fs $$(abspath $$<) $$@
375 $(java_bindir)/%: $($(1)_bindir)/%
377 ln -fs $$(abspath $$<) $$@
378 $(java_incdir)/%: $($(1)_incdir)/%
380 ln -fs $$(abspath $$<) $$@
382 $($1_libdir)/$(LIB)$2$(SO): $$($2_OBJS) $($2_LIBADD) $($2_DEPENDENCIES)
384 $($(TARGET)_CC) -o $$@ -shared \
385 $($(TARGET)_LDFLAGS) $($2_LDFLAGS) $$($2_OBJS) $($2_LIBADD) $($(TARGET)_LDLIBS) $($2_LDLIBS)
387 $($1_objdir)/%.o: src/$1/native/%.c
389 $($(TARGET)_CC) -Isrc/$1/native -Ibin/include/$1 \
390 $($(TARGET)_CPPFLAGS) $($2_CPPFLAGS) \
391 $($(TARGET)_CFLAGS) $($2_CFLAGS) -c -o $$@ $$<
393 $($1_objdir)/%.o: src/$1/native/%.cc
395 $($(TARGET)_CXX) -Isrc/$1/native -Ibin/include/$1 \
396 $($(TARGET)_CPPFLAGS) $($2_CPPFLAGS) \
397 $($(TARGET)_CXXFLAGS) $($2_CXXFLAGS) -c -o $$@ $$<
399 # auto-dependencies for c files
400 $($1_objdir)/%.d: src/$1/native/%.c
403 @$($(TARGET)_CC) -MM -MT "$$(@:.d=.o) $$@" -Isrc/$1/jni -Ibin/include/$1 \
404 $($(TARGET)_CPPFLAGS) $($2_CPPFLAGS) $$< -o $$@ 2>/dev/null
406 # auto-dependencies for c++ files
407 $($1_objdir)/%.d: src/$1/native/%.cc
410 @$($(TARGET)_CXX) -MM -MT "$$(@:.d=.o) $$@" -Isrc/$1/jni -Ibin/include/$1 \
411 $($(TARGET)_CPPFLAGS) $($2_CPPFLAGS) $$< -o $$@ 2>/dev/null
413 $(if $(filter clean dist gen,$(MAKECMDGOALS)),,-include $$($2_OBJS:.o=.d))
416 #$(foreach module,$(all_MODULES),$(foreach library,$($(module)_NATIVE_LIBRARIES),$(info $(call native_library,$(module),$(library)))))
417 $(foreach module,$(all_MODULES),$(foreach library,$($(module)_NATIVE_LIBRARIES),$(eval $(call native_library,$(module),$(library)))))
419 # ######################################################################
423 tar cfz bin/$(dist_NAME)-$(dist_VERSION).tar.gz \
424 --transform=s,^,$(dist_NAME)-$(dist_VERSION)/, \