]> git.xonotic.org Git - xonotic/darkplaces.git/blob - build.sh
cmake: Set policy 0076 to NEW so it stops yelling at me when I use relative paths...
[xonotic/darkplaces.git] / build.sh
1 #!/bin/bash
2 #------------------------------------------------------------------------------#
3 #   build.sh (DarkPlaces Build Script)                                         #
4 #                                                                              #
5 #   Copyright (c) 2019-2020 David Knapp                                        #
6 #                                                                              #
7 # Permission is hereby granted, free of charge, to any person obtaining a copy #
8 # of this software and associated documentation files (the "Software"), to     #
9 # deal in the Software without restriction, including without limitation the   #
10 # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or  #
11 # sell copies of the Software, and to permit persons to whom the Software is   #
12 # furnished to do so, subject to the following conditions:                     #
13 #                                                                              #
14 # The above copyright notice and this permission notice shall be included in   #
15 # all copies or substantial portions of the Software.                          #
16 #                                                                              #
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR   #
18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,     #
19 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  #
20 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER       #
21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      #
22 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS #
23 # IN THE SOFTWARE.                                                             #
24 #------------------------------------------------------------------------------#
25 if [ -z "${BASH_VERSION:-}" ]; then
26         echo "This script requires bash."
27         exit 1
28 fi
29 #------------------------------------------------------------------------------#
30 ### HELPER FUNCTIONS ###
31 perror() {
32         printf -- "\e[31m%b\e[0m" "$1"
33 }
34
35 pwarn() {
36         printf -- "\e[33m%b\e[0m" "$1"
37 }
38
39 psuccess() {
40         printf -- "\e[32m%b\e[0m" "$1"
41 }
42
43 phelp() {
44         local full=$2
45         printf "
46 Usage: %s [OPTIONS] PROJECT" "$me"
47         if (( ! full )); then
48                 printf "
49
50 For more information, run again with --help.
51
52 "
53
54         else printf "
55 Options
56     --cc=               specify a C compiler
57     --cxx=              specify a C++ compiler
58     --threads= | --jN   set how many threads to compile with
59     --generator=        cmake generator to use. Run 'cmake --help' for a list
60     --cmake-options=    pass additional options to cmake
61     --config-dir=       override the location of the config.cmake file
62     --build-dir=        override the location cmake will write build files
63     --reset-build       delete build files of PROJECT
64     --reset-cache       delete the cache
65     --new-options       specify a new set of options
66     --nocache           do not read from, or write to the cache
67     --auto              do not display any prompts, even with --reset
68     --help              print this message then exit
69
70 Unless you set --config-dir, the PROJECT you specify is assumed to be a
71 correspondingly named subdirectory of the 'game' directory. The build directory
72 is also relative to the config directory by default, unless --build-dir is set.
73 If the directory (assumed or specified) doesn't exist, a new project can be
74 created for you from a template.
75
76 The script maintains a cache of your build settings so you don't have to input
77 the same settings for a specified PROJECT more than once. You can simply run
78 the script with PROJECT, and optionally --build, and it will configure and/or
79 build PROJECT with the cached settings automatically.
80
81 This script will run in auto mode if ran from a non-interactive shell.
82 "; fi
83         exit "$1"
84 }
85
86 check_empty()
87 {
88         if [ ! -d "$1" ] ||
89         ! command -v ls -A "$1" >/dev/null; then return 0; fi
90         return 1
91 }
92 #------------------------------------------------------------------------------#
93 check_env() { # Make sure the environment is sane before continuing.
94         local failed=0
95
96         if ! (( "$(id -u)" )); then
97                 if (( ! option_asroot )); then
98                         perror "*** This script cannot be run as root. Use --jackass to override\n\n"
99                         failed+=1
100                 else pwarn "* Running as root as you requested. Welcome to Jackass!\n\n"; fi
101         fi
102
103         if [[ $- == *i* ]]; then
104                 option_auto=1
105                 pwarn "* Shell is non-interactive. Prompts are impossible/pointless. --auto enabled.\n\n"
106         fi
107
108
109         if [ ! -d "$(pwd)/engine" ]; then perror "*** Required directory '\"$(pwd)\"/engine' was not found.\n" ; failed+=1; fi
110         if [ ! -d "$(pwd)/game" ] || [ ! -w "$(pwd)/game" ]; then perror "*** Required directory '\"$(pwd)\"/game' was not found or is not writable.\n" ; failed+=1; fi
111         if [ ! -d "$(pwd)/game/default" ]; then perror "*** Required directory '\"$(pwd)\"/game/default' was not found.\n"; failed+=1; fi
112         if [ ! -f "$(pwd)/CMakeLists.txt" ]; then perror "*** Required file '\"$(pwd)\"/engine/CMakeLists.txt' was not found.\n"; failed+=1; fi
113         if [ ! -f "$(pwd)/game/default/dpconfig.cmake" ]; then perror "*** Required file '\"$(pwd)\"/game/default/config.cmake' was not found.\n"; failed+=1; fi
114
115         if ! command -v cmake >/dev/null; then perror "*** Could not find cmake. Please install it and make sure it's in your PATH.\n"; failed+=1; fi
116
117         if (( failed )); then
118                 perror "*** The script failed to initialize. Please check the output for more information.\n\n"
119                 phelp 1 0
120         fi
121 }
122 #------------------------------------------------------------------------------#
123 option_cache_read() {
124         cache_file="${cache_dir}/${option_project}"
125
126         if [ -f "${cache_file}" ]; then
127                 if grep -q "cache_" "${cache_file}" ; then
128                         source "$cache_file"
129                         psuccess "* Loaded cached settings for '$option_project'\n\n"
130                         return
131                 else
132                         perror "* Could not load '$option_project' from the cache. Please check if this is a\nvalid cache file.\n\n"
133                 fi
134         fi
135         cache_changed=1
136         option_new=1
137         cache_new=1
138 }
139
140 option_cache_write() {
141         if [ ! -d "${cache_dir}" ]; then 
142                 if [ -f "${cache_dir}" ]; then
143                         perror "* The cache directory cannot be created because a file of the same name exists.\nThe cache cannot function. Please rename or delete this file.\n\n"
144                         return
145                 fi
146                 mkdir "${cache_dir}"
147         fi
148
149         if (( cache_changed )); then
150                 if (( ! option_cache_off )); then
151                         echo "#!/bin/bash
152
153 cache_project_dir=\"${option_project_dir}\"
154 cache_build_dir=\"${option_build_dir}\"
155 cache_build_cc=\"${option_build_cc}\"
156 cache_build_cxx=\"${option_build_cxx}\"
157 cache_build_threads=\"${option_build_threads}\"
158 cache_build_cmake_generator=\"${option_build_cmake_generator}\"
159 cache_build_cmake_options=\"${option_build_cmake_options}\"
160 " > "$cache_file"
161
162                         printf "\
163 Your build options for \"%s\" has been written to the cache. You only have to
164 run '%s %s' to build the same project again.
165
166 If you wish to change any setting later, you can pass --new-options to the
167 script.
168
169 " "$option_project" "$me" "$option_project"
170                 else pwarn "* The cache is disabled. Skipping write.\n\n"; fi
171         fi
172 }
173
174 option_cache_compare() {
175         local option=$1; local cache=$2
176
177         if ! [ "${option}" = "${cache}" ]; then cache_changed=1; return 1; fi
178         return 0
179 }
180
181 option_cache_list() {
182         local cache_list; cache_list="$(pwd)/.temp"
183         local cache_select
184
185         if (( option_auto )) || check_empty "${cache_dir}" || [ "$option_project" ]; then
186                 return; fi
187
188         printf "Please select a project."
189
190         if (( ! option_run_reset_build )); then
191                 printf " Leave blank to create a new one."
192         fi
193
194         printf "\n\n"
195         
196         while [ ! "$option_project" ]; do
197                 local j=1
198                 
199                 rm -f "$cache_list"
200                 for i in "${cache_dir}"/*; do
201                         printf "%s. %s\n" "$j" "$(basename "$i")" >> "$cache_list"
202                         j=$((j+1))
203                 done
204                 cat "$cache_list"
205                 printf "\nChoose: "
206                 read -r cache_select
207                 if [ ! "$cache_select" ]; then break; fi
208                 option_project="$(sed -n -e "s/^.*$cache_select. //p" "$cache_list")"
209                 printf "\n"
210         done
211 }
212 #------------------------------------------------------------------------------#
213 option_get_prompt() { # Generic prompt function
214         local -n option=$1;             local default=$2
215         local message=$3;               local required=$4
216         local error=$5;                 local default_text="[$default]"
217
218         if ! [ "$default" ]; then default_text=""; fi
219
220         if (( option_auto )); then # No prompts in auto mode.
221                 if (( required )); then
222                         perror "$error\n"
223                         phelp 1 0
224                 else
225                         option="${default}"
226                         return
227                 fi
228         fi
229
230         printf -- "%b\n" "$message"
231         read -rp "$default_text: " option
232         option=${option:-$default}
233         printf "\n"
234         return
235 }
236
237 option_get_cmdline() {  # Iterate over any args.
238         for (( i=0; i<${#args[@]}; i++)); do
239                 if [[ "${args[$i]}" == "-"* ]]; then
240                         case "${args[$i]}" in
241                                 "--new-options" )
242                                         option_new=1 ;;
243                                 "--reset-build" )
244                                         option_run_reset_build=1 ;;
245                                 "--reset-cache" )
246                                         option_run_reset_cache=1 ;;
247                                 "--auto" )
248                                         option_auto=1 ;;
249                                 "--build-dir="* )
250                                         option_build_dir=${args[$i]##--build-dir=} ;;
251                                 "--config-dir="* )
252                                         option_project_dir=${args[$i]##--config-dir=} ;;
253                                 "--cc="* )
254                                         option_build_cc=${args[$i]##--cc=} ;;
255                                 "--cxx="* )
256                                         option_build_cxx=${args[$i]##--cxx=} ;;
257                                 "--threads="*[0-9] )
258                                         option_build_threads=${args[$i]##--threads=} ;;                         
259                                 "--j"*[0-9] )
260                                         option_build_threads=${args[$i]##--j} ;;
261                                 "-j"*[0-9] )
262                                         option_build_threads=${args[$i]##-j} ;;
263                                 "--generator="* )
264                                         option_build_cmake_generator=${args[$i]##--generator=} ;;
265                                 "--cmake-options="* )
266                                         option_build_cmake_options=${args[$i]##--cmake-options=} ;;
267                                 "--nocache" )
268                                         option_cache_off=1 ;;
269                                 "--from-cmake" )
270                                         option_from_cmake=1 ;;
271                                 "--jackass" )
272                                         option_asroot=1 ;;
273                                 "--help" )
274                                         phelp 0 1 ;;
275                                 * )
276                                         pwarn "Unknown option '${args[$i]}'\n"
277                                         phelp 1 0 ;;
278                         esac
279                 # Last arg should be the build config, but not the first arg.
280                 else option_project=${args[$i]}; fi
281         done
282 }
283 #------------------------------------------------------------------------------#
284 option_get_check() {
285         if (( option_run_reset_cache )); then reset_cache; fi
286
287         if (( option_auto )); then
288                 pwarn "* --auto is set. Prompts will not appear.\n\n"
289                 if (( option_new )); then
290                         option_new=0
291                         pwarn "* --new-options is useless in auto mode. Ignoring.\n\n"
292                 fi
293         fi
294
295         option_cache_list
296         option_get_check_config
297
298         if ! (( option_cache_off )); then option_cache_read
299         else pwarn "* The cache is disabled. Skipping read.\n\n"; fi
300
301         if (( option_run_reset_build )); then reset_build; exit 0; fi
302
303         option_get_check_config_dir
304         option_get_check_build_dir
305         if (( ! option_from_cmake )); then
306                 option_get_check_build_cc
307                 option_get_check_build_cxx
308                 option_get_check_build_threads
309                 option_get_check_build_cmake_generator
310                 option_get_check_build_cmake_options
311         fi
312 }
313
314 option_get_check_config() { # If the user didn't give us anything, ask.
315         if (( option_run_reset_build )); then pwarn "* Resetting build files...\n\n"; fi
316         
317         while true; do
318                 if [ "$option_project" ]; then
319                         if [ "${option_project}" == "default" ]; then
320                                 pwarn "* H-hey...! Get your own project! That's the template. You can't use that!\n\n"
321                                 option_project=""
322                         else break; fi
323                 else option_get_prompt \
324                         option_project \
325                         "$cache_project" \
326                         "Please specify the name of your project" \
327                         "" \
328                         ""
329                 fi
330         done
331 }
332
333 option_get_check_config_dir() {
334         local new_config
335
336         if [ ! "$cache_project_dir" ]; then # Set the default
337                 cache_project_dir="$(pwd)/game/$option_project"; fi
338
339         # Don't prompt for this unless something is wrong. Assume the default.
340         if [ ! "$option_project_dir" ]; then
341                 if (( cache_new )) || (( ! option_new )); then
342                         option_project_dir="$cache_project_dir"
343                 fi
344         fi
345
346         while true; do
347                 if [ "$option_project_dir" ]; then
348                         if [ -d "${option_project_dir}" ]; then
349                                 option_cache_compare "$option_project_dir" "$cache_project_dir"
350                                 return  # We're good. Proceed.
351                         else printf "* The directory of the specified project does not exist.\n\n"
352                                 if [ -w "$(dirname "$option_project_dir")" ]; then
353                                         option_get_prompt \
354                                                 new_config \
355                                                 "Y" \
356                                                 "Would you like to create a new project from the template in:\n$option_project_dir?" \
357                                                 "" \
358                                                 ""
359                                         if [[ "$new_config" =~ ^(Y|y)$ ]]; then
360                                                 cp -rv "$config_template" "$option_project_dir"
361                                                 continue
362                                         fi
363                                 elif [ -f "${option_project_dir}" ]; then
364                                         pwarn "* The directory of the specified project is a file. Cannot create a new project\nfrom the template here.\n\n"
365                                 else
366                                         pwarn "* The parent directory is also not writable or doesn't exist. Cannot create a new\nproject from the template here.\n\n"
367                                 fi
368                         fi
369                 elif (( ! option_new )); then
370                         pwarn "* No config directory has been specified and --new-options isn't set. Something is wrong with your configuration, or there's\na bug in the script.\n\n"
371                 fi
372                 
373                 # Get our answer unless --auto is set.
374                 option_get_prompt \
375                         option_project_dir \
376                         "$cache_project_dir" \
377                         "Specify the location of '${option_project}'. If it doesn't exist, it can be created\nfrom a template." \
378                         1 \
379                         "You must provide a valid project directory with --auto set\n\n"
380         done
381 }
382
383 option_get_check_build_dir() {
384         local finished=0; local force=0; local ask=0
385
386         if [ ! "$cache_build_dir" ]; then
387                 cache_build_dir="$(pwd)/output/$option_project/"; fi
388
389         # Don't prompt for this unless something is wrong. Assume the default.
390         if [ ! "$option_build_dir" ]; then
391                 if (( cache_new )) || (( ! option_new )); then
392                         option_build_dir="$cache_build_dir"
393                 fi
394         fi
395
396         while ! (( finished )); do
397                 if [ "$option_build_dir" ]; then
398                         # Check if it even exists first.
399                         if [ -d "$option_build_dir" ]; then # Exists
400                                 # Check if writable. Permissions change.
401                                 if ! [ -w "$option_build_dir" ]; then
402                                         pwarn "* The directory '$option_build_dir' is NOT writable.\n\n"
403                                         ask=1
404                                 elif ! check_empty "$option_build_dir" &&
405                                 [[ $cache_build_dir != "$option_build_dir" ]]; then
406                                         if (( ! option_from_cmake )) && [ ! -f "$option_build_dir/CMakeCache.txt" ]; then
407                                                 pwarn "* The directory '$option_build_dir' is NOT empty.\n\n"
408                                                 option_get_prompt \
409                                                         force \
410                                                         "y/N" \
411                                                         "Would you like to build here anyway?" \
412                                                         1 \
413                                                         "*** You must specify an empty directory when --auto is set."
414                                                 if [[ "$force" =~ ^(Y|y)$ ]]; then ask=1; fi
415                                         fi
416                                 fi
417                         else
418                                 pwarn "* Build directory doesn't exist. CMake will create the directory for you.\n\n"
419                         fi
420                 else ask=1; fi
421
422                 if (( ask )); then
423                         option_get_prompt \
424                                 option_build_dir \
425                                 "$cache_build_dir" \
426                                 "Please provide an empty and writable directory for the build files" \
427                                 1 \
428                                 "*** You must provide a valid build directory with --auto set\n\n"
429                         ask=0
430                 else finished=1; fi
431         done
432 }
433
434 option_get_check_build_cc() {
435         if [ ! "$option_build_cc" ] && (( option_new )); then
436                 option_get_prompt \
437                         option_build_cc \
438                         "$cache_build_cc" \
439                         "Which C compiler would you like to use? Leave this default to use the compiler\nspecified in the cache, or if blank, for CMake to autodetect the compiler,\nunless you have something specific in mind (like clang)" \
440                         "" \
441                         ""
442         fi
443
444         export CC="$option_build_cc"
445
446         if ! option_cache_compare "$option_build_cc" "$cache_build_cc" && (( ! cache_new )); then
447                 pwarn "* The cmake cache must be deleted and regenerated when changing compilers.\n\n"
448                 reset_build
449         fi
450 }
451
452 option_get_check_build_cxx() {
453         if [ ! "$option_build_cxx" ] && (( option_new )); then
454                 option_get_prompt \
455                         option_build_cxx \
456                         "$cache_build_cxx" \
457                         "Which C++ compiler would you like to use? Leave this default to use the compiler\nspecified in the cache, or if blank, for CMake to autodetect the compiler,\nunless you have something specific in mind (like clang++)" \
458                         "" \
459                         ""
460         fi
461
462         export CXX="$option_build_cxx"
463
464         if ! option_cache_compare "$option_build_cxx" "$cache_build_cxx" && (( ! cache_new )); then
465                 pwarn "* The cmake cache must be deleted and regenerated when changing compilers.\n\n"
466                 reset_build
467         fi
468 }
469
470 option_get_check_build_threads() {
471         if [ ! "$option_build_threads" ] && (( ! option_new )); then
472                 option_build_threads="$cache_build_threads"
473         fi
474
475         while true; do
476                 if [ "$option_build_threads" ]; then
477                         if (( ! option_build_threads )); then
478                                 pwarn "* Threads must be a number, silly!\n\n"
479                         elif (( option_build_threads < 0 )); then
480                                 pwarn "* Threads can't be a negative number, silly!\n\n"
481                         else break; fi
482                 fi
483                 option_get_prompt \
484                         option_build_threads \
485                         "$cache_build_threads" \
486                         "How many threads would you like to compile with? Enter 0 to run the configure\nstep only." \
487                         "" \
488                         ""
489         done
490         option_cache_compare "$option_build_threads" "$cache_build_threads"
491 }
492
493 option_get_check_build_cmake_generator() {
494         if [ ! "$option_build_cmake_generator" ]; then
495                 if (( ! option_new )); then
496                         option_build_cmake_generator="$cache_build_cmake_generator"
497                 else
498                         option_get_prompt \
499                                 option_build_cmake_generator \
500                                 "$cache_build_cmake_generator" \
501                                 "What CMake generator would you like to use?" \
502                                 "" \
503                                 ""
504                 fi
505         fi
506         if ! option_cache_compare "$option_build_cmake_generator" "$cache_build_cmake_generator" && (( ! cache_new )); then
507                 pwarn "* The cmake cache must be deleted and regenerated when changing generators.\n\n"
508                 reset_build
509         fi
510 }
511
512 option_get_check_build_cmake_options() {
513         if (( option_new )); then
514                 option_get_prompt \
515                         option_build_cmake_options \
516                         "$cache_build_cmake_options" \
517                         "Specify additional command-line options for CMake" \
518                         "" \
519                         ""
520         else
521                 option_build_cmake_options="$cache_build_cmake_options"
522         fi
523         option_cache_compare "$option_build_cmake_options" "$cache_build_cmake_options"
524 }
525 #------------------------------------------------------------------------------#
526 build_start_config() {
527         local cmd_cmake_config="cmake -G\"${option_build_cmake_generator}\" -B$option_build_dir -DGAME_PROJECT=\"${option_project}\" -DGAME_PROJECT_DIR=\"${option_project_dir}\" $option_build_cmake_options"
528
529         printf "* Running CMake...\n\n" 
530         printf "* Using \"%s\" build config.\n\n" "$option_project"
531
532         # Try to configure. If that's successful, go ahead and build.
533         printf "* CMake config commandline: %s\n\n" "$cmd_cmake_config"
534         if ! eval "$cmd_cmake_config"; then
535                 perror "*** Configure failed. Please check the output for more information.\n\n"
536                 exit 1
537         fi
538         psuccess "* Configure completed successfully.\n\n"
539 }
540
541 build_start_compile() {
542         local cmd_cmake_build="cmake --build $option_build_dir -- -j$option_build_threads"
543
544         printf "* CMake build commandline: %s\n\n" "$cmd_cmake_build"
545         if ! eval "$cmd_cmake_build"; then
546                 pwarn "* Build failed, but configure was successful. Please check the output for more information.\n\n"
547                 return
548         fi
549         psuccess "* Build completed successfully.\n\n"
550 }
551
552 build_start() {
553                 build_start_config
554                 build_start_compile
555 }
556 #------------------------------------------------------------------------------#
557 reset_build() {
558         local reset="Y" # Defaults to Y in case --auto is set
559         if ! [ "$cache_build_dir" ]; then # Not set?
560                 pwarn "* --reset-build: No build directory for '$option_project' was specified or\nfound in the cache, or the cache is disabled.\n\n"
561         elif ! [ -d "$cache_build_dir" ]; then # Doesn't exist?
562                 pwarn "* --reset-build: The build directory of '$option_project' doesn't exist.\nNothing to delete.\n\n"
563         else
564                 option_get_prompt \
565                         reset \
566                         "Y" \
567                         "Do you wish to delete all build files under\n'$cache_build_dir'?"
568                 if [[ "$reset" =~ ^(Y|y)$ ]]; then
569                         if ! rm -rfv "$cache_build_dir" ; then # Can't delete?
570                                 perror "*** --reset-build: Failed to delete build files under '$cache_build_dir'\n\n"
571                         else
572                                 pwarn "* --reset-build: Deleted the build directory of '$option_project'.\n\n"
573                         fi
574                 else return; fi
575         fi
576 }
577
578 reset_cache() { # It resets the cache.
579         local reset="Y" # Defaults to Y in case --auto is set
580
581         if [ -d "$cache_dir" ]; then
582                 option_get_prompt \
583                         reset \
584                         "Y" \
585                         "Do you wish to delete the entire build cache?"
586                 if [[ "$reset" =~ ^(Y|y)$ ]]; then
587                         rm -rfv "$cache_dir"
588                         pwarn "* --reset-cache: Deleted the build cache.\n\n"
589                 else return; fi
590         else
591                 pwarn "* --reset-cache: The build cache doesn't exist. Nothing to delete.\n\n"
592         fi
593         exit 0
594 }
595 #------------------------------------------------------------------------------#
596 printf "\n\e[1;34m---Darkplaces Build Wizard---\e[0m\n\n"
597
598 declare -g args=("$@") # Put cmdline in separate array to be read in functions
599 declare -g me=$0 # Script can refer to itself regardless of filename in global scope
600 declare -g cache_dir; cache_dir="./.cache"
601 declare -g cache_file # Current cache file handle.
602 declare -g config_template; config_template="$(pwd)/game/default"
603
604 ### Default options ###
605 # These are changed by the cache (if it exists) and compared with user input.
606 declare -g cache_project="darkplaces"
607 declare -g cache_project_dir="" # Defined later
608 declare -g cache_build_dir="" # Defined later
609 declare -g cache_build_cc=""
610 declare -g cache_build_cxx=""
611 declare -g cache_build_threads=1
612 declare -g cache_build_cmake_options=""
613 declare -g cache_build_cmake_generator="Unix Makefiles"
614
615 ### User options ###
616 # If any of these don't match the cache, write to it.
617 declare -g option_project
618 declare -g option_project_dir
619 declare -g option_build_dir
620 declare -g option_build_cc
621 declare -g option_build_cxx
622 declare -g option_build_threads
623 declare -g option_build_cmake_options
624 declare -g option_build_cmake_generator
625 # Per-build options
626 declare -g option_auto=0
627 declare -g option_new=0
628 declare -g option_asroot=0
629 declare -g option_run_reset_build=0
630 declare -g option_run_reset_cache=0
631 declare -g option_cache_off=0
632 declare -g option_from_cmake=0
633
634 # State tracking variables
635 declare -g cache_new=0
636 declare -g cache_loaded=0
637 declare -g cache_changed=0 # Set to 1 if any options don't match the cache.
638
639 check_env                               # Make sure the environment is sane first
640 option_get_cmdline              # Get input from command-line
641 option_get_check                # Check that input and ask for new input
642 build_start                             # Start build with options
643 option_cache_write              # Write to cache
644
645 psuccess "* The Darkplaces Build Wizard has completed the requested operations\n successfully.\n\n"