#! /bin/bash PROJECT=ellcc # Available sub-projects. AVAILABLE_PROJECTS=( ellcc ) # Enabled sub-projects. PROJECTS=( ellcc ) # Additional options (see functions sources below). # Options followed by a ':' require an argument, by '::' allow an optional argument. SHORT_OPTIONS= # Long options are not available with BSD getopt. LONG_OPTIONS= # Help for additional options usage() { # option h "help" "display this help and exit" return } # Find the directory containing this script. source="${BASH_SOURCE[0]}" while [ -h "${source}" ] ; do source="$(readlink "${source}")" [[ ${source} != /* ]] && source="${ellcc}/${source}" done ellcc="$(cd -P "$(dirname "${source}")" && pwd)" if [ ! -d ${ellcc}/scripts ] ; then # In the ellcc/bin directory ellcc="$(cd -P "$(dirname "${source}")/.." && pwd)" fi SCRIPTS=${ellcc}/scripts if [ ! -d ${SCRIPTS} ] ; then echo "ELLCC assumed to be '$ellcc' but can't find '${SCRIPTS}'." exit 1 fi check_target() { echo "" } get_targets() { echo ${commands} } # Install ELLCC. commands+=" install" # Build packages. commands+=" build" # Build libraries. commands+=" libraries" # Upgrade the ELLCC binary distribution. commands+=" upgrade" # Display package versions. commands+=" versions" # Update packages from repositories. commands+=" update" # Get support functions and definitions. source ${SCRIPTS}/support get_packages() { echo $(cd ${SCRIPTS}; echo build-* | sed -e 's/build-//g') } # Get the list of available target hosts. get_hosts() { echo $(cat ${TOOLINFO}/buildhosts | grep -v ^\#) } # Get the list of available targets. get_targets() { echo $(cat ${TOOLINFO}/libraries | grep -v ^\# | sed -e 's/.*-elk*//g') } package() { echo $1 | sed -s "s/\(.*\)-${REVISION}.*/\1/" } curl_update() { if [ -e $2 ] ; then # We have the file, check for an update. if [ "$(run ${CURL} $1/$2 -z $2 -o $2 -s -L -w %{http_code})" != "200" ] ; then # No new version available. echo "package '"$(package $2)"' is up to date." return 0 fi else # Get the file. run ${CURL} $1/$2 -o $2 -L fi # Unpack the new version. run tar xvfp $2 -C $3 } install() { if [ "$1" = "help" ] ; then echo "usage: $0 install [libraries|src|ellcc]" echo "Finish ellcc installation in the current directory." echo "Subcommands:" echo " libraries: Install libraries for all supported targets." echo " src: Install the source code used to build this version of ELLCC." echo " ellcc: Install the ellcc binary package." exit 0 elif [ "$1" = "" ] ; then # Fix musl dynamic library path files. for f in $(find ${ELLCC}/libecc/lib -name ld-musl.path) ; do d=$(dirname $f) echo $d > ${d}/ld-musl.path done # Save the ellcc tarball, if available. host=$(bin/ecc -print-libgcc-file-name | sed -e 's:.*lib/\([^/]*\).*:\1:') if [ -e ${ELLCC}/../ellcc-${host}-${REVISION}.bz2 ] ; then echo "Moving the ellcc tarball to ellcc/build for future updates." run mkdir -p ${TOP} run mv ${ELLCC}/../ellcc-${host}-${REVISION}.bz2 ${TOP} fi # Copy ellcc to make it accessible in the PATH. mkdir -p ${ELLCC}/bin cp -p ellcc ${ELLCC}/bin if [ -e ${ELLCC}/bin/patchelf ] ; then # Fix the ELF interpreter name of dynamically linked files. interp=${LIBECC}/lib/${host}/libc.so for e in ${ELLCC}/bin/* ; do fileout=$(file -b ${e}) echo ${fileout} | grep "dynamically linked" > /dev/null if [ $? -ne 0 ] ; then # Not dynamically linked. continue fi if [ "${interp}" != "${oldinterp}" ] ; then # Patch the interpreter. ${ELLCC}/bin/patchelf --set-interpreter ${interp} ${e} fi done fi elif [ "$1" = "libraries" ] ; then run mkdir -p ${TOP} run cd ${TOP} curl_update http://ellcc.org/releases/release-${REVISION} \ ellcc-libraries-${REVISION}.bz2 ${ELLCC} elif [ "$1" = "src" ] ; then run mkdir -p ${TOP} run cd ${TOP} curl_update http://ellcc.org/releases/release-${REVISION} \ ellcc-src-${REVISION}.bz2 ${TOP} elif [ "$1" = "ellcc" ] ; then run mkdir -p ${TOP} run cd ${TOP} curl_update http://ellcc.org/releases/release-${REVISION} \ ellcc-${HOSTTUPLE}-${REVISION}.bz2 ${ELLCC}/.. else bailout "Unknown subcommand for 'install': '$1'." fi } build() { if [ "$1" = "help" ] ; then echo "usage: $0 build [all| ...]" echo "Build all or selected target hosts." echo "hosts: $(get_hosts)" exit 0 elif [ "$1" = "" ] ; then # Make for the host system. run ${SCRIPTS}/make-ellcc -Cb elif [ "$1" = "all" ] ; then for h in $(get_hosts) ; do run ${SCRIPTS}/make-ellcc -Cb ${h} done else for h in $* ; do run ${SCRIPTS}/make-ellcc -Cb ${h} done fi } libraries() { if [ "$1" = "" -o "$1" = "help" ] ; then echo "usage: $0 libraries [all| ...]" echo "Build libraries for all or selected targets." echo "targets: $(get_targets)" exit 0 elif [ "$1" = "all" ] ; then run ${SCRIPTS}/make-libraries all else for t in $* ; do run ${SCRIPTS}/make-libraries ${t} done fi } upgrade() { if [ "$1" = "help" ] ; then echo "usage: $0 upgrade" echo "Upgrade to the latest ELLCC binary distribution." exit 0 elif [ "$1" = "" ] ; then run mkdir -p ${TOP} cd ${TOP} latest=$(${CURL} http://ellcc.org/releases/latest/ -L | grep "ellcc-${HOSTTUPLE}.*\.bz2" | \ sed -e "s/.*>ellcc-${HOSTTUPLE}-\([^.]*\)\.bz2.*/\1/") if [ "${latest}" = "${REVISION}" ] ; then echo "At the latest revision: ${REVISION}" else # Install the latest version. run curl_update http://ellcc.org/releases/latest \ ellcc-${HOSTTUPLE}-${latest}.bz2 ${ELLCC}/.. fi REVISION=($(last_revision ellcc)) REVISION=${REVISION[0]} # Update any installed packages. for p in $(cd ${TOP} ; echo ellcc-*.bz2) ; do p=$(echo ${p} | sed -s "s/ellcc-\(.*\)-[0-9]*-[0-9]*-[0-9]*\.bz2$/\1/") if [ $p != ${HOSTTUPLE} ] ; then run install $p fi done else bailout "Unknown subcommand for 'upgrade': '$1'." fi } update() { # RICH: add checks for repository checkouts. if [ "$1" = "" -o "$1" = "help" ] ; then echo "usage: $0 update [all| ...]" echo "Update all or selected packages from their original repositories." echo "If you have used 'ellcc install' to install the ELLCC source tree," echo "then this command will not work, use 'ellcc upgrade' instead." echo "packages: $(get_packages)" exit 0 elif [ "$1" = "all" ] ; then run ${SCRIPTS}/update-ellcc all else for p in $* ; do run ${SCRIPTS}/update-ellcc ${p} done fi } packages=() links=() _ellcc=0 packages[_ellcc]="The latest ELLCC release" links[_ellcc]="http://ellcc.org" _binutils_gdb=1 packages[_binutils_gdb]="Source level debugger, assemblers, linker, and utilities" links[_binutils_gdb]="http://www.gnu.org/software/binutils" _c_ares=2 packages[_c_ares]="Asynchronous DNS library" links[_c_ares]="http://c-ares.haxx.se" _compiler_rt=3 packages[_compiler_rt]="Low level compiler support library" links[_compiler_rt]="https://compiler-rt.llvm.org/" _curl=4 packages[_curl]="Command line tool and library for transferring data with URL syntax" links[_curl]="http://curl.haxx.se" _curses=5 packages[_curses]="NetBSD curses terminal handling library" links[_curses]="https://github.com/sabotage-linux/netbsd-curses" _expat=6 packages[_expat]="XML parsing library" links[_expat]="http://expat.sourceforge.net" _libcxx=7 packages[_libcxx]="LLVM's libc++ standard library" links[_libcxx]="https://libcxx.llvm.org" _libedit=8 packages[_libedit]="Command history editing library" links[_libedit]="http://thrysoee.dk/editline" _libmetalink=9 packages[_libmetalink]="Add Metalink functionality such as parsing Metalink XML files" links[_libmetalink]="https://launchpad.net/libmetalink" _libssh2=10 packages[_libssh2]="Client-side library implementing the SSH2 protocol" links[_libssh2]="http://www.libssh2.org" _llvm=11 packages[_llvm]="clang/LLVM C/C++ compiler" links[_llvm]="http://www.llvm.org" _mbedtls=12 packages[_mbedtls]="Transport Layer Security (TLS) library" links[_mbedtls]="https://tls.mbed.org" _musl=13 packages[_musl]="C standard library" links[_musl]="http://www.musl-libc.org" _nghttp2=14 packages[_nghttp2]="Library providing HTTP/2 support" links[_nghttp2]="https://nghttp2.org" _patchelf=15 packages[_patchelf]="Patch ELF files" links[_patchelf]="https://nixos.org/patchelf.html" _zlib=16 packages[_zlib]="Compression library" links[_zlib]="http://www.zlib.net" versions() { if [ "$1" = "help" ] ; then echo "usage: $0 versions [html]" echo "Display package version information." exit 0 fi if [ "$1" != "" -a "$1" != "html" ] ; then bailout "'$1' is not a valid argument to 'versions'" fi if [ "$1" = "html" ] ; then cat << EOF EOF else echo "Current versions:" printf "%16s: %-44s %s\n" Package Revision Date echo "-----------------------------------------------------------------------------" fi for r in ${PATCHES}/*.revision ; do value=($(cat $r)) project=$(basename $r .revision) index=_$(echo ${project} | sed -e "s/-/_/g") revision=${value[0]} mode=${value[1]} date=${value[2]} if [ "${mode}" != "main" ] ; then continue fi if [ "$1" = "html" ] ; then printf "\n" printf "" printf "" printf "" printf "\n" else printf "%16s: %s\n" ${project} ${revision} printf "%16s %s\n" "" "${packages[${index}]}" printf "%16s %s\n" "" ${links[${index}]} fi done for r in ${PATCHES}/*.revision ; do value=($(cat $r)) project=$(basename $r .revision) index=_$(echo ${project} | sed -e "s/-/_/g") revision=${value[0]} mode=${value[1]} date=${value[2]} if [ "${mode}" = "main" ] ; then continue fi if [ "$1" = "html" ] ; then printf "\n" printf "" printf "" printf "" printf "\n" else printf "%16s: %-44s %s\n" ${project} ${mode}-${revision} ${date} printf "%16s %s\n" "" "${packages[${index}]}" printf "%16s %s\n" "" ${links[${index}]} fi done if [ "$1" = "html" ] ; then cat << EOF
${project}${revision}${packages[${index}]}
${project}${mode}-${revision} (${date})${packages[${index}]}
EOF fi } if [ "$TARGET" = "install" ] ; then install $* elif [ "$TARGET" = "build" ] ; then build $* elif [ "$TARGET" = "libraries" ] ; then libraries $* elif [ "$TARGET" = "upgrade" ] ; then upgrade $* elif [ "$TARGET" = "versions" ] ; then versions $* elif [ "$TARGET" = "update" ] ; then update $* elif [ "$TARGET" = "" ] ; then # Enter the ELLCC environment. # Return to the user's directory. env PATH=${ELLCC}/bin:${PATH} ${SHELL} else echo "usage: $0 [help|]" echo "commands: ${commands[@]}" if [ "${TARGET}" != "help" ] ; then bailout "Unknown command '${TARGET}'." fi fi