| 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. © or �xA9; 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. © 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 © 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 |