blob: 017ad6292fc95fdd1f8ef7da31540f89dc6297c4 [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
4# least the core components - the test harness, shell, and TCL
5# 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
14# the parser are derived from "parse.y" using lemon. And the
15# "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#
20# tclsh mksqlite3c.tcl
21#
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
26# from in this file. The versioon number is needed to generate the header
27# comment of the amalgamation.
28#
29if {[lsearch $argv --nostatic]>=0} {
30 set addstatic 0
31} else {
32 set addstatic 1
33}
34if {[lsearch $argv --linemacros]>=0} {
35 set linemacros 1
36} else {
37 set linemacros 0
38}
39set in [open tsrc/sqlite3.h]
40set cnt 0
41set VERSION ?????
42while {![eof $in]} {
43 set line [gets $in]
44 if {$line=="" && [eof $in]} break
45 incr cnt
46 regexp {#define\s+SQLITE_VERSION\s+"(.*)"} $line all VERSION
47}
48close $in
49
50# Open the output file and write a header comment at the beginning
51# of the file.
52#
53set out [open sqlite3.c w]
54# Force the output to use unix line endings, even on Windows.
55fconfigure $out -translation lf
56set today [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S UTC" -gmt 1]
57puts $out [subst \
58{/******************************************************************************
59** This file is an amalgamation of many separate C source files from SQLite
60** version $VERSION. By combining all the individual C code files into this
61** single large file, the entire code can be compiled as a single translation
62** unit. This allows many compilers to do optimizations that would not be
63** possible if the files were compiled separately. Performance improvements
64** of 5% or more are commonly seen when SQLite is compiled as a single
65** translation unit.
66**
67** This file is all you need to compile SQLite. To use SQLite in other
68** programs, you need this file and the "sqlite3.h" header file that defines
69** the programming interface to the SQLite library. (If you do not have
70** the "sqlite3.h" header file at hand, you will find a copy embedded within
71** the text of this file. Search for "Begin file sqlite3.h" to find the start
72** of the embedded sqlite3.h header file.) Additional code files may be needed
73** if you want a wrapper to interface SQLite with your choice of programming
74** language. The code for the "sqlite3" command-line shell is also in a
75** separate file. This file contains only code for the core SQLite library.
76*/
77#define SQLITE_CORE 1
78#define SQLITE_AMALGAMATION 1}]
79if {$addstatic} {
80 puts $out \
81{#ifndef SQLITE_PRIVATE
82# define SQLITE_PRIVATE static
83#endif
84#ifndef SQLITE_API
85# define SQLITE_API
86#endif}
87}
88
89# These are the header files used by SQLite. The first time any of these
90# files are seen in a #include statement in the C code, include the complete
91# text of the file in-line. The file only needs to be included once.
92#
93foreach hdr {
94 btree.h
95 btreeInt.h
96 hash.h
97 hwtime.h
98 keywordhash.h
99 mutex.h
100 opcodes.h
101 os_common.h
102 os.h
drh168f9f52011-09-17 17:29:20 +0000103 pager.h
104 parse.h
105 pcache.h
106 sqlite3ext.h
107 sqlite3.h
108 sqliteicu.h
109 sqliteInt.h
110 sqliteLimit.h
111 vdbe.h
112 vdbeInt.h
113 wal.h
114} {
115 set available_hdr($hdr) 1
116}
117set available_hdr(sqliteInt.h) 0
118
119# 78 stars used for comment formatting.
120set s78 \
121{*****************************************************************************}
122
123# Insert a comment into the code
124#
125proc section_comment {text} {
126 global out s78
127 set n [string length $text]
128 set nstar [expr {60 - $n}]
129 set stars [string range $s78 0 $nstar]
130 puts $out "/************** $text $stars/"
131}
132
133# Read the source file named $filename and write it into the
134# sqlite3.c output file. If any #include statements are seen,
135# process them approprately.
136#
137proc copy_file {filename} {
138 global seen_hdr available_hdr out addstatic linemacros
139 set ln 0
140 set tail [file tail $filename]
141 section_comment "Begin file $tail"
142 if {$linemacros} {puts $out "#line 1 \"$filename\""}
143 set in [open $filename r]
144 set varpattern {^[a-zA-Z][a-zA-Z_0-9 *]+(sqlite3[_a-zA-Z0-9]+)(\[|;| =)}
145 set declpattern {[a-zA-Z][a-zA-Z_0-9 ]+ \**(sqlite3[_a-zA-Z0-9]+)\(}
146 if {[file extension $filename]==".h"} {
147 set declpattern " *$declpattern"
148 }
149 set declpattern ^$declpattern
150 while {![eof $in]} {
151 set line [gets $in]
152 incr ln
153 if {[regexp {^\s*#\s*include\s+["<]([^">]+)[">]} $line all hdr]} {
154 if {[info exists available_hdr($hdr)]} {
155 if {$available_hdr($hdr)} {
156 if {$hdr!="os_common.h" && $hdr!="hwtime.h"} {
157 set available_hdr($hdr) 0
158 }
159 section_comment "Include $hdr in the middle of $tail"
160 copy_file tsrc/$hdr
161 section_comment "Continuing where we left off in $tail"
162 if {$linemacros} {puts $out "#line [expr {$ln+1}] \"$filename\""}
163 }
164 } elseif {![info exists seen_hdr($hdr)]} {
165 set seen_hdr($hdr) 1
166 puts $out $line
167 } else {
168 puts $out "/* $line */"
169 }
170 } elseif {[regexp {^#ifdef __cplusplus} $line]} {
171 puts $out "#if 0"
172 } elseif {!$linemacros && [regexp {^#line} $line]} {
173 # Skip #line directives.
174 } elseif {$addstatic && ![regexp {^(static|typedef)} $line]} {
175 regsub {^SQLITE_API } $line {} line
176 if {[regexp $declpattern $line all funcname]} {
177 # Add the SQLITE_PRIVATE or SQLITE_API keyword before functions.
178 # so that linkage can be modified at compile-time.
179 if {[regexp {^sqlite3_} $funcname]} {
180 puts $out "SQLITE_API $line"
181 } else {
182 puts $out "SQLITE_PRIVATE $line"
183 }
184 } elseif {[regexp $varpattern $line all varname]} {
185 # Add the SQLITE_PRIVATE before variable declarations or
186 # definitions for internal use
187 if {![regexp {^sqlite3_} $varname]} {
188 regsub {^extern } $line {} line
189 puts $out "SQLITE_PRIVATE $line"
190 } else {
191 if {[regexp {const char sqlite3_version\[\];} $line]} {
192 set line {const char sqlite3_version[] = SQLITE_VERSION;}
193 }
194 regsub {^SQLITE_EXTERN } $line {} line
195 puts $out "SQLITE_API $line"
196 }
197 } elseif {[regexp {^(SQLITE_EXTERN )?void \(\*sqlite3IoTrace\)} $line]} {
198 regsub {^SQLITE_EXTERN } $line {} line
199 puts $out "SQLITE_PRIVATE $line"
200 } elseif {[regexp {^void \(\*sqlite3Os} $line]} {
201 puts $out "SQLITE_PRIVATE $line"
202 } else {
203 puts $out $line
204 }
205 } else {
206 puts $out $line
207 }
208 }
209 close $in
210 section_comment "End of $tail"
211}
212
213
214# Process the source files. Process files containing commonly
215# used subroutines first in order to help the compiler find
216# inlining opportunities.
217#
218foreach file {
219 sqliteInt.h
220
221 global.c
222 ctime.c
223 status.c
224 date.c
225 os.c
226
227 fault.c
228 mem0.c
229 mem1.c
230 mem2.c
231 mem3.c
232 mem5.c
233 mutex.c
234 mutex_noop.c
drh168f9f52011-09-17 17:29:20 +0000235 mutex_unix.c
236 mutex_w32.c
237 malloc.c
238 printf.c
239 random.c
240 utf.c
241 util.c
242 hash.c
243 opcodes.c
244
drh168f9f52011-09-17 17:29:20 +0000245 os_unix.c
246 os_win.c
247
248 bitvec.c
249 pcache.c
250 pcache1.c
251 rowset.c
252 pager.c
253 wal.c
254
255 btmutex.c
256 btree.c
257 backup.c
258
259 vdbemem.c
260 vdbeaux.c
261 vdbeapi.c
262 vdbetrace.c
263 vdbe.c
264 vdbeblob.c
265 vdbesort.c
266 journal.c
267 memjournal.c
268
269 walker.c
270 resolve.c
271 expr.c
272 alter.c
273 analyze.c
274 attach.c
275 auth.c
276 build.c
277 callback.c
278 delete.c
279 func.c
280 fkey.c
281 insert.c
282 legacy.c
283 loadext.c
284 pragma.c
285 prepare.c
286 select.c
287 table.c
288 trigger.c
289 update.c
290 vacuum.c
291 vtab.c
292 where.c
293
294 parse.c
295
296 tokenize.c
297 complete.c
298
299 main.c
300 notify.c
301} {
302 copy_file tsrc/$file
303}
304
305close $out