into what directory should one install the various pieces of a tcl application or extension

Summary

A discussion for developers of extensions or applications about recommended installation directory structure. The directory structure here refers to the final installed structure, as opposed to that of the source archive or build directory.

There might even be some crossover with the directory structure of a starkit or similar construct.

See Also

TEA2
contains some recommendations for a template for arranging code so that it builds and installs in some standard location.
CANTCL
a system for distributing code.

Description

Extensions should use two main groups of directories for installing things, one for architecture-independent files, and one for architecture-dependent files.

Architecture-Independent Files

--prefix
specifies the directory of the architecture-independent files (e.g. Tcl scripts, header files, documentation) and is conventionally /usr/local by default. Beneath this directory, the following directories are usually defined:
include
Directory into which one installs the header file(s) needed when writing code against a library. These are header files for C/C++/etc., and not Tcl code
lib
Directory into which Tcl-only extensions are installed, each into their own directory.
lib/extension-version.level
Directory for pkgIndex.tcl files, tcl files, etc.
bin
Place to install Tcl-only applications and script demos and examples.
man
Place to install nroff manual pages.
share
Place to install miscellaneous other files, such as HTML pages or data files.

Architecture-Dependent Files

--exec-prefix
specifies the directory where architecture-dependent files (binary extensions, etc.) are to be installed.
lib
Directory into which binary extensions and their pkgIndex.tcl are installed, each into their own directory.
lib/extension-version.level
Directory for pkgIndex.tcl files, .so/.dll files, static archives (.a, .lib), etc.
bin
Directory where binary applications and demos are installed.

--exec-prefix defaults to the value of --prefix, except that there is a long-standing bug in TEA which makes this not the case.


jenglish I find it works better to put the entire package runtime in a sibling directory of info library. This is usually the same as ${libdir}, but not always.

Splitting up architecture-dependent (e.g. shared libraries) and architecture-independent (e.g., scripts) parts makes it more difficult for the former to locate the latter.

[someone asks]: Joe, into which of the above directories are you referring? ${prefix}/library?

jenglish The GNU build system conventions (which most projects use nowadays, including TEA-based ones) specify:

  prefix = /usr/local
  exec_prefix = ${prefix}
  libdir = ${exec_prefix}/lib

where you can override the setting for ${prefix} at configure time. If desired, ${exec_prefix} may be overridden independently. So if you install your package into ${libdir}/mypkg-X.Y and you use the same settings for --prefix and --exec-prefix as were used to build Tcl, then tcl_pkgUnknown will be able to find your package. Note that the TEA_PREFIX autoconf macro defined in tclconfig/tcl.m4 will take care of setting --prefix and --exec_prefix to the right values.


It is the eternal difficulty of keeping parallel versions in sync versus keeping a single copy of sharable code and a binary for each platform that causes me to recommend considering the above structure. Also, are you thus recommending that one put the name of the platform into the name of the library?

How about a specific example to help me visualize your suggestion?

For instance, the description above allows either of the following approaches:

 /usr/local/bin/tkconsole
 /usr/local/include/tcl.h
 /usr/local/include/tk.h
 /usr/local/lib/BWidgets1.3/pkgIndex.tcl
 /usr/local/sun4/bin/wish8.4
 /usr/local/sun4/lib/tcl8.4/pkgIndex.tcl
 /usr/local/sun4/lib/tcl8.4/libtcl8.4.so
 /usr/local/sun4/lib/tk8.4/pkgIndex.tcl
 /usr/local/sun4/lib/tk8.4/libtk8.4.so
 /usr/local/hpux5/bin/wish8.4
 /usr/local/hpux5/lib/tcl8.4/pkgIndex.tcl
 /usr/local/hpux5/lib/tcl8.4/libtcl8.4.so
 /usr/local/hpux5/lib/tk8.4/pkgIndex.tcl
 /usr/local/hpux5/lib/tk8.4/libtk8.4.so
 /usr/local/redhat7.2/bin/wish8.4
 /usr/local/redhat7.2/lib/tcl8.4/pkgIndex.tcl
 /usr/local/redhat7.2/lib/tcl8.4/libtcl8.4.so
 /usr/local/redhat7.2/lib/tk8.4/pkgIndex.tcl
 /usr/local/redhat7.2/lib/tk8.4/libtk8.4.so
 /usr/local/share/html/tutorial/file1.html

or, if you had only one platform:

 /usr/local/bin/tkconsole
 /usr/local/bin/wish8.4
 /usr/local/include/tcl.h
 /usr/local/include/tk.h
 /usr/local/lib/BWidgets1.3/pkgIndex.tcl
 /usr/local/lib/tcl8.4/libtcl8.4.so
 /usr/local/lib/tcl8.4/pkgIndex.tcl
 /usr/local/lib/tk8.4/libtk8.4.so
 /usr/local/lib/tk8.4/pkgIndex.tcl
 /usr/local/share/html/tutorial/file1.html

Note that right now, I don't know whether the TEA structure follows the above directory structure or not. The reason I say this is that when I look at my install directory, I find some .a and .so files being directly installed under ${exec_prefix}/lib/ and some being installed under ${exec_prefix}/lib/{extension}*/ .

The downside of installing everything under its own directory is that link statements become more complex. The upside is consistency in the way that the install software gets written, the pattern that new packages follow, etc..


What are your thoughts about installed extensions having version numbers in their directory names?

Some people use multiple versions of an extension to keep from having to relink compiled language based programs. Other people see no reason to distribute anything more than one version and just expect people to install things into separate trees if parallel versions need to be maintained.


What about demos? I would prefer to see demo executables be installed in $prefix/bin, instead of the current practice of some extensions of putting them into $prefix/lib/extension$version.$level/demos or whatever .

What about graphical files - icons, fonts, etc.? Should these go into ${prefix}/lib/{extension}*/ or should they perhaps be installed in ${prefix}/share ?


CL noted in comp.lang.tcl on the problem of where to put config files:

What a mess.  Someone ought to go off for a few years,
and create a useful solution to such common and stupid
deployment problems.  Maybe it should be called TclKit,
or perhaps called that, but renamed to StarKit.  Just
think if it were portable, too!  The masses would re-
joice.

to which BBH replied: Amen, Brother Laird!

(NB. A Starkit is a single file per app that contains all configuration, source, binaries, etc.) Installation is by copying, deinstallation by deleting.


Kevin Walzer commented, "... The standard tool is PackageMaker, which Apple provides with its developer tools for free.

However, using an installer on the Mac is generally recommended only if you are installing a lot of different components in different locations (i.e. a GUI in /Applications, a command-line tool in /usr/local/bin, and a library in /Library/Frameworks). If you have all of your bits in a single app bundle, an installer is strongly discouraged by Apple. Users prefer to install their applications in their own preferred location, via drag-and-drop.

I know this is different from Windows. The Mac doesn't have anything that is analogous to the registry, where users expect and appreciate an installer. In fact, it's quite the opposite."


LV: I've seen a variety of approaches for dealing with documentation as well. Some packages install nroff man pages, some make HTML files available , some provide the means to install the HTML into destinations, some provide plain text, PDF, etc. formatted files. Some packages make one doc file which contains all the commands of a package (tclx for example) while others make separate pages for each command. Some make certain their man page names begin with the name of their extension, so that they don't accidentally overwrite someone else's man page, and others just install overtop of anything already there.