changed: split overly long SRCS file lines, and sort them
[xbmc:xbmc-antiquated.git] / build.sh
1 #!/bin/bash
2
3 error() {
4   RET=$?
5   if [[ $RET != 0 ]]
6   then
7     echo
8     echo -e "\n FAILED! Exiting. ($RET)"
9     LANG="${OLDLANG}"
10     exit
11   fi
12 }
13
14 usage() {
15   echo " build.sh by default checks that your source is up-to-date, updates it"
16   echo "  if not, compile, and create a working build of XBMC in ./BUILD."
17   echo "  userdata and scripts dirs as well as 3rd party skins will be backed"
18   echo "  up if existing."
19   echo " Usage: build.sh [OPTIONS]"
20   echo "  OPTIONS:"
21   echo "   --help [-h]                      : Display this text."
22   echo "   DEST=<build-dest>                : Path to install XBMC to"
23   echo "   NOUPDATE                         : Don't update source."
24   echo "   NOCOMPILE                        : Don't compile."
25   echo "   NOCLEAN                          : Don't run \"make clean\" first."
26   echo "   NOCOPY                           : Don't create XBMC file structure."
27   echo "   NODEBUG                          : Don't create debugging info, strip binary."
28   echo "   CONFIRM                          : Don't ask about anything"
29 #  echo "   SHOWMAKE                         : Don't suppress make output"
30 ## SHOWMAKE requires changes to Makefile.in
31   echo "   NOCONFIG                         : Don't automatically run configure"
32   echo "   NOCHANGELOG                      : Don't create Changelog.txt"
33   echo "   CONFIGOPT=<config-option>        : Option to pass to configure."
34   echo "                                      One option per CONFIGOPT=,"
35   echo "                                      can pass more than one"
36   echo "   WEB=<path/to/web_int.rar>        : Web interface to use."
37   echo "                                      Default = PM3"
38   echo "   VERBOSE                          : Print way too much stuff than to"
39   echo "                                      be useful in most cases."
40   echo " These options can be defaulted in ~/.xbmc-build-settings."
41   echo " Just make a white space separated list on the first line."
42   exit
43 }
44
45 view_log() {
46   PROMPT=""
47   while [[ $PROMPT != "y" && $PROMPT != "n" ]]
48   do
49     printf "\r View compile log? (y/n) :  \b"
50     read -n 1 PROMPT
51   done
52   echo
53   if [[ $PROMPT = "y" ]]
54   then
55     less "${SOURCEDIR}/compile.log"
56   fi
57   exit
58 }
59
60 parse_args() {
61   for I in "$@"
62   do
63     OPT=${I%=*}
64     PAR=${I#*=}
65     case $OPT in
66       --help|-h)
67         usage
68         ;;
69       DEST)
70           BUILDDIR=$PAR
71         ;;
72       NOUPDATE)
73         (( UPDATE=0 ))
74         ;;
75       NOCOMPILE)
76         (( COMPILE=0 ))
77         ;;
78       NOCLEAN)
79         (( CLEAN=0 ))
80         ;;
81       NOCOPY)
82         (( COPY=0 ))
83         ;;
84       QUICKCOPY)
85         (( QUICKCOPY=1 ))
86         ;;
87       NOCHANGELOG)
88         (( CHANGELOG=0 ))
89         ;;
90       CONFIRM)
91         (( CONFIRM=1 ))
92         ;;
93       SHOWMAKE)
94         (( SHOW_MAKE=1 ))
95         ;;
96       CONFIGOPT)
97         (( CONFIGURE=1 ))
98         CONFIGOPTS="$CONFIGOPTS $PAR"
99         ;;
100       NODEBUG)
101         (( DEBUG=0 ))
102               CONFIGOPTS="$CONFIGOPTS --disable-debug"
103         ;;
104       WEB)
105         if [[ -e $PAR ]]
106         then
107           WEB=$PAR
108         else
109           echo "  $PAR doesn't exist!"
110           exit
111         fi
112         ;;
113       NOCONFIG)
114         CONFIGURE=0
115         ;;
116       VERBOSE)
117         VERBOSE=1
118         ;;
119       *)
120         echo " Invalid option $OPT"
121         usage
122         ;;
123     esac
124   done
125 }
126
127 update() {
128   echo " Local source revision : $LOCAL_REVISION"
129   echo -n " Repository revision : Checking..."
130   HEAD_REVISION=$(expr "$(svn info "$SOURCEDIR" -r HEAD 2>&1 | grep "Revision")" : '.*: \(.*\)')
131   printf "\r Repository revision : %-11.11s\n" $HEAD_REVISION
132   
133   if [[ $LOCAL_REVISION = "" || $HEAD_REVISION = "" ]]
134   then
135     echo " Couldn't determine if source is upto date!"
136     echo " This is probably due to network errors, skipping update."
137     PROMPT=""
138     while [[ $PROMPT != "y" && $PROMPT != "n" ]]
139     do
140       printf "\r Continue? (y/n) :  \b"
141       read -n 1 PROMPT
142     done
143     echo
144     if [[ $PROMPT == "n" ]]
145     then
146       exit
147     fi
148   else
149     if (( $LOCAL_REVISION < $HEAD_REVISION ))
150     then
151       if (( CONFIRM ))
152       then
153         PROMPT="y"
154       else
155         PROMPT=""
156       fi
157       echo " Your source is outdated."
158       while [[ $PROMPT != "y" && $PROMPT != "n" ]]
159       do
160         printf "\r Update? (y/n) :  \b"
161         read -n 1 PROMPT
162       done
163       if ! (( CONFIRM ))
164       then
165         echo
166       fi
167       if [[ $PROMPT == "y" ]]
168       then
169         echo " Updating source code."
170         # a bit of a sorry hack to account for the odd chance that
171         # a commit occurs while we're waiting for user input 
172         HEAD_REVISION=$(expr "$(svn info "$SOURCEDIR" -r HEAD 2>&1 | grep "Revision")" : '.*: \(.*\)')
173         svn up "$SOURCEDIR" 2>&1 | tee "$SOURCEDIR/.build.sh.svn"
174         grep "$HEAD_REVISION" "$SOURCEDIR/.build.sh.svn" &> /dev/null
175         error
176         LOCAL_REVISION="$HEADREVISION"
177       fi
178     else
179       echo " Your source is up to date."
180       UPDATE=0
181     fi
182   fi
183 }
184
185 config() {
186   if [[ $CONFIGOPTS = "" ]]
187   then
188     echo " Configuring build."
189   else
190     echo " Configuring build with $CONFIGOPTS."
191   fi
192   DIR=$PWD
193   cd "$SOURCEDIR"
194   ./configure $CONFIGOPTS
195   error
196   cd "$DIR"
197 }
198
199 compile() {
200   if (( COMPILE ))
201   then
202     if (( CLEAN ))
203     then
204       echo " Cleaning source directory."
205       if (( VERBOSE ))
206       then
207         make -C "${SOURCEDIR}" distclean
208       else
209         make -C "${SOURCEDIR}" distclean &> /dev/null
210       fi
211     else
212       echo " Skipping source directory cleaning."
213     fi
214   fi
215   if (( CONFIGURE )) 
216   then
217     config
218   fi
219   if (( COMPILE ))
220   then
221     if ! [[ -e "$SOURCEDIR/Makefile" ]]
222     then
223       config
224     fi
225     echo " Compiling source."
226     if [[ $MAKEFLAGS = "" ]]
227     then
228       CORES=$(grep "^processor" /proc/cpuinfo | wc -l)
229       echo "  Detected ${CORES} procs/cores, using -j${CORES}"
230       MAKEFLAGS=-j${CORES}
231     else
232       echo "Using MAKEFLAGS=${MAKEFLAGS}"
233     fi
234     if (( $SHOW_MAKE ))
235     then
236       make ${MAKEFLAGS} -C "${SOURCEDIR}" 2>&1 | tee "${SOURCEDIR}/compile.log"
237     else
238       make ${MAKEFLAGS} -C "${SOURCEDIR}" 2>&1 | tee "${SOURCEDIR}/compile.log" | grep -E "Linking|Building|Compiling"
239     fi
240    
241     if [[ ${PIPESTATUS[0]} != "0" ]]
242     then
243       echo
244       echo " Errors have occurred!"
245       view_log
246     fi
247   fi
248 }
249
250 copy() {
251   BACKUPDIR="${BUILDDIR}.bak"
252   if [[ -e "$BUILDDIR" ]]
253   then
254     #backup
255     echo " Backing up old ${BUILDDIR} to ${BACKUPDIR}."
256     if [[ -e "$BACKUPDIR" ]] 
257     then
258       echo "  Removing old $BACKUPDIR first."
259       if (( VERBOSE ))
260       then
261         rm -vrf "$BACKUPDIR"
262       else
263         rm -rf "$BACKUPDIR" &> /dev/null
264       fi
265     fi
266     if (( VERBOSE ))
267     then
268       mv -v "$BUILDDIR" "${BACKUPDIR}"
269     else
270       mv "$BUILDDIR" "${BACKUPDIR}" &> /dev/null
271     fi
272     if [[ $? != 0 ]]
273     then
274       echo " You don't have permission to move"
275       echo "  the old $BUILDDIR. Please fix this"
276       echo "  and rerun with options NOUPDATE"
277       echo "  and NOCOMPILE"
278       exit
279     fi
280   fi
281
282   echo " Creating ${BUILDDIR}."
283   if (( VERBOSE ))
284   then
285     mkdir -v "$BUILDDIR"
286   else
287     mkdir "$BUILDDIR" &> /dev/null
288   fi
289   error
290
291   for I in credits language media screensavers scripts skin sounds system userdata visualisations web xbmc-xrandr xbmc.bin README.linux copying.txt Changelog.txt LICENSE.GPL
292   do
293     printf "\r Copying %-16.16s" $I 
294     if [[ "$I" == "skin" ]]
295     then
296       if (( VERBOSE ))
297       then
298         mkdir -vp "${BUILDDIR}/skin/Project Mayhem III"
299       else
300         mkdir -p "${BUILDDIR}/skin/Project Mayhem III" &> /dev/null
301       fi
302       for J in $(ls "${SOURCEDIR}/skin/Project Mayhem III")
303       do
304         if [[ "$J" == "media" ]]
305         then
306           if (( VERBOSE )) 
307           then
308             mkdir -v "${BUILDDIR}/skin/Project Mayhem III/media"
309             tools/XBMCTex/XBMCTex -input "\"skin/Project Mayhem III/media/\"" -output "\"${BUILDDIR}/skin/Project Mayhem III/media/Textures.xpr\""
310           else
311             mkdir "${BUILDDIR}/skin/Project Mayhem III/media" &> /dev/null
312             tools/XBMCTex/XBMCTex -input "\"skin/Project Mayhem III/media/\"" -output "\"${BUILDDIR}/skin/Project Mayhem III/media/Textures.xpr\"" &> /dev/null
313           fi
314         else
315           if (( VERBOSE ))
316           then
317             cp -vrf "${SOURCEDIR}/skin/Project Mayhem III/${J}" "${BUILDDIR}/skin/Project Mayhem III"
318           else
319             cp -rf "${SOURCEDIR}/skin/Project Mayhem III/${J}" "${BUILDDIR}/skin/Project Mayhem III" &> /dev/null
320           fi
321         fi
322       done
323     elif [[ "$I" == "userdata" ]]
324     then
325       if [[ -e "$BACKUPDIR/userdata" ]]
326       then
327         if (( VERBOSE ))
328         then 
329           cp -vrf "$BACKUPDIR/userdata" "$BUILDDIR"
330         else
331           cp -rf "$BACKUPDIR/userdata" "$BUILDDIR" &> /dev/null
332         fi
333       else
334         if (( VERBOSE ))
335         then 
336           cp -vrf "${SOURCEDIR}/${I}" "$BUILDDIR"
337         else
338           cp -rf "${SOURCEDIR}/${I}" "$BUILDDIR" &> /dev/null
339         fi
340       fi
341     elif [[ "$I" == "web" ]]
342     then
343       UNZIP="$(which unzip)"
344       if ! [[ $UNZIP == "" ]]
345       then
346         if (( VERBOSE ))
347         then
348           mkdir -vp "$BUILDDIR/web"
349           "$UNZIP" "$WEB" -d "$BUILDDIR/web/"
350         else
351           mkdir -p "$BUILDDIR/web" &> /dev/null
352           "$UNZIP" -q "$WEB" -d "$BUILDDIR/web/"
353         fi
354       fi
355     elif [[ "$I" == "xbmc.bin" ]]
356     then
357       if [[ -e "${SOURCEDIR}/$I" ]]
358       then
359         if (( VERBOSE ))
360         then
361           mv -v "${SOURCEDIR}/${I}" "$BUILDDIR"
362         else
363           mv "${SOURCEDIR}/${I}" "$BUILDDIR" &> /dev/null
364         fi
365       elif [[ -e "${BACKUPDIR}/${I}" ]]
366       then
367         echo
368         echo " Couldn't find new binary, using old one from backup!"
369         if (( VERBOSE ))
370         then
371           cp -vf "${BACKUPDIR}/${I}" "${BUILDDIR}/${I}"
372         else
373           cp -f "${BACKUPDIR}/${I}" "${BUILDDIR}/${I}" &> /dev/null
374         fi
375       else 
376         ls "..." &> /dev/null  # force $? to be non-zero
377       fi
378     elif [[ "$I" == "Changelog.txt" ]]
379     then
380       if (( CHANGELOG ))
381       then
382         if (( VERBOSE ))
383         then
384           cp -vrf "${SOURCEDIR}/${I}" "$BUILDDIR"
385         else
386           cp -rf "${SOURCEDIR}/${I}" "$BUILDDIR" &> /dev/null
387         fi
388       fi
389     else
390       if (( VERBOSE ))
391       then
392         cp -vrf "${SOURCEDIR}/${I}" "$BUILDDIR"
393       else
394         cp -rf "${SOURCEDIR}/${I}" "$BUILDDIR" &> /dev/null
395       fi
396     fi
397     error
398   done
399   
400   if ! (( DEBUG ))
401   then
402     echo " Stripping binary."
403     strip "$BUILDDIR/xbmc.bin"
404   fi
405
406   printf "\r Copying %-16.16s\n" "complete!" 
407   if [[ $UNZIP == "" ]]
408   then
409     echo "  Couldn't find \"unzip\" please install to use web interface"
410   fi
411 }
412
413 cleanup() {
414   if [ -d $1 ]
415   then
416     printf "\r Cleaning %-60.60s" $1
417     if (( VERBOSE ))
418     then
419       rm -vrf $I/src $I/.svn $I/*.DLL $I/*.dll $I/*osx.so
420     else
421       rm -rf $I/src $I/.svn $I/*.DLL $I/*.dll $I/*osx.so &> /dev/null
422     fi
423     for I in $1/* #$(ls -d $1/* 2> /dev/null)
424     do
425       cleanup "${I}"
426     done
427   fi
428 }
429
430 merge() {
431   if [[ -d "$BACKUPDIR/$1" ]]
432   then
433     if [[ -e "$BUILDDIR/$1" ]]
434     then
435       for I in $(ls -d $BACKUPDIR/$1/* 2> /dev/null)
436       do
437         I=${I#"${BACKUPDIR}/"}
438         merge "$I"
439       done
440     else
441       echo "  Merged ${1#"${BACKUPDIR}/"}"
442       if (( VERBOSE ))
443       then
444         cp -vrf "$BACKUPDIR/$1" "$BUILDDIR/$1"
445       else
446         cp -rf "$BACKUPDIR/$1" "$BUILDDIR/$1" &> /dev/null
447       fi
448     fi
449   else
450     if ! [[ -e "$BUILDDIR/$1" ]]
451     then
452       echo "  Merged ${1#"${BACKUPDIR}/"}"
453       if (( VERBOSE ))
454       then
455         cp -vf "$BACKUPDIR/$1" "$BUILDDIR/$1"
456       else
457         cp -f "$BACKUPDIR/$1" "$BUILDDIR/$1" &> /dev/null
458       fi
459     fi
460   fi
461 }
462
463 fix() {
464   echo " Fixing some case-sensitivity issues."
465
466   echo "  Renaming arial.ttf to Arial.ttf."
467   mv  "${BUILDDIR}/media/Fonts/arial.ttf" "${BUILDDIR}/media/Fonts/Arial.ttf"
468
469   echo "  Renaming Splash.png to splash.png."
470   mv "${BUILDDIR}/media/Splash.png" "${BUILDDIR}/media/splash.png"
471
472   if [[ -e "$BACKUPDIR" ]]
473   then
474     echo " Merging 3rd party files from backup."
475     for I in $(ls $BACKUPDIR) #screensavers scripts skin sounds system visualisations
476     do
477       IFS=$'\t\n'
478       merge "$I"
479       IFS=$_IFS
480     done
481     echo " Merge complete!"
482   fi
483   _IFS=$IFS
484   IFS=$'\t\n'
485   cleanup "$BUILDDIR"
486   printf "\r Cleaning %-60.60s\n" "complete!"
487   IFS=$_IFS
488 }
489
490 SOURCEDIR=${0%/*}
491 BACKUPDIR="$SOURCEDIR/.backup"
492 # Don't touch these. Make a ~/.xbmc-build-settings instead.
493 # See ./build.sh --help
494 BUILDDIR="./BUILD"
495 WEB=""
496 CONFIGOPTS="-C"
497 OLDLANG="${LANG}"
498 LANG=""
499 (( UPDATE=1 ))
500 (( COMPILE=1 ))
501 (( CLEAN=1 ))
502 (( COPY=1 ))
503 (( QUICKCOPY=0 ))
504 (( CHANGELOG=1 ))
505 (( CONFIRM=0 ))
506 (( SHOW_MAKE=1 ))
507 (( CONFIGURE=1 ))
508 (( DEBUG=1 ))
509 (( VERBOSE=0 ))
510
511 echo " ******************** NOTICE **********************"
512 echo " This script is DEPRECATED and its usage no longer"
513 echo " supported. See README.linux for the recommended"
514 echo " build instructions. If you insist on continuing"
515 echo " use of build.sh, you do so at your own risk."
516 echo " DO NOT seek assistance with this script or any"
517 echo " build of XBMC that was created using it. We will"
518 echo " only repeat this message."
519 echo " *************************************************"
520 echo " Press ctrl+c (^c) now to save yourself much grief,"
521 echo " or any other key to continue being a fool"
522 read -n1
523
524 if ! [[ -e "$SOURCEDIR/.firstrun" ]]
525 then
526   touch "$SOURCEDIR/.firstrun"
527   echo
528   echo "*** FIRST RUN DETECTED. YOU'D BETTER READ THIS CAREFULLY! ***"
529   echo
530   usage
531 fi
532
533 echo -ne "\e]0;Building XBMC\a"
534
535 if (( VERBOSE ))
536 then
537   touch "/root/.test"
538 else
539   touch "/root/.test" &> /dev/null
540 fi
541
542 if ! (( $? )) 
543 then
544   rm "/root/.test" &> /dev/null
545   PROMPT=""
546   echo " There is really no reason to run this as root or with sudo."
547   while [[ $PROMPT != "y" && $PROMPT != "n" ]]
548   do
549     printf "\r Run anyway? (y/n) :  \b"
550     read -n 1 PROMPT
551   done
552   echo
553   if [[ $PROMPT = "n" ]]
554   then
555     exit
556   fi
557 fi
558
559 if [[ -e ~/.xbmc-build-settings ]]
560 then
561   SETTINGS=$(head -n1 ~/.xbmc-build-settings)
562   parse_args $SETTINGS
563 fi
564
565 parse_args "$@"
566
567 if [[ "${BUILDDIR:(-1)}" = "/" ]]
568 then
569   BUILDDIR="${BUILDDIR%/}"
570 fi
571
572 LOCAL_REVISION=$(expr "$(svn info "$SOURCEDIR" 2>&1 | grep "Revision")" : '.*: \(.*\)')
573
574 if [[ -e "$BUILDDIR" ]]
575 then
576   if ! [[ -dwr "$BUILDDIR" ]]
577   then
578     echo " $BUILDDIR exists, but you can't modify it or it is a file."
579     exit
580   fi
581 else
582   if (( VERBOSE ))
583   then
584     mkdir -vp "$BUILDDIR"
585   else
586     mkdir -p "$BUILDDIR" &> /dev/null
587   fi
588   if [[ $? != 0 ]]
589   then
590     echo " You don't have permission to create $BUILDDIR"
591     exit
592   fi
593   if (( VERBOSE ))
594   then
595     rm -vrf "$BUILDDIR"
596   else
597     rm -rf "$BUILDDIR" &> /dev/null
598   fi
599 fi
600
601 if [[ $WEB == "" ]]
602 then
603   WEB="$SOURCEDIR/web/Project_Mayhem_III_webserver_v1.0.zip"
604 fi
605
606 if (( UPDATE ))
607 then
608   update
609 else
610   echo " Skipping update."
611 fi
612
613 if [[ -e "$SOURCEDIR/.build.sh.svn" ]]
614 then
615   CMD="$0 $*"
616   grep -E "configure$|\.in$" "$SOURCEDIR/.build.sh.svn" &> /dev/null
617   if ! (($?))
618   then
619     CONFIGURE=1
620   fi
621   if ! (( $CONFIRM ))
622   then
623     grep -E "README.linux$" "$SOURCEDIR/.build.sh.svn" &> /dev/null
624     if ! (($?))
625     then
626       sed -i "s/README.linux//g" "$SOURCEDIR/.build.sh.svn" #&> /dev/null
627       echo " **************************************************"
628       echo "  Detected changes to README.linux"
629       echo "  You will now be forced to read it :)"
630       echo "  Use pgup, pgdn or space to navigate"
631       echo "  PAY ATTENTION to the aptget line for your distro!"
632       echo " **************************************************"
633       echo " Press any key to continue..."
634       read -n1
635       less -e "$SOURCEDIR/README.linux"
636       
637       PROMPT=""
638       while [[ $PROMPT != "y" && $PROMPT != "n" ]]
639       do
640         printf "\r Continue? (y/n) :  \b"
641         read -n 1 PROMPT
642       done
643       
644       echo
645
646       if [[ $PROMPT == "n" ]]
647       then
648         exit
649       fi
650     fi
651   fi
652   grep -E "build.sh$" "$SOURCEDIR/.build.sh.svn" &> /dev/null
653   if ! (( $? ))
654   then
655     CMD="$CMD NOUPDATE"
656     sed -i "s/build.sh//g" "$SOURCEDIR/.build.sh.svn" #&> /dev/null
657     echo " Detected new version of build.sh"
658     echo " Rerunning with \"$CMD\""
659     $CMD
660     exit
661   fi
662   rm -f "$SOURCEDIR/.build.sh.svn" &> /dev/null
663 fi
664
665 if (( COMPILE ))
666 then
667   compile
668 else
669   echo " Skipping compile."
670 fi
671
672 if (( (UPDATE || COMPILE || COPY) && CHANGELOG ))
673 then
674   echo " Generating Changelog.txt"
675   "$SOURCEDIR/tools/Changelog/Changelog.py" -r $LOCAL_REVISION -d "$SOURCEDIR"
676 fi
677
678 if (( COPY ))
679 then
680   if (( QUICKCOPY ))
681   then
682     if [[ -e "${SOURCEDIR}/xbmc.bin" ]]
683     then
684       if (( VERBOSE ))
685       then
686         mv -v "${SOURCEDIR}/xbmc.bin" "$BUILDDIR"
687       else
688         mv "${SOURCEDIR}/xbmc.bin" "$BUILDDIR" &> /dev/null
689       fi
690     fi
691   else
692     copy
693     fix
694   fi
695 else
696   echo " Skipping XBMC file structure creation."
697 fi
698
699 LANG="${OLDLANG}"
700 echo " All done!"
701
702 if (( COMPILE && !CONFIRM))
703 then
704   view_log
705 fi