The geant4make.csh script is designed to be |source|d from the user's shell in order to define envvars for subsequent GMake builds (e.g., of applications). It includes a code block to determine it's own absolute path, by evaluating the $_ tcsh variable, which holds the last command executed from the terminal. Unfortunately, this "self-discovery" fails when the geant4make.csh script is being |source|d from another, wrapper script. This can be demonstrated easily as follows: % cat > g4make-wrapper.csh # Wrapper script to source installed version of geant4make.csh source /usr/geant4/geant4.9.6/share/Geant4-9.6.0/geant4make/geant4make.csh [Ctrl-D] % source g4make-wrapper.csh (use whatever your local installation path is). This script will generate error messages: /Users/kelsey/geant4/../../../include/Geant4: No such file or directory. /Users/kelsey/geant4/../../../lib/Geant4-9.6.0: No such file or directory. /Users/kelsey/geant4/../../../lib: No such file or directory. and will also produce a set of invalid environment variables. With nested |source| commands, $_ is defined, but it points back to the user's original command (the outer script). Here, that is $_ = "source g4make-wrapper.csh". The self-discovery code collects the directory name as effectively the user's PWD (here "/Users/kelsey/geant4"), which is NOT where G4 9.6 is installed. I have also tried using the "change directories" method suggested in the geant4make.csh script: % cat >! g4make-wrapper.csh # Wrapper script to source installed version of geant4make.csh pushd /usr/geant4/geant4.9.6/share/Geant4-9.6.0/geant4make/ source geant4make.csh popd [Ctrl-D] This also fails, because the test for $_ happens before the "in current directory" test in the self-discovery code.
I have found a workable solution for "self-discovery," in the case of both invocation from an executable script and from nested |source|d scripts. The existing code in geant4make.csh should be replaced with the following: ========== unset g4sls_sourced_dir unset geant4make_root set ARGS=($_) if ("$ARGS" != "") then if ("$ARGS[2]" =~ */geant4make.csh) then set g4sls_sourced_dir = "`dirname ${ARGS[2]}`" endif endif if (! $?g4sls_sourced_dir) then # Oh great, we were sourced non-interactively. This means that $_ # wasn't set to point to this script, so we need an external source # of information on where the script is located. # We obtain this in one of two ways: # 1) Current directory: # cd script_dir ; source geant4make.csh # # 2) Supply the directory as an argument to the script: # source script_dir/geant4make.csh script_dir # if ( -e geant4make.csh ) then set g4sls_sourced_dir = "`pwd`" else if ( "$1" != "" ) then if ( -e ${1}/geant4make.csh ) then set g4sls_sourced_dir = ${1} else echo "ERROR: ${1} does not contain a Geant4 installation" endif endif endif if (! $?g4sls_sourced_dir) then echo "ERROR: geant4make.csh could NOT self-locate Geant4 installation" echo "because it was sourced (i.e. embedded) in another script." echo "This is due to limitations of (t)csh but can be worked around by providing" echo "the directory where geant4make.csh is located" echo "to it, either via cd-ing to the directory before sourcing:" echo " cd where_script_is ; source geant4make.csh" echo "or by supplying the directory as an argument to the script:" echo " source where_script_is/geant4make.csh where_script_is" echo " " exit 1 endif set geant4make_root = "`cd ${g4sls_sourced_dir} > /dev/null ; pwd`" ========== The first part uses $_ as before, but checks to see that the command actually does refer to "source ...../geant4make.csh" before parsing it. The second part is triggered unconditionally (not as an else-block), if the directory wasn't found the first time. It uses the existing conditions to identify the installation area (current dir, argument to |source|). Third, if the directory still has not been found, the descriptive error is reported and an exit status occurs. This avoids having the script fall through and set all the G4 envvars incorrectly. Finally, the terminal "endif" at the end of the script should be removed.
Thanks for the fix Mike! I'll add this in ASAP.
Patch applied in r68414 Mike, could you test this revision please? I have checked that it works in general, but I'm not sure I've covered all the corner cases as I'm not a C-shell expert...
I thought I replied to this long ago...Ben's implementation works fine for me in CSH. geant4make.csh and all the related scripts can be sourced in a nested way successfully.