1 # Quick-and-dirty makefile to bootstrap the sqlite3-jni project. This
2 # build assumes a Linux-like system.
5 JAVA_HOME ?
= $(HOME
)/jdk
/current
6 # e.g. /usr/lib/jvm/default-javajava-19-openjdk-amd64
7 JDK_HOME ?
= $(JAVA_HOME
)
8 # ^^^ JDK_HOME is not as widely used as JAVA_HOME
9 bin.jar
:= $(JDK_HOME
)/bin
/jar
10 bin.java
:= $(JDK_HOME
)/bin
/java
11 bin.javac
:= $(JDK_HOME
)/bin
/javac
12 bin.javadoc
:= $(JDK_HOME
)/bin
/javadoc
13 ifeq (,$(wildcard $(JDK_HOME
)))
14 $(error set JDK_HOME to the top-most
dir of your JDK installation.
)
16 MAKEFILE
:= $(lastword
$(MAKEFILE_LIST
))
19 package.jar
:= sqlite3-jni.jar
22 dir.tool
:= ..
/..
/tool
23 dir.jni
:= $(patsubst %/,%,$(dir $(MAKEFILE
)))
24 dir.src
:= $(dir.jni
)/src
25 dir.src.c
:= $(dir.src
)/c
26 dir.bld
:= $(dir.jni
)/bld
27 dir.bld.c
:= $(dir.bld
)
28 dir.src.jni
:= $(dir.src
)/org
/sqlite
/jni
29 dir.src.capi
:= $(dir.src.jni
)/capi
30 dir.src.fts5
:= $(dir.src.jni
)/fts5
31 dir.tests
:= $(dir.src
)/tests
36 javac.flags ?
= -Xlint
:unchecked
-Xlint
:deprecation
38 javac.flags
+= -encoding utf8
39 # -------------^^^^^^^^^^^^^^ required for Windows builds
42 java.flags
+= -Xcheck
:jni
45 classpath
:= $(dir.src
)
46 CLEAN_FILES
:= $(package.jar
)
47 DISTCLEAN_FILES
:= $(dir.jni
)/*~
$(dir.src.c
)/*~
$(dir.src.jni
)/*~
49 sqlite3-jni.h
:= $(dir.src.c
)/sqlite3-jni.h
50 .NOTPARALLEL
: $(sqlite3-jni.h
)
51 CApi.java
:= $(dir.src.capi
)/CApi.java
52 SQLTester.java
:= $(dir.src.capi
)/SQLTester.java
53 CApi.class
:= $(CApi.java
:.java
=.class
)
54 SQLTester.class
:= $(SQLTester.java
:.java
=.class
)
56 ########################################################################
57 # The future of FTS5 customization in this API is as yet unclear.
58 # The pieces are all in place, and are all thin proxies so not much
59 # complexity, but some semantic changes were required in porting
60 # which are largely untested.
62 # Reminder: this flag influences the contents of $(sqlite3-jni.h),
63 # which is checked in. Please do not check in changes to that file in
64 # which the fts5 APIs have been stripped unless that feature is
65 # intended to be stripped for good.
68 ifeq (,$(wildcard $(dir.tests
)/*))
74 # bin.version-info = binary to output various sqlite3 version info
75 # building the distribution zip file.
76 bin.version-info
:= $(dir.top
)/version-info
77 .NOTPARALLEL
: $(bin.version-info
)
78 $(bin.version-info
): $(dir.tool
)/version-info.c
$(sqlite3.h
) $(dir.top
)/Makefile
79 $(MAKE
) -C
$(dir.top
) version-info
81 # Be explicit about which Java files to compile so that we can work on
82 # in-progress files without requiring them to be in a compilable statae.
83 JAVA_FILES.main
:= $(patsubst %,$(dir.src.jni
)/annotation
/%,\
87 ) $(patsubst %,$(dir.src.capi
)/%,\
88 AbstractCollationCallback.java \
89 AggregateFunction.java \
90 AuthorizerCallback.java \
91 AutoExtensionCallback.java \
92 BusyHandlerCallback.java \
93 CollationCallback.java \
94 CollationNeededCallback.java \
95 CommitHookCallback.java \
96 ConfigLogCallback.java \
97 ConfigSqlLogCallback.java \
98 NativePointerHolder.java \
100 PrepareMultiCallback.java \
101 PreupdateHookCallback.java \
102 ProgressHandlerCallback.java \
104 RollbackHookCallback.java \
105 ScalarFunction.java \
109 TableColumnMetadata.java \
110 TraceV2Callback.java \
111 UpdateHookCallback.java \
113 WindowFunction.java \
114 XDestroyCallback.java \
117 sqlite3_context.java \
120 ) $(patsubst %,$(dir.src.jni
)/wrapper1
/%,\
121 AggregateFunction.java \
122 ScalarFunction.java \
125 SqliteException.java \
127 WindowFunction.java \
130 JAVA_FILES.unittest
:= $(patsubst %,$(dir.src.jni
)/%,\
132 wrapper1
/Tester2.java \
134 ifeq (1,$(enable.fts5
))
135 JAVA_FILES.unittest
+= $(patsubst %,$(dir.src.fts5
)/%,\
138 JAVA_FILES.main
+= $(patsubst %,$(dir.src.fts5
)/%,\
140 fts5_extension_function.java \
141 fts5_tokenizer.java \
144 Fts5ExtensionApi.java \
145 Fts5PhraseIter.java \
147 XTokenizeCallback.java \
150 JAVA_FILES.tester
:= $(SQLTester.java
)
151 JAVA_FILES.package.
info := \
152 $(dir.src.jni
)/package-info.java \
153 $(dir.src.jni
)/annotation
/package-info.java
155 CLASS_FILES.main
:= $(JAVA_FILES.main
:.java
=.class
)
156 CLASS_FILES.unittest
:= $(JAVA_FILES.unittest
:.java
=.class
)
157 CLASS_FILES.tester
:= $(JAVA_FILES.tester
:.java
=.class
)
159 JAVA_FILES
+= $(JAVA_FILES.main
) $(JAVA_FILES.unittest
)
160 ifeq (1,$(enable.tester
))
161 JAVA_FILES
+= $(JAVA_FILES.tester
)
165 define CLASSFILE_DEPS
167 $(1).class
: $(1).java
168 CLASS_FILES
+= $(1).class
170 $(foreach B
,$(basename \
171 $(JAVA_FILES.main
) $(JAVA_FILES.unittest
) $(JAVA_FILES.tester
)),\
172 $(eval
$(call CLASSFILE_DEPS
,$(B
))))
173 $(CLASS_FILES
): $(MAKEFILE
)
174 $(bin.javac
) $(javac.flags
) -h
$(dir.bld.c
) -cp
$(classpath
) $(JAVA_FILES
)
178 ########################################################################
179 # Set up sqlite3.c and sqlite3.h...
181 # To build with SEE (https://sqlite.org/see), either put sqlite3-see.c
182 # in the top of this build tree or pass
183 # sqlite3.c=PATH_TO_sqlite3-see.c to the build. Note that only
184 # encryption modules with no 3rd-party dependencies will currently
185 # work here: AES256-OFB, AES128-OFB, and AES128-CCM. Not
186 # coincidentally, those 3 modules are included in the sqlite3-see.c
189 # A custom sqlite3.c must not have any spaces in its name.
190 # $(sqlite3.canonical.c) must point to the sqlite3.c in
191 # the sqlite3 canonical source tree, as that source file
192 # is required for certain utility and test code.
193 sqlite3.canonical.c
:= $(firstword $(wildcard $(dir.src.c
)/sqlite3.c
) $(dir.top
)/sqlite3.c
)
194 sqlite3.canonical.h
:= $(firstword $(wildcard $(dir.src.c
)/sqlite3.h
) $(dir.top
)/sqlite3.h
)
195 sqlite3.c
:= $(sqlite3.canonical.c
)
196 sqlite3.h
:= $(sqlite3.canonical.h
)
197 #ifeq (,$(shell grep sqlite3_activate_see $(sqlite3.c) 2>/dev/null))
198 # SQLITE_C_IS_SEE := 0
200 # SQLITE_C_IS_SEE := 1
201 # $(info This is an SEE build.)
204 .NOTPARALLEL
: $(sqlite3.h
)
206 $(MAKE
) -C
$(dir.top
) sqlite3.c
207 $(sqlite3.c
): $(sqlite3.h
)
214 -DSQLITE_THREADSAFE
=$(opt.threadsafe
) \
215 -DSQLITE_TEMP_STORE
=2 \
217 -DSQLITE_OMIT_LOAD_EXTENSION \
218 -DSQLITE_OMIT_DEPRECATED \
219 -DSQLITE_OMIT_SHARED_CACHE \
220 -DSQLITE_C
=$(sqlite3.c
) \
221 -DSQLITE_JNI_FATAL_OOM
=$(opt.fatal-oom
) \
222 -DSQLITE_JNI_ENABLE_METRICS
=$(opt.metrics
)
225 ifeq (1,$(opt.extras
))
226 SQLITE_OPT
+= -DSQLITE_ENABLE_RTREE \
227 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
228 -DSQLITE_ENABLE_STMTVTAB \
229 -DSQLITE_ENABLE_DBPAGE_VTAB \
230 -DSQLITE_ENABLE_DBSTAT_VTAB \
231 -DSQLITE_ENABLE_BYTECODE_VTAB \
232 -DSQLITE_ENABLE_OFFSET_SQL_FUNC \
233 -DSQLITE_ENABLE_PREUPDATE_HOOK \
234 -DSQLITE_ENABLE_NORMALIZE \
235 -DSQLITE_ENABLE_SQLLOG \
236 -DSQLITE_ENABLE_COLUMN_METADATA
239 ifeq (1,$(opt.debug
))
240 SQLITE_OPT
+= -DSQLITE_DEBUG
-g
-DDEBUG
-UNDEBUG
245 ifeq (1,$(enable.fts5
))
246 SQLITE_OPT
+= -DSQLITE_ENABLE_FTS5
249 sqlite3-jni.c
:= $(dir.src.c
)/sqlite3-jni.c
250 sqlite3-jni.o
:= $(dir.bld.c
)/sqlite3-jni.o
251 sqlite3-jni.h
:= $(dir.src.c
)/sqlite3-jni.h
252 package.dll
:= $(dir.bld.c
)/libsqlite3-jni.so
253 # All javac-generated .h files must be listed in $(sqlite3-jni.h.in):
255 # $(java.with.jni) lists all Java files which contain JNI decls:
258 sqlite3-jni.h.in
+= $$(dir.bld.c
)/org_sqlite_jni
$(3)_
$(2).h
259 java.with.jni
+= $(1)/$(2).java
260 $$(dir.bld.c
)/org_sqlite_jni
$(3)_
$(2).h
: $(1)/$(2).java
262 # Invoke ADD_JNI_H once for each Java file which includes JNI
264 $(eval
$(call ADD_JNI_H
,$(dir.src.capi
),CApi
,_capi
))
265 $(eval
$(call ADD_JNI_H
,$(dir.src.capi
),SQLTester
,_capi
))
266 ifeq (1,$(enable.fts5
))
267 $(eval
$(call ADD_JNI_H
,$(dir.src.fts5
),Fts5ExtensionApi
,_fts5
))
268 $(eval
$(call ADD_JNI_H
,$(dir.src.fts5
),fts5_api
,_fts5
))
269 $(eval
$(call ADD_JNI_H
,$(dir.src.fts5
),fts5_tokenizer
,_fts5
))
271 $(sqlite3-jni.h.in
): $(dir.bld.c
)
273 #package.dll.cfiles :=
274 package.dll.
cflags = \
278 -I
$(dir $(sqlite3.h
)) \
280 -I
$(JDK_HOME
)/include \
281 $(patsubst %,-I
%,$(patsubst %.h
,,$(wildcard $(JDK_HOME
)/include/*))) \
283 # The gross $(patsubst...) above is to include the platform-specific
284 # subdir which lives under $(JDK_HOME)/include and is a required
285 # include path for client-level code.
287 # Using (-Wall -Wextra) triggers an untennable number of
288 # gcc warnings from sqlite3.c for mundane things like
290 ########################################################################
291 ifeq (1,$(enable.tester
))
292 package.dll.
cflags += -DSQLITE_JNI_ENABLE_SQLTester
295 $(sqlite3-jni.h
): $(sqlite3-jni.h.in
) $(MAKEFILE
)
296 @cat
$(sqlite3-jni.h.in
) > $@.tmp
297 @if cmp
$@
$@.tmp
>/dev
/null
; then \
299 echo
"$@ not modified"; \
304 @if
[ x1
!= x
$(enable.fts5
) ]; then \
305 echo
"*** REMINDER:"; \
306 echo
"*** enable.fts5=0, so please do not check in changes to $@."; \
309 $(package.dll
): $(sqlite3-jni.h
) $(sqlite3.c
) $(sqlite3.h
)
310 $(package.dll
): $(sqlite3-jni.c
) $(MAKEFILE
)
311 $(CC
) $(package.dll.
cflags) $(SQLITE_OPT
) \
312 $(sqlite3-jni.c
) -shared
-o
$@
315 .PHONY
: test test-one
318 test.flags.jvm
= -ea
-Djava.library.path
=$(dir.bld.c
) \
319 $(java.flags
) -cp
$(classpath
)
320 test.deps
:= $(CLASS_FILES
) $(package.dll
)
321 test-one
: $(test.deps
)
322 $(bin.java
) $(test.flags.jvm
) org.sqlite.jni.capi.Tester1
$(Tester1.flags
)
323 $(bin.java
) $(test.flags.jvm
) org.sqlite.jni.wrapper1.Tester2
$(Tester2.flags
)
324 test-sqllog
: $(test.deps
)
325 @echo
"Testing with -sqllog..."
326 $(bin.java
) $(test.flags.jvm
) org.sqlite.jni.capi.Tester1
$(Tester1.flags
) -sqllog
327 test-mt
: $(test.deps
)
328 @echo
"Testing in multi-threaded mode:";
329 $(bin.java
) $(test.flags.jvm
) org.sqlite.jni.capi.Tester1 \
330 -t
7 -r
50 -shuffle
$(Tester1.flags
)
331 $(bin.java
) $(test.flags.jvm
) org.sqlite.jni.wrapper1.Tester2 \
332 -t
7 -r
50 -shuffle
$(Tester2.flags
)
334 test: test-one test-mt
335 tests
: test test-sqllog
337 tester.scripts
:= $(sort $(wildcard $(dir.src
)/tests
/*.
test))
338 tester.flags ?
= # --verbose
339 .PHONY
: tester tester-local tester-ext
340 ifeq (1,$(enable.tester
))
341 tester-local
: $(CLASS_FILES.tester
) $(package.dll
)
342 $(bin.java
) -ea
-Djava.library.path
=$(dir.bld.c
) \
343 $(java.flags
) -cp
$(classpath
) \
344 org.sqlite.jni.capi.SQLTester
$(tester.flags
) $(tester.scripts
)
348 @echo
"SQLTester support is disabled."
351 tester.extdir.default
:= $(dir.tests
)/ext
352 tester.extdir ?
= $(tester.extdir.default
)
353 tester.extern-scripts
:= $(wildcard $(tester.extdir
)/*.
test)
354 ifneq (,$(tester.extern-scripts
))
356 $(bin.java
) -ea
-Djava.library.path
=$(dir.bld.c
) \
357 $(java.flags
) -cp
$(classpath
) \
358 org.sqlite.jni.capi.SQLTester
$(tester.flags
) $(tester.extern-scripts
)
361 @echo
"******************************************************"; \
362 echo
"*** Include the out-of-tree test suite in the 'tester'"; \
363 echo
"*** target by either symlinking its directory to"; \
364 echo
"*** $(tester.extdir.default) or passing it to make"; \
365 echo
"*** as tester.extdir=/path/to/that/dir."; \
366 echo
"******************************************************";
369 tester-ext
: tester-local
372 ########################################################################
373 # Build each SQLITE_THREADMODE variant and run all tests against them.
376 multitest
: multitest-
$(1)
378 $$(MAKE
) opt.debug
=$$(opt.debug
) $(patsubst %,opt.
%,$(2)) \
379 tests
clean enable.fts5
=1
382 $(eval
$(call MULTIOPT
,01,threadsafe
=0 oom
=1))
383 $(eval
$(call MULTIOPT
,00,threadsafe
=0 oom
=0))
384 $(eval
$(call MULTIOPT
,11,threadsafe
=1 oom
=1))
385 $(eval
$(call MULTIOPT
,10,threadsafe
=1 oom
=0))
386 $(eval
$(call MULTIOPT
,21,threadsafe
=2 oom
=1))
387 $(eval
$(call MULTIOPT
,20,threadsafe
=2 oom
=0))
390 ########################################################################
392 package.jar.in
:= $(abspath
$(dir.src
)/jar.in
)
393 CLEAN_FILES
+= $(package.jar.in
)
394 JAVA_FILES.jar
:= $(JAVA_FILES.main
) $(JAVA_FILES.unittest
) $(JAVA_FILES.package.
info)
395 CLASS_FILES.jar
:= $(filter-out %/package-info.class
,$(JAVA_FILES.jar
:.java
=.class
))
396 $(package.jar.in
): $(package.dll
) $(MAKEFILE
)
398 $(dir.src.jni
)/*/*.java
$(dir.src.jni
)/*/*.class \
399 | sed
-e
's,^$(dir.src)/,,' |
sort > $@
401 $(package.jar
): $(CLASS_FILES.jar
) $(MAKEFILE
) $(package.jar.in
)
402 @
rm -f
$(dir.src
)/c
/*~
$(dir.src.jni
)/*~
403 cd
$(dir.src
); $(bin.jar
) -cfe ..
/$@ org.sqlite.jni.capi.Tester1 @
$(package.jar.in
)
405 @echo
"To use this jar you will need the -Djava.library.path=DIR/CONTAINING/libsqlite3-jni.so flag."
406 @echo
"e.g. java -Djava.library.path=bld -jar $@"
409 run-jar
: $(package.jar
) $(package.dll
)
410 $(bin.java
) -Djava.library.path
=$(dir.bld
) -jar
$(package.jar
) $(run-jar.flags
)
412 ########################################################################
414 dir.doc
:= $(dir.jni
)/javadoc
415 doc.index
:= $(dir.doc
)/index.html
416 javadoc.exclude
:= -exclude org.sqlite.jni.fts5
417 # ^^^^ 2023-09-13: elide the fts5 parts from the public docs for
418 # the time being, as it's not clear where the Java bindings for
419 # those bits are going.
420 # javadoc.exclude += -exclude org.sqlite.jni.capi
421 # ^^^^ exclude the capi API only for certain builds (TBD)
422 $(doc.index
): $(JAVA_FILES.main
) $(MAKEFILE
)
423 @if
[ -d
$(dir.doc
) ]; then
rm -fr
$(dir.doc
)/*; fi
424 $(bin.javadoc
) -cp
$(classpath
) -d
$(dir.doc
) -quiet \
425 -subpackages org.sqlite.jni
$(javadoc.exclude
)
426 @echo
"javadoc output is in $@"
428 .PHONY
: doc javadoc docserve
431 javadoc
: $(doc.index
)
432 # Force rebild of docs
436 docserve
: $(doc.index
)
437 cd
$(dir.doc
) && althttpd
-max-age
1 -page index.html
438 ########################################################################
440 CLEAN_FILES
+= $(dir.bld.c
)/* \
441 $(dir.src.jni
)/*.class \
442 $(dir.src.jni
)/*/*.class \
446 .PHONY
: clean distclean
448 -rm -f
$(CLEAN_FILES
)
450 -rm -f
$(DISTCLEAN_FILES
)
451 -rm -fr
$(dir.bld.c
) $(dir.doc
)
453 ########################################################################
454 # disttribution bundle rules...
456 ifeq (,$(filter snapshot
,$(MAKECMDGOALS
)))
457 dist-name-prefix
:= sqlite-jni
459 dist-name-prefix
:= sqlite-jni-snapshot-
$(shell /usr
/bin
/date
+%Y
%m
%d
)
461 dist-name
:= $(dist-name-prefix
)-TEMP
464 dist-dir.top
:= $(dist-name
)
465 dist-dir.src
:= $(dist-dir.top
)/src
469 .PHONY
: dist snapshot
472 $(bin.version-info
) $(sqlite3.canonical.c
) \
473 $(package.jar
) $(MAKEFILE
)
474 @echo
"Making end-user deliverables..."
475 @echo
"****************************************************************************"; \
476 echo
"*** WARNING: be sure to build this with JDK8 (javac 1.8) for compatibility."; \
477 echo
"*** reasons!"; $$($(bin.javac
) -version
); \
478 echo
"****************************************************************************"
479 @
rm -fr
$(dist-dir.top
)
480 @mkdir
-p
$(dist-dir.src
)
481 @cp
-p
$(dist.top.extras
) $(dist-dir.top
)/.
482 @cp
-p jar-dist.make
$(dist-dir.top
)/Makefile
483 @cp
-p
$(dir.src.c
)/*.
[ch
] $(dist-dir.src
)/.
484 @cp
-p
$(sqlite3.canonical.c
) $(sqlite3.canonical.h
) $(dist-dir.src
)/.
486 vnum
=$$($(bin.version-info
) --download-version
); \
487 vjar
=$$($(bin.version-info
) --version
); \
488 vdir
=$(dist-name-prefix
)-$$vnum; \
490 cp
-p
$(package.jar
) $(dist-dir.top
)/sqlite3-jni-
$${vjar}.jar
; \
491 echo
"Making $$arczip ..."; \
492 rm -fr
$$arczip $$vdir; \
493 mv
$(dist-dir.top
) $$vdir; \
494 zip
-qr
$$arczip $$vdir; \
498 unzip
-lv
$$arczip || echo
"Missing unzip app? Not fatal."
505 rm -fr
$(dist-name
) $(wildcard sqlite-jni-
*.zip
)