Apply the JNI OOM checks to memory returned by JDK APIs, as distinct from our APIs.
[sqlite.git] / ext / jni / GNUmakefile
blobdd8df07bc4d3af33776409c085fbd70f738d4720
1 # Quick-and-dirty makefile to bootstrap the sqlite3-jni project. This
2 # build assumes a Linux-like system.
3 default: all
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.)
15 endif
16 MAKEFILE := $(lastword $(MAKEFILE_LIST))
17 $(MAKEFILE):
19 package.jar := sqlite3-jni.jar
21 dir.top := ../..
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.jni.tester := $(dir.src.jni)/tester
30 mkdir := mkdir -p
31 $(dir.bld.c):
32 $(mkdir) $@
34 classpath := $(dir.src)
35 CLEAN_FILES := $(package.jar)
36 DISTCLEAN_FILES := $(dir.jni)/*~ $(dir.src.c)/*~ $(dir.src.jni)/*~
38 sqlite3-jni.h := $(dir.src.c)/sqlite3-jni.h
39 .NOTPARALLEL: $(sqlite3-jni.h)
40 SQLite3Jni.java := src/org/sqlite/jni/SQLite3Jni.java
41 SQLTester.java := src/org/sqlite/jni/tester/SQLTester.java
42 SQLite3Jni.class := $(SQLite3Jni.java:.java=.class)
43 SQLTester.class := $(SQLTester.java:.java=.class)
45 ########################################################################
46 # The future of FTS5 customization in this API is as yet unclear.
47 # It would be a real doozy to bind to JNI.
48 enable.fts5 ?= 1
49 # If enable.tester is 0, the org/sqlite/jni/tester/* bits are elided.
50 enable.tester ?= 1
52 # bin.version-info = binary to output various sqlite3 version info
53 # building the distribution zip file.
54 bin.version-info := $(dir.top)/version-info
55 .NOTPARALLEL: $(bin.version-info)
56 $(bin.version-info): $(dir.tool)/version-info.c $(sqlite3.h) $(dir.top)/Makefile
57 $(MAKE) -C $(dir.top) version-info
59 # Be explicit about which Java files to compile so that we can work on
60 # in-progress files without requiring them to be in a compilable statae.
61 JAVA_FILES.main := $(patsubst %,$(dir.src.jni)/%,\
62 AggregateFunction.java \
63 AuthorizerCallback.java \
64 AutoExtensionCallback.java \
65 BusyHandlerCallback.java \
66 CollationCallback.java \
67 CollationNeededCallback.java \
68 CommitHookCallback.java \
69 ConfigSqllogCallback.java \
70 NativePointerHolder.java \
71 NotNull.java \
72 Nullable.java \
73 OutputPointer.java \
74 PreupdateHookCallback.java \
75 ProgressHandlerCallback.java \
76 ResultCode.java \
77 RollbackHookCallback.java \
78 ScalarFunction.java \
79 SQLFunction.java \
80 SQLite3Jni.java \
81 Tester1.java \
82 TraceV2Callback.java \
83 UpdateHookCallback.java \
84 ValueHolder.java \
85 WindowFunction.java \
86 XDestroyCallback.java \
87 package-info.java \
88 sqlite3.java \
89 sqlite3_context.java \
90 sqlite3_stmt.java \
91 sqlite3_value.java \
93 ifeq (1,$(enable.fts5))
94 JAVA_FILES.main += $(patsubst %,$(dir.src.jni)/%,\
95 fts5_api.java \
96 fts5_extension_function.java \
97 fts5_tokenizer.java \
98 Fts5.java \
99 Fts5Context.java \
100 Fts5ExtensionApi.java \
101 Fts5Function.java \
102 Fts5PhraseIter.java \
103 Fts5Tokenizer.java \
104 TesterFts5.java \
106 endif
107 JAVA_FILES.tester := $(dir.src.jni.tester)/SQLTester.java
109 CLASS_FILES.main := $(JAVA_FILES.main:.java=.class)
110 CLASS_FILES.tester := $(JAVA_FILES.tester:.java=.class)
112 JAVA_FILES += $(JAVA_FILES.main)
113 ifeq (1,$(enable.tester))
114 JAVA_FILES += $(JAVA_FILES.tester)
115 endif
117 CLASS_FILES :=
118 define DOTCLASS_DEPS
119 $(1).class: $(1).java $(MAKEFILE)
120 all: $(1).class
121 CLASS_FILES += $(1).class
122 endef
123 $(foreach B,$(basename $(JAVA_FILES)),$(eval $(call DOTCLASS_DEPS,$(B))))
124 $(CLASS_FILES.tester): $(CLASS_FILES.main)
125 javac.flags ?= -Xlint:unchecked -Xlint:deprecation
126 java.flags ?=
127 jnicheck ?= 1
128 ifeq (1,$(jnicheck))
129 java.flags += -Xcheck:jni
130 endif
131 $(SQLite3Jni.class): $(JAVA_FILES)
132 $(bin.javac) $(javac.flags) -h $(dir.bld.c) -cp $(classpath) $(JAVA_FILES)
133 all: $(SQLite3Jni.class)
134 #.PHONY: classfiles
136 ########################################################################
137 # Set up sqlite3.c and sqlite3.h...
139 # To build with SEE (https://sqlite.org/see), either put sqlite3-see.c
140 # in the top of this build tree or pass
141 # sqlite3.c=PATH_TO_sqlite3-see.c to the build. Note that only
142 # encryption modules with no 3rd-party dependencies will currently
143 # work here: AES256-OFB, AES128-OFB, and AES128-CCM. Not
144 # coincidentally, those 3 modules are included in the sqlite3-see.c
145 # bundle.
147 # A custom sqlite3.c must not have any spaces in its name.
148 # $(sqlite3.canonical.c) must point to the sqlite3.c in
149 # the sqlite3 canonical source tree, as that source file
150 # is required for certain utility and test code.
151 sqlite3.canonical.c := $(firstword $(wildcard $(dir.src.c)/sqlite3.c) $(dir.top)/sqlite3.c)
152 sqlite3.canonical.h := $(firstword $(wildcard $(dir.src.c)/sqlite3.h) $(dir.top)/sqlite3.h)
153 sqlite3.c := $(sqlite3.canonical.c)
154 sqlite3.h := $(sqlite3.canonical.h)
155 #ifeq (,$(shell grep sqlite3_activate_see $(sqlite3.c) 2>/dev/null))
156 # SQLITE_C_IS_SEE := 0
157 #else
158 # SQLITE_C_IS_SEE := 1
159 # $(info This is an SEE build.)
160 #endif
162 .NOTPARALLEL: $(sqlite3.h)
163 $(sqlite3.h):
164 $(MAKE) -C $(dir.top) sqlite3.c
165 $(sqlite3.c): $(sqlite3.h)
167 opt.threadsafe ?= 1
168 SQLITE_OPT = \
169 -DSQLITE_ENABLE_RTREE \
170 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
171 -DSQLITE_ENABLE_STMTVTAB \
172 -DSQLITE_ENABLE_DBPAGE_VTAB \
173 -DSQLITE_ENABLE_DBSTAT_VTAB \
174 -DSQLITE_ENABLE_BYTECODE_VTAB \
175 -DSQLITE_ENABLE_OFFSET_SQL_FUNC \
176 -DSQLITE_ENABLE_PREUPDATE_HOOK \
177 -DSQLITE_ENABLE_SQLLOG \
178 -DSQLITE_OMIT_LOAD_EXTENSION \
179 -DSQLITE_OMIT_DEPRECATED \
180 -DSQLITE_OMIT_SHARED_CACHE \
181 -DSQLITE_THREADSAFE=$(opt.threadsafe) \
182 -DSQLITE_TEMP_STORE=2 \
183 -DSQLITE_USE_URI=1 \
184 -DSQLITE_C=$(sqlite3.c) \
185 -DSQLITE_JNI_FATAL_OOM=1 \
186 -DSQLITE_DEBUG
188 SQLITE_OPT += -g -DDEBUG -UNDEBUG
190 ifeq (1,$(enable.fts5))
191 SQLITE_OPT += -DSQLITE_ENABLE_FTS5
192 endif
194 sqlite3-jni.c := $(dir.src.c)/sqlite3-jni.c
195 sqlite3-jni.o := $(dir.bld.c)/sqlite3-jni.o
196 sqlite3-jni.h := $(dir.src.c)/sqlite3-jni.h
197 sqlite3-jni.dll := $(dir.bld.c)/libsqlite3-jni.so
198 # All javac-generated .h files must be listed in $(sqlite3-jni.h.in):
199 sqlite3-jni.h.in :=
200 define ADD_JNI_H
201 sqlite3-jni.h.in += $$(dir.bld.c)/org_sqlite_jni_$(1).h
202 $$(dir.bld.c)/org_sqlite_jni_$(1).h: $$(dir.src.jni)/$(1).java
203 endef
204 $(eval $(call ADD_JNI_H,SQLite3Jni))
205 ifeq (1,$(enable.fts5))
206 $(eval $(call ADD_JNI_H,Fts5ExtensionApi))
207 $(eval $(call ADD_JNI_H,fts5_api))
208 $(eval $(call ADD_JNI_H,fts5_tokenizer))
209 endif
210 ifeq (1,$(enable.tester))
211 sqlite3-jni.h.in += $(dir.bld.c)/org_sqlite_jni_tester_SQLTester.h
212 $(dir.bld.c)/org_sqlite_jni_tester_SQLTester.h: $(dir.src.jni.tester)/SQLTester.java
213 endif
214 #sqlite3-jni.dll.cfiles := $(dir.src.c)
215 sqlite3-jni.dll.cflags = \
216 -fPIC \
217 -I. \
218 -I$(dir $(sqlite3.h)) \
219 -I$(dir.src.c) \
220 -I$(JDK_HOME)/include \
221 $(patsubst %,-I%,$(patsubst %.h,,$(wildcard $(JDK_HOME)/include/*))) \
222 -Wall
223 # Using (-Wall -Wextra) triggers an untennable number of
224 # gcc warnings from sqlite3.c for mundane things like
225 # unused parameters.
227 # The gross $(patsubst...) above is to include the platform-specific
228 # subdir which lives under $(JDK_HOME)/include and is a required
229 # include path for client-level code.
230 ########################################################################
231 ifeq (1,$(enable.tester))
232 sqlite3-jni.dll.cflags += -DSQLITE_JNI_ENABLE_SQLTester
233 endif
234 $(sqlite3-jni.h): $(sqlite3-jni.h.in) $(MAKEFILE)
235 cat $(sqlite3-jni.h.in) > $@
236 $(sqlite3-jni.dll): $(sqlite3-jni.h) $(sqlite3.c) $(sqlite3.h)
237 $(sqlite3-jni.dll): $(dir.bld.c) $(sqlite3-jni.c) $(SQLite3Jni.java) $(MAKEFILE)
238 $(CC) $(sqlite3-jni.dll.cflags) $(SQLITE_OPT) \
239 $(sqlite3-jni.c) -shared -o $@
240 all: $(sqlite3-jni.dll)
242 .PHONY: test test-one
243 test.flags ?=
244 test.main.flags = -ea -Djava.library.path=$(dir.bld.c) \
245 $(java.flags) -cp $(classpath) \
246 org.sqlite.jni.Tester1
247 test.deps := $(SQLite3Jni.class) $(sqlite3-jni.dll)
248 test-one: $(test.deps)
249 $(bin.java) $(test.main.flags) $(test.flags)
250 test-sqllog: $(test.deps)
251 @echo "Testing with -sqllog..."
252 $(bin.java) $(test.main.flags) -sqllog
253 test-mt: $(test.deps)
254 @echo "Testing in multi-threaded mode:";
255 $(bin.java) $(test.main.flags) -t 5 -r 20 -shuffle $(test.flags)
257 test: test-one test-mt
258 tests: test test-sqllog
260 tester.scripts := $(sort $(wildcard $(dir.src)/tests/*.test))
261 tester.flags ?= # --verbose
262 .PHONY: tester tester-local tester-ext
263 ifeq (1,$(enable.tester))
264 tester-local: $(CLASS_FILES.tester) $(sqlite3-jni.dll)
265 $(bin.java) -ea -Djava.library.path=$(dir.bld.c) \
266 $(java.flags) -cp $(classpath) \
267 org.sqlite.jni.tester.SQLTester $(tester.flags) $(tester.scripts)
268 tester: tester-local
269 else
270 tester:
271 @echo "SQLTester support is disabled. Build with enable.tester=1 to enable it."
272 endif
274 tester.extdir.default := src/tests/ext
275 tester.extdir ?= $(tester.extdir.default)
276 tester.extern-scripts := $(wildcard $(tester.extdir)/*.test)
277 ifneq (,$(tester.extern-scripts))
278 tester-ext:
279 $(bin.java) -ea -Djava.library.path=$(dir.bld.c) \
280 $(java.flags) -cp $(classpath) \
281 org.sqlite.jni.tester.SQLTester $(tester.flags) $(tester.extern-scripts)
282 else
283 tester-ext:
284 @echo "******************************************************"; \
285 echo "*** Include the out-of-tree test suite in the 'tester'"; \
286 echo "*** target by either symlinking its directory to"; \
287 echo "*** $(tester.extdir.default) or passing it to make"; \
288 echo "*** as tester.extdir=/path/to/that/dir."; \
289 echo "******************************************************";
290 endif
292 tester-ext: tester-local
293 tester: tester-ext
294 tests: tester
296 ########################################################################
297 # Build each SQLITE_THREADMODE variant and run all tests against them.
298 multitest: clean
299 $(MAKE) opt.threadsafe=0 tests clean
300 $(MAKE) opt.threadsafe=1 tests clean
301 $(MAKE) opt.threadsafe=2 tests clean
304 ########################################################################
305 # jar bundle...
306 package.jar.in := $(abspath $(dir.src)/jar.in)
307 CLEAN_FILES += $(package.jar.in)
308 $(package.jar.in): $(MAKEFILE) $(CLASS_FILES.main)
309 cd $(dir.src); ls -1 org/sqlite/jni/*.java org/sqlite/jni/*.class > $@
310 @echo "To use this jar you will need the -Djava.library.path=DIR/CONTAINING/libsqlite3-jni.so flag."
311 @echo "e.g. java -jar $@ -Djava.library.path=bld"
313 $(package.jar): $(CLASS_FILES) $(MAKEFILE) $(package.jar.in)
314 rm -f $(dir.src)/c/*~ $(dir.src.jni)/*~
315 cd $(dir.src); $(bin.jar) -cfe ../$@ org.sqlite.jni.Tester1 @$(package.jar.in)
317 jar: $(package.jar)
319 ########################################################################
320 # javadoc...
321 dir.doc := $(dir.jni)/javadoc
322 doc.index := $(dir.doc)/index.html
323 $(doc.index): $(JAVA_FILES.main) $(MAKEFILE)
324 @if [ -d $(dir.doc) ]; then rm -fr $(dir.doc)/*; fi
325 $(bin.javadoc) -cp $(classpath) -d $(dir.doc) -quiet org.sqlite.jni
326 @echo "javadoc output is in $@"
328 .PHONY: doc javadoc docserve
329 .FORCE: doc
330 doc: $(doc.index)
331 javadoc: $(doc.index)
332 # Force rebild of docs
333 redoc:
334 @rm -f $(doc.index)
335 @$(MAKE) doc
336 docserve: $(doc.index)
337 cd $(dir.doc) && althttpd -max-age 1 -page index.html
338 ########################################################################
339 # Clean up...
340 CLEAN_FILES += $(dir.bld.c)/* \
341 $(dir.src.jni)/*.class \
342 $(dir.src.jni.tester)/*.class \
343 $(sqlite3-jni.dll) \
344 hs_err_pid*.log
346 .PHONY: clean distclean
347 clean:
348 -rm -f $(CLEAN_FILES)
349 distclean: clean
350 -rm -f $(DISTCLEAN_FILES)
351 -rm -fr $(dir.bld.c) $(dir.doc)
353 ########################################################################
354 # disttribution bundle rules...
356 ifeq (,$(filter snapshot,$(MAKECMDGOALS)))
357 dist-name-prefix := sqlite-jni
358 else
359 dist-name-prefix := sqlite-jni-snapshot-$(shell /usr/bin/date +%Y%m%d)
360 endif
361 dist-name := $(dist-name-prefix)-TEMP
364 dist-dir.top := $(dist-name)
365 dist-dir.src := $(dist-dir.top)/src
366 dist.top.extras := \
367 README.md
369 .PHONY: dist snapshot
371 dist: \
372 $(bin.version-info) $(sqlite3.canonical.c) \
373 $(package.jar) $(MAKEFILE)
374 @echo "Making end-user deliverables..."
375 @echo "****************************************************************************"; \
376 echo "*** WARNING: be sure to build this with JDK8 (javac 1.8) for compatibility."; \
377 echo "*** reasons!"; $$($(bin.javac) -version); \
378 echo "****************************************************************************"
379 @rm -fr $(dist-dir.top)
380 @mkdir -p $(dist-dir.src)
381 @cp -p $(dist.top.extras) $(dist-dir.top)/.
382 @cp -p jar-dist.make $(dist-dir.top)/Makefile
383 @cp -p $(dir.src.c)/*.[ch] $(dist-dir.src)/.
384 @cp -p $(sqlite3.canonical.c) $(sqlite3.canonical.h) $(dist-dir.src)/.
385 @set -e; \
386 vnum=$$($(bin.version-info) --download-version); \
387 vjar=$$($(bin.version-info) --version); \
388 vdir=$(dist-name-prefix)-$$vnum; \
389 arczip=$$vdir.zip; \
390 cp -p $(package.jar) $(dist-dir.top)/sqlite3-jni-$${vjar}.jar; \
391 echo "Making $$arczip ..."; \
392 rm -fr $$arczip $$vdir; \
393 mv $(dist-dir.top) $$vdir; \
394 zip -qr $$arczip $$vdir; \
395 rm -fr $$vdir; \
396 ls -la $$arczip; \
397 set +e; \
398 unzip -lv $$arczip || echo "Missing unzip app? Not fatal."
400 snapshot: dist
402 .PHONY: dist-clean
403 clean: dist-clean
404 dist-clean:
405 rm -fr $(dist-name) $(wildcard sqlite-jni-*.zip)