-
Notifications
You must be signed in to change notification settings - Fork 1
/
Makefile.in
1299 lines (988 loc) · 45.8 KB
/
Makefile.in
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# make4java - A Makefile for Java projects
#
# Written in 2016 by Francesco Lattanzio <franz.lattanzio@gmail.com>
#
# To the extent possible under law, the author have dedicated all
# copyright and related and neighboring rights to this software to
# the public domain worldwide. This software is distributed without
# any warranty.
#
# You should have received a copy of the CC0 Public Domain Dedication
# along with this software.
# If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
# To enabled incremental compilation you need the "jdeps" utility
# (available in OpenJDK 1.8). If not found it will revert to full
# compilation every time one or more source files are modified or
# added.
#
# NOTE: Only file modification and/or addition is supported, that is,
# if a (re)source file is removed you have to perform a full
# compilation ("make clean compile") in order to get rid of the
# old classes and "filtered" resources.
#
# If you want to use jdeps but don't want to generate 1.8 bytecode,
# just pass the JAVAC variable to "configure", e.g.:
#
# ./configure "JAVAC=javac -source 1.7 -target 1.7 -bootclasspath \
# /usr/lib/jvm/java-7-openjdk/jre/lib/rt.jar"
#
# Choose appropriate source, target and bootclasspath's values for you
# project.
#
# NOTE: For small projects a full compilation may be faster than an
# incremental compilation followed by a jdeps run. In such cases
# you may wish to run "configure" with the "--disable-jdeps"
# option.
# Enable support for distinct "build tree" and "source tree"
VPATH = @top_srcdir@
top_srcdir = @top_srcdir@
#########
# Tools #
#########
# Sample optional feature -- disabled by default
ENABLE_FOO_FEATURE = @ENABLE_FOO_FEATURE@
# Java tools
JAR = @JAR@
JAVA = @JAVA@
JAVAC = @JAVAC@
JAVADOC = @JAVADOC@
JAVAH = @JAVAH@
JDEPS = @JDEPS@
JAVA_PATH_SEPARATOR = @JAVA_PATH_SEPARATOR@
JAVA_PREPENDS_LIB = @JAVA_PREPENDS_LIB@
# Common tools -- every UNIX-like OS should have these (and a
# Bourne-like shell)
AWK = @AWK@
CC = @CC@
CPP = @CPP@
FIND = @FIND@
MAKE_ALIAS = @LN_S@
MKDIR_P = @MKDIR_P@
# RM = rm -f # this variable is predefined by make
SED = @SED@
TAR = @am__tar@
XARGS = @XARGS@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
# The followings expand, respectively, to the gzip command and '.gz',
# if gzip is available, or to 'cat' and the empty string if not
COMPRESS = @COMPRESS@
COMPRESS_EXT = @COMPRESS_EXT@
# Native code support -- if defined, the values of the CPPFLAGS and
# CFLAGS variables will be passed to the C compiler to compile the C
# source files into object files, whereas the value of the LDFLAGS
# variable will be used to link those object files into the native
# dynamic library.
# NOTE: The '-I.' is required to find "config.h". If your project does
# not have any "config.h" you can remove it.
CFLAGS = @CFLAGS@
CPPFLAGS = @CPPFLAGS@ -I.
JAVAH_CPPFLAGS = @JAVAH_CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
# To build shared libraries with Libtool, the directory where they will
# be installed must be specified a link time. You can use configure's
# '--libdir' option to change it.
prefix = @prefix@
exec_prefix = @exec_prefix@
LIB_INSTALL_PATH = @libdir@
# The following are required in the Libtool rules.
# NOTE: Do not remove 'top_builddir' nor 'SHELL' as they are both used
# by the LIBTOOL variable.
abs_top_builddir = @abs_top_builddir@
top_builddir = @top_builddir@
LIBTOOL = @LIBTOOL@
SHELL = @SHELL@
SHREXT = @SHREXT@
# Options for the Java API Documentation Generator
# NOTE: '-locale', if present, must be the first one
JAVADOC_OPTIONS = -locale en_GB -encoding UTF-8 -charset UTF-8 -protected
# If GNU Make version is greater than or equal to 4.0, then it has the
# $(file ...) function, else we must resort to more convoluted and less
# efficient substitutes.
# NOTE: The $(file ...) function is employed to write lists of source,
# resource, Java class filenames and other items into files. In
# case it is missing, the substitutes will use the shell to write
# those items into the files. However, for those lists could be
# really long (longer than the maximum command line length) a
# single item is written per shell invocation. This is quite
# inefficient but ensures that each command executed won't exceed
# the maximum command line length.
ifeq ($(filter $(firstword $(subst ., ,$(MAKE_VERSION))),0 1 2 3),)
HAS_FILE = yes
else
HAS_FILE = no
endif
####################################
# Project properties and structure #
####################################
# Name of the package
package.name := @PACKAGE_NAME@
# This and the next variable are used to build the name of the source
# and binary packages
PACKAGE_NAME := @PACKAGE_TARNAME@
# Version number of the package (each component has its own version
# number)
package.version := @PACKAGE_VERSION@
# The name of the directory inside the built JARs that will hold
# included JARs
resources.jars := jars
# The name of the directory inside the built JARs that will hold
# included native libraries
resources.libs := libs
# The name of the directory inside the binary package(s) that will hold
# native libraries.
# NOTE: For some platforms Libtool requires this path to end in the same
# path specified in the '-rpath' option, i.e., $(LIB_INSTALL_PATH)
native.path := $(patsubst /%,%,$(LIB_INSTALL_PATH))
# Usually Java's System.loadLibrary() prepends the "lib" prefix to the
# name of the loaded library, but on some OSs (e.g., Windows) it does
# not.
ifeq ($(JAVA_PREPENDS_LIB),no)
lib.prefix := lib
else
lib.prefix :=
endif
# Component-relative path to Java source files
SOURCES_PATH := src
# Component-relative path to resource files
RESOURCES_PATH := resources
# Component-relative path to native C source files
NATIVE_SOURCES_PATH := src
# The name of a subdirectory of the topmost directory that holds all
# the project's dependencies (JAR files only).
# NOTE: The project's README or INSTALL file should contain a list of
# all the dependencies required and should also instruct the user
# to download them into this directory, optionally arranging them
# into a hierachy of directories.
EXTERNAL_LIBRARIES_DIR := libs
# The name of a subdirectory of the topmost directory that will hold all
# the intermediate files produced by the build process
BUILD_DIR := build
# The name of the file that will hold the list of all the source files
SOURCE_FILES_FULL_LIST := $(BUILD_DIR)/source-files
# The name of the file that will hold the list of Java packages (this is
# used by Javadoc and won't include packages defined by
# BUILD_TEST_MAKE_RULES)
JAVA_PACKAGES_LIST := $(BUILD_DIR)/java-packages
# The name of the file that will hold the .class to .java dependencies
JAVA_DEPENDENCIES := $(BUILD_DIR)/java-dependencies
# The name of the file that will hold all the -sourcepath option
# for javac and javadoc
JAVAC_SOURCEPATH_LIST := $(BUILD_DIR)/javac-sourcepath
# The name of the file that will hold the list of source files
# to be compiled
JAVAC_SOURCE_FILES_LIST := $(BUILD_DIR)/javac-source-files
# The name of the file that will hold the list of the class files to be
# reprocessed through javah, i.e., class files from the previous
# variable that were modified since last compilation
JAVAH_CLASSES_LIST := $(BUILD_DIR)/javah-classes
# The name of the directory that will hold all the class files
# compiled...
CLASSES_DIR := $(BUILD_DIR)/classes
# ... and its alias directory
CLASSES_ALIAS_DIR := $(BUILD_DIR)/classes-alias
# The name of the directory that will hold all the resource files ready
# to be stored in the JARs
RESOURCES_DIR := $(BUILD_DIR)/resources
# The name of the file holding the sed script used to filter resource
# files
RESOURCES_FILTER_SCRIPT := $(BUILD_DIR)/sed-script
# The name of the directory that will hold all the JAR files built
JARS_DIR := $(BUILD_DIR)/$(resources.jars)
# The name of the directory that will hold all the object files compiled
# from native C code
OBJECTS_DIR := $(BUILD_DIR)/obj
# The name of the directory that will hold all the include files
# generated by javah
INCLUDE_DIR := $(BUILD_DIR)/include
# The name of the directory that will hold all the native library built
NATIVE_DIR := $(BUILD_DIR)/$(resources.libs)
# The list of files, among the distributed ones, required to generate
# "configure", "aclocal.m4" and "config.h.in". This list is used by
# the "Automatic remake" section.
AUTOCONF_DIST_FILES := configure.ac m4/fltt_prog_jar.m4 \
m4/fltt_prog_java_pathsep.m4 \
m4/fltt_prog_java.m4 m4/fltt_prog_javac.m4 \
m4/fltt_prog_javadoc.m4 m4/fltt_prog_javah.m4 \
m4/fltt_prog_jdeps.m4 m4/libtool.m4 \
m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 \
m4/lt~obsolete.m4 m4/tar.m4
# The list of files to be distributed. The components' source and
# resources files are added automatically (see BUILD_MAKE_RULES,
# BUILD_TEST_MAKE_RULES and BUILD_NATIVE_MAKE_RULES).
DIST_FILES := aclocal.m4 config.h.in configure COPYING Makefile.in \
README.md bin/run.sh build-aux/config.guess \
build-aux/config.sub build-aux/install-sh \
build-aux/ltmain.sh doc/README doc/overview.html \
stamp-h.in $(AUTOCONF_DIST_FILES) \
bar/java/src/dummy/bar/package-info.java \
foo/java/src/dummy/foo/package-info.java
# The name of the single top level directory that will contain all
# the files and directory of the source and binary packages
TAR_ROOT_DIR := $(PACKAGE_NAME)-$(package.version)
# The name of the directory that will hold all the files to be put into
# the source package(s)
DIST_DIR := $(BUILD_DIR)/dist
# The name of the directory that will hold Javadoc generated files
DOC_DIR := $(BUILD_DIR)/doc
# The name of the directory that will hold all the files to be put into
# the binary package(s)
STAGE_DIR := $(BUILD_DIR)/stage
# The name of the directory that will hold all the packages built (for
# this sample Makefile there will be only a binary package and a source
# package)
PACKAGE_DIR := packages
# This is a list of targets that must not trigger automatic (re)build
# of the .d files (see BUILD_NATIVE_COMPILE_RULES below)
NO_BUILD_TARGETS := uninstall clean distclean dist doc
# The default target
all:
$(BUILD_DIR) $(PACKAGE_DIR):
$(MKDIR_P) '$@'
$(CLASSES_DIR) $(INCLUDE_DIR) $(JARS_DIR) $(NATIVE_DIR): | $(BUILD_DIR)
$(MKDIR_P) '$@'
$(CLASSES_ALIAS_DIR): | $(CLASSES_DIR)
@cd '$(dir $@)' && \
$(MAKE_ALIAS) '$(notdir $|)' '$(notdir $@)'
###################################
# build.mk's variables and macros #
###################################
# For each external dependency (see EXTERNAL_LIBRARIES_DIR above),
# component's JAR library or native library, the following "library
# variables" will be defined:
# <libname>.version - version of the library
# <libname>.basename - file name of the library, without path
# <libname>.buildname - file name of the library, with path relative
# to the project's topmost directory
# <libname>.jarname - file name of the library, with path relative
# to the root directory of an including JAR,
# i.e., in case this library is included within
# some component's JAR archive, this variable
# will tell where it is to be found *inside* the
# JAR archive
# where <libname> is the name of the JAR/native library file without the
# .jar or .so extension nor the version number.
# The PARSE_LIB_AND_VER, BUILD_MAKE_RULES, BUILD_TEST_MAKE_RULES and
# BUILD_NATIVE_MAKE_RULES macros will define them. They are described
# here as their main use is to be listed in the RESOURCE_PLACEHOLDERS
# variable (see below) to provide values to filter the resources with.
# Of course, you can employ them wherever you see fit, e.g., to define
# new rules.
# NOTE: <libname>.version and <libname>.jarname are automatically added
# to the RESOURCE_PLACEHOLDERS variable
# Lists the variables that will be used to "filter" the resources,
# i.e., for each "varname" listed, the string "${varname}" will be
# looked for in the resources and replaced with the value of
# the variable "varname"
RESOURCE_PLACEHOLDERS := package.name package.version resources.jars resources.libs native.path lib.prefix
# The following macros are meant to be used in the components' build.mk.
# The "component base directory" is where the build.mk file is located
# (see the sample build.mk's for examples of use).
# Arguments:
# $(1) - component base directory (must end with '/')
FIND_SOURCES = $(shell test -d '$(1)$(SOURCES_PATH)' && $(FIND) '$(1)$(SOURCES_PATH)' -name '*.java' | LC_ALL=C $(SED) -n '\|/[A-Za-z_$$][0-9A-Za-z_$$]*\.java$$|p')
# Arguments:
# $(1) - component base directory (must end with '/')
FIND_RESOURCES = $(shell test -d '$(1)$(RESOURCES_PATH)' && $(FIND) '$(1)$(RESOURCES_PATH)' -type f)
# Arguments:
# $(1) - component base directory (must end with '/')
FIND_NATIVE_SOURCES = $(shell test -d '$(1)$(NATIVE_SOURCES_PATH)' && $(FIND) '$(1)$(NATIVE_SOURCES_PATH)' -name '*.c')
######################
# External libraries #
######################
# Retrieve all the external dependencies
LIBRARIES := $(shell test -d '$(EXTERNAL_LIBRARIES_DIR)' && $(FIND) '$(EXTERNAL_LIBRARIES_DIR)' -name '*.jar')
# Convert the parsed library name (see further below) into values
# to be put into the "library variables", adds <libname>.version and
# <libname>.jarname to RESOURCE_PLACEHOLDERS and define a rule to copy
# the library into the $(JARS_DIR) directory, should the external
# library be included into some component's JAR archive.
# Arguments:
# $(1) - parsed library name (in the <libname>:<version> format)
define PARSE_LIB_AND_VER
MK_NAME := $(word 1,$(subst :, ,$(1)))
MK_VERSION := $(word 2,$(subst :, ,$(1)))
MK_JARNAME := $$(if $$(MK_VERSION),$$(MK_NAME)-$$(MK_VERSION).jar,$$(MK_NAME).jar)
$$(MK_NAME).version := $$(MK_VERSION)
$$(MK_NAME).basename := $$(MK_JARNAME)
$$(MK_NAME).buildname := $$(filter %/$$(MK_JARNAME),$$(LIBRARIES))
$$(MK_NAME).jarname := $(resources.jars)/$$(MK_JARNAME)
RESOURCE_PLACEHOLDERS += $$(MK_NAME).version $$(MK_NAME).jarname
# 'ln' is faster than 'cp -fpR', but will fail if source and build
# trees reside in different file systems.
$(BUILD_DIR)/$$(value $$(MK_NAME).jarname): $$(value $$(MK_NAME).buildname) | $(JARS_DIR)
@$(RM) '$$@'
ln '$$<' '$$@'
endef # PARSE_LIB_AND_VER
# For each dependency found under the $(EXTERNAL_LIBRARIES_DIR)
# directory, define the four library variables.
# First, parse the file names and convert them into <libname>:<version>
# strings, ...
LIBS_AND_VERS := $(shell echo '$(basename $(notdir $(LIBRARIES)))' | $(SED) 's|\([^ ]*\)-\(\([0-9.]\{1,\}\)\(-[^ ]*\)\{0,1\}\)|\1:\2|g')
# ... then for each such string define the aforementioned library
# variables.
$(foreach var,$(LIBS_AND_VERS),$(eval $(call PARSE_LIB_AND_VER,$(var))))
###################
# Java components #
###################
# Java components' JAR archives
JAR_ARCHIVES :=
# javac's and javadoc's -sourcepath directories list
SOURCE_DIRECTORIES :=
# More javac's -sourcepath directories
TEST_SOURCE_DIRECTORIES :=
# Java source files
SOURCE_FILES :=
# Java tests source files
TEST_SOURCE_FILES :=
# Java packages
JAVA_PACKAGES :=
# List of targets to run all the tests
TEST_TARGETS :=
# Missing included JARs and native libraries
# NOTE: A missing Java or native library may be caused by specifying the
# including component *before* the included component.
MISSING_INCLUDED_COMPONENTS :=
# Classpath for javac and javah
# NOTE: The "empty" variable must NOT be defined
CLASSPATH := -classpath '$(subst $(empty) $(empty),$(JAVA_PATH_SEPARATOR),$(strip $(CLASSES_DIR) $(LIBRARIES)))'
# Classpath for javadoc
# NOTE: The "empty" variable must NOT be defined
DOC_CLASSPATH := -classpath '$(subst $(empty) $(empty),$(JAVA_PATH_SEPARATOR),$(strip $(LIBRARIES)))'
# Verify the specified library has been defined
# Arguments:
# $(1) - component name
define CHECK_INCLUDED
ifndef $(1).jarname
MISSING_INCLUDED_COMPONENTS += $(1)
endif
endef # CHECK_INCLUDED
# Convert Java source file names into their corresponding Java package
# names
# Arguments:
# $(1) - component base directory (must end with '/')
# $(2) - Java source file names
SOURCES_TO_PACKAGES = $(sort $(subst /,.,$(patsubst $(1)$(SOURCES_PATH)/%/,%,$(dir $(2)))))
# Convert Java source file names into their corresponding alias class
# file names
# Arguments:
# $(1) - component base directory (must end with '/')
# $(2) - Java source file names
SOURCES_TO_ALIAS_CLASSES = $(patsubst $(1)$(SOURCES_PATH)/%.java,$(CLASSES_ALIAS_DIR)/%.class,$(2))
# Convert Java source file names into their corresponding class file
# names
# Arguments:
# $(1) - component base directory (must end with '/')
# $(2) - Java source file names
SOURCES_TO_CLASSES = $(patsubst $(1)$(SOURCES_PATH)/%.java,$(CLASSES_DIR)/%.class,$(2))
# Compute the file names of filtered resources
# Arguments:
# $(1) - component base directory (must end with '/')
# $(2) - component/JAR name
# $(3) - unfiltered resource file names
RESOURCES_TO_JAR = $(patsubst $(1)$(RESOURCES_PATH)/%,$(RESOURCES_DIR)/$(2)/%,$(3))
# Convert a classname into the corresponding class file name
# Arguments:
# $(1) - classname (in the package.subpackage.classname format)
CLASSNAME_TO_CLASSFILE = $(patsubst %,$(CLASSES_DIR)/%.class,$(subst .,/,$(1)))
.PHONY: compile
# Create rules to build a JAR component from Java source files.
# Define the library variables and the filtered to unfiltered resource
# dependencies and verifies that all the included libraries are defined
# (this means that the build.mk file of any included JAR or native
# library must be included in the Makefile before the including JAR's
# build.mk -- see also the "Components' build.mk files" section).
# The implicit %.class rule below will write all the classes older than
# their respective source files and/or older than any other source files
# they depends on (see the "-include $(JAVA_DEPENDENCIES)" below) to the
# $(JAVAC_SOURCE_FILES_LIST) file.
# The implicit $(RESOURCES_DIR)/% rule below will filter all the
# resource files before copying them into the $(RESOURCES_DIR)
# directory.
# Also, note that if the JAR archive is already existing, only the
# classes, resources or included libraries modified since last build
# will be updated.
# Arguments:
# $(1) - component/JAR name
# $(2) - component/JAR version
# $(3) - enable ('yes' or 'no')
# $(4) - component base directory (must end with '/')
# $(5) - Java source files list
# $(6) - resource files list
# $(7) - JARs and/or native libraries to be included in
# this component's JAR archive
# $(8) - additional classes (from other components, in
# the package.subpackage.classname format)
define BUILD_MAKE_RULES
ifeq ($(1),)
$$(error Missing jar basename)
endif
MK_JARNAME := $(if $(2),$(1)-$(2).jar,$(1).jar)
$(1).version := $(2)
$(1).basename := $$(MK_JARNAME)
DIST_FILES += $(patsubst $(top_srcdir)/%,%,$(lastword $(MAKEFILE_LIST)))
DIST_FILES += $(patsubst $(top_srcdir)/%,%,$(5))
DIST_FILES += $(patsubst $(top_srcdir)/%,%,$(6))
RESOURCE_PLACEHOLDERS += $(1).version $(1).jarname
ifeq ($(3),yes)
$$(foreach var,$(7),$$(eval $$(call CHECK_INCLUDED,$$(var))))
$(1).buildname := $(JARS_DIR)/$$(MK_JARNAME)
$(1).jarname := $(resources.jars)/$$(MK_JARNAME)
JAR_ARCHIVES += $$(value $(1).buildname)
SOURCE_DIRECTORIES += $(4)
SOURCE_FILES += $(5)
JAVA_PACKAGES += $$(call SOURCES_TO_PACKAGES,$(4),$(5))
$$(foreach var,$(5),$$(eval $$(call SOURCES_TO_ALIAS_CLASSES,$(4),$$(var)): $$(var)))
run-javac: $$(call SOURCES_TO_ALIAS_CLASSES,$(4),$(5))
# The empty recipe force reevaluation of target timestamp after
# run-javac has been processed
$$(foreach var,$(5),$$(eval $$(call SOURCES_TO_CLASSES,$(4),$$(var)): run-javac;))
compile: $$(call SOURCES_TO_CLASSES,$(4),$(5))
$$(foreach var,$(6),$$(eval $$(call RESOURCES_TO_JAR,$(4),$(1),$$(var)): $$(var)))
$$(value $(1).buildname): $$(call SOURCES_TO_CLASSES,$(4),$(5)) \
$$(call CLASSNAME_TO_CLASSFILE,$(8)) \
$$(call RESOURCES_TO_JAR,$(4),$(1),$(6)) \
$$(foreach var,$(7),$$(value $$(var).buildname)) | $(JARS_DIR)
if test -f '$$@'; then cmd=u; else cmd=c; fi && \
$(JAR) $$$${cmd}vf '$$@' \
$$(addprefix -C '$(CLASSES_DIR)' ,$$(patsubst $(CLASSES_DIR)/%,'%',$$(filter $(CLASSES_DIR)/%,$$?) \
$$(wildcard $$(patsubst %.class,%$$$$*.class,$$(filter $(CLASSES_DIR)/%,$$?))))) \
$$(addprefix -C '$(RESOURCES_DIR)/$(1)' ,$$(patsubst $(RESOURCES_DIR)/$(1)/%,'%',$$(filter $(RESOURCES_DIR)/%,$$?))) \
$$(addprefix -C '$(BUILD_DIR)' ,$$(patsubst $(BUILD_DIR)/%,'%',$$(filter $(JARS_DIR)/%,$$?) \
$$(filter $(NATIVE_DIR)/%,$$?)))
endif # eq ($(3),yes)
endef # BUILD_MAKE_RULES
# Arguments:
# $(1) - component/JAR name
# $(2) - component/JAR version
# $(3) - enable ('yes' or 'no')
# $(4) - component base directory (must end with '/')
# $(5) - Java source files list
# $(6) - resource files list
# $(7) - list of component's names tests depend on (at run-time)
# $(8) - main class name (in the package.subpackage.classname format)
define BUILD_TEST_MAKE_RULES
ifeq ($(1),)
$$(error Missing jar basename)
endif
MK_JARNAME := $(if $(2),$(1)-$(2).jar,$(1).jar)
$(1).version := $(2)
$(1).basename := $$(MK_JARNAME)
DIST_FILES += $(patsubst $(top_srcdir)/%,%,$(lastword $(MAKEFILE_LIST)))
DIST_FILES += $(patsubst $(top_srcdir)/%,%,$(5))
DIST_FILES += $(patsubst $(top_srcdir)/%,%,$(6))
RESOURCE_PLACEHOLDERS += $(1).version $(1).jarname
ifeq ($(3),yes)
$$(foreach var,$(7),$$(eval $$(call CHECK_INCLUDED,$$(var))))
$(1).buildname := $(JARS_DIR)/$$(MK_JARNAME)
$(1).jarname := $(resources.jars)/$$(MK_JARNAME)
TEST_SOURCE_DIRECTORIES += $(4)
TEST_SOURCE_FILES += $(5)
TEST_TARGETS += check-$(1)
$$(foreach var,$(5),$$(eval $$(call SOURCES_TO_ALIAS_CLASSES,$(4),$$(var)): $$(var)))
run-javac: $$(call SOURCES_TO_ALIAS_CLASSES,$(4),$(5))
# The empty recipe force reevaluation of target timestamp after
# run-javac has been processed
$$(foreach var,$(5),$$(eval $$(call SOURCES_TO_CLASSES,$(4),$$(var)): run-javac;))
compile: $$(call SOURCES_TO_CLASSES,$(4),$(5))
$$(foreach var,$(6),$$(eval $$(call RESOURCES_TO_JAR,$(4),$(1),$$(var)): $$(var)))
$$(value $(1).buildname): $$(call SOURCES_TO_CLASSES,$(4),$(5)) \
$$(call RESOURCES_TO_JAR,$(4),$(1),$(6)) | $(JARS_DIR)
if test -f '$$@'; then cmd=u; else cmd=c; fi && \
$(JAR) $$$${cmd}vf '$$@' \
$$(addprefix -C '$(CLASSES_DIR)' ,$$(patsubst $(CLASSES_DIR)/%,'%',$$(filter $(CLASSES_DIR)/%,$$?) \
$$(wildcard $$(patsubst %.class,%$$$$*.class,$$(filter $(CLASSES_DIR)/%,$$?))))) \
$$(addprefix -C '$(RESOURCES_DIR)/$(1)' ,$$(patsubst $(RESOURCES_DIR)/$(1)/%,'%',$$(filter $(RESOURCES_DIR)/%,$$?)))
check-$(1): $$(value $(1).buildname) \
$$(foreach var,$(7),$$(value $$(var).buildname))
$(JAVA) '-Djava.class.path=$$(subst $$(empty) $$(empty),$(JAVA_PATH_SEPARATOR),$$(strip $$(filter %.jar,$$^)))' \
'-Djava.library.path=$(NATIVE_DIR)/.libs$(JAVA_PATH_SEPARATOR)$(NATIVE_DIR)/_libs' $(8)
endif # eq ($(3),yes)
endef # BUILD_TEST_MAKE_RULES
# Store a list of -sourcepath directories -- the .PHONY special target
# ensures that it is rebuilt at every run
.PHONY: $(JAVAC_SOURCEPATH_LIST)
$(JAVAC_SOURCEPATH_LIST): | $(BUILD_DIR)
ifeq ($(strip $(SOURCE_DIRECTORIES) $(TEST_SOURCE_DIRECTORIES)),)
@echo 'Building $@'; \
: >'$@'
else ifeq ($(HAS_FILE),yes)
@echo 'Building $@' \
$(file >$@,-sourcepath $(subst $(empty) $(empty),$(JAVA_PATH_SEPARATOR),$(addsuffix $(SOURCES_PATH),$(SOURCE_DIRECTORIES) $(TEST_SOURCE_DIRECTORIES))))
else
@echo 'Building $@'; \
$(shell echo $(ECHO_N) "x-sourcepath $(ECHO_C)" >'$@.tmp') \
$(foreach var,$(SOURCE_DIRECTORIES) $(TEST_SOURCE_DIRECTORIES),$(shell echo $(ECHO_N) "$(var)$(SOURCES_PATH)$(JAVA_PATH_SEPARATOR)$(ECHO_C)" >>'$@.tmp')) \
$(shell echo "" >>'$@.tmp') \
cat '$@.tmp' | $(SED) '1sa^x\(.*\)$(JAVA_PATH_SEPARATOR)$$a\1a' >'$@'
@$(RM) '$@.tmp'
endif
# Store the list of all the Java source files -- the .PHONY special
# target ensures that it is rebuilt at every run
.PHONY: $(SOURCE_FILES_FULL_LIST)
$(SOURCE_FILES_FULL_LIST): | $(BUILD_DIR)
ifeq ($(HAS_FILE),yes)
@echo 'Building $@' \
$(file >$@) \
$(foreach var,$(SOURCE_FILES) $(TEST_SOURCE_FILES),$(file >>$@,$(var)))
else
@echo 'Building $@' \
$(shell : >'$@') \
$(foreach var,$(SOURCE_FILES) $(TEST_SOURCE_FILES),$(shell echo '$(var)' >>'$@'))
endif
# Clean-up the list of to-be-compiled Java source files (it will be
# filled-up by the next rule) -- the .PHONY special target ensures that
# it is always cleaned-up
.PHONY: $(JAVAC_SOURCE_FILES_LIST)
$(JAVAC_SOURCE_FILES_LIST): | $(BUILD_DIR)
@: >'$@'
# Take note of the source files to be compiled (see also
# the BUILD_MAKE_RULES and BUILD_TEST_MAKE_RULES macros above)
$(CLASSES_ALIAS_DIR)/%.class: | $(JAVAC_SOURCE_FILES_LIST)
echo '$<' >>'$(JAVAC_SOURCE_FILES_LIST)'
# Build the sed script used to filter the resources -- for it must be
# created once at every run, we need the .PHONY special target.
# The script will parse the resource files looking for strings of the
# form "${varname}" and will substitute those strings with the value of
# the make variable named "varname".
# Only the varnames listed in RESOURCE_PLACEHOLDERS will be substituted -- any
# string of the form "${varname}" where varname is not listed in
# RESOURCE_PLACEHOLDERS will be left untouched.
.PHONY: $(RESOURCES_FILTER_SCRIPT)
$(RESOURCES_FILTER_SCRIPT): | $(BUILD_DIR)
ifeq ($(HAS_FILE),yes)
@echo 'Building $@' \
$(file >$@) \
$(foreach var,$(RESOURCE_PLACEHOLDERS),$(file >>$@,s|$${$(var)}|$($(var))|g))
else
@echo 'Building $@' \
$(shell : >'$@') \
$(foreach var,$(RESOURCE_PLACEHOLDERS),$(shell echo 's|$${$(var)}|$($(var))|g' >>'$@'))
endif
# This rule applies the aforementioned sed script to the resource files.
# NOTE: For text-only files this is good enough, but for binary,
# in particular *big* binary files, this could cause some trouble.
# A possible solution would be to split the resources into two
# distinct directories -- one for resources to filter and the
# other for resources to keep as are.
$(RESOURCES_DIR)/%: | $(RESOURCES_FILTER_SCRIPT)
@$(MKDIR_P) '$(dir $@)'
$(SED) -f '$(RESOURCES_FILTER_SCRIPT)' '$<' >'$@'
# The 'run-javac' rule will actually compile the code and extract
# the dependencies (if jdeps is available and enabled).
# The difficult part is the dependencies extraction:
# 1) first the newly compiled classes are removed from the
# $(JAVA_DEPENDENCIES) files
# 2) then an AWK script is built to convert partial (without component
# name) source file names into full (comlete with component name)
# file names
# 3) afterward jdeps is run against the newly compiled classes and each
# class to class dependency it outputs is converted into a class file
# name to partial source file name depencency
# 4) finally the AWK script is run through the class file name to
# partial source file name depencencies to convert them into class
# file name to component-complete source file name dependencies
.PHONY: run-javac
run-javac: | $(CLASSES_ALIAS_DIR) $(JAVAC_SOURCEPATH_LIST) $(SOURCE_FILES_FULL_LIST)
ifdef JDEPS
@if test -s '$(JAVAC_SOURCE_FILES_LIST)'; then \
echo '$(JAVAC) -Xlint:deprecation,unchecked -d $(CLASSES_DIR) $(CLASSPATH) @$(JAVAC_SOURCEPATH_LIST) @$(JAVAC_SOURCE_FILES_LIST)'; \
$(JAVAC) -Xlint:deprecation,unchecked -d '$(CLASSES_DIR)' $(CLASSPATH) '@$(JAVAC_SOURCEPATH_LIST)' '@$(JAVAC_SOURCE_FILES_LIST)' && \
if test -f '$(JAVA_DEPENDENCIES)'; then \
echo 'Updating $(JAVA_DEPENDENCIES)'; \
$(FIND) -H '$(CLASSES_ALIAS_DIR)' -name '*.class' -cnewer '$(JAVA_DEPENDENCIES)' >'$(JAVA_DEPENDENCIES).tmp' && \
cat '$(JAVA_DEPENDENCIES).tmp' | while read cf; do \
cf=$$(echo $$cf | $(SED) 's|\$$|\\$$|g'); \
$(SED) "\|^$$cf: |d" '$(JAVA_DEPENDENCIES)' >'$(JAVA_DEPENDENCIES).bak' && \
mv '$(JAVA_DEPENDENCIES).bak' '$(JAVA_DEPENDENCIES)'; \
done \
else \
echo 'Building $(JAVA_DEPENDENCIES)'; \
$(FIND) -H '$(CLASSES_ALIAS_DIR)' -name '*.class' >'$(JAVA_DEPENDENCIES).tmp'; \
fi && \
echo 'BEGIN {' >'$(SOURCE_FILES_FULL_LIST).awk'; \
$(SED) 's|^.*\(/$(SOURCES_PATH)/.*\)$$|sf["\1"]="&"|' '$(SOURCE_FILES_FULL_LIST)' >>'$(SOURCE_FILES_FULL_LIST).awk'; \
echo '}' >>'$(SOURCE_FILES_FULL_LIST).awk'; \
echo '{ if (sf[$$2]) print $$1 " " sf[$$2] }' >>'$(SOURCE_FILES_FULL_LIST).awk'; \
echo 'cat $(JAVA_DEPENDENCIES).tmp | $(XARGS) $(JDEPS) -v' && \
cat '$(JAVA_DEPENDENCIES).tmp' | $(XARGS) $(JDEPS) -v | \
$(SED) -n 's|\.|/|g;s|^ *\([^ ]\{1,\}\) *-> *\([^ ]\{1,\}\).*$$|$(CLASSES_ALIAS_DIR)/\1.class: /$(SOURCES_PATH)/\2.java|p' | \
$(AWK) -f '$(SOURCE_FILES_FULL_LIST).awk' >>'$(JAVA_DEPENDENCIES)' && \
$(RM) '$(SOURCE_FILES_FULL_LIST).awk' '$(JAVA_DEPENDENCIES).tmp'; \
fi
else # def JDEPS
@if test -s '$(SOURCE_FILES_FULL_LIST)' -a -s '$(JAVAC_SOURCE_FILES_LIST)'; then \
echo '$(JAVAC) -Xlint:deprecation,unchecked -d $(CLASSES_DIR) $(CLASSPATH) @$(JAVAC_SOURCEPATH_LIST) @$(SOURCE_FILES_FULL_LIST)'; \
$(JAVAC) -Xlint:deprecation,unchecked -d '$(CLASSES_DIR)' $(CLASSPATH) '@$(JAVAC_SOURCEPATH_LIST)' '@$(SOURCE_FILES_FULL_LIST)'; \
fi
endif # def JDEPS
#####################
# Native components #
#####################
# Native components' libraries
NATIVE_LIBRARIES :=
# Class names to be processed through javah
JAVAH_CLASS_NAMES :=
# Convert C source file names into the names of their respective object
# files
# Arguments:
# $(1) - component/native library name
# $(2) - component base directory (must end with '/')
# $(3) - C source file names
SOURCES_TO_OBJECTS = $(patsubst $(2)$(NATIVE_SOURCES_PATH)/%.c,$(OBJECTS_DIR)/$(1)/%.lo,$(3))
# Convert C source file names into the names of their respective
# dependencies files -- files used to store the names of all the files
# recursively #include'd
# Arguments:
# $(1) - component/native library name
# $(2) - component base directory (must end with '/')
# $(3) - C source file names
SOURCES_TO_DEPENDENCIES = $(patsubst $(2)$(NATIVE_SOURCES_PATH)/%.c,$(OBJECTS_DIR)/$(1)/%.d,$(3))
# Convert a class file name into the corresponding classname
# Arguments:
# $(1) - class file name
CLASSFILE_TO_CLASSNAME = $(subst /,.,$(patsubst $(CLASSES_DIR)/%.class,%,$(1)))
# Convert a classname into the corresponding JNI include file name
# NOTE: We need two convertion macros to solve a chicken-egg dependency
# issue.
# When compiling for the first time, or after a clean, the
# dependencies files included by the 'include' directive in the
# BUILD_NATIVE_COMPILE_RULES macro don't exist and must be created
# by the rule next to the 'include' directive. But the JNI headers
# they depend on don't exist either and if it were not for the
# '-MG' option the recipe would fail. Instead the dependencies
# files are created despite the error, but using file names for
# the JNI headers taken from the C '#include' directives, that is,
# in their "short" version -- without full path. To allow 'make'
# to build the JNI header files, despite the wrong file names
# used, we must define targets for the JNI header files using the
# wrong "short" names -- that's what the first macro is used for.
# Once the JNI header files are built, the dependencies files will
# be rebuilt, this time, however, the JNI header files do exist
# enabling the C preprocessor to compute the correct "full" names
# of the headers. So now we need a different set of targets to
# deal with the "full" version of the file names -- that's the
# purpose of the second macro.
# Arguments:
# $(1) - classname (in the package.subpackage.classname format)
CLASSNAME_TO_SHORT_INCLUDEFILE = $(patsubst %,%.h,$(subst .,_,$(1)))
# Arguments:
# $(1) - classname (in the package.subpackage.classname format)
CLASSNAME_TO_FULL_INCLUDEFILE = $(patsubst %,$(INCLUDE_DIR)/%.h,$(subst .,_,$(1)))
# Define the rules to compile object files (.o) and dependencies files
# (.d).
# Including the dependency files into the Makefile ensures that they
# will be built if non existent or older than the C source file or any
# other object file's dependency -- in fact, each dependency file will
# declare both the object file and itself as dependant from all the
# files (recursively) included in the C source file.
# NOTE: I've tested this rules with both gcc and clang. Other
# compilers may require some tweak, especially in the recipes.
# Arguments:
# $(1) - component/native library name
# $(2) - component base directory (must end with '/')
# $(3) - component-specific CFLAGS
# $(4) - C source file name
define BUILD_NATIVE_COMPILE_RULES
# The conditional avoids to compile the Java code (to build the JNI
# header files the .d file depends on) when executing targets that do
# not build any object or executable file (e.g., the clean target)
ifeq ($(findstring $(empty) $(MAKECMDGOALS) , $(NO_BUILD_TARGETS) ),)
-include $$(call SOURCES_TO_DEPENDENCIES,$(1),$(2),$(4))
endif
$$(call SOURCES_TO_OBJECTS,$(1),$(2),$(4)): $(JAVAH_CLASSES_LIST)
@$(MKDIR_P) '$$(dir $$@)'
$(LIBTOOL) --tag=CC --mode=compile $(CC) $(CFLAGS) $(3) \
$(CPPFLAGS) $(JAVAH_CPPFLAGS) '-I$(INCLUDE_DIR)' -MT '$$@' -MD \
-MP -MF '$$(call SOURCES_TO_DEPENDENCIES,$(1),$(2),$(4)).tmp' \
-c -o '$$@' '$(4)'
@mv -f '$$(call SOURCES_TO_DEPENDENCIES,$(1),$(2),$(4)).tmp' \
'$$(call SOURCES_TO_DEPENDENCIES,$(1),$(2),$(4))'
endef # BUILD_NATIVE_COMPILE_RULES
# Create rules to build a native library from C source files.
# Define the library variables, the library link rule, the source and
# dependencies files compile rules and build the list of classes to
# process through javah, storing them in the JAVAH_CLASS_NAMES
# variable.
# Arguments:
# $(1) - component/native library name
# $(2) - component/native library version
# $(3) - enable ('yes' or 'no')
# $(4) - component base directory (must end with '/')
# $(5) - C source files list
# $(6) - C compiler flags (CFLAGS)
# $(7) - linker flags (LDFLAGS)
# $(8) - javah classes (in the package.subpackage.classname format)
# $(9) - additional object files (from other components, in
# the native-library-name/object-file-name.o format)
define BUILD_NATIVE_MAKE_RULES
ifeq ($(1),)
$$(error Missing library basename)
endif
MK_LIBNAME := $(if $(2),$(1)-$(2).la,$(1).la)
$(1).version := $(2)
$(1).basename := $$(MK_LIBNAME)
DIST_FILES += $(patsubst $(top_srcdir)/%,%,$(lastword $(MAKEFILE_LIST)))
DIST_FILES += $(patsubst $(top_srcdir)/%,%,$(5))
RESOURCE_PLACEHOLDERS += $(1).version $(1).jarname
ifeq ($(3),yes)
$(1).buildname := $(NATIVE_DIR)/$$(MK_LIBNAME)
$(1).jarname := $(resources.libs)/$$(MK_LIBNAME)
JAVAH_CLASS_NAMES += $(8)
NATIVE_LIBRARIES += $$(value $(1).buildname)
compile: $$(call SOURCES_TO_OBJECTS,$(1),$(4),$(5))
$(JAVAH_CLASSES_LIST): $$(call CLASSNAME_TO_CLASSFILE,$(8))
$$(call CLASSNAME_TO_SHORT_INCLUDEFILE,$(8)): $(JAVAH_CLASSES_LIST)
# The empty recipe force reevaluation of target timestamp after
# run-javah has been processed
$$(call CLASSNAME_TO_FULL_INCLUDEFILE,$(8)): $(JAVAH_CLASSES_LIST);
$$(foreach var,$(5),$$(eval $$(call BUILD_NATIVE_COMPILE_RULES,$(1),$(4),$(6),$$(var))))
$$(value $(1).buildname): $$(call SOURCES_TO_OBJECTS,$(1),$(4),$(5)) $$(patsubst %,$(OBJECTS_DIR)/%,$(9)) | $(NATIVE_DIR)
$(LIBTOOL) --tag=CC --mode=link $(CC) -module -avoid-version \
-no-undefined -shrext $(SHREXT) -rpath '$(LIB_INSTALL_PATH)' \
$(CFLAGS) $(6) $(LDFLAGS) $(7) -o '$$@' \
$$(patsubst %,'%',$$^) $(LIBS)
endif # eq ($(3),yes)
endef # BUILD_NATIVE_MAKE_RULES
# The next rule will run javah to build the JNI header files -- only
# the recompiled classes will be processed through javah
$(JAVAH_CLASSES_LIST): | $(INCLUDE_DIR)
ifeq ($(HAS_FILE),yes)
@echo 'Building $@'; \
$(file >$@) \
$(foreach var,$?,$(file >>$@,$(call CLASSFILE_TO_CLASSNAME,$(var)))) \
if test -s '$@'; then \
echo 'Building JNI headers'; \
echo 'cat $@ | $(XARGS) $(JAVAH) -d $(INCLUDE_DIR) $(CLASSPATH)'; \
cat '$@' | $(XARGS) $(JAVAH) -d '$(INCLUDE_DIR)' $(CLASSPATH); \
fi
else
@echo 'Building $@'; \
$(shell : >'$@') \
$(foreach var,$?,$(shell echo '$(call CLASSFILE_TO_CLASSNAME,$(var))' >>'$@')) \
if test -s '$@'; then \
echo 'Building JNI headers'; \
echo 'cat $@ | $(XARGS) $(JAVAH) -d $(INCLUDE_DIR) $(CLASSPATH)'; \
cat '$@' | $(XARGS) $(JAVAH) -d '$(INCLUDE_DIR)' $(CLASSPATH); \
fi
endif
##############################