A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 938 lines 30 kB view raw
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 ""