An application might be written that sources needed files, makes use of images files, etc. All the files are relative to the physical location of the actual program.ProblemHow do you determine the directory (without hardcoding it in the program) that contains your executable? This isn't as easy as you might first think. What if the executable is executed via an alias (UNIX) or shortcut (Windows). Or perhaps a symbolic link (UNIX) to the executable is used.SolutionThis bit of code will do the trick. The while loop is used to resolve multiple symbolic links.
set originalPath [pwd] set scriptPath $::argv0 set workingPath [file dirname $::argv0] while {![catch {file readlink $scriptPath} result]} { cd $workingPath set scriptPath [file join [pwd] $result] set workingPath [file dirname $scriptPath] } cd [file dirname $scriptPath] set scriptPath [pwd] cd $originalPathSee Making a Path Absolute for a related discussion
If you are using a Starkit, the root directory is contained in the starkit::topdir variable
package require starkit puts stderr "root directory = $starkit::topdir"
JOB: The following start sequence in the starkit's main.tcl allows to handle both cases: manually call up main.tcl during development as well as for regular usage of the starkit package:
#!/usr/bin/env tclkit # startup if {[catch { package require starkit if {[starkit::startup] eq {sourced}} return}]} { namespace eval ::starkit { variable topdir [file normalize [file dirname [info script]]] } } # set auto_path [linsert $auto_path 0 [file join $::starkit::topdir]]
FW: Of course, if you're satisfied with it only working if the application is invoked directly, then you can just invoke this code to retrieve the application root:
file dirname [info script]
jys: I wish this functionality was built into Tcl, it's really a necessity for writing code that'll run from your PATH. Anyway, this is my more compact version:
set resolved_path [info script] while {![catch [list file readlink $resolved_path] target]} { set resolved_path $target} source [file join [file dirname $resolved_path] file_to_source.tcl]
US: See also: Techniques for reading and writing application configuration files