libmodules.tcl 8.56 KB
Newer Older
1 2 3 4 5 6
#
# :TODO:
# switch/swap
# unload modules if parent removed
#

gsell's avatar
gsell committed
7
if {[info exists env(PMODULES_DEBUG)] && $env(PMODULES_DEBUG)} {
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
	proc debug {msg} {
		set level [expr [info level] -2] 
		set r [catch {info level ${level}} e]
		if {$r} {
			set caller ""
		} else {
			set caller [lindex [split [info level [expr [info level] - 3]]] 0]
		}
		puts -nonewline stderr "${caller}: "
		puts stderr ${msg}
	}
} else {
	proc debug {msg} {}
}

gsell's avatar
gsell committed
23 24 25
debug "loading libmodules"

proc module-addgroup { group } {
26 27 28 29
	global env
	global name
	global version

gsell's avatar
gsell committed
30 31
	debug $group
	set Implementation [file join {*}$::implementation]
32

gsell's avatar
gsell committed
33 34 35 36
	set	GROUP [string toupper $group]
	regsub -- "-" ${GROUP} "_" GROUP
	setenv	${GROUP}		$name
	setenv	${GROUP}_VERSION	$version
37

gsell's avatar
gsell committed
38 39
	set	::${group}		$name
	set	::${group}_version	$version
40 41 42

	if { [module-info mode load] } {
		debug "mode is load"
gsell's avatar
gsell committed
43 44 45

		append-path MODULEPATH $::PmodulesRoot/$group/$::PmodulesModulfilesDir/$Implementation
		append-path PMODULES_USED_GROUPS $group
46
		debug "mode=load: new MODULEPATH=$env(MODULEPATH)"
gsell's avatar
gsell committed
47
		debug "mode=load: new PMODULES_USED_GROUPS=$env(PMODULES_USED_GROUPS)"
48 49 50
	} elseif { [module-info mode remove] } {
		# remove orphan modules
		debug "remove orphan modules"
gsell's avatar
gsell committed
51 52 53
		set GROUP [string toupper $group]
		if { [info exists env(PMODULES_LOADED_${GROUP})] } {
			set modules [split $env(PMODULES_LOADED_${GROUP}) ":"]
54 55 56 57
			foreach m ${modules} {
				if { ${m} == "--APPMARKER--" } {
					continue
				}
gsell's avatar
gsell committed
58 59 60 61
				if { [is-loaded ${module_name}] } {
					debug "unloading module: $m"
					module unload ${m}
				}
62 63
			}
		}
gsell's avatar
gsell committed
64 65
		remove-path MODULEPATH $::PmodulesRoot/$group/$::PmodulesModulfilesDir/$Implementation
		remove-path PMODULES_USED_GROUPS $group
66
		debug "mode=remove: $env(MODULEPATH)"
gsell's avatar
gsell committed
67
		debug "mode=remove: $env(PMODULES_USED_GROUPS)"
68 69 70
	}
	if { [module-info mode switch2] } {
		debug "mode=switch2"
gsell's avatar
gsell committed
71 72
		append-path MODULEPATH $::PmodulesRoot/$group/$::PmodulesModulfilesDir/[module-info name]
		append-path PMODULES_USED_GROUPS ${group}
73 74 75
	}
}

gsell's avatar
gsell committed
76 77
proc set-family { group } {
        module-addgroup $group
78 79
}

gsell's avatar
gsell committed
80 81 82
proc _pmodules_update_loaded_modules { group name version } {
	if { ${group} == "--APPMARKER--" } {
		return
83
	}
gsell's avatar
gsell committed
84 85 86 87
	set GROUP [string toupper $group]
	debug "${GROUP} $name/$version"
	append-path PMODULES_LOADED_${GROUP} "$name/$version"
	remove-path PMODULES_LOADED_${GROUP} "--APPMARKER--"
88 89 90 91 92
}

#
# load dependencies, but do *not* unload dependencies
#
gsell's avatar
gsell committed
93
proc _pmodules_load_dependencies { fname } {
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
	if { ! [ file exists ${fname} ] } {
		return
	}
	if { ! [module-info mode load] } {
		return
	}
	debug "load dependencies from: ${fname}"
	#  Slurp up the data file
	set fp [open ${fname} r]
	set file_data [read ${fp}]
	close ${fp}
	set data [split ${file_data} "\n"]
	foreach line ${data} {
		debug "MODULEPATH=$::env(MODULEPATH)"
		set module_name [string trim $line]
		if { ${module_name} == "#" || ${module_name} == "" } {
			continue
		}
		if { [is-loaded ${module_name}] } {
			debug "module already loaded: ${module_name}"
			continue
		}
		debug "module load: ${module_name}"
		module load ${module_name}
     }
}

