diff --git a/tcltk/Makefile b/tcltk/Makefile index 97f214ad2..283f8293c 100644 --- a/tcltk/Makefile +++ b/tcltk/Makefile @@ -32,6 +32,11 @@ TCL_FILES = \ readspice.tcl \ magic.tcl +TCL_DIR_REL_OR_ABS = $(shell ${MAGICDIR}/tcltk/relpath.sh "$(DESTDIR)${INSTALL_BINDIR}" ${TCLDIR}) +ifeq ($(TCL_DIR_REL_OR_ABS),) +TCL_DIR_REL_OR_ABS = ${TCLDIR} +endif + BIN_FILES = \ $(DESTDIR)${INSTALL_BINDIR}/magic.sh \ $(DESTDIR)${INSTALL_BINDIR}/ext2spice.sh \ @@ -65,16 +70,16 @@ magic.tcl: magic.tcl.in ${MAGICDIR}/defs.mak ${MAGICDIR}/VERSION magic.tcl.in > magic.tcl magic.sh: magic.sh.in ${MAGICDIR}/defs.mak - sed -e /TCL_DIR/s%TCL_DIR%${TCLDIR}%g \ + sed -e /TCL_DIR_REL_OR_ABS/s%TCL_DIR_REL_OR_ABS%${TCL_DIR_REL_OR_ABS}%g \ -e /TCLLIB_DIR/s%TCLLIB_DIR%${TCL_LIB_DIR}%g \ -e /WISH_EXE/s%WISH_EXE%${WISH_EXE}%g magic.sh.in > magic.sh ext2spice.sh: ext2spice.sh.in ${MAGICDIR}/defs.mak - sed -e /TCL_DIR/s%TCL_DIR%${TCLDIR}%g \ + sed -e /TCL_DIR_REL_OR_ABS/s%TCL_DIR_REL_OR_ABS%${TCL_DIR_REL_OR_ABS}%g \ ext2spice.sh.in > ext2spice.sh ext2sim.sh: ext2sim.sh.in ${MAGICDIR}/defs.mak - sed -e /TCL_DIR/s%TCL_DIR%${TCLDIR}%g \ + sed -e /TCL_DIR_REL_OR_ABS/s%TCL_DIR_REL_OR_ABS%${TCL_DIR_REL_OR_ABS}%g \ ext2sim.sh.in > ext2sim.sh $(DESTDIR)${INSTALL_TCLDIR}/%: % diff --git a/tcltk/ext2sim.sh.in b/tcltk/ext2sim.sh.in index d07400983..61d69cf81 100755 --- a/tcltk/ext2sim.sh.in +++ b/tcltk/ext2sim.sh.in @@ -14,12 +14,14 @@ for i in $@; do *) esargs="$esargs $i" ;; esac done -TCL_MAG_DIR=${CAD_ROOT}/magic/tcl -if [ "${TCL_MAG_DIR}" = "/magic/tcl" ]; then - TCL_MAG_DIR=TCL_DIR +TCL_REL_OR_ABS=TCL_DIR_REL_OR_ABS +if [ "${TCL_REL_OR_ABS:0:1}" = "/" ]; then + TCL_DIR=$TCL_REL_OR_ABS +else + TCL_DIR=$(cd $(dirname ${BASH_SOURCE[0]})/$TCL_REL_OR_ABS; pwd -P) fi # -eval ${TCL_MAG_DIR}/magicdnull -dnull -noconsole -nowrapper $mgargs <= 8.6} { load -lazy [file join $MAGIC_TCL_DIR tclmagic[info sharedlibextension]] diff --git a/tcltk/magicdnull.c b/tcltk/magicdnull.c index b75531b2f..263f19b69 100644 --- a/tcltk/magicdnull.c +++ b/tcltk/magicdnull.c @@ -28,8 +28,17 @@ magic_AppInit(interp) /* This is where we replace the home ".tclshrc" file with */ /* magic's startup script. */ - - Tcl_SetVar(interp, "tcl_rcFileName", TCL_DIR "/magic.tcl", TCL_GLOBAL_ONLY); + /* Try to find magic.tcl relative to the current executable. + If that fails, try to load it from the path where it was located + at build time. + */ + const char *magic_tcl_path = NULL; + if (Tcl_ExprString(interp, "[file join [file dirname [info nameofexecutable]] magic.tcl]") == TCL_OK) { + magic_tcl_path = Tcl_GetStringResult(interp); + } else { + magic_tcl_path = TCL_DIR "/magic.tcl"; + } + Tcl_SetVar(interp, "tcl_rcFileName", magic_tcl_path, TCL_GLOBAL_ONLY); /* Additional variable can be used to tell if magic is in batch mode */ Tcl_SetVar(interp, "batch_mode", "true", TCL_GLOBAL_ONLY); diff --git a/tcltk/magicexec.c b/tcltk/magicexec.c index 73abbd3ac..621dbd2f6 100644 --- a/tcltk/magicexec.c +++ b/tcltk/magicexec.c @@ -59,7 +59,17 @@ magic_AppInit(interp) /* This is where we replace the home ".wishrc" file with */ /* magic's startup script. */ - Tcl_SetVar(interp, "tcl_rcFileName", TCL_DIR "/magic.tcl", TCL_GLOBAL_ONLY); + /* Try to find magic.tcl relative to the current executable. + If that fails, try to load it from the path where it was located + at build time. + */ + const char *magic_tcl_path = NULL; + if (Tcl_ExprString(interp, "[file join [file dirname [info nameofexecutable]] magic.tcl]") == TCL_OK) { + magic_tcl_path = Tcl_GetStringResult(interp); + } else { + magic_tcl_path = TCL_DIR "/magic.tcl"; + } + Tcl_SetVar(interp, "tcl_rcFileName", magic_tcl_path, TCL_GLOBAL_ONLY); return TCL_OK; } diff --git a/tcltk/relpath.sh b/tcltk/relpath.sh new file mode 100755 index 000000000..abeac9591 --- /dev/null +++ b/tcltk/relpath.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# From https://stackoverflow.com/questions/2564634/convert-absolute-path-into-relative-path-given-a-current-directory-using-bash +# both $1 and $2 are absolute paths beginning with / +# returns relative path to $2/$target from $1/$source +source=$1 +target=$2 + +common_part=$source # for now +result="" # for now + +while [[ "${target#$common_part}" == "${target}" ]]; do + # no match, means that candidate common part is not correct + # go up one level (reduce common part) + common_part="$(dirname $common_part)" + # and record that we went back, with correct / handling + if [[ -z $result ]]; then + result=".." + else + result="../$result" + fi +done + +if [[ $common_part == "/" ]]; then + # special case for root (no common path) + result="$result/" +fi + +# since we now have identified the common part, +# compute the non-common part +forward_part="${target#$common_part}" + +# and now stick all parts together +if [[ -n $result ]] && [[ -n $forward_part ]]; then + result="$result$forward_part" +elif [[ -n $forward_part ]]; then + # extra slash removal + result="${forward_part:1}" +fi + +echo $result