#! /bin/sh # @configure_input@ #---------------------------------------------------------------------------# # Copyright (C) 1995-1997 The University of Melbourne. # This file may only be copied under the terms of the GNU General # Public License - see the file COPYING in the Mercury distribution. #---------------------------------------------------------------------------# # # ML - Mercury Linker. # # Invokes GCC with the appropriate options to link in the Mercury library. # # Usage: see below. # # Environment variables: MERCURY_C_LIB_DIR, MERCURY_DEFAULT_GRADE, ... Help="\ Name: ml - Mercury Linker Usage: ml [] [-- ] files... Options: -h, --help Print this help message. -v, --verbose Echo the gcc command line before executing it. --mercury-libs {shared, static, none} Specify which version of the standard Mercury libraries to link with: --mercury-libs shared Link with the shared libraries (*.so), if possible, otherwise with the static ones. --mercury-libs static Link with the static libraries (*.a). --mercury-libs none Don't link in the Mercury standard libraries. -shared, --shared Similar to \`--mercury-libs shared', but applies to all libraries, not just the standard Mercury libraries. -static, --static Similar to \`--mercury-libs static', but applies to all libraries, not just the standard Mercury libraries. --make-shared-lib Produce a shared library, rather than an executable. -R , --shared-lib-dir Include in the list of directories that the dynamic linker will use to search for shared libraries. --no-demangle Don't pipe the output of the linker through the Mercury demangler. -g, --no-strip Do not strip debugging information. -s , --grade --asm-labels --gcc-non-local-gotos --gcc-global-registers -p, --profiling --profile-calls --profile-time --profile-memory --debug --use-trail --args {simple, compact} --pic-reg See the documentation in the \"Invocation\" section of the Mercury User's Guide." FULLARCH=@FULLARCH@ NONSHARED_LIB_DIR=${MERCURY_NONSHARED_LIB_DIR=@NONSHARED_LIB_DIR@} DEFAULT_LIBDIR=@LIBDIR@/lib LIBDIR=${MERCURY_C_LIB_DIR=$DEFAULT_LIBDIR} DEFAULT_GRADE=${MERCURY_DEFAULT_GRADE=@DEFAULT_GRADE@} # DEMANGLER=${MERCURY_DEMANGLER=@LIBDIR@/bin/@FULLARCH@/mdemangle} DEMANGLER=${MERCURY_DEMANGLER=mdemangle} CC=${MERCURY_C_COMPILER="@CC@"} MKFIFO=${MERCURY_MKFIFO="@MKFIFO@"} EXE_RPATH_OPT=${MERCURY_EXE_RPATH_OPT="@EXE_RPATH_OPT@"} EXE_RPATH_SEP=${MERCURY_EXE_RPATH_SEP="@EXE_RPATH_SEP@"} EXT_FOR_SHARED_LIB=${MERCURY_EXT_FOR_SHARED_LIB="@EXT_FOR_SHARED_LIB@"} LINK_SHARED_OBJ=${MERCURY_LINK_SHARED_OBJ="@LINK_SHARED_OBJ@"} SHLIB_RPATH_OPT=${MERCURY_SHLIB_RPATH_OPT="@SHLIB_RPATH_OPT@"} SHLIB_RPATH_SEP=${MERCURY_SHLIB_RPATH_SEP="@SHLIB_RPATH_SEP@"} SHARED_LIBS=${MERCURY_SHARED_LIBS="@SHARED_LIBS@"} verbose=false case $FULLARCH in *-win95|*-winnt|*-win32|*-cygwin32) # `gcc -s' is broken in gnu-win32 strip=false ;; *) strip=true ;; esac mercury_libs=default demangle=true MAYBE_STATIC_OPT="" make_shared_lib=false user_shlib_dirs="" # include the file `init_grade_options.sh-subr' @INIT_GRADE_OPTIONS@ while : ; do case "$1" in -h|--help|"-?") echo "$Help" exit 0 ;; -v|--verbose) verbose=true ;; --demangle) demangle=true ;; --no-demangle) demangle=false ;; --strip) strip=true ;; -g|--no-strip) strip=false ;; --make-shared-lib) make_shared_lib=true # on some targets, stripping shared libraries will # make them unusable, I think, so don't strip strip=false ;; --no-libs) progname=`basename $0` cat 1>&2 << EOF $progname: Warning: option \`--no-libs' is deprecated -- $progname: please use the new option \`--mercury-libs none' instead. $progname: Support for \`--no-libs' may be removed in a future release. EOF mercury_libs=none ;; --mercury-libs) case "$2" in shared|static|none|default) mercury_libs="$2" shift ;; *) progname=`basename $0` cat 1>&2 << EOF $progname: Error: parameter to \`--mercury-libs' option should be either $progname: \`shared', \`static', \`none', or \`default', not \`$2'. $progname: Try `$0 --help' for help. EOF exit 1 ;; esac ;; -shared|--shared) MAYBE_STATIC_OPT="" case $mercury_libs in static|default) mercury_libs=shared ;; esac ;; -static|--static) case $FULLARCH in *-linux*) # On Linux, if we're linking statically, we need to # pass `-defsym _DYNAMIC=0' to the linker, to avoid # undefined references to _DYNAMIC in # boehm_gc/dyn_load.c. # (We might eventually need similar treatment # for other OSs too) MAYBE_STATIC_OPT="-static -Wl,-defsym,_DYNAMIC=0" ;; *) MAYBE_STATIC_OPT=-static ;; esac case $mercury_libs in shared|default) mercury_libs=static ;; esac ;; -R|--shared-lib-dir) dir="$2" user_shlib_dirs="$user_shlib_dirs $dir" shift ;; -R*) dir="` expr $1 : '-R\(.*\)' `" user_shlib_dirs="$user_shlib_dirs $dir" ;; # include the file `parse_grade_options.sh-subr' @PARSE_GRADE_OPTIONS@ --) shift break ;; *) break ;; esac shift done case $mercury_libs in default) mercury_libs=shared case $FULLARCH in i?86-*-linux*) # shared libraries are not the default on Linux # -- see README.Linux case $make_shared_lib in false) mercury_libs=static ;; esac ;; esac ;; esac # # compute the grade from the options settings # case $non_local_gotos,$global_regs in true,true) GRADE="fast" ;; true,false) GRADE="jump" ;; false,true) GRADE="reg" ;; false,false) GRADE="none" ;; esac case $asm_labels in true) GRADE="asm_$GRADE" ;; false) ;; esac case $gc_method in conservative) GRADE="$GRADE.gc" ;; accurate) GRADE="$GRADE.agc" ;; esac case $profile_time,$profile_calls,$profile_memory in true,true,false) GRADE="$GRADE.prof" ;; true,false,false) GRADE="$GRADE.proftime" ;; false,true,false) GRADE="$GRADE.profcalls" ;; true,true,true) GRADE="$GRADE.profall" ;; false,true,true) GRADE="$GRADE.memprof" ;; false,false,false) ;; *) progname=`basename $0` echo \ "$progname: Error: invalid combination of profiling options." 1>&2 exit 1 ;; esac case $use_trail in true) GRADE="$GRADE.tr" ;; false) ;; esac case $args_method in simple) GRADE="$GRADE.sa" ;; compact) ;; esac case $debug in true) GRADE="$GRADE.debug" ;; false) ;; esac case "$GRADE" in *.gc.prof*) LIBGC="-lgc_prof" LIBGC_STATIC="$LIBDIR/$FULLARCH/libgc_prof.a" ;; *.gc*) LIBGC="-lgc" LIBGC_STATIC="$LIBDIR/$FULLARCH/libgc.a" ;; *) LIBGC= LIBGC_STATIC= ;; esac case $strip in true) STRIP_OPTS="-s" ;; false) STRIP_OPTS="" ;; esac case $make_shared_lib in true) LINKER="$LINK_SHARED_OBJ" RPATH_OPT="$SHLIB_RPATH_OPT" RPATH_SEP="$SHLIB_RPATH_SEP" STDLIBS="$SHARED_LIBS" ;; false) LINKER="$CC" RPATH_OPT="$EXE_RPATH_OPT" RPATH_SEP="$EXE_RPATH_SEP" STDLIBS="-lm" ;; esac LIBDIR_OPTS=" -L$LIBDIR/$GRADE/$FULLARCH -L$LIBDIR/$FULLARCH " case $mercury_libs in shared) LIBS=${MERCURY_LIBS="-lmercury -lmer $LIBGC $STDLIBS"} merc_shlib_dirs="$merc_shlib_dirs $LIBDIR/$GRADE/$FULLARCH" merc_shlib_dirs="$merc_shlib_dirs $LIBDIR/$FULLARCH" ;; static) LIBS=${MERCURY_LIBS="\ $LIBDIR/$GRADE/$FULLARCH/libmercury.a \ $LIBDIR/$GRADE/$FULLARCH/libmer.a \ $LIBGC_STATIC \ $STDLIBS"} merc_shlib_dirs="" ;; none) LIBS="$STDLIBS" LIBDIR_OPTS="" merc_shlib_dirs="" ;; esac RPATH_OPT_LIST= # only set RPATH_OPT_LIST if the system supports shared libraries case $EXT_FOR_SHARED_LIB in so) prev="" for dir in $user_shlib_dirs $merc_shlib_dirs 'kludge for broken shells' do case "$dir" in 'kludge for broken shells') ;; *) case "$prev" in "") RPATH_OPT_LIST="$RPATH_OPT$dir" ;; *) RPATH_OPT_LIST="$RPATH_OPT_LIST$RPATH_SEP$dir" ;; esac ;; esac prev=$dir done ;; esac # On Irix 5, grades `fast' and `jump' only work in non_shared mode. case $FULLARCH in *-sgi-irix5*) case $non_local_gotos in true) ARCH_OPTS=-non_shared NONSHARED_PATH="$NONSHARED_LIB_DIR:/usr/lib/nonshared" LIBRARY_PATH="$NONSHARED_PATH:$LIBRARY_PATH" export LIBRARY_PATH ;; esac ;; esac case "$MKFIFO" in none) demangle=false ;; esac case $verbose in true) echo "ml: using grade \`$GRADE'" case $demangle in false) echo $LINKER $STRIP_OPTS $MAYBE_STATIC_OPT $ARCH_OPTS \ "$@" $LIBDIR_OPTS $RPATH_OPT_LIST $LIBS ;; true) echo $LINKER $STRIP_OPTS $MAYBE_STATIC_OPT $ARCH_OPTS \ "$@" $LIBDIR_OPTS $RPATH_OPT_LIST $LIBS "|" echo "$DEMANGLER" ;; esac ;; esac case $demangle in true) # we would like to just run $CC and pipe the result into $DEMANGLER, # but `$CC | $DEMANGLER' would return the wrong exit status, so # we need to use a named pipe; if the system doesn't have named # pipes, then we don't use the demangler # create the pipe, making sure we remove it if interrupted PIPE=/tmp/ml.$$ trap 'rm -f $PIPE; exit 1' 1 2 3 13 15 $MKFIFO $PIPE # execute the demangler in the background, with stdin # coming from the pipe and with stdout redirected to stderr exec $DEMANGLER 1>&2 < $PIPE & # redirect our stdout and stderr into the pipe exec >$PIPE 2>&1 # now we can remove the pipe; since is an open file, it will # stay around until $CC and $DEMANGLER exit rm -f $PIPE # finally execute $CC; stdout & stderr will # go via the pipe to $DEMANGLER and then to stderr ;; esac case $# in 0) exec $LINKER $STRIP_OPTS $MAYBE_STATIC_OPT $ARCH_OPTS \ $LIBDIR_OPTS $RPATH_OPT_LIST $LIBS ;; *) exec $LINKER $STRIP_OPTS $MAYBE_STATIC_OPT $ARCH_OPTS "$@" \ $LIBDIR_OPTS $RPATH_OPT_LIST $LIBS ;; esac