proc lreverse_n { list n } {
        set res {}
        set i [expr [llength $list] - $n]
        while {$i >= 0} {
                lappend res {*}[lrange $list $i [expr $i+$n-1]]
                incr i -$n
        }
        set res
}

#
# set standard environment variables
#
gsell's avatar
gsell committed
134
proc _pmodules_setenv { PREFIX name version } {
135 136
	#
	# Hack for supporting legacy modules
gsell's avatar
gsell committed
137
	if { "${::group}" == "Legacy" } {
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
		debug "this is a legacy module..."
		return
	}

	set		NAME			[string toupper $name]
	regsub -- "-" ${NAME} "_" NAME

	if { ! [info exist ::dont-setenv] } {
		set ::dont-setenv {}
	}

	if { ${version} != "" } {
		if { [lsearch ${::dont-setenv} "${NAME}_VERSION"] == -1 } {
			setenv		${NAME}_VERSION		$version
		}
	}

	if { [file isdirectory "$PREFIX"] } {
		if { [lsearch ${::dont-setenv} "${NAME}_PREFIX"] == -1 } {
			setenv		${NAME}_PREFIX		$PREFIX
		}
		if { [lsearch ${::dont-setenv} "${NAME}_DIR"] == -1 } {
			setenv		${NAME}_DIR		$PREFIX
		}
		if { [lsearch ${::dont-setenv} "${NAME}_HOME"] == -1 } {
			setenv		${NAME}_HOME		$PREFIX
		}
165 166
	} else {
		debug "$PREFIX is not a directory"
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
	}

	if { [file isdirectory "$PREFIX/bin"] } {
		if { [lsearch ${::dont-setenv} "PATH"] == -1 } {
			prepend-path	PATH			$PREFIX/bin
		}
	}

	if { [file isdirectory "$PREFIX/sbin"] } {
		if { [lsearch ${::dont-setenv} "PATH"] == -1 } {
			prepend-path	PATH			$PREFIX/sbin
		}
	}

	if { [file isdirectory "$PREFIX/share/man"] } {
		if { [lsearch ${::dont-setenv} "MANPATH"] == -1 } {
			prepend-path	MANPATH			$PREFIX/share/man
		}
	}

	# set various environment variables - as long as they are not blacklisted
	debug "prepend to include paths"
	if { [file isdirectory "$PREFIX/include"] } {
		if { [lsearch ${::dont-setenv} "C_INCLUDE_PATH"] == -1 } {
			prepend-path	C_INCLUDE_PATH		$PREFIX/include
		}
		if { [lsearch ${::dont-setenv} "CPLUS_INCLUDE_PATH"] == -1 } {
			prepend-path	CPLUS_INCLUDE_PATH	$PREFIX/include
		}
		if { [lsearch ${::dont-setenv} "${NAME}_INCLUDE_DIR"] == -1 } {
			setenv		${NAME}_INCLUDE_DIR	$PREFIX/include
		}
	}

	debug "prepend to library paths"
	if { [file isdirectory "$PREFIX/lib"] } {
		if { [lsearch ${::dont-setenv} "LIBRARY_PATH"] == -1 } {
			prepend-path	LIBRARY_PATH		$PREFIX/lib
		}
		if { [lsearch ${::dont-setenv} "LD_LIBRARY_PATH"] == -1 } {
			prepend-path	LD_LIBRARY_PATH		$PREFIX/lib
		}
		if { [lsearch ${::dont-setenv} "${NAME}_LIBRARY_DIR"] == -1 } {
			setenv		${NAME}_LIBRARY_DIR	$PREFIX/lib
		}
	}

	debug "prepend to library paths (64bit)"
	if { [file isdirectory "$PREFIX/lib64"] } {
		if { [lsearch ${::dont-setenv} "LIBRARY_PATH"] == -1 } {
			prepend-path	LIBRARY_PATH		$PREFIX/lib64
		}
		if { [lsearch ${::dont-setenv} "LD_LIBRARY_PATH"] == -1 } {
			prepend-path	LD_LIBRARY_PATH		$PREFIX/lib64
		}
		if { [lsearch ${::dont-setenv} "${NAME}_LIBRARY_DIR"] == -1 } {
			setenv		${NAME}_LIBRARY_DIR	$PREFIX/lib64
		}
	}
}

