# Shared setup for the run_magic* launchers -- sourced, not run directly. # # Generated by configure from scripts/magic_run_common.sh.in. It stages a # CAD_ROOT directory of *symlinks* into the build (generated) and source trees -- # the same layout `make install` copies, but instantly and always reflecting the # latest build -- and exports the environment magic needs to start straight from # the build tree without `make install`. # # See magic's runtime file discovery: MAGIC_SYS_PATH = ". $CAD_ROOT/magic/sys # $CAD_ROOT/magic/sys/current" (utils/paths.h) for tech/glyphs/fonts/styles, the # system .magicrc at $CAD_ROOT/magic/sys/.magicrc, and (since tcltk/tcldir.h) # magic.tcl / tclmagic / auto_path at $CAD_ROOT/magic/tcl. # # --------------------------------------------------------------------------- # Environment overrides (every value below can be pre-set in the environment; # each is initialized with ${VAR:-} so the caller's value wins): # # CAD_ROOT Root of the staged runtime tree. Default: the build tree's # own $builddir/CAD_DIR (a directory of symlinks, created on # first run). Point it elsewhere to reuse a shared/installed # tree instead of staging one. # MAGIC_WISH The "wish" binary magic uses for the Tk console. Default: # WISH, i.e. the wish detected by configure to match the Tcl/Tk # this build linked against (--with-tk / --with-wish). A build # against a non-standard Tk therefore uses the correct absolute # wish automatically; override to force a different one. # WISH Same as above; MAGIC_WISH defaults from it. Baked default is # the configure-detected wish (may be empty on a --disable-tcl # build -- the launchers use the self-contained magicexec and do # not require an external wish). # TCLSH tclsh matching this build's Tcl (--with-tcl). Provided for # convenience/diagnostics; may be empty if configure found none. # MAGIC_BUILDDIR Absolute build-tree top. Default: baked @abs_top_builddir@. # MAGIC_SRCDIR Absolute source-tree top. Default: baked @abs_top_srcdir@. # # Any value that is inherited from the environment (or a baked default that no # longer resolves) is sanity-checked below; problems are reported on stderr as # non-fatal warnings to aid diagnosis -- see magic_check_env(). # --------------------------------------------------------------------------- # Record which values the caller supplied (vs. the configure-baked default) so # diagnostics can name the origin, then fall back to the baked-in defaults. # ${VAR+x} is "x" only when VAR is already set -- safe under `set -u`. _origin_MAGIC_BUILDDIR="build default"; [ -n "${MAGIC_BUILDDIR+x}" ] && _origin_MAGIC_BUILDDIR=environment _origin_MAGIC_SRCDIR="build default"; [ -n "${MAGIC_SRCDIR+x}" ] && _origin_MAGIC_SRCDIR=environment _origin_CAD_ROOT="build default"; [ -n "${CAD_ROOT+x}" ] && _origin_CAD_ROOT=environment _origin_WISH="build default"; [ -n "${WISH+x}" ] && _origin_WISH=environment _origin_MAGIC_WISH="build default"; [ -n "${MAGIC_WISH+x}" ] && _origin_MAGIC_WISH=environment _origin_TCLSH="build default"; [ -n "${TCLSH+x}" ] && _origin_TCLSH=environment MAGIC_BUILDDIR="${MAGIC_BUILDDIR:-@abs_top_builddir@}" MAGIC_SRCDIR="${MAGIC_SRCDIR:-@abs_top_srcdir@}" SHDLIB_EXT="${SHDLIB_EXT:-@SHDLIB_EXT@}" CAD_ROOT="${CAD_ROOT:-${MAGIC_BUILDDIR}/CAD_DIR}" export CAD_ROOT MAGIC_SYS="${CAD_ROOT}/magic/sys" MAGIC_TCL="${CAD_ROOT}/magic/tcl" # wish/tclsh that match the Tcl/Tk this tree was configured against. WISH="${WISH:-@WISH_EXE@}" TCLSH="${TCLSH:-@TCLSH_EXE@}" # tkcon.tcl launches the console via ${MAGIC_WISH:=wish}; hand it the matching one. MAGIC_WISH="${MAGIC_WISH:-$WISH}" [ -n "$MAGIC_WISH" ] && export MAGIC_WISH # One warning helper for all launchers. magic_warn() { printf 'run_magic: warning: %s\n' "$*" >&2; } # _magic_check NAME KIND ORIGIN VALUE # KIND: mustdir -- must exist and be a directory # newdir -- may be absent (created later); if present must be a directory # exec -- must exist, be a regular file, and be executable # optexec -- empty is fine (feature not configured); else same as exec _magic_check() { _n="$1"; _k="$2"; _o="$3"; _v="$4" case "$_k" in optexec) [ -n "$_v" ] || return 0; _k=exec ;; esac case "$_k" in mustdir) [ -d "$_v" ] || magic_warn "\$$_n ($_o) = '$_v' is not a directory (build tree moved or removed?)" ;; newdir) { [ ! -e "$_v" ] || [ -d "$_v" ]; } || \ magic_warn "\$$_n ($_o) = '$_v' exists but is not a directory" ;; exec) if [ ! -e "$_v" ]; then magic_warn "\$$_n ($_o) = '$_v' does not exist" elif [ ! -f "$_v" ]; then magic_warn "\$$_n ($_o) = '$_v' is not a regular file" elif [ ! -x "$_v" ]; then magic_warn "\$$_n ($_o) = '$_v' is not executable" fi ;; esac } # Validate the (possibly environment-inherited) configuration and warn -- never # fail -- on anything that looks wrong, so a bad override is easy to spot. magic_check_env() { _magic_check MAGIC_BUILDDIR mustdir "$_origin_MAGIC_BUILDDIR" "$MAGIC_BUILDDIR" _magic_check MAGIC_SRCDIR mustdir "$_origin_MAGIC_SRCDIR" "$MAGIC_SRCDIR" _magic_check CAD_ROOT newdir "$_origin_CAD_ROOT" "$CAD_ROOT" _magic_check WISH optexec "$_origin_WISH" "$WISH" # MAGIC_WISH defaults from WISH; only check it separately when it diverges # (an explicit MAGIC_WISH override) to avoid a duplicate warning. [ "$MAGIC_WISH" = "$WISH" ] || \ _magic_check MAGIC_WISH optexec "$_origin_MAGIC_WISH" "$MAGIC_WISH" _magic_check TCLSH optexec "$_origin_TCLSH" "$TCLSH" } # (Re)build the symlink layout. Idempotent; `ln -sf` relinks so a rebuilt target # is always current. Missing globs (a partial build) are tolerated. magic_stage() { local b="$MAGIC_BUILDDIR" s="$MAGIC_SRCDIR" mkdir -p "$MAGIC_SYS" "$MAGIC_TCL" # --- sys/ : generated tech (build) + display files/glyphs/fonts (source) --- ln -sf "$b"/scmos/*.tech "$MAGIC_SYS"/ 2>/dev/null || : ln -sf "$s"/scmos/*.cmap "$s"/scmos/*dstyle "$MAGIC_SYS"/ 2>/dev/null || : ln -sf "$s"/windows/*.glyphs "$s"/windows/vfont.* "$MAGIC_SYS"/ 2>/dev/null || : ln -sf "$s"/graphics/*.glyphs "$s"/graphics/*.pt3 "$MAGIC_SYS"/ 2>/dev/null || : ln -sf "$b"/magic/proto.magicrc "$MAGIC_SYS"/.magicrc 2>/dev/null || : ln -sf "$b"/magic/proto.initrc "$MAGIC_SYS"/.initrc 2>/dev/null || : if [ -f "$b"/magic/magicps.pro ]; then ln -sf "$b"/magic/magicps.pro "$MAGIC_SYS"/ 2>/dev/null || : else ln -sf "$s"/magic/magicps.pro "$MAGIC_SYS"/ 2>/dev/null || : fi # --- tcl/ : source scripts + generated magic.tcl + .so + execs + bitmaps --- ln -sf "$s"/tcltk/*.tcl "$MAGIC_TCL"/ 2>/dev/null || : ln -sf "$b"/tcltk/magic.tcl "$MAGIC_TCL"/ 2>/dev/null || : ln -sf "$b"/magic/tclmagic${SHDLIB_EXT} "$MAGIC_TCL"/ 2>/dev/null || : ln -sf "$b"/tcltk/magicexec "$b"/tcltk/magicdnull "$MAGIC_TCL"/ 2>/dev/null || : # bitmaps is a *directory*: use -n so a re-stage replaces the existing # symlink instead of dereferencing it and dropping a self-link *inside* the # source tree (magic/bitmaps/bitmaps -> .../magic/bitmaps). ln -sfn "$s"/magic/bitmaps "$MAGIC_TCL"/bitmaps 2>/dev/null || : } # Split a launcher's argv on the first "--": # -- # Everything before "--" is for the wrapper tool (gdb/valgrind); everything after # is magic's. With no "--" present, ALL arguments are treated as magic's -- the # common case where no tool options are needed. Results are returned in the # arrays MAGIC_TOOL_OPTS and MAGIC_ARGS. magic_split_args() { MAGIC_TOOL_OPTS=() MAGIC_ARGS=() local seen=0 a for a in "$@"; do if [ "$seen" -eq 0 ] && [ "$a" = "--" ]; then seen=1; continue; fi if [ "$seen" -eq 1 ]; then MAGIC_ARGS+=("$a"); else MAGIC_TOOL_OPTS+=("$a"); fi done if [ "$seen" -eq 0 ]; then MAGIC_ARGS=(${MAGIC_TOOL_OPTS[@]+"${MAGIC_TOOL_OPTS[@]}"}) MAGIC_TOOL_OPTS=() fi } # Fail early with a clear message if the build has not produced the binaries yet. magic_require_built() { if [ ! -x "$MAGIC_BUILDDIR/tcltk/magicexec" ] && \ [ ! -x "$MAGIC_BUILDDIR/tcltk/magicdnull" ]; then echo "error: magic is not built yet -- run 'make' in ${MAGIC_BUILDDIR} first." >&2 exit 1 fi } # Validate the environment as soon as this file is sourced (warnings only). magic_check_env