1+ #! /bin/bash
2+ #
3+ # Wrapper around the spack environment that defines some useful commands.
4+ #
5+ # Activate the environment by sourcing this file with
6+ # . activate_h3env
7+ #
8+ # Run 'help_h3env' with the environment activated to see the available commands
9+
10+ # Record top-level dir
11+ REPO_ROOT=$( cd -- " $( realpath $( dirname -- " ${BASH_SOURCE[0]} " ) ) " & > /dev/null && pwd )
12+
13+ # Save shell options
14+ OLD_SHOPTS=" $( set +o) "
15+
16+ # ======================= Convenience aliases/functions ========================
17+
18+ # Creates a link to the specified target (first argument) with the specified
19+ # name (second argument), unless a link with that target and name already
20+ # exists. It will overwrite links to different targets. Also print a message
21+ # saying what it is doing.
22+ _create-link () {
23+ target=" $1 "
24+ link=" $2 "
25+ if ! [[ -L " $link " && $( readlink " $link " ) == " $target " ]]
26+ then
27+ echo " Linking $( realpath -s --relative-to=" $REPO_ROOT " " $link " ) => $target "
28+ rm -f " $link " > /dev/null
29+ ln -s " $target " " $link "
30+ fi
31+ }
32+
33+ # Remove the DEBUG trap and restore original shell options
34+ _disable_link_updates_hook () {
35+ trap - DEBUG
36+ set +vx; eval " ${OLD_SHOPTS} "
37+ }
38+
39+ # Activate temporary DEBUG trap to update build links
40+ _enable_link_updates_hook () {
41+ shopt -s extdebug
42+ trap _update_links_on_spack_install DEBUG
43+ }
44+
45+ # Intercept all simple commands and, if spack (un)install is executing, update build links afterwards
46+ # N.B. the simple command itself runs AFTER this function iff it runs zero
47+ function _update_links_on_spack_install ()
48+ {
49+ if [[ $BASH_COMMAND == " spack " * " install" * ]]; then
50+ $BASH_COMMAND
51+ updatelinks_h3env
52+ # (We've already run the command explicitly, return non-zero so that it doesn't run again.)
53+ return 1
54+ else
55+ # (Just run the command as usual after this function returns)
56+ return 0
57+ fi
58+ }
59+
60+ # Perform cleanup tasks
61+ cleanup_h3env () {
62+ # Just update build links for now
63+ updatelinks_h3env
64+ }
65+
66+ # Remove convenience aliases/function definitions and deactivate the env
67+ deactivate_h3env () {
68+
69+ _disable_link_updates_hook
70+
71+ unset -f _create-link
72+ unset -f cleanup_h3env
73+ unset -f deactivate_h3env
74+ unset -f _disable_link_updates_hook
75+ unset -f _enable_link_updates_hook
76+ unalias help_h3env
77+ unset -f in_h3env
78+ unset REPO_ROOT
79+ unset -f _update_links_on_spack_install
80+ unset -f updatelinks_h3env
81+ unset -f usage_h3env
82+
83+ spack env deactivate
84+ }
85+
86+ # Run commands in the build environment
87+ h3spec=" hermes-3%gcc"
88+ in_h3env () {
89+ if [ $# -eq 0 ]; then
90+ usage_h3env
91+ return
92+ fi
93+ cmd=" spack build-env ${h3spec} $@ "
94+ echo $cmd
95+ eval $cmd
96+ }
97+
98+ # Update the links at <REPO_ROOT>/builds/spack-* such that there's
99+ # exactly one link for every package returned by 'spack find hermes-3'
100+ updatelinks_h3env () {
101+ local links_dir=" ${REPO_ROOT} /builds"
102+ local link_prefix=" spack-"
103+
104+ # Use 'spack find' to get the hashes of currently installed hermes-3 packages
105+ # Discard stderr to suppress error message when no installs are found
106+ local identifier_fmt=" {hash:7}"
107+ installed_hashes=$( spack find --format " $identifier_fmt " " hermes-3" 2> /dev/null)
108+
109+ # Create any links for installed packages that don't exist already
110+ mkdir -p " ${links_dir} "
111+ for hash in $installed_hashes ; do
112+ spack_build_dir=$( spack location -b " hermes-3/$hash " )
113+ _create-link " ${spack_build_dir} " " ${links_dir} /${link_prefix}${hash} "
114+ done
115+
116+ # Check whether existing links are still valid (Could also just use find -xtype l ?)
117+ for l in " ${links_dir} /${link_prefix} " * ; do
118+ # Skip if l isn't a link (also guards against case where pattern has zero matches)
119+ [ ! -L " $l " ] && break ;
120+ hash=$( echo " $l " | rev| cut -c -7| rev)
121+ # Remove link if 'spack find' returns non-zero for this hash
122+ spack find " hermes-3/$hash " & > /dev/null
123+ if [ $? -ne 0 ]; then
124+ echo " Removing stale link at $l "
125+ rm -f " $l "
126+ fi
127+ done
128+
129+ # Also clean up top-level build links created by spack install
130+ spack_link_paths=$( find " $REPO_ROOT " -type l -regextype posix-egrep -regex " ${REPO_ROOT} /build-.*-[a-z0-9]{7}$" )
131+ for link_path in $spack_link_paths ; do
132+ local hash=" ${link_path: (-7)} "
133+ if ! [[ " ${installed_hashes[*]} " =~ " ${hash} " ]]
134+ then
135+ echo " Removing stale spack link at ${link_path} "
136+ rm -Rf " $link_path " > /dev/null
137+ fi
138+ done
139+ }
140+
141+ # Print help/usage info
142+ usage_h3env () {
143+ echo " . activate_h3env : Activate the environment"
144+ echo " cleanup_h3env : Perform cleanup tasks (includes updatelinks_h3env)"
145+ echo " deactivate_h3env : Deactivate the environment"
146+ echo " help_h3env : Show this message"
147+ echo ' in_h3env [args] : Run a command in the build environment: (e.g. export h3_build="./builds/my_build" && in_h3env cmake -B "$h3_build" && in_h3env cmake --build "$h3_build" -j8)'
148+ echo " updatelinks_h3env : Update all build links (Remove stale links and add new ones in ./builds/spack-* where necessary)"
149+ }
150+ alias help_h3env=usage_h3env
151+
152+ # ============================== Run on activate ===============================
153+
154+ # Check that spack has been set up
155+ spacktivate_cmd=" spacktivate"
156+ if ! command -v " $spacktivate_cmd " & > /dev/null
157+ then
158+ echo " The $spacktivate_cmd alias doesn't seem to be defined. Have you installed spack and sourced \$ SPACK_ROOT/share/spack/setup-env.sh?"
159+ return 1
160+ fi
161+
162+ # Check that BOUT-spack has been cloned
163+ sm_name=" BOUT-spack"
164+ repo_yaml=" ${REPO_ROOT} /external/${sm_name} /repo.yaml"
165+ if [ ! -f " $repo_yaml " ]
166+ then
167+ echo " $repo_yaml doesn't exist. Has the ${sm_name} git submodule been initialised?"
168+ echo " (git submodule update --init)"
169+ return
170+ fi
171+
172+ # Activate the environment and load the view
173+ spacktivate . -p -v gcc
174+
175+ # Update build links
176+ cleanup_h3env
177+
178+ _enable_link_updates_hook
0 commit comments