Line # Revision Author
1 1 kittycat # Example cbuild script file, which can be used to build itself with GCC.
2 # Note: This is a comparitively simple example, and in no way showcases
3 # CBuild's extensive capabilities. For more in-depth information, please see
4 # the AWiki entry at <http://awiki.tomasu.org/bin/view/Main/CBUILD>
5
6 # Everything past the first '#' character in a line is ignored. To put a '#'
7 # character in a line, escape it like '\#', or put it in quotes.
8 # Use ${var} to dereference the environment variable 'var', and $(cmd) to
9 # replace text using sub-command 'cmd'.
10 # &#xxxx; will give you the character the given number value represents, in
11 # UTF-8 (ie. &#169; or &#0xA9; will give you the copyright symbol on a UTF-8
12 # compatible console). In addition, the standard HTML entity names are also
13 # valid (ie. &copy; will also give you the copyright symbol).
14
15 # All whitespace between a command and its option(s) are eaten by the parser.
16
17
18 # You can use 'echo' to print a line to the console. Use 'put' to print a
19 # line without a trailing newline
20 echo "CBuild &copy; 2006"
21 echo ""
22
23
24 # 'ifopt' checks the command line for the specified option. The rest of the
25 # line will only be processed if it was passed. Whitespace between the option
26 # name and next command is ignored. If the command line opt has a =, it will
27 # be treated as an opt=val pair and only the portion before the = needs to
28 # match.
29 # 'verbose' causes cbuild to display the commands being run for a number of
30 # commands, in place of the cleaner, more readable output.
31
32 ifopt verbose verbose 1
33
34
35 # To keep the main directory clean, it's usually best to put the temporary
36 # object and dependancy files into subdirectories. Changing the variables
37 # OBJ_DIR and DEP_DIR will do just this.
38
39 OBJ_DIR = obj
40 DEP_DIR = dep
41
42
43 # The 'do' command allows cbuild to execute a block if the following if-type
44 # check passes. End the block with 'done' or use 'else' (which can also be
45 # followed by an if-type command) to make another block to run if the initial
46 # check failed. Indentation is unimportant.
47
48 do ifopt help
49 echo "
50 CBuild - a platform-independant build system using (mostly) ANSI C.
51
52 Available options:
53 verbose - Enable more verbose command printing
54 clean - Clean a previously compiled build
55 --install path - Installs the optimized executable to the specified path
56 --disable-gui - Disables using the GUI for installation on some platforms
57 help - Display this help message
58
59 For advanced scripting information, please see CBuild's AWiki entry at
60 <http://awiki.tomasu.org/bin/view/Main/CBUILD>
61 To report bugs, please email me at <kcat@strangesoft.net> or
62 <chris.kcat@gmail.com>.
63 "
64
65 # 'exit' returns from the script, and cbuild will return with the specified
66 # number as the exit code
67
68 exit 0
69 done
70
71
72 # 'goto' jumps to the specified label (prepended with ':') which can be ahead
73 # of or behind the current line.
74
75 ifopt clean goto clean
76
77
78 # Here we set some standard optimizing C flags. This only persists until
79 # another line is encountered that sets them differently. You can use ?=
80 # instead of = to set a variable only if its not already set. If you wish
81 # to start with spaces, encapsulate the value in ''s or ""s, or escape
82 # the first whitespace character with \
83
84 CFLAGS ?= "-O2 -W -Wall"
85
86
87 # Create the object and dependancy file directories. 'ifnexist' will run the
88 # following command if the specified file or directory doesn't exist. Testing
89 # "name/." will make sure "name" is actually a directory.
90
91 ifnexist "${OBJ_DIR}/." mkdir ${OBJ_DIR}
92 ifnexist "${DEP_DIR}/." mkdir ${DEP_DIR}
93
94
95 # There be a lot of funky magic in here. Only advanced users will want to worry
96 # about this.
97 define dialog 'noop'
98 define dcop 'noop'
99 do ifnopt --disable-gui
100
101 # Locate dcop and make sure it's running. Also, look for kdialog.
102 DCOP = $(*which dcop)
103 do ifnot ${'DCOP'}=''
104 setoutput /dev/null
105 seterror /dev/null
106 @!call ${'DCOP'}
107 do ifret 0
108 DIALOG = $(*which kdialog)
109 if ${'DIALOG'}='' DCOP = ''
110 else
111 DCOP = ''
112 done
113 setoutput
114 seterror
115 done
116
117 # If KDE's not available, bail out and go console-only
118 if ${'DCOP'}='' goto build_it
119
120 # Set up a 4-part progress bar. The dcop reference will be stored in a temp
121 # file
122 seterror /dev/null
123 @!readexec DCOP_REF ${'DIALOG'} --title "Building CBuild" --progressbar "Building CBuild, please wait..." 4
124 do ifnret 0
125 seterror
126 goto build_it
127 done
128 seterror
129
130 define dialog @!readexec '"${1}"' \'${'DIALOG'}\' '${@2}'
131 define dcop @!call \'${'DCOP'}\' '${\'DCOP_REF\'} ${@}'
132
133 # Setup an exit command, to make sure the progress bar is removed on exit
134 define atexit_dcop dcop close
135 else
136 DCOP = ''
137 done
138
139
140 :build_it
141 echo "- Building optimized version -"
142
143
144 # This compiles a list of source files, one at a time. Files with the '.c'
145 # extension are compiled using the program specified in 'CC' (default: 'gcc').
146 # The source files will have their extension changed to 'OBJ_EXT' (default
147 # value: '.o') when compiled, and be placed in 'OBJ_DIR'. 'CFLAGS' and
148 # 'CPPFLAGS' will be applied to the command line for C files.
149
150 dcop setLabel "Compiling cbuild.c..."
151 compile cbuild.c
152 dcop setProgress 1
153
154
155 # linkexec will link the previously-compiled objects into the named file with
156 # the command named in 'LD' (default: 'gcc'). LDFLAGS will be applied to the
157 # end of the command line. The specified output file will have 'EXE_EXT'
158 # (default: '.exe' in Win32/DOS, nothing elsewhere) appended.
159
160 dcop setLabel "Linking cbuild"${'EXE_EXT'}"..."
161 linkexec cbuild
162 dcop setProgress 2
163
164
165 echo ""
166 echo "- Building debug version -"
167
168 # This sets some debug cflags and sets the object extension to '-dbg.o', causing
169 # the source file to compile as 'cbuild-dbg.o'
170
171 CFLAGS = "-MMD -g3 -W -Wall"
172 OBJ_EXT = "-dbg.o"
173
174 dcop setLabel "Compiling cbuild.c..."
175 compile cbuild.c
176 dcop setProgress 3
177 dcop setLabel "Linking cbuild-dbg"${'EXE_EXT'}"..."
178 linkexec cbuild-dbg
179 dcop setProgress 4
180
181 echo ""
182
183 # The getoptval directive gives the value of an option passed to the command
184 # line in the form of 'option=value' or 'option value'. Prefixing the command
185 # name with * causes the returned string to be encapsulated in 'hard quotes'
186 # (important for dealing with user input which may contain $ characters).
187
188 INSTALL_PATH = $(*getoptval --install)
189
190 dcop close
191 define atexit_dcop
192 ifnot ${'DCOP'}='' goto kde_install
193
194
195 # 'ifnot' will run the following command(s) if the two values (in the form x=y)
196 # are not equal. Putting the variable name in 'hard quotes' causes the expanded
197 # string to be encapsulated similarly (important when dealing with unknown
198 # input which may contain $ characters)
199
200 do ifnot ${'INSTALL_PATH'}=''
201 INPUT = ${'INSTALL_PATH'}
202 goto check_dir
203 done
204
205 put "Do you wish to install CBuild? [y/N] "
206
207 # 'read' will read user keyboard input until enter/return is pressed
208 read INPUT
209
210 # 'ifnret' will execute the follow command if the previous command's return
211 # value is not the specified value. A return value of 0 typically indicates
212 # success (and non-0 is failure).
213 ifnret 0 exit 1
214
215
216 if ${'INPUT'}='' exit 0
217 if $(*tolower ${'INPUT'})='n' exit 0
218 if $(*tolower ${'INPUT'})='no' exit 0
219 if $(*tolower ${'INPUT'})='y' goto input_ok
220 if $(*tolower ${'INPUT'})='yes' goto input_ok
221
222 echo "Invalid response '"${'INPUT'}"'"
223 echo "Aborting installation"
224 exit 0
225
226 :input_ok
227 do ifplat win32
228 INSTALL_PATH = ${'WINDIR'}
229 else ifplat dos
230 INSTALL_PATH = C:/DOS
231 else
232 INSTALL_PATH = /usr/local/bin
233 done
234
235 # 'fixpath' converts \ directory seperators to / in the specified var. This
236 # is required for CBuild to behave properly with directories
237 fixpath INSTALL_PATH
238
239
240 echo ""
241 echo "CBuild will install to '"${'INSTALL_PATH'}"'."
242 echo "If you wish to use a different location, please specify it below (press enter"
243 echo "for the default, type 'abort' to abort installation)"
244 put "-> "
245
246 :get_path
247 read INPUT
248 ifnret 0 exit 1
249
250 fixpath INPUT
251
252 do ifnot ${'INPUT'}=''
253 if $(*tolower ${'INPUT'})='abort' exit 0
254 :check_dir
255 do ifnexist ${'INPUT'}/.
256 echo ""
257 echo "The directory '"${'INPUT'}"/' doesn't appear to be valid."
258 echo "Please specify a valid path, or 'abort' to abort installation."
259 put "-> "
260 goto get_path
261 done
262 INSTALL_PATH = ${'INPUT'}
263 done
264
265 :copy_files
266 copy cbuild${EXE_EXT} ${'INSTALL_PATH'}/
267 echo ""
268
269 exit 0
270
271
272 :clean
273
274 # Here's the cleanup area, accessible if you pass "clean" to cbuild. "rmexec"
275 # deletes the specified executables (prepending 'EXE_EXT' to the filenames),
276 # and "rmobj" deletes the object and dependancy files that would be generated
277 # by compiling the specified file. Prepending a command with "-" will cause
278 # cbuild to continue even if the command fails, while prepending with '!' will
279 # cause cbuild to continue without any error messages.
280
281 -rmexec cbuild cbuild-dbg
282
283 -rmobj cbuild
284 OBJ_EXT = "-dbg.o"
285 -rmobj cbuild
286
287 -rm "${OBJ_DIR}" "${DEP_DIR}"
288
289 exit 0
290
291
292 :kde_install
293
294 define atexit_stdout seterror
295 seterror /dev/null
296
297 # This portion is used to install using KDE's kdialog program for user
298 # interaction. Much nicer than needing to use the keyboard.
299
300 # Ask if the user wants to install, if they didn't previously specify to
301 do if ${'INSTALL_PATH'}=''
302 dialog '' --title "Install CBuild?" --yesno "Do you wish to install CBuild?"
303 ifnret 0 exit 0
304
305 INSTALL_PATH = /usr/local/bin
306
307 :kde_get_path
308 # Get the install path from the user
309 dialog INSTALL_PATH --title "Install CBuild in..." --getexistingdirectory ${'INSTALL_PATH'}
310
311 do ifnexist ${'INSTALL_PATH'}
312 dialog '' --title "CBuild install error" --error "Could not read install directory from kdialog!
313 Install aborted!"
314
315 exit 1
316 done
317 done
318
319
320 # If we don't have write permissions, we'll need to use kdesu to try and get
321 # them. For larger projects, where you need to do much more than a simple copy,
322 # you can put the commands you need potential root access for into a seperate
323 # script, then call cbuild (with ${0}) using that script.
324
325 do ifwrite ${'INSTALL_PATH'}/.
326 @!call cp cbuild${'EXE_EXT'} ${'INSTALL_PATH'}/
327 else
328 @!call kdesu -t -c "cp cbuild"${'EXE_EXT'}" "${'INSTALL_PATH'}"/"
329 done
330
331
332 # Make sure the copy succeeded
333
334 do ifnret 0
335 dialog '' --title "Error installing CBuild" --warningyesno "Could not copy cbuild to "${'INSTALL_PATH'}"!
336 This may be due to invalid permissions. Please check with your system administrator.
337 Select a different location?"
338
339 ifret 0 goto kde_get_path
340 exit 1
341 done
342
343
344 dialog '' --title "Install succeeded" --msgbox "Installation was successful!
345 CBuild has been installed in "${'INSTALL_PATH'}
346
347 exit 0