A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1#!/bin/bash
2
3# Abort execution as soon as an error is encountered
4# That way the script do not let the user think the process completed correctly
5# and leave the opportunity to fix the problem and restart compilation where
6# it stopped
7set -e
8
9system=`uname -s`
10
11# MacOS is perpetually special
12if [ "$system" == "Darwin" ]; then
13 parallel=`sysctl -n hw.physicalcpu`
14 READLINK=greadlink
15 TMP="$TMPDIR"
16 SED=gsed
17 PATH="$HOMEBREW_PREFIX/opt/gnu-sed/libexec/gnubin:${PATH}"
18else
19 READLINK=readlink
20 parallel=`nproc`
21 TMP=/tmp
22 SED=sed
23fi
24
25# this is where this script will store downloaded files and check for already
26# downloaded files
27dlwhere="${RBDEV_DOWNLOAD:-$TMP/rbdev-dl}"
28
29# will append the target string to the prefix dir mentioned here
30# Note that the user running this script must be able to do make install in
31# this given prefix directory. Also make sure that this given root dir
32# exists.
33prefix="${RBDEV_PREFIX:-/usr/local}"
34
35# This directory is used to extract all files and to build everything in. It
36# must not exist before this script is invoked (as a security measure).
37builddir="${RBDEV_BUILD:-$TMP/rbdev-build}"
38
39# This script needs to use GNU Make. On Linux systems, GNU Make is invoked
40# by running the "make" command, on most BSD systems, GNU Make is invoked
41# by running the "gmake" command. Set the "make" variable accordingly.
42if [ -f "`which gmake 2>/dev/null`" ]; then
43 make="gmake"
44else
45 make="make"
46fi
47
48# record version
49makever=`$make -v |$SED -n '1p' | $SED -e 's/.* \([0-9]*\)\.\([0-9]*\).*/\1\2/'`
50
51# This is the absolute path to where the script resides.
52rockboxdevdir="$( $READLINK -f "$( dirname "${BASH_SOURCE[0]}" )" )"
53patch_dir="$rockboxdevdir/toolchain-patches"
54
55if [ $parallel -gt 1 ] ; then
56 make_parallel=-j$parallel
57fi
58
59if [ -z $GNU_MIRROR ] ; then
60 GNU_MIRROR=http://mirrors.kernel.org/gnu
61fi
62
63if [ -z $LINUX_MIRROR ] ; then
64 LINUX_MIRROR=http://www.kernel.org/pub/linux
65fi
66
67# These are the tools this script requires and depends upon.
68reqtools="gcc g++ xz bzip2 gzip $make patch makeinfo automake libtool autoconf flex bison"
69
70##############################################################################
71# Functions:
72
73findtool(){
74 file="$1"
75
76 IFS=":"
77 for path in $PATH
78 do
79 # echo "Checks for $file in $path" >&2
80 if test -f "$path/$file"; then
81 echo "$path/$file"
82 return
83 fi
84 done
85}
86
87findlib (){
88 lib="$1"
89 # on error, gcc will spit out "cannot find -lxxxx", but it may not be in
90 # english so grep for -lxxxx
91 if ! gcc -l$lib 2>&1 | grep -q -- "-l$lib"; then
92 echo "ok"
93 return
94 fi
95}
96
97# check if all the libraries in argument are installed, exit with error if not
98checklib() {
99 for t in "$@"; do
100 lib=`findlib $t`
101 if test -z "$lib"; then
102 echo "ROCKBOXDEV: library \"$t\" is required for this script to work."
103 missingtools="yes"
104 fi
105 done
106 if [ -n "$missingtools" ]; then
107 echo "ROCKBOXDEV: Please install the missing libraries and re-run the script."
108 exit 1
109 fi
110}
111
112input() {
113 read response
114 echo $response
115}
116
117# compare two versions, return 1 if first version is strictly before the second
118# version_lt ver1 ver2
119version_lt() {
120 # use sort with natural version sorting
121 ltver=`printf "$1\n$2" | sort -V | head -n 1`
122 [ "$1" = "$ltver" ] && true || false
123}
124
125# Download a file from a server (unless it already exists locally in $dlwhere).
126# The output file name is always $dlwhere/$1, and the function will try URLs
127# one after the other
128# $1 file
129# $2 server file name
130# $2,$3,... URL root list
131getfile_ex() {
132 out_file="$dlwhere/$1"
133 srv_file="$2"
134 if test -f $out_file; then
135 echo "ROCKBOXDEV: Skipping download of $1: File already exists"
136 return
137 fi
138 # find tool (curl or wget) and build download command
139 tool=`findtool curl`
140 if test -z "$tool"; then
141 tool=`findtool wget`
142 if test -n "$tool"; then
143 # wget download
144 echo "ROCKBOXDEV: Downloading $1 using wget"
145 tool="$tool -T 60 -O "
146 else
147 echo "ROCKBOXDEV: No downloader tool found!"
148 echo "ROCKBOXDEV: Please install curl or wget and re-run the script"
149 exit
150 fi
151 else
152 # curl download
153 echo "ROCKBOXDEV: Downloading $1 using curl"
154 tool="$tool -fLo "
155 fi
156
157 # shift arguments so that $@ is the list of URLs
158 shift
159 shift
160 for url in "$@"; do
161 echo "ROCKBOXDEV: try $url/$srv_file"
162 if $tool "$out_file" "$url/$srv_file"; then
163 return
164 fi
165 done
166
167 echo "ROCKBOXDEV: couldn't download the file!"
168 echo "ROCKBOXDEV: check your internet connection"
169 exit
170}
171
172#$1 file
173#$2 URL"root
174# Output file name is the same as the server file name ($1)
175# Does not download the file if it already exists locally in $dlwhere/
176getfile() {
177 getfile_ex "$1" "$1" "$2"
178}
179
180# wrapper around getfile to abstract url
181# getttool tool version
182# the file is always downloaded to "$dlwhere/$toolname-$version.tar.bz2"
183gettool() {
184 toolname="$1"
185 version="$2"
186 ext="tar.bz2"
187 file="$toolname-$version"
188 srv_file="$toolname-$version"
189 case $toolname in
190 gcc)
191 # before 4.7, the tarball was named gcc-core
192 if version_lt "$version" "4.7"; then
193 srv_file="gcc-core-$version"
194 fi
195 url="$GNU_MIRROR/gcc/gcc-$version"
196 if ! version_lt "$version" "7.2"; then
197 ext="tar.xz"
198 fi
199 ;;
200
201 binutils)
202 url="$GNU_MIRROR/binutils"
203 if ! version_lt "$version" "2.28.1"; then
204 ext="tar.xz"
205 fi
206 ;;
207
208 glibc)
209 url="$GNU_MIRROR/glibc"
210 if ! version_lt "$version" "2.11"; then
211 ext="tar.xz"
212 fi
213 ;;
214
215 alsa-lib)
216 url="ftp://ftp.alsa-project.org/pub/lib"
217 ;;
218
219 libffi)
220 url="ftp://sourceware.org/pub/libffi"
221 ext="tar.gz"
222 ;;
223
224 glib)
225 url="https://ftp.gnome.org/pub/gnome/sources/glib/2.46"
226 ext="tar.xz"
227 ;;
228
229 zlib)
230 url="https://www.zlib.net/fossils"
231 ext="tar.gz"
232 ;;
233
234 dbus)
235 url="https://dbus.freedesktop.org/releases/dbus"
236 ext="tar.gz"
237 ;;
238
239 expat)
240 url="https://src.fedoraproject.org/repo/pkgs/expat/expat-2.1.0.tar.gz/dd7dab7a5fea97d2a6a43f511449b7cd"
241 ext="tar.gz"
242 ;;
243
244 linux)
245 # FIXME linux kernel server uses an overcomplicated architecture,
246 # especially for longterm kernels, so we need to lookup several
247 # places. This will need fixing for non-4-part 2.6 versions but it
248 # is written in a way that should make it easy
249 case "$version" in
250 2.6.*.*)
251 # 4-part versions -> remove last digit for longterm
252 longterm_ver="${version%.*}"
253 top_dir="v2.6"
254 ;;
255 3.*)
256 longterm_ver=""
257 top_dir="v3.x"
258 ;;
259 *)
260 echo "ROCKBOXDEV: I don't know how to handle this kernel version: $version"
261 exit
262 ;;
263 esac
264 base_url="http://www.kernel.org/pub/linux/kernel/$top_dir"
265 # we try several URLs, the 2.6 versions are a mess and need that
266 url="$base_url $base_url/longterm/v$longterm_ver $base_url/longterm"
267 ext="tar.gz"
268 ;;
269
270 *)
271 echo "ROCKBOXDEV: Bad toolname $toolname"
272 exit
273 ;;
274 esac
275 getfile_ex "$file.$ext" "$srv_file.$ext" $url
276}
277
278# extract file to the current directory
279# extract file
280extract() {
281 if [ -d "$1" ]; then
282 echo "ROCKBOXDEV: Skipping extraction of $1: already done"
283 return
284 fi
285 echo "ROCKBOXDEV: extracting $1"
286 if [ -f "$dlwhere/$1.tar.bz2" ]; then
287 tar xjf "$dlwhere/$1.tar.bz2"
288 elif [ -f "$dlwhere/$1.tar.gz" ]; then
289 tar xzf "$dlwhere/$1.tar.gz"
290 elif [ -f "$dlwhere/$1.tar.xz" ]; then
291 tar xJf "$dlwhere/$1.tar.xz"
292 else
293 echo "ROCKBOXDEV: unknown compression for $1"
294 exit
295 fi
296}
297
298# run a command, and a log command and output to a file (append)
299# exit on error
300# run_cmd logfile cmd...
301run_cmd() {
302 logfile="$1"
303 shift
304 echo "Running '$@'" >>$logfile
305 if ! $@ >> "$logfile" 2>&1; then
306 echo "ROCKBOXDEV: an error occured, please see $logfile"
307 exit 1
308 fi
309}
310
311# check if the following should be executed or not, depending on RBDEV_RESTART variable:
312# $1=tool
313# If RBDEV_RESTART is empty, always perform step, otherwise only perform is there
314# is an exact match. On the first match, RBDEV_RESTART is reset to "" so that next step
315# are executed
316check_restart() {
317 if [ "x$RBDEV_RESTART" = "x" ]; then
318 return 0
319 elif [ "$1" = "$RBDEV_RESTART" ]; then
320 RBDEV_RESTART=""
321 return 0
322 else
323 return 1
324 fi
325}
326
327# advanced tool building: create a build directory, run configure, run make
328# and run make install. It is possible to customize all steps or disable them
329# $1=tool
330# $2=version
331# $3=configure options, or "NO_CONFIGURE" to disable step
332# $4=make options, or "NO_MAKE" to disable step
333# $5=make install options (will be replaced by "install" if left empty)
334# By default, the restary step is the toolname, but it can be changed by setting
335# RESTART_STEP
336buildtool () {
337 tool="$1"
338 version="$2"
339 toolname="$tool-$version"
340 config_opt="$3"
341 make_opts="$4"
342 install_opts="$5"
343 logfile="$builddir/build-$toolname.log"
344
345 stepname=${RESTART_STEP:-$tool}
346 if ! check_restart "$stepname"; then
347 echo "ROCKBOXDEV: Skipping step '$stepname' as requested per RBDEV_RESTART"
348 return
349 fi
350 echo "ROCKBOXDEV: Starting step '$stepname'"
351
352 echo "ROCKBOXDEV: logging to $logfile"
353 rm -f "$logfile"
354
355 echo "ROCKBOXDEV: mkdir build-$toolname"
356 mkdir "build-$toolname"
357
358 cd build-$toolname
359
360 # in-tree/out-of-tree build
361 case "$tool" in
362 linux|alsa-lib)
363 # in-intree
364 echo "ROCKBOXDEV: copy $toolname for in-tree build"
365 # copy the source directory to the build directory
366 cp -r ../$toolname/* .
367 cfg_dir="."
368 ;;
369 *)
370 # out-of-tree
371 cfg_dir="../$toolname";
372 ;;
373 esac
374
375 if [ "$RESTART_STEP" == "gcc-stage1" ] ; then
376 CXXFLAGS="-std=gnu++03"
377 elif [ "$RESTART_STEP" == "gcc-stage2" ] ; then
378 CXXFLAGS="-std=gnu++11"
379 else
380 CXXFLAGS=""
381 fi
382
383 if [ "$tool" == "zlib" ]; then
384 echo "ROCKBOXDEV: $toolname/configure"
385 # NOTE glibc requires to be compiled with optimization
386 CFLAGS='-U_FORTIFY_SOURCE -fgnu89-inline -O2' run_cmd "$logfile" \
387 "$cfg_dir/configure" "--prefix=$prefix" \
388 $config_opt
389 elif [ "$config_opt" != "NO_CONFIGURE" ]; then
390 echo "ROCKBOXDEV: $toolname/configure"
391 cflags='-U_FORTIFY_SOURCE -fgnu89-inline -O2'
392 if [ "$tool" == "glibc" ]; then
393 cflags="$cflags -fcommon" # glibc < 2.30 needs -fcommon for gcc10+
394 elif [ "$tool" == "glib" ]; then
395 run_cmd "$logfile" $SED -i -e 's/m4_copy/m4_copy_force/g' "$cfg_dir/m4macros/glib-gettext.m4"
396 run_cmd "$logfile" autoreconf -fiv "$cfg_dir"
397 cflags="$cflags -Wno-format-nonliteral -Wno-format-overflow"
398 fi
399 # NOTE glibc requires to be compiled with optimization
400 CFLAGS="$cflags" CXXFLAGS="$CXXFLAGS" run_cmd "$logfile" \
401 "$cfg_dir/configure" "--prefix=$prefix" \
402 --disable-docs $config_opt
403 fi
404
405 if [ "$make_opts" != "NO_MAKE" ]; then
406 echo "ROCKBOXDEV: $toolname/make"
407 run_cmd "$logfile" $make $make_parallel $make_opts
408 fi
409
410 if [ "$install_opts" = "" ]; then
411 install_opts="install"
412 fi
413 echo "ROCKBOXDEV: $toolname/make (install)"
414 run_cmd "$logfile" $make $install_opts
415
416 cd ..
417
418 echo "ROCKBOXDEV: rm -rf build-$toolname $toolname"
419 rm -rf build-$toolname
420 if [ "$stepname" != "gcc-stage1" ] ; then
421 echo "ROCKBOXDEV: rm -rf $toolname"
422 rm -rf $toolname
423 fi
424}
425
426build() {
427 toolname="$1"
428 target="$2"
429 version="$3"
430 patch="$4"
431 configure_params="$5"
432 needs_libs="$6"
433 logfile="$builddir/build-$toolname.log"
434
435 stepname=${RESTART_STEP:-$toolname}
436 if ! check_restart "$stepname"; then
437 echo "ROCKBOXDEV: Skipping step '$stepname' as requested per RBDEV_RESTART"
438 return
439 fi
440 echo "ROCKBOXDEV: Starting step '$stepname'"
441
442 # GCC is special..
443 if [ "$toolname" == "gcc" ]; then
444 configure_params="--enable-languages=c --disable-libssp $configure_params"
445
446 # For Apple targets only
447 if [ "$system" == "Darwin" ] ; then
448 # gcc-libcpp17: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111632
449 patch="$patch apple_silicon.patch apple_silicon-zlib.patch gcc-libcpp17.patch"
450 EXTRA_CXXFLAGS="-fbracket-depth=512"
451 fi
452 fi
453
454 if [ "$toolname" == "binutils" ] && [ "$system" == "Darwin" ]; then
455 patch="$patch apple_silicon-zlib.patch"
456 fi
457
458 # create build directory
459 if test -d $builddir; then
460 if test ! -w $builddir; then
461 echo "ROCKBOXDEV: No write permission for $builddir"
462 exit
463 fi
464 else
465 mkdir -p $builddir
466 fi
467
468 # download source tarball
469 gettool "$toolname" "$version"
470 file="$toolname-$version"
471
472 cd $builddir
473
474 extract "$toolname-$version"
475
476 # do we have a patch?
477 for p in $patch; do
478 echo "ROCKBOXDEV: applying patch $p"
479
480 # apply the patch
481 (cd $builddir/$toolname-$version && patch -p1 < "$patch_dir/$p")
482
483 # check if the patch applied cleanly
484 if [ $? -gt 0 ]; then
485 echo "ROCKBOXDEV: failed to apply patch $p"
486 exit
487 fi
488 done
489
490 # kludge to avoid having to install GMP, MPFR, MPC and ISL
491 if test -n "$needs_libs"; then
492 cd "$toolname-$version"
493 if (echo $needs_libs | grep -q gmp && test ! -d gmp); then
494 echo "ROCKBOXDEV: Getting GMP"
495 getfile "gmp-6.1.2.tar.bz2" "$GNU_MIRROR/gmp"
496 tar xjf $dlwhere/gmp-6.1.2.tar.bz2
497 ln -s gmp-6.1.2 gmp
498 fi
499
500 if (echo $needs_libs | grep -q mpfr && test ! -d mpfr); then
501 echo "ROCKBOXDEV: Getting MPFR"
502 getfile "mpfr-4.1.1.tar.xz" "$GNU_MIRROR/mpfr"
503 tar xJf $dlwhere/mpfr-4.1.1.tar.xz
504 ln -s mpfr-4.1.1 mpfr
505 fi
506
507 if (echo $needs_libs | grep -q mpc && test ! -d mpc); then
508 echo "ROCKBOXDEV: Getting MPC"
509 getfile "mpc-1.2.1.tar.gz" "http://www.multiprecision.org/downloads"
510 tar xzf $dlwhere/mpc-1.2.1.tar.gz
511 ln -s mpc-1.2.1 mpc
512 fi
513
514 if (echo $needs_libs | grep -q isl && test ! -d isl); then
515 echo "ROCKBOXDEV: Getting ISL"
516 getfile "isl-0.18.tar.bz2" "https://gcc.gnu.org/pub/gcc/infrastructure"
517 tar xjf $dlwhere/isl-0.18.tar.bz2
518 ln -s isl-0.18 isl
519 fi
520 cd $builddir
521 fi
522
523 echo "ROCKBOXDEV: logging to $logfile"
524 rm -f "$logfile"
525
526 echo "ROCKBOXDEV: mkdir build-$toolname"
527 mkdir build-$toolname
528
529 cd build-$toolname
530
531 echo "ROCKBOXDEV: $toolname/configure"
532 CFLAGS='-U_FORTIFY_SOURCE -fgnu89-inline -fcommon -O2' CXXFLAGS="-std=gnu++03 $EXTRA_CXXFLAGS" run_cmd "$logfile" ../$toolname-$version/configure --target=$target --prefix=$prefix --disable-docs $configure_params
533
534 echo "ROCKBOXDEV: $toolname/make"
535 run_cmd "$logfile" $make $make_parallel
536
537 echo "ROCKBOXDEV: $toolname/make install"
538 run_cmd "$logfile" $make install
539
540 cd ..
541
542 echo "ROCKBOXDEV: rm -rf build-$toolname $toolname-$version"
543 rm -rf build-$toolname $toolname-$version
544}
545
546# build a cross compiler toolchain for linux
547build_linux_toolchain () {
548 target="$1"
549 binutils_ver="$2"
550 binutils_opts="$3"
551 binutils_patches="$4"
552 gcc_ver="$5"
553 gcc_opts="$6"
554 linux_ver="$7"
555 linux_patches="$8"
556 glibc_ver="$9"
557 glibc_opts="${10}"
558 glibc_patches="${11}"
559
560 # where to put the sysroot
561 sysroot="$prefix/$target/sysroot"
562 # extract arch from target
563 arch=${target%%-*}
564
565 # check libraries:
566 # contrary to other toolchains that rely on a hack to avoid installing
567 # gmp, mpc, and mpfr, we simply require that they are installed on
568 # the system this is not a huge requirement since virtually all systems
569 # these days provide dev packages for them
570 # FIXME: maybe add an option to download and install them automatically
571 checklib "mpc" "gmp" "mpfr"
572
573 # create build directory
574 if test -d $builddir; then
575 if test ! -w $builddir; then
576 echo "ROCKBOXDEV: No write permission for $builddir"
577 exit
578 fi
579 else
580 mkdir -p $builddir
581 fi
582
583 if [ "$makever" -gt 43 ] ; then
584 glibc_make_opts="--jobserver-style=pipe --shuffle=none"
585# MAKEFLAGS="--jobserver-style=pipe --shuffle=none"
586 fi
587
588 # download all tools
589 gettool "binutils" "$binutils_ver"
590 gettool "gcc" "$gcc_ver"
591 gettool "linux" "$linux_ver"
592 gettool "glibc" "$glibc_ver"
593
594 # extract them
595 cd $builddir
596 extract "binutils-$binutils_ver"
597 extract "gcc-$gcc_ver"
598 extract "linux-$linux_ver"
599 extract "glibc-$glibc_ver"
600
601 # do we have any patches?
602 for p in $binutils_patches; do
603 echo "ROCKBOXDEV: applying patch $p"
604 (cd $builddir/binutils-$binutils_ver ; patch -p1 < "$patch_dir/$p")
605
606 # check if the patch applied cleanly
607 if [ $? -gt 0 ]; then
608 echo "ROCKBOXDEV: failed to apply patch $p"
609 exit
610 fi
611 done
612 for p in $glibc_patches; do
613 echo "ROCKBOXDEV: applying patch $p"
614 (cd $builddir/glibc-$glibc_ver ; patch -p1 < "$patch_dir/$p")
615
616 # check if the patch applied cleanly
617 if [ $? -gt 0 ]; then
618 echo "ROCKBOXDEV: failed to apply patch $p"
619 exit
620 fi
621 done
622 for p in $linux_patches; do
623 echo "ROCKBOXDEV: applying patch $p"
624 (cd $builddir/linux-$linux_ver ; patch -p1 < "$patch_dir/$p")
625 # check if the patch applied cleanly
626 if [ $? -gt 0 ]; then
627 echo "ROCKBOXDEV: failed to apply patch $p"
628 exit
629 fi
630 done
631
632 # we make it possible to restart a build on error by using the RBDEV_RESTART
633 # variable, the format is RBDEV_RESTART="tool" where tool is the toolname at which
634 # to restart (binutils, gcc)
635
636 # install binutils, with support for sysroot
637 buildtool "binutils" "$binutils_ver" "$binutils_opts --target=$target --disable-werror \
638 --with-sysroot=$sysroot --disable-nls" "" ""
639 # build stage 1 compiler: disable headers, disable threading so that
640 # pthread headers are not included, pretend we use newlib so that libgcc
641 # doesn't get linked at the end
642 # NOTE there is some magic involved here
643 RESTART_STEP="gcc-stage1" \
644 buildtool "gcc" "$gcc_ver" "$gcc_opts --enable-languages=c --target=$target \
645 --without-headers --disable-threads --disable-libgomp --disable-libmudflap \
646 --disable-libssp --disable-libquadmath --disable-libquadmath-support \
647 --disable-shared --with-newlib --disable-libitm \
648 --disable-libsanitizer --disable-libatomic" "" ""
649 # install linux headers
650 # NOTE: we need to tell make where to put the build files, since buildtool
651 # switches to the builddir, "." will be the correct builddir when ran
652 if [ "$arch" == "mipsel" ]; then
653 arch="mips"
654 fi
655 linux_opts="O=. ARCH=$arch INSTALL_HDR_PATH=$sysroot/usr/"
656 RESTART_STEP="linux-headers" \
657 buildtool "linux" "$linux_ver" "NO_CONFIGURE" \
658 "$linux_opts headers_install" "$linux_opts headers_check"
659 # build glibc using the first stage cross compiler
660 # we need to set the prefix to /usr because the glibc runs on the actual
661 # target and is indeed installed in /usr
662 RESTART_STEP="glibc" \
663 prefix="/usr" \
664 buildtool "glibc" "$glibc_ver" "--target=$target --host=$target --build=$MACHTYPE \
665 --with-__thread --with-headers=$sysroot/usr/include $glibc_opts" \
666 "$glibc_make_opts" "install install_root=$sysroot"
667 # build stage 2 compiler
668 RESTART_STEP="gcc-stage2" \
669 buildtool "gcc" "$gcc_ver" "$gcc_opts --enable-languages=c,c++ --target=$target \
670 --with-sysroot=$sysroot" "" ""
671}
672
673usage () {
674 echo "usage: rockboxdev.sh [options]"
675 echo "options:"
676 echo " --help Display this help"
677 echo " --target=LIST List of targets to build"
678 echo " --restart=STEP Restart build at given STEP (same as RBDEV_RESTART env var)"
679 echo " --prefix=PREFIX Set install prefix (same as RBDEV_PREFIX env var)"
680 echo " --dlwhere=DIR Set download directory (same as RBDEV_DOWNLOAD env var)"
681 echo " --builddir=DIR Set build directory (same as RBDEV_BUILD env var)"
682 echo " --makeflags=FLAGS Set make flags (same as MAKEFLAGS env var)"
683 exit 1
684}
685
686##############################################################################
687# Code:
688
689# Parse arguments
690for i in "$@"
691do
692case $i in
693 --help)
694 usage
695 ;;
696 --prefix=*)
697 prefix="${i#*=}"
698 shift
699 ;;
700 --target=*)
701 RBDEV_TARGET="${i#*=}"
702 shift
703 ;;
704 --restart=*)
705 RBDEV_RESTART="${i#*=}"
706 shift
707 ;;
708 --dlwhere=*)
709 dlwhere="${i#*=}"
710 shift
711 ;;
712 --builddir=*)
713 builddir="${i#*=}"
714 shift
715 ;;
716 --makeflags=*)
717 export MAKEFLAGS="${i#*=}" # export so it's available in make
718 shift
719 ;;
720 *)
721 echo "Unknown option '$i'"
722 exit 1
723 ;;
724esac
725done
726
727# Verify required tools and libraries
728for t in $reqtools; do
729 tool=`findtool $t`
730 if test -z "$tool"; then
731 echo "ROCKBOXDEV: \"$t\" is required for this script to work."
732 missingtools="yes"
733 fi
734done
735if [ -n "$missingtools" ]; then
736 echo "ROCKBOXDEV: Please install the missing tools and re-run the script."
737 exit 1
738fi
739
740if ! $make -v | grep -q GNU ; then
741 echo "ROCKBOXDEV: Building the rockbox toolchains requires GNU Make."
742 exit 1
743fi
744
745dlwhere=$($READLINK -f "$dlwhere")
746prefix=$($READLINK -f "$prefix")
747builddir=$($READLINK -f "$builddir")
748
749echo "Download directory : $dlwhere (set RBDEV_DOWNLOAD or use --dlwhere= to change)"
750echo "Install prefix : $prefix (set RBDEV_PREFIX or use --prefix= to change)"
751echo "Build dir : $builddir (set RBDEV_BUILD or use --builddir= to change)"
752echo "Make options : $MAKEFLAGS (set MAKEFLAGS or use --makeflags= to change)"
753echo "Restart step : $RBDEV_RESTART (set RBDEV_RESTART or use --restart= to change)"
754echo "Target arch : $RBDEV_TARGET (set RBDEV_TARGET or use --target= to change)"
755
756# Verify download directory
757if test -d "$dlwhere"; then
758 if ! test -w "$dlwhere"; then
759 echo "ROCKBOXDEV: No write permission for $dlwhere"
760 exit
761 fi
762else
763 mkdir $dlwhere
764 if test $? -ne 0; then
765 echo "ROCKBOXDEV: Failed creating directory $dlwhere"
766 exit
767 fi
768fi
769
770
771# Verify the prefix dir
772if test ! -d $prefix; then
773 mkdir -p $prefix
774 if test $? -ne 0; then
775 echo "ROCKBOXDEV: Failed creating directory $prefix"
776 exit
777 fi
778fi
779if test ! -w $prefix; then
780 echo "ROCKBOXDEV: No write permission for $prefix"
781 exit
782fi
783
784if [ -z "$RBDEV_TARGET" ]; then
785 echo "Select target arch:"
786 echo "m - m68k (iriver h1x0/h3x0, iaudio m3/m5/x5 and mpio hd200)"
787 echo "a - arm (ipods, iriver H10, Sansa, D2, Gigabeat, older Sony NWZ, etc)"
788 echo "i - mips (Jz47xx/x1000 based players)"
789 echo "x - arm-linux (Generic Linux ARM: Samsung ypr0, Linux-based Sony NWZ)"
790 echo "y - mips-linux (Generic Linux MIPS: eg the many HiBy-OS targets)"
791 echo "separate multiple targets with spaces"
792 echo "(Example: \"m a i\" will build m68k, arm, and mips)"
793 echo ""
794 selarch=`input`
795else
796 selarch=$RBDEV_TARGET
797fi
798
799# add target dir to path to ensure the new binutils are used in gcc build
800PATH="$prefix/bin:${PATH}"
801
802for arch in $selarch
803do
804 export MAKEFLAGS=`echo $MAKEFLAGS| $SED 's/ -r / /'` # We don't want -r
805 echo ""
806 case $arch in
807 [Ii])
808 build "binutils" "mipsel-elf" "2.38" "binutils-c23.patch" "--disable-werror" "gmp isl"
809 build "gcc" "mipsel-elf" "9.5.0" "" "" "gmp mpfr mpc isl"
810 ;;
811
812 [Mm])
813 build "binutils" "m68k-elf" "2.38" "" "--disable-werror" "gmp isl"
814 build "gcc" "m68k-elf" "9.5.0" "" "--with-arch=cf MAKEINFO=missing" "gmp mpfr mpc isl"
815 ;;
816
817 [Aa])
818 binopts=""
819 gccopts="--with-multilib-list=rmprofile"
820 case $system in
821 Darwin)
822 binopts="--disable-nls"
823 gccopts="--disable-nls"
824 ;;
825 esac
826 build "binutils" "arm-elf-eabi" "2.38" "" "$binopts --disable-werror" "gmp isl"
827 build "gcc" "arm-elf-eabi" "9.5.0" "rockbox-multilibs-noexceptions-arm-elf-eabi-gcc-9.5.0.diff" "$gccopts MAKEINFO=missing" "gmp mpfr mpc isl"
828 ;;
829 [Xx])
830 # IMPORTANT NOTE
831 # This toolchain must support several targets and thus must support
832 # the oldest possible configuration.
833 #
834 # Samsung YP-R0/R1:
835 # ARM1176JZF-S, softfp EABI
836 # kernel: device runs 2.6.24, but oem toolchain is built against 2.6.27.59
837 # glibc: device runs 2.4.2
838 #
839 # Sony NWZ:
840 # kernel: Varies from device to device; 2.6.23, 2.6.35, and 3.x seen.
841 # glibc: device runs 2.7
842 #
843 # Thus the lowest common denominator is to target 2.6.23 and glibc 2.4
844 # Use a recent 2.6.32 LTS kernel, but glibc 2.20 targeting 2.6.23 and API 2.4
845 #
846 glibcopts="--enable-kernel=2.6.23 --enable-oldest-abi=2.4"
847 build_linux_toolchain "arm-rockbox-linux-gnueabi" "2.38" "" "" "9.5.0" \
848 "$gccopts" "2.6.32.71" "" "2.20" "$glibcopts" "glibc-220-make44.patch glibc-2.20-gcc10.patch"
849 # build alsa-lib
850 # we need to set the prefix to how it is on device (/usr) and then
851 # tweak install dir at make install step
852 alsalib_ver="1.0.19"
853 gettool "alsa-lib" "$alsalib_ver"
854 extract "alsa-lib-$alsalib_ver"
855 prefix="/usr" buildtool "alsa-lib" "$alsalib_ver" \
856 "--host=$target --disable-python" "" "install DESTDIR=$prefix/$target/sysroot"
857 ;;
858 [Yy])
859 # IMPORTANT NOTE
860 # This toolchain must support several targets and thus must support
861 # the oldest possible configuration.
862 #
863 # AGPTek Rocker (and other HibyOS players):
864 # kernel: 3.10.14
865 # glibc: 2.16
866 # alsa: 1.0.29
867 #
868 # FiiO M3K Linux (Based on Ingenic SDK):
869 # kernel: 3.10.14
870 # glibc: 2.16
871 # alsa: 1.0.26
872 #
873 # Use a recent 3.10 LTS kernel, but glibc 2.27 targeting 3.2.x and API 2.16
874 #
875 glibcopts="--enable-kernel=3.2 --enable-oldest-abi=2.16 --disable-werror"
876 # FIXME: maybe add -mhard-float?
877 build_linux_toolchain "mipsel-rockbox-linux-gnu" "2.38" "" "binutils-c23.patch" "9.5.0" \
878 "$gccopts" "3.10.108" "linux-c23.patch" "2.27" "$glibcopts" "glibc-227-make44.patch"
879 # build alsa-lib
880 # we need to set the prefix to how it is on device (/usr) and then
881 # tweak install dir at make install step
882 alsalib_ver="1.0.26"
883 gettool "alsa-lib" "$alsalib_ver"
884 extract "alsa-lib-$alsalib_ver"
885 prefix="/usr" buildtool "alsa-lib" "$alsalib_ver" \
886 "--host=$target --disable-python" "" "install DESTDIR=$prefix/$target/sysroot"
887
888 ### Everything below here is needed only for bluetooth support
889
890 # build libffi
891 libffi_ver="3.2.1"
892 gettool "libffi" "$libffi_ver"
893 extract "libffi-$libffi_ver"
894 prefix="/usr" buildtool "libffi" "$libffi_ver" \
895 "--includedir=/usr/include --host=$target" "" "install DESTDIR=$prefix/$target/sysroot"
896 (cd $prefix/$target/sysroot/usr/include ; ln -sf ../lib/libffi-$libffi_ver/include/ffi.h . ; ln -sf ../lib/libffi-$libffi_ver/include/ffitarget.h . )
897
898 # build zlib
899 zlib_ver="1.2.13" # Target uses 1.2.8!
900 gettool "zlib" "$zlib_ver"
901 extract "zlib-$zlib_ver"
902 CHOST=$target prefix="/usr" buildtool "zlib" "$zlib_ver" \
903 "" "" "install DESTDIR=$prefix/$target/sysroot"
904
905 # build glib
906 glib_ver="2.46.2"
907 gettool "glib" "$glib_ver"
908 extract "glib-$glib_ver"
909 prefix="/usr" buildtool "glib" "$glib_ver" \
910 "--host=$target --with-sysroot=$prefix/$target/sysroot --disable-libelf glib_cv_stack_grows=no glib_cv_uscore=no ac_cv_func_posix_getpwuid_r=yes ac_cv_func_posix_getgrgid_r=yes CFLAGS=-Wno-error=format-nonliteral" "" "install DESTDIR=$prefix/$target/sysroot"
911
912 # build expat
913 expat_ver="2.1.0"
914 gettool "expat" "$expat_ver"
915 extract "expat-$expat_ver"
916 prefix="/usr" buildtool "expat" "$expat_ver" \
917 "--host=$target --includedir=/usr/include --enable-abstract-sockets" "" "install DESTDIR=$prefix/$target/sysroot "
918
919 # build dbus
920 dbus_ver="1.10.2"
921 gettool "dbus" "$dbus_ver"
922 extract "dbus-$dbus_ver"
923 prefix="/usr" buildtool "dbus" "$dbus_ver" \
924 "--host=$target --with-sysroot=$prefix/$target/sysroot --includedir=/usr/include --enable-abstract-sockets ac_cv_lib_expat_XML_ParserCreate_MM=yes --disable-systemd --disable-launchd --enable-x11-autolaunch=no --with-x=no -disable-selinux --disable-apparmor --disable-doxygen-docs " "" "install DESTDIR=$prefix/$target/sysroot "
925
926 ;;
927 *)
928 echo "ROCKBOXDEV: Unsupported architecture option: $arch"
929 exit
930 ;;
931 esac
932done
933
934echo ""
935echo "ROCKBOXDEV: Done!"
936echo ""
937echo "ROCKBOXDEV: Make sure your PATH includes $prefix/bin"
938echo ""