#!/bin/sh # # Copyright (c) 2015 Martin Lucina. All Rights Reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # # cc.in/c++.in: rumprun backend C/C++ compiler wrapper script # die() { exit 1 } PROGNAME=${0##*/} # Determine if we're being run as C or C++. case ${PROGNAME} in *-gcc|*-clang) CC="!LIBEXEC_CC!" CFLAGS="!CFLAGS!" EXTRALIBS= ;; *-g++|*-clang++) CC="!LIBEXEC_CXX!" CFLAGS="!CXXFLAGS!" EXTRALIBS="-lc++ -lunwind" ;; *) echo "${PROGNAME}: internal error, unknown invocation" exit 1 ;; esac PRMETA="$(dirname ${CC})/brprintmetainfo" # Figure out what we're supposed to be doing. Assume we're fermenting # and switch to compilation if -c / -S / -E was passed. MODE=ferment WANTARG= # OUTFILE gets set to whatever is specified with -o (the real output file). OUTFILE=a.out for arg in "$@"; do [ "${arg}" = "-c" ] && MODE=compile [ "${arg}" = "-S" ] && MODE=compile [ "${arg}" = "-E" ] && MODE=compile [ "${arg}" = "-o" ] && WANTARG=yes && continue [ -n "${WANTARG}" ] && OUTFILE=${arg} && WANTARG= # If either of these is present on the command line, the # behaviour of gcc seems to be that they silently override # all other flags [ "${arg}" = "-dumpmachine" ] && { MODE=dumpmachine; break; } [ "${arg}" = "-dumpspecs" ] && { MODE=dumpspecs; break; } # even if the backing compiler supports multiarch, we do not [ "${arg}" = "-print-multiarch" ] && \ { echo "${PROGNAME}: unrecognized option '-print-multiarch'" 2>&1; exit 1; } done case ${MODE} in compile) exec ${CC} ${CFLAGS} -no-integrated-cpp \ --sysroot !DESTDIR!/rumprun-!MACHINE_GNU_ARCH! \ -specs=!DESTDIR!/rumprun-!MACHINE_GNU_ARCH!/lib/specs-compile_or_ferment \ "$@" ${EXTRALIBS} ;; ferment) meta1="$(${PRMETA} "${OUTFILE}" 2>/dev/null)" # Link the real (from user's PoV) output file as a relocatable object, # with no rump components. '-u main' is necessary to pull in main if the # user is linking it in from a library. ${CC} ${CFLAGS} -no-integrated-cpp \ --sysroot !DESTDIR!/rumprun-!MACHINE_GNU_ARCH! \ -specs=!DESTDIR!/rumprun-!MACHINE_GNU_ARCH!/lib/specs-compile_or_ferment \ !EXTRACCFLAGS! -Wl,-r -Wl,-u,main \ "$@" !DESTDIR!/rumprun-!MACHINE_GNU_ARCH!/share/!TOOLTUPLE!-recipe.s ${EXTRALIBS} || die # If the presumed output file did not change, and the compiler # did not flag an error, assume this is a command which does not # generate output (e.g. cc -dumpspecs) and exit gracefully meta2="$(${PRMETA} "${OUTFILE}" 2>/dev/null)" [ "${meta1}" != "${meta2}" ] || exit 0 if [ "${RUMPRUN_STUBLINK}" = succeed ]; then exec 3>&1 2>&1 echo '!!!' echo '!!! WARNING: $RUMPRUN_STUBLINK may be desupported without' echo '!!! warning in the future. Do not rely on it' echo '!!! continuing to be available.' echo '!!!' exec 1>&3 3>&- fi # Try a stub link with minimal rump components. If that fails then stop. ${CC} ${CFLAGS} -no-integrated-cpp \ --sysroot !DESTDIR!/rumprun-!MACHINE_GNU_ARCH! \ -specs=!DESTDIR!/rumprun-!MACHINE_GNU_ARCH!/lib/specs-stub \ ${OUTFILE} -o /dev/null if [ $? -ne 0 ]; then if [ "${RUMPRUN_STUBLINK}" = "succeed" ]; then echo "${PROGNAME}: warning: stub link failed" 1>&2 else [ -f "${OUTFILE}" ] && rm -f ${OUTFILE} die fi fi # Some build systems insist that the output looks like an executable. chmod +x ${OUTFILE} ;; dumpmachine) echo !TOOLTUPLE! ;; dumpspecs) ${CC} -dumpspecs cat !DESTDIR!/rumprun-!MACHINE_GNU_ARCH!/lib/specs-compile_or_ferment ;; *) echo "${PROGNAME}: internal error, unknown mode" exit 1 ;; esac exit 0