gsell's avatar
gsell committed
228 229 230
proc module-url { _url } {
	set ::url ${_url}
}
231

gsell's avatar
gsell committed
232 233 234
proc module-license { _license } {
	set ::license ${_license}
}
235

gsell's avatar
gsell committed
236 237
proc module-maintainer { _maintainer } {
	set ::maintainer ${_maintainer}
238 239
}

gsell's avatar
gsell committed
240 241 242
proc module-help { _help } {
	set ::help ${_help}
}
243 244 245 246

proc ModulesHelp { } {
	if { [info exists ::whatis] } {
		puts stderr "${::whatis}"
gsell's avatar
gsell committed
247 248
	} else {
		module whatis ModulesCurrentModulefile
249 250 251
	}
	if { [info exists ::version] } {
		puts stderr "Version:    ${::version}"
gsell's avatar
gsell committed
252 253
	} else {
		module whatis
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
	}
	if { [info exists ::url] } {
		puts stderr "Homepage:   ${::url}"
	}
	if { [info exists ::license] } {
		puts stderr "License:    ${::license}"
	}
	if { [info exists ::maintainer] } {
		puts stderr "Maintainer: ${::maintainer}"
	}
	if { [info exists ::help] } {
		puts stderr "${::help}\n"
	}
}

gsell's avatar
gsell committed
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
#
# intialize global vars
# Modulefile is something like
#
#   ${PMODULES_ROOT}/group/${PMODULES_MODULEFILES_DIR}/name/version
# or
#   ${PMODULES_ROOT}/group/${PMODULES_MODULEFILES_DIR}/X1/Y1/name/version
# or
#   ${PMODULES_ROOT}/group/${PMODULES_MODULEFILES_DIR}/X1/Y1//X2/Y2/name/version
#
proc _pmodules_init_global_vars { } {
	global	group
	global  name
	global  version
	global	implementation
	global	PREFIX		# prefix of package

	debug	"$::ModulesCurrentModulefile"
	set	::PmodulesRoot		$::env(PMODULES_ROOT)
	set	::PmodulesModulfilesDir	$::env(PMODULES_MODULEFILES_DIR)
	set	modulefile		[file split $::ModulesCurrentModulefile]
	set	pmodules_root		[file split $::PmodulesRoot]
	set	pmodules_root_num_dirs	[llength $pmodules_root]

	set	modulefile_root	[file join {*}[lrange $modulefile 0 [expr $pmodules_root_num_dirs - 1]]]
	if { $::PmodulesRoot != $modulefile_root } {
		debug "stop sourcing: ${::PmodulesRoot} != $modulefile_root"
		return
	} 
	debug	"modulefile is inside our root"
	set	rel_modulefile	[lrange $modulefile [llength $pmodules_root] end]
	set	group		[lindex $rel_modulefile 0]
	set	name		[lindex $modulefile end-1]
	set	version		[lindex $modulefile end]
	set	implementation	[lrange $rel_modulefile 2 end]
	set	prefix		"$pmodules_root $group [lreverse_n $implementation 2]"
	set	PREFIX		[file join {*}$prefix]

	debug "PREFIX=$PREFIX"
	debug "group of module $name: $group"
}

proc _pmodules_output_message { fname } {
	if { [ file exists "${fname}" ] } {
		set fp [open "${fname}" r]
		set info_text [read $fp]
		close $fp
		puts stderr ${info_text}
	}
}

320 321 322
if { [info exists ::whatis] } {
	module-whatis	"$whatis"
}
gsell's avatar
gsell committed
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340

_pmodules_init_global_vars 

#
# we cannot load another module with the same name
#
conflict	$name

if { [module-info mode load] } {
	debug "${name}/${version}: loading ... "
	_pmodules_output_message "${PREFIX}/.info"
	_pmodules_load_dependencies "${PREFIX}/.dependencies"
}

_pmodules_setenv ${PREFIX} ${name} ${version}
_pmodules_update_loaded_modules ${group} ${name} ${version}

debug "return from lib"