Skip to content
File

Blob: build/BUILD.sqlite3

9.6 KB
1"""
2Builds sqlite3 from plain source.
3 
4This is just enough to build the sqlite3 library; it does not include
5the shell or any other utilities.
6"""
7 
8load("@rules_cc//cc:cc_binary.bzl", "cc_binary")
9load("@rules_cc//cc:cc_library.bzl", "cc_library")
10 
11package(default_visibility = ["//visibility:private"])
12 
13SQLITE_DEFINES = [
14 "SQLITE_MAX_ALLOCATION_SIZE=16777216", # 16MB
15 "SQLITE_PRINTF_PRECISION_LIMIT=100000",
16 "SQLITE_ENABLE_FTS5",
17 "SQLITE_ENABLE_NORMALIZE",
18 "SQLITE_ENABLE_MATH_FUNCTIONS",
19 "SQLITE_DEFAULT_FOREIGN_KEYS=1",
20 "SQLITE_ENABLE_UPDATE_DELETE_LIMIT",
21 "SQLITE_OMIT_SHARED_CACHE",
22]
23 
24SQLITE_DEFINES_FOR_LEMON = " ".join(["-D" + x for x in SQLITE_DEFINES])
25 
26GIVEN_SOURCES = glob([
27 "src/**/*.h",
28 "src/**/*.c",
29 "ext/**/*.h",
30 "ext/**/*.c",
31])
32 
33GENERATED_SOURCES = []
34 
35# Regarding src/vdbe.c: In the normal SQLite build process, the given
36# src/vdbe.c is run through tool/vdbe-compress.tcl before use. There
37# is an amalgamation-build-time option called SQLITE_SMALL_STACK; if
38# this option is not given, then vdbe-compress.tcl does nothing; it
39# just emits its input verbatim.
40#
41# We have not set SQLITE_SMALL_STACK, so this Bazel-build file does
42# not bother with tool/vdbe-compress.tcl.
43 
44cc_binary(
45 name = "lemon",
46 srcs = ["tool/lemon.c"],
47 copts = ["-w"],
48)
49 
50# ========================================================================
51# Constructs parse.{c,h} using the Lemon parser generator.
52 
53genrule(
54 name = "parse_ch",
55 srcs = [
56 "src/parse.y",
57 "tool/lempar.c",
58 ],
59 outs = [
60 "parse.h",
61 "parse.c",
62 ],
63 cmd = (
64 # lemon requires lempar.c to be in the current working
65 # directory, and parse.y has to be in a writable directory
66 # since the output files are created adjacent to it.
67 "cp $(SRCS) . " +
68 
69 # Creates parse.c and parse.h
70 "&& $(execpath :lemon) {} parse.y ".format(SQLITE_DEFINES_FOR_LEMON) +
71 
72 # Bazel expects genrule outputs to be in RULEDIR
73 "&& cp parse.h parse.c $(RULEDIR)"
74 ),
75 tools = [
76 ":lemon",
77 ],
78)
79 
80GENERATED_SOURCES += [
81 "parse.h",
82 "parse.c",
83]
84 
85# ========================================================================
86# Constructs fts5parse.{c,h} using the Lemon parser generator.
87 
88genrule(
89 name = "fts5parse_ch",
90 srcs = [
91 "ext/fts5/fts5parse.y",
92 "tool/lempar.c",
93 ],
94 outs = [
95 "fts5parse.h",
96 "fts5parse.c",
97 ],
98 cmd = (
99 # Same as :parse_ch
100 "cp $(SRCS) . " +
101 "&& $(execpath :lemon) {} fts5parse.y ".format(SQLITE_DEFINES_FOR_LEMON) +
102 # Bazel expects genrule outputs to be in RULEDIR
103 "&& cp fts5parse.h fts5parse.c $(RULEDIR)"
104 ),
105 tools = [
106 ":lemon",
107 ],
108)
109 
110GENERATED_SOURCES += [
111 "fts5parse.h",
112 "fts5parse.c",
113]
114 
115# ========================================================================
116# Constructs fts5.{c,h}. "FTS5" is version 5 of Full Text Search.
117 
118filegroup(
119 name = "fts5_sources",
120 srcs = glob([
121 "ext/fts5/*.h",
122 "ext/fts5/*.c",
123 ]),
124)
125 
126genrule(
127 name = "fts5_ch",
128 srcs = [
129 "fts5parse.h",
130 "fts5parse.c",
131 "manifest",
132 "manifest.uuid",
133 ":fts5_sources",
134 ],
135 outs = [
136 "fts5.h",
137 "fts5.c",
138 ],
139 cmd = (
140 "mkdir -p $(RULEDIR)/build/ext/fts5/tool " +
141 
142 # Copy all the inputs over so the directory structure is to
143 # mkfts5c.tcl's liking. This ends up putting everything not in
144 # :fts5_sources in there twice, once in build/ and once in
145 # build/ext/fts5/, but it doesn't hurt anything. :shrug:
146 "&& cp $(SRCS) $(RULEDIR)/build/ext/fts5 " +
147 "&& cp $(location manifest) $(RULEDIR)/build " +
148 "&& cp $(location manifest.uuid) $(RULEDIR)/build " +
149 "&& cp $(location fts5parse.h) $(RULEDIR)/build " +
150 "&& cp $(location fts5parse.c) $(RULEDIR)/build " +
151 "&& cp $(location ext/fts5/tool/mkfts5c.tcl) $(RULEDIR)/build/ext/fts5/tool " +
152 
153 # Okay, go.
154 "&& pushd $(RULEDIR)/build >/dev/null " +
155 "&& tclsh ext/fts5/tool/mkfts5c.tcl " +
156 "&& popd >/dev/null " +
157 
158 # Put the outputs where Bazel will see them.
159 "&& mv $(RULEDIR)/build/fts5.c $(RULEDIR)/build/ext/fts5/fts5.h $(RULEDIR) " +
160 
161 # Done. Clean up after ourselves.
162 "&& rm -r $(RULEDIR)/build"
163 ),
164 tools = [
165 "ext/fts5/tool/mkfts5c.tcl",
166 ],
167)
168 
169GENERATED_SOURCES += ["fts5.c"]
170 
171# ========================================================================
172# These rules construct various source files using provided utility programs.
173 
174genrule(
175 name = "opcodes_h",
176 srcs = [
177 "parse.h",
178 "src/vdbe.c",
179 ],
180 outs = ["opcodes.h"],
181 cmd = "cat $(location parse.h) $(location src/vdbe.c) | tclsh $(location tool/mkopcodeh.tcl) > $(RULEDIR)/opcodes.h",
182 tools = ["tool/mkopcodeh.tcl"],
183)
184 
185GENERATED_SOURCES += ["opcodes.h"]
186 
187genrule(
188 name = "opcodes_c",
189 srcs = ["opcodes.h"],
190 outs = ["opcodes.c"],
191 cmd = "tclsh $(location tool/mkopcodec.tcl) $(location opcodes.h) > $(RULEDIR)/opcodes.c",
192 tools = ["tool/mkopcodec.tcl"],
193)
194 
195GENERATED_SOURCES += ["opcodes.c"]
196 
197cc_binary(
198 name = "mkkeywordhash",
199 srcs = ["tool/mkkeywordhash.c"],
200 copts = ["-w"],
201)
202 
203genrule(
204 name = "keywordhash_h",
205 outs = ["keywordhash.h"],
206 cmd = "$(execpath :mkkeywordhash) > $(RULEDIR)/keywordhash.h",
207 tools = [":mkkeywordhash"],
208)
209 
210GENERATED_SOURCES += ["keywordhash.h"]
211 
212# ========================================================================
213# Constructs sqlite3.h.
214 
215cc_binary(
216 name = "mksourceid",
217 srcs = ["tool/mksourceid.c"],
218 copts = ["-w"],
219)
220 
221genrule(
222 name = "sqlite3_h",
223 srcs = [
224 # The first few dependencies come from the "sqlite3.h" target
225 # in main.mk in the SQLite source distribution.
226 "src/sqlite.h.in",
227 "manifest",
228 "VERSION",
229 "ext/rtree/sqlite3rtree.h",
230 
231 # These come from looking for "set filelist" in mksqlite3h.tcl
232 # and looking for files not named above. The script fails with
233 # a complaint about a missing file if these aren't here.
234 "ext/session/sqlite3session.h",
235 "ext/fts5/fts5.h",
236 ],
237 outs = ["sqlite3.h"],
238 
239 # mksqlite3h.tcl expects to run in a directory with a very
240 # particular structure, so we have to set that up for it.
241 #
242 # We use $(RULEDIR)/build since RULEDIR is guaranteed to be
243 # writable.
244 cmd = (
245 "mkdir -p $(RULEDIR)/build/src $(RULEDIR)/build/ext/rtree $(RULEDIR)/build/ext/session $(RULEDIR)/build/ext/fts5 " +
246 
247 # TODO(cleanup): come up with a less-repetitive way to do this.
248 "&& cp $(location tool/mksqlite3h.tcl) $(RULEDIR)/build " +
249 "&& cp $(location src/sqlite.h.in) $(RULEDIR)/build/src/sqlite.h.in " +
250 "&& cp $(location manifest) $(RULEDIR)/build/manifest " +
251 "&& cp $(location VERSION) $(RULEDIR)/build/VERSION " +
252 "&& cp $(location ext/rtree/sqlite3rtree.h) $(RULEDIR)/build/ext/rtree/sqlite3rtree.h " +
253 "&& cp $(location ext/session/sqlite3session.h) $(RULEDIR)/build/ext/session/sqlite3session.h " +
254 "&& cp $(location ext/fts5/fts5.h) $(RULEDIR)/build/ext/fts5/fts5.h " +
255 
256 # It also expects to invoke mksourceid.
257 "&& cp $(execpath :mksourceid) $(RULEDIR)/build/mksourceid " +
258 
259 # Okay, go.
260 "&& pushd $(RULEDIR)/build >/dev/null " +
261 "&& tclsh mksqlite3h.tcl . > ../sqlite3.h " +
262 "&& popd >/dev/null " +
263 
264 # Done. Clean up after ourselves.
265 "&& rm -r $(RULEDIR)/build"
266 ),
267 tools = [
268 "tool/mksqlite3h.tcl",
269 ":mksourceid",
270 ],
271)
272 
273GENERATED_SOURCES += ["sqlite3.h"]
274 
275# ========================================================================
276# Constructs the amalgamation. Well, the rest of it; sqlite3.h is one
277# of the files in the amalgamation.
278 
279genrule(
280 name = "amalgamation",
281 srcs = GIVEN_SOURCES + GENERATED_SOURCES,
282 outs = [
283 "sqlite3.c",
284 "sqlite3ext.h",
285 ],
286 
287 # mksqlite3c.tcl expects to run in a directory with a very
288 # particular structure, so we have to set that up for it.
289 #
290 # We use $(RULEDIR)/build/tsrc since RULEDIR is guaranteed to be
291 # writable. ("tsrc" matches the directory name in the SQLite
292 # Makefile.)
293 cmd = (
294 "mkdir -p $(RULEDIR)/build/tsrc $(RULEDIR)/build/tool " +
295 
296 # Copy everything in. There's no subdirectories; everything
297 # but mksqlite3c.tcl just goes in tsrc.
298 "&& cp $(SRCS) $(RULEDIR)/build/tsrc " +
299 "&& cp $(location tool/mksqlite3c.tcl) $(RULEDIR)/build/tool " +
300 
301 # Build the thing.
302 #
303 # This step ("make sqlite3c") is where the SQLite Makefile
304 # would also construct tclsqlite3.c, but we don't use that
305 # file, so we don't bother building it.
306 "&& pushd $(RULEDIR)/build >/dev/null " +
307 "&& tclsh tool/mksqlite3c.tcl " +
308 "&& popd >/dev/null " +
309 
310 # Copy the outputs somewhere that Bazel will find them.
311 "&& cp $(RULEDIR)/build/sqlite3.c $(RULEDIR)/build/tsrc/sqlite3ext.h $(RULEDIR)/ " +
312 
313 # Done. Clean up after ourselves.
314 "&& rm -r $(RULEDIR)/build"
315 ),
316 tools = [
317 "tool/mksqlite3c.tcl",
318 ],
319)
320# ========================================================================
321# Actually builds the library.
322 
323cc_library(
324 name = "sqlite3",
325 srcs = ["sqlite3.c"],
326 hdrs = [
327 "sqlite3.h",
328 "sqlite3ext.h",
329 ],
330 copts = ["-w"], # Ignore all warnings. This is not our code, we can't fix the warnings.
331 defines = SQLITE_DEFINES,
332 include_prefix = ".",
333 visibility = ["//visibility:public"],
334)