blob: 84520725646ec187e7cd77bf2ac3f1165ee7871c [file] [log] [blame]
drh168f9f52011-09-17 17:29:20 +00001#!/usr/bin/tclsh
2#
3# To build a single huge source file holding all of SQLite (or at
mistachkin4ef916e2016-08-24 19:58:46 +00004# least the core components - the test harness, shell, and TCL
drh168f9f52011-09-17 17:29:20 +00005# interface are omitted.) first do
6#
7# make target_source
8#
9# The make target above moves all of the source code files into
10# a subdirectory named "tsrc". (This script expects to find the files
11# there and will not work if they are not found.) There are a few
12# generated C code files that are also added to the tsrc directory.
13# For example, the "parse.c" and "parse.h" files to implement the
mistachkin4ef916e2016-08-24 19:58:46 +000014# the parser are derived from "parse.y" using lemon. And the
drh168f9f52011-09-17 17:29:20 +000015# "keywordhash.h" files is generated by a program named "mkkeywordhash".
16#
17# After the "tsrc" directory has been created and populated, run
18# this script:
19#
mistachkin26bbfaa2015-03-24 21:34:53 +000020# tclsh mksqlite3c-noext.tcl
drh168f9f52011-09-17 17:29:20 +000021#
22# The amalgamated SQLite code will be written into sqlite3.c
23#
24
25# Begin by reading the "sqlite3.h" header file. Extract the version number
mistachkin26bbfaa2015-03-24 21:34:53 +000026# from in this file. The version number is needed to generate the header
drh168f9f52011-09-17 17:29:20 +000027# comment of the amalgamation.
28#
mistachkin4ef916e2016-08-24 19:58:46 +000029set addstatic 1
30set linemacros 0
31set useapicall 0
32for {set i 0} {$i<[llength $argv]} {incr i} {
33 set x [lindex $argv $i]
34 if {[regexp {^-+nostatic$} $x]} {
35 set addstatic 0
36 } elseif {[regexp {^-+linemacros} $x]} {
37 set linemacros 1
38 } elseif {[regexp {^-+useapicall} $x]} {
39 set useapicall 1
40 } else {
41 error "unknown command-line option: $x"
42 }
drh168f9f52011-09-17 17:29:20 +000043}
44set in [open tsrc/sqlite3.h]
45set cnt 0
46set VERSION ?????
47while {![eof $in]} {
48 set line [gets $in]
49 if {$line=="" && [eof $in]} break
50 incr cnt
51 regexp {#define\s+SQLITE_VERSION\s+"(.*)"} $line all VERSION
52}
53close $in
54
55# Open the output file and write a header comment at the beginning
56# of the file.
57#
58set out [open sqlite3.c w]
59# Force the output to use unix line endings, even on Windows.
60fconfigure $out -translation lf
61set today [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S UTC" -gmt 1]
62puts $out [subst \
63{/******************************************************************************
64** This file is an amalgamation of many separate C source files from SQLite
mistachkin4ef916e2016-08-24 19:58:46 +000065** version $VERSION. By combining all the individual C code files into this
drh168f9f52011-09-17 17:29:20 +000066** single large file, the entire code can be compiled as a single translation
67** unit. This allows many compilers to do optimizations that would not be
68** possible if the files were compiled separately. Performance improvements
69** of 5% or more are commonly seen when SQLite is compiled as a single
70** translation unit.
71**
72** This file is all you need to compile SQLite. To use SQLite in other
73** programs, you need this file and the "sqlite3.h" header file that defines
mistachkin4ef916e2016-08-24 19:58:46 +000074** the programming interface to the SQLite library. (If you do not have
drh168f9f52011-09-17 17:29:20 +000075** the "sqlite3.h" header file at hand, you will find a copy embedded within
76** the text of this file. Search for "Begin file sqlite3.h" to find the start
77** of the embedded sqlite3.h header file.) Additional code files may be needed
78** if you want a wrapper to interface SQLite with your choice of programming
79** language. The code for the "sqlite3" command-line shell is also in a
80** separate file. This file contains only code for the core SQLite library.
81*/
82#define SQLITE_CORE 1
83#define SQLITE_AMALGAMATION 1}]
84if {$addstatic} {
85 puts $out \
86{#ifndef SQLITE_PRIVATE
87# define SQLITE_PRIVATE static
drh168f9f52011-09-17 17:29:20 +000088#endif}
89}
90
mistachkin4ef916e2016-08-24 19:58:46 +000091# These are the header files used by SQLite. The first time any of these
drh168f9f52011-09-17 17:29:20 +000092# files are seen in a #include statement in the C code, include the complete
93# text of the file in-line. The file only needs to be included once.
94#
95foreach hdr {
96 btree.h
97 btreeInt.h
98 hash.h
99 hwtime.h
100 keywordhash.h
mistachkin2318d332015-01-12 18:02:52 +0000101 msvc.h
drh168f9f52011-09-17 17:29:20 +0000102 mutex.h
103 opcodes.h
104 os_common.h
mistachkinf74b9e02013-11-26 01:00:31 +0000105 os_setup.h
mistachkin8bc52622013-11-25 09:36:07 +0000106 os_win.h
drh168f9f52011-09-17 17:29:20 +0000107 os.h
drh168f9f52011-09-17 17:29:20 +0000108 pager.h
109 parse.h
110 pcache.h
mistachkin8de12502015-03-24 21:52:12 +0000111 pragma.h
drh168f9f52011-09-17 17:29:20 +0000112 sqlite3.h
mistachkin4ef916e2016-08-24 19:58:46 +0000113 sqlite3ext.h
drh168f9f52011-09-17 17:29:20 +0000114 sqliteicu.h
115 sqliteInt.h
116 sqliteLimit.h
117 vdbe.h
118 vdbeInt.h
mistachkin8de12502015-03-24 21:52:12 +0000119 vxworks.h
drh168f9f52011-09-17 17:29:20 +0000120 wal.h
mistachkin8de12502015-03-24 21:52:12 +0000121 whereInt.h
drh168f9f52011-09-17 17:29:20 +0000122} {
123 set available_hdr($hdr) 1
124}
125set available_hdr(sqliteInt.h) 0
126
mistachkin8de12502015-03-24 21:52:12 +0000127# These headers should be copied into the amalgamation without modifying any
128# of their function declarations or definitions.
129set varonly_hdr(sqlite3.h) 1
130
131# These are the functions that accept a variable number of arguments. They
132# always need to use the "cdecl" calling convention even when another calling
133# convention (e.g. "stcall") is being used for the rest of the library.
134set cdecllist {
135 sqlite3_config
136 sqlite3_db_config
137 sqlite3_log
138 sqlite3_mprintf
139 sqlite3_snprintf
140 sqlite3_test_control
141 sqlite3_vtab_config
142}
143
drh168f9f52011-09-17 17:29:20 +0000144# 78 stars used for comment formatting.
145set s78 \
146{*****************************************************************************}
147
148# Insert a comment into the code
149#
150proc section_comment {text} {
151 global out s78
152 set n [string length $text]
153 set nstar [expr {60 - $n}]
154 set stars [string range $s78 0 $nstar]
155 puts $out "/************** $text $stars/"
156}
157
158# Read the source file named $filename and write it into the
159# sqlite3.c output file. If any #include statements are seen,
mistachkin8de12502015-03-24 21:52:12 +0000160# process them appropriately.
drh168f9f52011-09-17 17:29:20 +0000161#
162proc copy_file {filename} {
mistachkin4ef916e2016-08-24 19:58:46 +0000163 global seen_hdr available_hdr varonly_hdr cdecllist out
164 global addstatic linemacros useapicall
drh168f9f52011-09-17 17:29:20 +0000165 set ln 0
166 set tail [file tail $filename]
167 section_comment "Begin file $tail"
168 if {$linemacros} {puts $out "#line 1 \"$filename\""}
169 set in [open $filename r]
170 set varpattern {^[a-zA-Z][a-zA-Z_0-9 *]+(sqlite3[_a-zA-Z0-9]+)(\[|;| =)}
mistachkin8de12502015-03-24 21:52:12 +0000171 set declpattern {([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3[_a-zA-Z0-9]+)(\(.*)}
drh168f9f52011-09-17 17:29:20 +0000172 if {[file extension $filename]==".h"} {
173 set declpattern " *$declpattern"
174 }
mistachkin8de12502015-03-24 21:52:12 +0000175 set declpattern ^$declpattern\$
drh168f9f52011-09-17 17:29:20 +0000176 while {![eof $in]} {
177 set line [gets $in]
178 incr ln
179 if {[regexp {^\s*#\s*include\s+["<]([^">]+)[">]} $line all hdr]} {
180 if {[info exists available_hdr($hdr)]} {
181 if {$available_hdr($hdr)} {
182 if {$hdr!="os_common.h" && $hdr!="hwtime.h"} {
183 set available_hdr($hdr) 0
184 }
185 section_comment "Include $hdr in the middle of $tail"
186 copy_file tsrc/$hdr
187 section_comment "Continuing where we left off in $tail"
188 if {$linemacros} {puts $out "#line [expr {$ln+1}] \"$filename\""}
mistachkin3a2a6862015-07-15 21:00:33 +0000189 } else {
190 # Comment out the entire line, replacing any nested comment
191 # begin/end markers with the harmless substring "**".
192 puts $out "/* [string map [list /* ** */ **] $line] */"
drh168f9f52011-09-17 17:29:20 +0000193 }
194 } elseif {![info exists seen_hdr($hdr)]} {
mistachkin8de12502015-03-24 21:52:12 +0000195 if {![regexp {/\*\s+amalgamator:\s+dontcache\s+\*/} $line]} {
196 set seen_hdr($hdr) 1
197 }
198 puts $out $line
199 } elseif {[regexp {/\*\s+amalgamator:\s+keep\s+\*/} $line]} {
200 # This include file must be kept because there was a "keep"
201 # directive inside of a line comment.
drh168f9f52011-09-17 17:29:20 +0000202 puts $out $line
203 } else {
mistachkin8de12502015-03-24 21:52:12 +0000204 # Comment out the entire line, replacing any nested comment
205 # begin/end markers with the harmless substring "**".
206 puts $out "/* [string map [list /* ** */ **] $line] */"
drh168f9f52011-09-17 17:29:20 +0000207 }
208 } elseif {[regexp {^#ifdef __cplusplus} $line]} {
209 puts $out "#if 0"
210 } elseif {!$linemacros && [regexp {^#line} $line]} {
211 # Skip #line directives.
mistachkin4ef916e2016-08-24 19:58:46 +0000212 } elseif {$addstatic
213 && ![regexp {^(static|typedef|SQLITE_PRIVATE)} $line]} {
mistachkin8de12502015-03-24 21:52:12 +0000214 # Skip adding the SQLITE_PRIVATE or SQLITE_API keyword before
215 # functions if this header file does not need it.
216 if {![info exists varonly_hdr($tail)]
217 && [regexp $declpattern $line all rettype funcname rest]} {
218 regsub {^SQLITE_API } $line {} line
drh168f9f52011-09-17 17:29:20 +0000219 # Add the SQLITE_PRIVATE or SQLITE_API keyword before functions.
220 # so that linkage can be modified at compile-time.
mistachkin4ef916e2016-08-24 19:58:46 +0000221 if {[regexp {^sqlite3[a-z]*_} $funcname]} {
mistachkin8de12502015-03-24 21:52:12 +0000222 set line SQLITE_API
223 append line " " [string trim $rettype]
224 if {[string index $rettype end] ne "*"} {
225 append line " "
226 }
mistachkin4ef916e2016-08-24 19:58:46 +0000227 if {$useapicall} {
228 if {[lsearch -exact $cdecllist $funcname] >= 0} {
mistachkin0e4125a2016-09-08 23:16:02 +0000229 append line SQLITE_CDECL " "
mistachkin4ef916e2016-08-24 19:58:46 +0000230 } else {
mistachkin0e4125a2016-09-08 23:16:02 +0000231 append line SQLITE_APICALL " "
mistachkin4ef916e2016-08-24 19:58:46 +0000232 }
mistachkin8de12502015-03-24 21:52:12 +0000233 }
mistachkin0e4125a2016-09-08 23:16:02 +0000234 append line $funcname $rest
mistachkin8de12502015-03-24 21:52:12 +0000235 puts $out $line
drh168f9f52011-09-17 17:29:20 +0000236 } else {
237 puts $out "SQLITE_PRIVATE $line"
238 }
239 } elseif {[regexp $varpattern $line all varname]} {
mistachkin8de12502015-03-24 21:52:12 +0000240 # Add the SQLITE_PRIVATE before variable declarations or
241 # definitions for internal use
242 regsub {^SQLITE_API } $line {} line
243 if {![regexp {^sqlite3_} $varname]} {
244 regsub {^extern } $line {} line
245 puts $out "SQLITE_PRIVATE $line"
246 } else {
247 if {[regexp {const char sqlite3_version\[\];} $line]} {
248 set line {const char sqlite3_version[] = SQLITE_VERSION;}
249 }
250 regsub {^SQLITE_EXTERN } $line {} line
251 puts $out "SQLITE_API $line"
drh168f9f52011-09-17 17:29:20 +0000252 }
drh168f9f52011-09-17 17:29:20 +0000253 } elseif {[regexp {^(SQLITE_EXTERN )?void \(\*sqlite3IoTrace\)} $line]} {
mistachkin8de12502015-03-24 21:52:12 +0000254 regsub {^SQLITE_API } $line {} line
drh168f9f52011-09-17 17:29:20 +0000255 regsub {^SQLITE_EXTERN } $line {} line
mistachkin8de12502015-03-24 21:52:12 +0000256 puts $out $line
drh168f9f52011-09-17 17:29:20 +0000257 } elseif {[regexp {^void \(\*sqlite3Os} $line]} {
mistachkin8de12502015-03-24 21:52:12 +0000258 regsub {^SQLITE_API } $line {} line
drh168f9f52011-09-17 17:29:20 +0000259 puts $out "SQLITE_PRIVATE $line"
260 } else {
261 puts $out $line
262 }
263 } else {
264 puts $out $line
265 }
266 }
267 close $in
268 section_comment "End of $tail"
269}
270
271
272# Process the source files. Process files containing commonly
273# used subroutines first in order to help the compiler find
274# inlining opportunities.
275#
276foreach file {
277 sqliteInt.h
278
279 global.c
280 ctime.c
281 status.c
282 date.c
283 os.c
284
285 fault.c
286 mem0.c
287 mem1.c
288 mem2.c
289 mem3.c
290 mem5.c
291 mutex.c
292 mutex_noop.c
drh168f9f52011-09-17 17:29:20 +0000293 mutex_unix.c
294 mutex_w32.c
295 malloc.c
296 printf.c
mistachkin4ef916e2016-08-24 19:58:46 +0000297 treeview.c
drh168f9f52011-09-17 17:29:20 +0000298 random.c
drhf51446a2012-07-21 19:40:42 +0000299 threads.c
drh168f9f52011-09-17 17:29:20 +0000300 utf.c
301 util.c
302 hash.c
303 opcodes.c
304
drh168f9f52011-09-17 17:29:20 +0000305 os_unix.c
306 os_win.c
307
308 bitvec.c
309 pcache.c
310 pcache1.c
311 rowset.c
312 pager.c
313 wal.c
314
315 btmutex.c
316 btree.c
317 backup.c
318
319 vdbemem.c
320 vdbeaux.c
321 vdbeapi.c
322 vdbetrace.c
323 vdbe.c
324 vdbeblob.c
325 vdbesort.c
drh168f9f52011-09-17 17:29:20 +0000326 memjournal.c
327
328 walker.c
329 resolve.c
330 expr.c
331 alter.c
332 analyze.c
333 attach.c
334 auth.c
335 build.c
336 callback.c
337 delete.c
338 func.c
339 fkey.c
340 insert.c
341 legacy.c
342 loadext.c
343 pragma.c
344 prepare.c
345 select.c
346 table.c
347 trigger.c
348 update.c
349 vacuum.c
350 vtab.c
mistachkin4ef916e2016-08-24 19:58:46 +0000351 wherecode.c
352 whereexpr.c
drh168f9f52011-09-17 17:29:20 +0000353 where.c
dand31e7ad2018-06-09 17:58:51 +0000354 window.c
drh168f9f52011-09-17 17:29:20 +0000355
356 parse.c
357
358 tokenize.c
359 complete.c
360
361 main.c
362 notify.c
363} {
364 copy_file tsrc/$file
365}
366
367close $out