Your IP : 216.73.217.87
| Current Path : /usr/X11R6/bin/ |
|
|
| Current File : //usr/X11R6/bin/clisp-link |
#!/bin/sh
# Usage: clisp-link command [more args]
# where
# command = create, add, run, install
# For more usage information, see <doc/impnotes.html#mod-overview>.
# Or <http://clisp.cons.org/modules.html#mod-overview>.
# Bruno Haible 19.10.1994
# Sam Steingold 2002-2009
# This could as well be written in Lisp, for portability, but syscalls is
# a module, so most useful scripting functionality will not be available.
# Nuisances.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
usage () {
echo "Usage: $0 [ create | add | run | install ] ..." 1>&2
exit 1
}
normalize(){ # dir rel -> abs path for rel
dirname=`dirname "$2"`
echo `cd $1; cd ${dirname}; pwd`/`basename "$2"`
}
lncp () {
# Make a link from $1 to $2. Try symbolic link, hard link, file copying.
rm -f "$2"
ln -s "`normalize . $1`" "$2" 2>/dev/null || \
ln "$1" "$2" 2>/dev/null || \
cp -p "$1" "$2"
}
lncp_some () {
src_dir=$1; shift
destdir=$1; shift
ret=''
for f in $*; do
b=`basename $f`
lncp "`normalize "${src_dir}" "$f"`" "${destdir}"/$b
ret=${ret}" "$b
done
echo ${ret}
}
echotab () {
cat <<!!
$1
!!
}
# Print the commands being executed
vecho () {
echo "$@"
}
# print an error message and exit
fail () { echo "$0: $@" 1>&2; exit 1; }
# ensure that "$1" is a directory
check_dir () { test -d "$1" || fail "$1 is not a directory"; }
# make "$1" as a new directory
make_dest () {
if [ -r "$1" ] ; then
if [ -d "$1" ] ; then
fail "$1 already exists"
else
fail "$1 is not a directory"
fi
fi
mkdir "$1"
}
LISPRUN="lisp.run"
# ensure that "$1" contains a CLISP linking set
check_linkset () {
test -r "$1"/lisp.a -a -x "$1"/${LISPRUN} -a -r "$1"/lispinit.mem \
-a -r "$1"/modules.h -a -r "$1"/modules.o -a -r "$1"/makevars ||
fail "directory $1 does not contain a CLISP linking set"
}
# ensure that "$1" contains a CLISP module
check_module () {
if test \! -r "$1/link.sh"; then
if test -r "$1/configure"; then
echo "$0: no $1/link.sh, running $1/configure"
olddir=`pwd`;
cd $1; ./configure --with-clisp=${CLISP}; cd ${olddir}
test -f "$1/link.sh" \
|| fail "directory $1 still does not contain a CLISP module"
else fail "directory $1 does not contain a CLISP module"
fi
fi
}
verbose () {
echo "$@"
"$@" || fail "failed in `pwd`"
}
make_lisprun () {
# Generate new modules.o, compiled from modules.c, includes modules.h
lncp "$absolute_linkkitdir"/modules.c modules.c
verbose ${CC} ${CPPFLAGS} ${CFLAGS} -I"$absolute_linkkitdir" -c modules.c
rm -f modules.c
# Generate new ${LISPRUN}
verbose ${CC} ${CFLAGS} ${CLFLAGS} modules.o ${LIBS} -o ${LISPRUN}
}
# func_tmpdir
# creates a temporary directory.
# Sets variable
# - tmp pathname of freshly created temporary directory
func_tmpdir ()
{
# Use the environment variable TMPDIR, falling back to /tmp. This allows
# users to specify a different temporary directory, for example, if their
# /tmp is filled up or too small.
: ${TMPDIR=/tmp}
{
# Use the mktemp program if available. If not available, hide the error
# message.
tmp=`(umask 077 && mktemp -d -q "$TMPDIR/gtXXXXXX") 2>/dev/null` &&
test -n "$tmp" && test -d "$tmp"
} ||
{
# Use a simple mkdir command. It is guaranteed to fail if the directory
# already exists. $RANDOM is bash specific and expands to empty in shells
# other than bash, ksh and zsh. Its use does not increase security;
# rather, it minimizes the probability of failure in a very cluttered /tmp
# directory.
tmp=$TMPDIR/gt$$-$RANDOM
(umask 077 && mkdir "$tmp")
} || fail "cannot create a temporary directory in $TMPDIR"
}
# evaluate in clisp and strip quotes
clisp_eval() {
${CLISP} -q -x "$*" 2>/dev/null | tail -n 1 | sed -e 's/^"//' -e 's/"$//'
}
# Where do we install?
DYNMOD="dynmod" # should be in sync with defs1.lisp:require
LIBDIR=""
set_dynamic_module_location() {
if test -z "${LIBDIR}"; then
if touch ${CLISP_LIBDIR}/${DYNMOD}/.abazonk 2>/dev/null; then
rm -f ${CLISP_LIBDIR}/${DYNMOD}/.abazonk
LIBDIR=${CLISP_LIBDIR}
else # cf. src/m4/clisp.m4
CLISP_LIBDIR_USER=`clisp_eval '(and *user-lib-directory* (namestring *user-lib-directory*))'`
test "${CLISP_LIBDIR_USER}" = "NIL" && \
fail "Cannot determine the dynamic module directory: *lib-directory* is not writable and *user-lib-directory* is not specified"
mkdir -p ${CLISP_LIBDIR_USER}/${DYNMOD} || \
fail "Cannot write in *user-lib-directory*"
if touch ${CLISP_LIBDIR_USER}/${DYNMOD}/.abazonk 2>/dev/null; then
rm -f ${CLISP_LIBDIR_USER}/${DYNMOD}/.abazonk
LIBDIR=${CLISP_LIBDIR_USER}
else fail "Cannot determine the dynamic module directory: neither *lib-directory* nor *user-lib-directory* are writable"
fi
fi
fi
}
current_linking_set() {
DIR=`clisp_eval '(sys::program-name)'`
DIR=`dirname ${DIR}`
check_linkset ${DIR};
echo ${DIR}
}
# setting $with_dynamic_modules overrides the default
with_dynamic_modules=${with_dynamic_modules-yes}
# prepare the loading infrastructure for the current dynamic module.
# this can be invoked only after "./link.sh" and relies on its variables.
# also uses:
# ${absolute_currentdir} : the top level directory
prepare_dynamic_module() {
if test "$with_dynamic_modules" != no; then
set_dynamic_module_location
dyndir=${LIBDIR}/${DYNMOD}
dll="lib"; for m in ${NEW_MODULES}; do dll=${dll}-$m; done; dll=${dll}.so
lib=${dyndir}/${dll}; libs="${NEW_LIBS} "; verbose ${CC} ${CFLAGS} ${CLFLAGS} -shared -o $lib $libs
# for each module there will be a hard link to a REQUIRE file
firstmod=''; othermods=''
for m in ${NEW_MODULES}; do
if test -z "${firstmod}"; then
firstmod=$m
else
othermods=${othermods}' '$m
fi
done
# create the REQUIRE file
reqfile=${dyndir}/${firstmod}.lisp
rm -f ${reqfile}
for f in ${TO_PRELOAD}; do
# preload files are not compiled
echo "(cl:load (cl:merge-pathnames \"../${moduledir}/${f}\" cl:*load-truename*))" >> ${reqfile}
done
# dll has SHREXT extension
DM="(sys::dynload-modules (cl:merge-pathnames \"${dll}\" cl:*load-truename*) (quote ("
for m in ${NEW_MODULES}; do
DM=${DM}" \"$m\""
done
echo ${DM}" )))" >> ${reqfile}
if test -n "${TO_LOAD}"; then
echo ";; for def-call-out to non-existent functions" >> ${reqfile}
echo "(ext:appease-cerrors" >> ${reqfile}
for f in ${TO_LOAD}; do
# module files must be compiled
echo " (cl:load (cl:merge-pathnames \"../${moduledir}/${f}.fas\" cl:*load-truename*))" >> ${reqfile}
done
echo ")" >> ${reqfile}
fi
# create links to the REQUIRE file
for m in ${othermods}; do
ln ${dyndir}/$m.lisp ${reqfile}
done
fi
}
# Remove the comment to Set debugging output on
#set -x
# Exit immediately if some command fails.
set -e
# Check number of arguments. Need at least one argument.
if [ $# = 0 ] ; then
usage
fi
# Where is clisp?
if test -z "${CLISP}"; then
CLISP=`dirname $0`
CLISP=`cd ${CLISP}; pwd`/clisp
fi
# cd src/m4/clisp.m4
${CLISP} --version 2>/dev/null | head -n 1 | grep "GNU CLISP" >/dev/null 2>&1 \
|| fail "${CLISP} is not GNU CLISP"
CLISP_LIBDIR=`${CLISP} -b`
# Where is the link kit?
if [ -n "$CLISP_LINKKIT" ] ; then
linkkitdir="$CLISP_LINKKIT"
else
linkkitdir=${CLISP_LIBDIR}/linkkit
fi
test -r "$linkkitdir"/modules.c -a -r "$linkkitdir"/clisp.h ||
fail "No link kit found in $linkkitdir (is CLISP_LINKKIT set?)"
absolute_linkkitdir=`cd "$linkkitdir" ; /bin/pwd`
# Dispatch according to the first argument.
case "$1" in
create)
# Usage: clisp-link create moduledir {file}*
case $# in
0 | 1) echo "Usage: $0 create moduledir file ..." 1>&2
exit 1 ;;
esac
moduledir="$2"
shift
shift
files="$*"
make_dest "$moduledir"
modulename=`echo "$moduledir" | sed -e 's,^.*/,,'`
files_c=''
files_o=''
for file in $files; do
file=`echo "$file" | sed -e 's,\.c$,,'`.c
filename=`echo "$file" | sed -e 's,^.*/,,'`
case "$file" in
/*) relative_file="$file" ;;
*) case "$moduledir" in
/*) relative_file="$file" ;;
*) relative_file=`echo "$moduledir"/ | sed -e 's,[^/][^/]*/*/,../,g'`"$file" ;;
esac ;;
esac
ln -s "$relative_file" "$moduledir"/"$filename" || ln "$file" "$moduledir"/"$filename" || cp -p "$file" "$moduledir"/"$filename"
files_c="$files_c"' '"$filename"
files_o="$files_o"' '`echo "$filename" | sed -e 's,\.c$,,'`.o
done
if false; then
# No Makefile
(echo "file_list=''"
for fc in $files_c; do
fo=`echo "$fc" | sed -e 's,\.c$,,'`.o
echo 'if test -r '"$fc"'; then'
echo " if test '"'!'"' -f $fo || test $fo -ot $fc; then"
echo ' ${CC} ${CPPFLAGS} ${CFLAGS} -I"$absolute_linkkitdir" -c '"$fc"
echo ' fi'
echo ' file_list="$file_list"'"' $fo'"
echo 'fi'
done
echo 'NEW_FILES="$file_list"'
echo 'NEW_LIBS="$file_list"'
echo "TO_LOAD=''"
) > "$moduledir"/link.sh
else
# With Makefile
(echo "# Makefile for CLISP module set $modulename"
echo
echo "srcdir = ."
echo "CC ="
echo "CPPFLAGS ="
echo "CFLAGS ="
echo "CLISP = clisp -q -norc"
echo 'CLISP_LINKKIT = $$($(CLISP) -b)/linkkit'
echo "LN = ln"
echo "MAKE = make"
echo "SHELL = /bin/sh"
echo
echo "DISTRIBFILES ="
echo "distribdir ="
echo
for fc in $files_c; do
fo=`echo "$fc" | sed -e 's,\.c$,,'`.o
echo "$fo : \$(srcdir)/$fc"
echotab '$(CC) $(CPPFLAGS) $(CFLAGS) -I$(CLISP_LINKKIT) -c $<'
echo
done
echo "clisp-module :$files_o"
echo
echo 'clisp-module-distrib : clisp-module force'
echotab '$(LN) $(DISTRIBFILES) $(distribdir)'
echo
) > "$moduledir"/Makefile
(echo "file_list=''"
echo "mod_list=''"
for fc in $files_c; do
fo=`echo "$fc" | sed -e 's,\.c$,,'`.o
mod=`echo "$fc" | sed -e 's,\.c$,,' | sed -e 's,[^A-Za-z0-9_],_,g'`
# The last sed command must agree with foreign1.lisp:to-module-name.
echo 'if test -r '"$fc"'; then'
echo ' file_list="$file_list"'"' $fo'"
echo ' mod_list="$mod_list"'"' $mod'"
echo 'fi'
done
echo 'make clisp-module CC="${CC}" CPPFLAGS="${CPPFLAGS}" CFLAGS="${CFLAGS}" CLISP_LINKKIT="$absolute_linkkitdir" SHREXT=${SHREXT} $(CLISP)=${CLISP}'
echo 'NEW_FILES="$file_list"'
echo 'NEW_LIBS="$file_list"'
echo 'NEW_MODULES="$mod_list"'
echo "TO_LOAD=''"
echo "TO_PRELOAD=''"
) > "$moduledir"/link.sh
fi
;;
add)
# Usage: clisp-link add source-dir destination-dir moduledir...
if [ $# -lt 3 ] ; then
echo "Usage: $0 add source-dir destination-dir moduledir..." 1>&2
exit 1
fi
sourcedir="$2"
destinationdir="$3"
shift
shift
shift
moduledirs="$@"
check_dir "$sourcedir"
make_dest "$destinationdir"
for moduledir in $moduledirs; do check_dir "$moduledir"; done
absolute_currentdir=`/bin/pwd`
absolute_sourcedir=`cd "$sourcedir" ; /bin/pwd`
absolute_destinationdir=`cd "$destinationdir" ; /bin/pwd`
installbasedir=`dirname "$sourcedir"`
# What to do if we abort.
trap 'rm -rf "$absolute_destinationdir"' 1 2 15
test "$absolute_sourcedir" = "$absolute_destinationdir" &&
fail "directories $sourcedir and $destinationdir may not be the same"
check_linkset "$sourcedir"
for moduledir in $moduledirs; do check_module "$moduledir"; done
# Read the variables CC, CPPFLAGS, CFLAGS, CLFLAGS, LIBS, X_LIBS, RANLIB, FILES
. "$sourcedir"/makevars
if [ -z "$moduledirs" ] ; then
# Just make links from $destinationdir to $sourcedir
lncp_some "$sourcedir" "$destinationdir" ${LISPRUN} lispinit.mem modules.h modules.o makevars ${FILES};
else
cp "$sourcedir"/modules.h "$destinationdir"/modules.h
FILES=`lncp_some "$sourcedir" "$destinationdir" ${FILES}`
# Prepare the module directories and read their variables
PRELOAD=''
LOAD=''
for moduledir in $moduledirs; do
modulename=`basename "$moduledir"`
# Prepare the module directory and read the variables NEW_FILES, NEW_LIBS
NEW_FILES=''
NEW_LIBS=''
NEW_MODULES=''
TO_PRELOAD=''
TO_LOAD=''
SHREXT=.so
cd "$moduledir"
. ./link.sh
cd "$absolute_currentdir"
for mod in $NEW_MODULES ; do # update modules.h
echo 'MODULE('"$mod"')' >> "$destinationdir"/modules.h
done
FILES=${FILES}' '`lncp_some "$moduledir" "$destinationdir" ${NEW_FILES}`
LIBS=${NEW_LIBS}' '${LIBS}
for f in $TO_PRELOAD; do
PRELOAD=${PRELOAD}' -i '"$moduledir/$f"
done
for f in $TO_LOAD; do
LOAD=${LOAD}' -i '"$moduledir/$f"
done
cd "$destinationdir"
prepare_dynamic_module
cd "$absolute_currentdir"
done
start_dir=`pwd`
cd "$destinationdir"
make_lisprun
cd "${start_dir}"
if [ -n "$PRELOAD" ] ; then
# Generate new preliminary lispinit.mem
verbose "$sourcedir"/${LISPRUN} -B "$installbasedir" -M "$sourcedir"/lispinit.mem -norc -q ${PRELOAD} -x "(saveinitmem \"$destinationdir/lispinit.mem\")"
fi
# Generate new lispinit.mem
if [ -n "$PRELOAD" ] ; then
verbose "$destinationdir"/${LISPRUN} -B "$installbasedir" -M "$destinationdir"/lispinit.mem -norc -q ${LOAD} -x "(saveinitmem \"$destinationdir/lispinit.mem\")"
else
verbose "$destinationdir"/${LISPRUN} -B "$installbasedir" -M "$sourcedir"/lispinit.mem -norc -q ${LOAD} -x "(saveinitmem \"$destinationdir/lispinit.mem\")"
fi
# Generate new makevars
sed_escape_commas='s/,/\\,/g'
LIBS_escaped=`echo "$LIBS" | sed -e "$sed_escape_commas"`
sed -e "s,^LIBS=.*\$,LIBS='${LIBS_escaped}'," -e "s,^FILES=.*\$,FILES='${FILES}'," < "$sourcedir"/makevars > "$destinationdir"/makevars
fi
# Done.
trap '' 1 2 15
;;
run)
# This is functionally the same as an add command, followed
# by running the resulting linking set, but is faster and requires less
# disk space if dynamic loading is available.
# Usage: clisp-link run source-dir moduledir...
if [ $# -lt 2 ] ; then
echo "Usage: $0 run source-dir moduledir..." 1>&2
exit 1
fi
sourcedir="$2"
installbasedir=`dirname "$sourcedir"`
shift
shift
if test "$with_dynamic_modules" != no; then
moduledirs="$@"
check_dir "$sourcedir"
for moduledir in $moduledirs; do check_dir "$moduledir"; done
absolute_currentdir=`/bin/pwd`
check_linkset "$sourcedir"
for moduledir in $moduledirs; do check_module "$moduledir"; done
# Read the variables CC, CPPFLAGS, CFLAGS, CLFLAGS, LIBS, X_LIBS, RANLIB, FILES
. "$sourcedir"/makevars
if [ -z "$moduledirs" ] ; then
"$sourcedir"/${LISPRUN} -B "$installbasedir" -M "$sourcedir"/lispinit.mem
else
func_tmpdir
FILES=`lncp_some "$sourcedir" "$tmp" ${FILES}`
# Prepare the module directories and read their variables
PRELOAD=''
LIBS=''
MODULES=''
LOAD=''
for moduledir in $moduledirs; do
modulename=`basename "$moduledir"`
# Prepare the module directory and read the variables NEW_FILES, NEW_LIBS
NEW_FILES=''
NEW_LIBS=''
NEW_MODULES=''
TO_PRELOAD=''
TO_LOAD=''
SHREXT=.so
cd "$moduledir"
. ./link.sh
cd "$absolute_currentdir"
for f in $TO_PRELOAD; do
PRELOAD=${PRELOAD}' '"$moduledir/$f"
done
FILES=${FILES}' '`lncp_some "$moduledir" "$tmp" ${NEW_FILES}`
LIBS=${NEW_LIBS}' '${LIBS}
for mod in $NEW_MODULES; do
MODULES=${MODULES}' '"$mod"
done
for f in $TO_LOAD; do
LOAD=${LOAD}' '"$moduledir/$f"
done
done
tmpsharedlib="$tmp/clisplink.so"
tmpinitlisp="$tmp/clisplink.lisp"
# What to do if we abort.
trap 'rm -rf "$tmp"' 0 1 2 15
# Create an initialization file with a couple of load forms.
(for f in $PRELOAD; do echo "(load \"${f}\")"; done
echo "(system::dynload-modules \"$tmpsharedlib\" (quote ("
for mod in $MODULES; do echo " \"${mod}\""; done
echo ")))"
for f in $LOAD; do echo "(load \"${f}\")"; done ) > "$tmpinitlisp"
# Create a shared library.
start_dir=`pwd`; cd $tmp;
lib="$tmpsharedlib"; libs="$LIBS"; verbose ${CC} ${CFLAGS} ${CLFLAGS} -shared -o $lib $libs
cd "$start_dir"
# Run clisp, attach the shared library and load the Lisp stuff.
"$sourcedir"/${LISPRUN} -B "$installbasedir" -M "$sourcedir"/lispinit.mem -i "$tmpinitlisp"
rm -rf "$tmp"
trap '' 0 1 2 15
fi
else
func_tmpdir
destinationdir="$tmp"
# What to do if we abort.
trap 'rm -rf "$tmp"' 0 1 2 15
rm -rf $destinationdir # must not exist for make_dest; bug #[ 1469663 ]
"$0" add "$sourcedir" "$destinationdir" "$@" && "$destinationdir"/${LISPRUN} -B "$installbasedir" -M "$destinationdir"/lispinit.mem
rm -rf "$tmp"
trap '' 0 1 2 15
fi
;;
install)
# Usage: clisp-link install moduledir...
if [ $# -lt 1 ] ; then
echo "Usage: $0 install moduledir..." 1>&2
exit 1
fi
sourcedir=`current_linking_set`
shift
moduledirs="$@"
absolute_currentdir=`/bin/pwd`
absolute_sourcedir=`cd "$sourcedir" ; /bin/pwd`
for moduledir in $moduledirs; do
check_dir "$moduledir"
check_module "$moduledir"
test -r "${moduledir}"/Makefile || \
fail "No Makefile in ${moduledir}, cannot install"
done
# Read the variables CC, CPPFLAGS, CFLAGS, CLFLAGS, LIBS, X_LIBS, RANLIB, FILES
. "$sourcedir"/makevars
# Prepare the module directories and read their variables
for moduledir in $moduledirs; do
modulename=`basename "$moduledir"`
# Prepare the module directory
NEW_FILES=''
NEW_LIBS=''
NEW_MODULES=''
TO_PRELOAD=''
TO_LOAD=''
SHREXT=.so
cd "$moduledir"
absolute_moduledir=`/bin/pwd`
. ./link.sh
prepare_dynamic_module # sets LIBDIR
mkdir -p "${LIBDIR}/$moduledir"
# when running "CLISP=./clisp ./clisp-link install <modname>"
# in the build directory, avoid "cp: `...' and `...' are the same file"
absolute_distribdir=`cd "${LIBDIR}/$moduledir"; /bin/pwd`
test "${absolute_moduledir}" = "${absolute_distribdir}" || \
make clisp-module-distrib LN=cp distribdir="${LIBDIR}/$moduledir"
cd "$absolute_currentdir"
done
;;
*) usage;;
esac