add using
[factor/jcg.git] / build-support / factor.sh
blob44c047155d78a5c5bc9fa4b6714929e1bdf77a7e
1 #!/usr/bin/env bash
3 # Programs returning != 0 will not cause script to exit
4 set +e
6 # Case insensitive string comparison
7 shopt -s nocaseglob
8 #shopt -s nocasematch
10 ECHO=echo
11 OS=
12 ARCH=
13 WORD=
14 NO_UI=
15 GIT_PROTOCOL=${GIT_PROTOCOL:="git"}
16 GIT_URL=${GIT_URL:=$GIT_PROTOCOL"://factorcode.org/git/factor.git"}
18 test_program_installed() {
19 if ! [[ -n `type -p $1` ]] ; then
20 return 0;
22 return 1;
25 ensure_program_installed() {
26 installed=0;
27 for i in $* ;
29 $ECHO -n "Checking for $i..."
30 test_program_installed $i
31 if [[ $? -eq 0 ]]; then
32 echo -n "not "
33 else
34 installed=$(( $installed + 1 ))
36 $ECHO "found!"
37 done
38 if [[ $installed -eq 0 ]] ; then
39 $ECHO -n "Install "
40 if [[ $# -eq 1 ]] ; then
41 $ECHO -n $1
42 else
43 $ECHO -n "any of [ $* ]"
45 $ECHO " and try again."
46 exit 1
50 check_ret() {
51 RET=$?
52 if [[ $RET -ne 0 ]] ; then
53 $ECHO $1 failed
54 exit 2
58 check_gcc_version() {
59 $ECHO -n "Checking gcc version..."
60 GCC_VERSION=`$CC --version`
61 check_ret gcc
62 if [[ $GCC_VERSION == *3.3.* ]] ; then
63 $ECHO "You have a known buggy version of gcc (3.3)"
64 $ECHO "Install gcc 3.4 or higher and try again."
65 exit 3
66 elif [[ $GCC_VERSION == *4.3.* ]] ; then
67 MAKE_OPTS="$MAKE_OPTS SITE_CFLAGS=-fno-forward-propagate"
69 $ECHO "ok."
72 set_downloader() {
73 test_program_installed wget curl
74 if [[ $? -ne 0 ]] ; then
75 DOWNLOADER=wget
76 else
77 DOWNLOADER="curl -O"
81 set_md5sum() {
82 test_program_installed md5sum
83 if [[ $? -ne 0 ]] ; then
84 MD5SUM=md5sum
85 else
86 MD5SUM="md5 -r"
90 set_gcc() {
91 case $OS in
92 openbsd) ensure_program_installed egcc; CC=egcc;;
93 *) CC=gcc;;
94 esac
97 set_make() {
98 case $OS in
99 netbsd) MAKE='gmake';;
100 freebsd) MAKE='gmake';;
101 openbsd) MAKE='gmake';;
102 dragonflybsd) MAKE='gmake';;
103 *) MAKE='make';;
104 esac
105 if ! [[ $MAKE -eq 'gmake' ]] ; then
106 ensure_program_installed gmake
110 check_installed_programs() {
111 ensure_program_installed chmod
112 ensure_program_installed uname
113 ensure_program_installed git
114 ensure_program_installed wget curl
115 ensure_program_installed gcc
116 ensure_program_installed make gmake
117 ensure_program_installed md5sum md5
118 ensure_program_installed cut
119 check_gcc_version
122 check_library_exists() {
123 GCC_TEST=factor-library-test.c
124 GCC_OUT=factor-library-test.out
125 $ECHO -n "Checking for library $1..."
126 $ECHO "int main(){return 0;}" > $GCC_TEST
127 $CC $GCC_TEST -o $GCC_OUT -l $1
128 if [[ $? -ne 0 ]] ; then
129 $ECHO "not found!"
130 $ECHO "Warning: library $1 not found."
131 $ECHO "***Factor will compile NO_UI=1"
132 NO_UI=1
134 $DELETE -f $GCC_TEST
135 check_ret $DELETE
136 $DELETE -f $GCC_OUT
137 check_ret $DELETE
138 $ECHO "found."
141 check_X11_libraries() {
142 check_library_exists freetype
143 check_library_exists GLU
144 check_library_exists GL
145 check_library_exists X11
148 check_libraries() {
149 case $OS in
150 linux) check_X11_libraries;;
151 esac
154 check_factor_exists() {
155 if [[ -d "factor" ]] ; then
156 $ECHO "A directory called 'factor' already exists."
157 $ECHO "Rename or delete it and try again."
158 exit 4
162 find_os() {
163 if [[ -n $OS ]] ; then return; fi
164 $ECHO "Finding OS..."
165 uname_s=`uname -s`
166 check_ret uname
167 case $uname_s in
168 CYGWIN_NT-5.2-WOW64) OS=winnt;;
169 *CYGWIN_NT*) OS=winnt;;
170 *CYGWIN*) OS=winnt;;
171 *darwin*) OS=macosx;;
172 *Darwin*) OS=macosx;;
173 *linux*) OS=linux;;
174 *Linux*) OS=linux;;
175 *NetBSD*) OS=netbsd;;
176 *FreeBSD*) OS=freebsd;;
177 *OpenBSD*) OS=openbsd;;
178 *DragonFly*) OS=dragonflybsd;;
179 SunOS) OS=solaris;;
180 esac
183 find_architecture() {
184 if [[ -n $ARCH ]] ; then return; fi
185 $ECHO "Finding ARCH..."
186 uname_m=`uname -m`
187 check_ret uname
188 case $uname_m in
189 i386) ARCH=x86;;
190 i686) ARCH=x86;;
191 i86pc) ARCH=x86;;
192 amd64) ARCH=x86;;
193 ppc64) ARCH=ppc;;
194 *86) ARCH=x86;;
195 *86_64) ARCH=x86;;
196 "Power Macintosh") ARCH=ppc;;
197 esac
200 write_test_program() {
201 echo "#include <stdio.h>" > $C_WORD.c
202 echo "int main(){printf(\"%d\", 8*sizeof(void*)); return 0; }" >> $C_WORD.c
205 c_find_word_size() {
206 $ECHO "Finding WORD..."
207 C_WORD=factor-word-size
208 write_test_program
209 gcc -o $C_WORD $C_WORD.c
210 WORD=$(./$C_WORD)
211 check_ret $C_WORD
212 $DELETE -f $C_WORD*
215 intel_macosx_word_size() {
216 ensure_program_installed sysctl
217 $ECHO -n "Testing if your Intel Mac supports 64bit binaries..."
218 sysctl machdep.cpu.extfeatures | grep EM64T >/dev/null
219 if [[ $? -eq 0 ]] ; then
220 WORD=64
221 $ECHO "yes!"
222 else
223 WORD=32
224 $ECHO "no."
228 find_word_size() {
229 if [[ -n $WORD ]] ; then return; fi
230 if [[ $OS == macosx && $ARCH == x86 ]] ; then
231 intel_macosx_word_size
232 else
233 c_find_word_size
237 set_factor_binary() {
238 case $OS in
239 winnt) FACTOR_BINARY=factor-console.exe;;
240 *) FACTOR_BINARY=factor;;
241 esac
244 set_factor_library() {
245 case $OS in
246 winnt) FACTOR_LIBRARY=factor.dll;;
247 macosx) FACTOR_LIBRARY=libfactor.dylib;;
248 *) FACTOR_LIBRARY=libfactor.a;;
249 esac
252 set_factor_image() {
253 FACTOR_IMAGE=factor.image
256 echo_build_info() {
257 $ECHO OS=$OS
258 $ECHO ARCH=$ARCH
259 $ECHO WORD=$WORD
260 $ECHO FACTOR_BINARY=$FACTOR_BINARY
261 $ECHO FACTOR_LIBRARY=$FACTOR_LIBRARY
262 $ECHO FACTOR_IMAGE=$FACTOR_IMAGE
263 $ECHO MAKE_TARGET=$MAKE_TARGET
264 $ECHO BOOT_IMAGE=$BOOT_IMAGE
265 $ECHO MAKE_IMAGE_TARGET=$MAKE_IMAGE_TARGET
266 $ECHO GIT_PROTOCOL=$GIT_PROTOCOL
267 $ECHO GIT_URL=$GIT_URL
268 $ECHO DOWNLOADER=$DOWNLOADER
269 $ECHO CC=$CC
270 $ECHO MAKE=$MAKE
271 $ECHO COPY=$COPY
272 $ECHO DELETE=$DELETE
275 check_os_arch_word() {
276 if ! [[ -n $OS && -n $ARCH && -n $WORD ]] ; then
277 $ECHO "OS: $OS"
278 $ECHO "ARCH: $ARCH"
279 $ECHO "WORD: $WORD"
280 $ECHO "OS, ARCH, or WORD is empty. Please report this."
282 echo $MAKE_TARGET
283 exit 5
287 set_build_info() {
288 check_os_arch_word
289 if [[ $OS == macosx && $ARCH == ppc ]] ; then
290 MAKE_IMAGE_TARGET=macosx-ppc
291 MAKE_TARGET=macosx-ppc
292 elif [[ $OS == linux && $ARCH == ppc ]] ; then
293 MAKE_IMAGE_TARGET=linux-ppc
294 MAKE_TARGET=linux-ppc
295 elif [[ $OS == winnt && $ARCH == x86 && $WORD == 64 ]] ; then
296 MAKE_IMAGE_TARGET=winnt-x86.64
297 MAKE_TARGET=winnt-x86-64
298 elif [[ $ARCH == x86 && $WORD == 64 ]] ; then
299 MAKE_IMAGE_TARGET=unix-x86.64
300 MAKE_TARGET=$OS-x86-64
301 else
302 MAKE_IMAGE_TARGET=$ARCH.$WORD
303 MAKE_TARGET=$OS-$ARCH-$WORD
305 BOOT_IMAGE=boot.$MAKE_IMAGE_TARGET.image
308 parse_build_info() {
309 ensure_program_installed cut
310 $ECHO "Parsing make target from command line: $1"
311 OS=`echo $1 | cut -d '-' -f 1`
312 ARCH=`echo $1 | cut -d '-' -f 2`
313 WORD=`echo $1 | cut -d '-' -f 3`
315 if [[ $OS == linux && $ARCH == ppc ]] ; then WORD=32; fi
316 if [[ $OS == linux && $ARCH == arm ]] ; then WORD=32; fi
317 if [[ $OS == macosx && $ARCH == ppc ]] ; then WORD=32; fi
318 if [[ $OS == wince && $ARCH == arm ]] ; then WORD=32; fi
320 $ECHO "OS=$OS"
321 $ECHO "ARCH=$ARCH"
322 $ECHO "WORD=$WORD"
325 find_build_info() {
326 find_os
327 find_architecture
328 find_word_size
329 set_factor_binary
330 set_factor_library
331 set_factor_image
332 set_build_info
333 set_downloader
334 set_gcc
335 set_make
336 echo_build_info
339 invoke_git() {
340 git $*
341 check_ret git
344 git_clone() {
345 echo "Downloading the git repository from factorcode.org..."
346 invoke_git clone $GIT_URL
349 git_pull_factorcode() {
350 echo "Updating the git repository from factorcode.org..."
351 invoke_git pull $GIT_URL master
354 cd_factor() {
355 cd factor
356 check_ret cd
359 set_copy() {
360 case $OS in
361 winnt) COPY=cp;;
362 *) COPY=cp;;
363 esac
366 set_delete() {
367 case $OS in
368 winnt) DELETE=rm;;
369 *) DELETE=rm;;
370 esac
373 backup_factor() {
374 $ECHO "Backing up factor..."
375 $COPY $FACTOR_BINARY $FACTOR_BINARY.bak
376 $COPY $FACTOR_LIBRARY $FACTOR_LIBRARY.bak
377 $COPY $BOOT_IMAGE $BOOT_IMAGE.bak
378 $COPY $FACTOR_IMAGE $FACTOR_IMAGE.bak
379 $ECHO "Done with backup."
382 check_makefile_exists() {
383 if [[ ! -e "Makefile" ]] ; then
384 echo ""
385 echo "***Makefile not found***"
386 echo "You are likely in the wrong directory."
387 echo "Run this script from your factor directory:"
388 echo " ./build-support/factor.sh"
389 exit 6
393 invoke_make() {
394 check_makefile_exists
395 $MAKE $MAKE_OPTS $*
396 check_ret $MAKE
399 make_clean() {
400 invoke_make clean
403 make_factor() {
404 invoke_make NO_UI=$NO_UI $MAKE_TARGET -j5
407 update_boot_images() {
408 echo "Deleting old images..."
409 $DELETE checksums.txt* > /dev/null 2>&1
410 # delete boot images with one or two characters after the dot
411 $DELETE $BOOT_IMAGE.{?,??} > /dev/null 2>&1
412 $DELETE temp/staging.*.image > /dev/null 2>&1
413 if [[ -f $BOOT_IMAGE ]] ; then
414 get_url http://factorcode.org/images/latest/checksums.txt
415 factorcode_md5=`cat checksums.txt|grep $BOOT_IMAGE|cut -f2 -d' '`;
416 set_md5sum
417 case $OS in
418 netbsd) disk_md5=`md5 $BOOT_IMAGE | cut -f4 -d' '`;;
419 *) disk_md5=`$MD5SUM $BOOT_IMAGE|cut -f1 -d' '` ;;
420 esac
421 echo "Factorcode md5: $factorcode_md5";
422 echo "Disk md5: $disk_md5";
423 if [[ "$factorcode_md5" == "$disk_md5" ]] ; then
424 echo "Your disk boot image matches the one on factorcode.org."
425 else
426 $DELETE $BOOT_IMAGE > /dev/null 2>&1
427 get_boot_image;
429 else
430 get_boot_image
434 get_boot_image() {
435 echo "Downloading boot image $BOOT_IMAGE."
436 get_url http://factorcode.org/images/latest/$BOOT_IMAGE
439 get_url() {
440 if [[ $DOWNLOADER -eq "" ]] ; then
441 set_downloader;
443 echo $DOWNLOADER $1 ;
444 $DOWNLOADER $1
445 check_ret $DOWNLOADER
448 maybe_download_dlls() {
449 if [[ $OS == winnt ]] ; then
450 get_url http://factorcode.org/dlls/freetype6.dll
451 get_url http://factorcode.org/dlls/zlib1.dll
452 get_url http://factorcode.org/dlls/OpenAL32.dll
453 get_url http://factorcode.org/dlls/alut.dll
454 get_url http://factorcode.org/dlls/comerr32.dll
455 get_url http://factorcode.org/dlls/gssapi32.dll
456 get_url http://factorcode.org/dlls/iconv.dll
457 get_url http://factorcode.org/dlls/k5sprt32.dll
458 get_url http://factorcode.org/dlls/krb5_32.dll
459 get_url http://factorcode.org/dlls/libcairo-2.dll
460 get_url http://factorcode.org/dlls/libeay32.dll
461 get_url http://factorcode.org/dlls/libiconv2.dll
462 get_url http://factorcode.org/dlls/libintl3.dll
463 get_url http://factorcode.org/dlls/libpq.dll
464 get_url http://factorcode.org/dlls/libxml2.dll
465 get_url http://factorcode.org/dlls/libxslt.dll
466 get_url http://factorcode.org/dlls/msvcr71.dll
467 get_url http://factorcode.org/dlls/ogg.dll
468 get_url http://factorcode.org/dlls/pgaevent.dll
469 get_url http://factorcode.org/dlls/sqlite3.dll
470 get_url http://factorcode.org/dlls/ssleay32.dll
471 get_url http://factorcode.org/dlls/theora.dll
472 get_url http://factorcode.org/dlls/vorbis.dll
473 chmod 777 *.dll
474 check_ret chmod
478 get_config_info() {
479 find_build_info
480 check_installed_programs
481 check_libraries
484 bootstrap() {
485 ./$FACTOR_BINARY -i=$BOOT_IMAGE
488 install() {
489 check_factor_exists
490 get_config_info
491 git_clone
492 cd_factor
493 make_factor
494 get_boot_image
495 maybe_download_dlls
496 bootstrap
500 update() {
501 get_config_info
502 git_pull_factorcode
503 backup_factor
504 make_clean
505 make_factor
508 update_bootstrap() {
509 update_boot_images
510 bootstrap
513 refresh_image() {
514 ./$FACTOR_BINARY -script -e="USE: vocabs.loader USE: system refresh-all USE: memory save 0 exit"
515 check_ret factor
518 make_boot_image() {
519 ./$FACTOR_BINARY -script -e="\"$MAKE_IMAGE_TARGET\" USE: system USE: bootstrap.image make-image save 0 exit"
520 check_ret factor
524 install_build_system_apt() {
525 sudo apt-get --yes install libc6-dev libfreetype6-dev libx11-dev xorg-dev glutg3-dev wget git-core git-doc rlwrap gcc make
526 check_ret sudo
529 install_build_system_port() {
530 test_program_installed git
531 if [[ $? -ne 1 ]] ; then
532 ensure_program_installed yes
533 echo "git not found."
534 echo "This script requires either git-core or port."
535 echo "If it fails, install git-core or port and try again."
536 ensure_program_installed port
537 echo "Installing git-core with port...this will take awhile."
538 yes | sudo port install git-core
542 usage() {
543 echo "usage: $0 install|install-x11|install-macosx|self-update|quick-update|update|bootstrap|dlls|net-bootstrap|make-target|report [optional-target]"
544 echo "If you are behind a firewall, invoke as:"
545 echo "env GIT_PROTOCOL=http $0 <command>"
546 echo ""
547 echo "Example for overriding the default target:"
548 echo " $0 update macosx-x86-32"
551 MAKE_TARGET=unknown
553 # -n is nonzero length, -z is zero length
554 if [[ -n "$2" ]] ; then
555 parse_build_info $2
558 set_copy
559 set_delete
561 case "$1" in
562 install) install ;;
563 install-x11) install_build_system_apt; install ;;
564 install-macosx) install_build_system_port; install ;;
565 self-update) update; make_boot_image; bootstrap;;
566 quick-update) update; refresh_image ;;
567 update) update; update_bootstrap ;;
568 bootstrap) get_config_info; bootstrap ;;
569 report) find_build_info ;;
570 dlls) get_config_info; maybe_download_dlls;;
571 net-bootstrap) get_config_info; update_boot_images; bootstrap ;;
572 make-target) ECHO=false; find_build_info; echo $MAKE_TARGET ;;
573 *) usage ;;
574 esac