This creates a file.o file whenever file.h, otherfile.h, or file.c changes. The file.o file is not an executable; it is an "object file"; a semi-compiled edition of the code, readied for merging with other libraries and pieces of executable.

Advice: The ordering of the .o files, and the LIBS, are often quite sensitive. If you get messages about 'unresolved references', either during the link step or at the time of execution, then this means that the values used are incomplete or inaccurate. For a custom tcl shell, you'd have at least -ltcl in LIBS.

DKF: When linking, it's best to put all the .o (or .obj) files first, and then put libraries after that, either by putting them directly (only suitable for .a/.lib files) or through the -l option. The order of libraries is important (at least with Unix linkers) because symbols missing from later libraries are not satisfied by earlier ones. Getting the library order right can be a distinctly black art at times!

The link step is the step where the program is building your executable. The concept is that each .o object module is loaded in order into a final file. A table of unresolved function references (calls to functions not found in the object file) is created. As these files are encountered, the linker may also encounter -L flags. These flags indicate directory names which contain various 'libraries' of general functions. These files tend to have names with patterns like lib*.a or lib*.so . The .a files are archive libraries containing static object files. Each of these .o files are physically read and searched to see if they contain functions with a name that matches an entry in the unresolved function reference table, the entire .o file is also loaded into the final file. The .so files are shared libraries. They are also searched for matches to unresolved references. In this case however, a special alias name for the shared library is loaded into the image, used to tell the OS at run time that it should search its known path (often called the LD_RUN_PATH or LD_LIB_PATH) for the library name. At run time the loading of the object modules is into memory, not into disk.

One problem that can often be encountered is that the shared library is installed into a directory other than the default or standard locations for shared libraries. In that case, one is faced with two choices. One can force each user to modify appropriate environment variables in a way that the right library is found in the right directory at the right time (this can be tricky if different apps require different shared libraries which share the same name) or when running the linker, one can provide -R flags which embed additional directories to search directly into the executable. The downside of this approach is that it is yet another tie of a binary to a fixed directory naming structure.

Yes: you need to call 'Tcl_FindExecutable(argv[0]);' before 'Tcl_CreateInterp();'. Without this, Tcl's encoding system won't be initialized properly.

The examples at the top of this page do not have to confront the Tcl_FindExecutable() issue, because they take the simplest approach and call Tcl_Main() or Tk_Main(). *_Main() takes care of the call to Tcl_FindExecutable(), the call to Tcl_CreateInterp() to create the master interpreter, and setting up the global argv variable. Tk_Main() also starts an event loop. You only have to worry about these matters if neither Tcl_Main() nor Tk_Main() is suitable for your needs.

DGP

2001-03-27 6:10PM, corrected minor spelling error and changed [] to [[]] in code fragment, so it should look like [] instead of linking to [0]. -EE

Stu 2007-09-29 Tcl provides an easy method to make a custom shell. Simply "borrow" the file tclAppinit.c from the Tcl sources and use the #defines TCL_LOCAL_MAIN_HOOK and TCL_LOCAL_APPINIT.

The result of the following is a tclsh with an added command and the ability to set a global var with a command line option.