Development/Tasks/Packaging/Policies/Tcl
From Mandriva Community Wiki
These conventions apply to Tcl packages in Mandriva Linux 2009 Spring and later (and Cooker since the upload of Tcl / Tk 8.6 on 2008/12/04). Earlier releases followed no clear policy; Tcl / Tk modules placed anywhere within /usr/lib or /usr/lib64 will work. The macros discussed in this policy have been or will be provided for Mandriva Linux 2008 Spring and Mandriva Linux 2009 in updated packages in the /backports repository, so that Tcl-based packages can still be easily backported to these releases from Cooker without conditionals being needed.
Contents |
Naming Conventions
The name for all Tcl/Tk extensions must be prefixed with tcl-. The rest of the name should be based on the name of the module (not the name of the upstream tarball), lower-cased if necessary. So if upstream tarball name monkeys provides a Tcl extension named nuts, the Tcl package should be named tcl-nuts. This rule applies even for Tcl/Tk packages that are already prefixed with tcl in the name (see examples below). An optional Provides: foo is recommended to allow selecting the package based on the upstream name, as long as the upstream name is not excessively generic and does not conflict with an existing package name. You may also add a Provides: for the upstream tarball name if different from the Tcl module name. Tk extensions have the option of adding additional Provides: with the prefix tk-.
Examples:
Name: tcl-bwidget
Provides: bwidget = %{version}-%{release}, tk-bwidget = %{version}-%{release}
Name: tcl-tclxml
Provides: tclxml = %{version}-%{release}
Name: tcl-thread
The exception to this naming rule are existing packages that provide both an extension and a shell, such as expect. However, note that providing a shell is strongly discouraged (see below). If a Tcl extension is provided as part of a larger package this rule may also not apply, but in general, the Tcl extension should be split out into a separate package in this case.
Applications
Tcl and Tk applications must use a non-versioned interpreter name in shebang line. This is to prevent any unnecessary dependency on the version of the interpreter being used. Most dependencies are with specific Tcl extensions, not the command line applications. Nevertheless, if an application does require a specific version of Tcl, it should use the standard Tcl package system to express this.
Bad:
#!/usr/bin/tclsh8.6
Good:
#!/usr/bin/tclsh package require -exact Tcl 8.6
The same rules apply for Tk applications. The non-versioned wish interpreter name must be used.
Extensions
Tcl in Mandriva Linux 2009 and earlier searches for extensions in all subdirectories of the following directories: %{_libdir} and %{_prefix}/lib. In Mandriva Linux 2009 Spring, %{_libdir} and %{_prefix}/lib have been removed from the search path to optimize package loading times. Instead, Tcl extension packages must be installed in %{_datadir}/tcl8.x if they are noarch packages containing only Tcl code, or %{_libdir}/tcl8.x if they are arch-specific extensions containing shared libraries. Note that most Tcl extensions are not configured do install in these directories out of the box, and may need to use additional configure switches, patches, or script code in %install to move the files to the correct location.
Note that this will result in all packages which provide Tcl modules needing to be re-compiled for new minor versions of Tcl - 8.7 vs. 8.6, for instance - but this is a relatively minor inconvenience, and many would likely require other fixes in such a situation in any case.
Macros
The libtcl-devel (or lib64tcl-devel) package, since version 8.6, now provides three important macros:
%tcl_version %tcl_sitelib %tcl_sitearch
%tcl_version simply gives the current major/minor version of Tcl. %tcl_sitelib is the correct arch-independent location for installing pure Tcl extensions: for instance, at present, it returns /usr/share/tcl8.6. %tcl_sitearch is the correct arch-dependent location for installing compiled, arch-dependent Tcl extensions: for instance, at present, it returns /usr/lib/tcl8.6 or /usr/lib64/tcl8.6, depending on the architecture in use. All packages must use these macros rather than attempting to provide their own for the same information, or creating the paths as %{_datadir}/tcl8.6 or similar. Note that as the macros are provided in the -devel package, even pure Tcl packages which require no compilation must BuildRequire tcl-devel.
noarch packages
Merely adding the %{tcl_sitearch} and %{tcl_sitelib} is not enough to ensure that the packages get installed into the correct location. Most Tcl extensions will install into %{_libdir} by default. There are two ways to change this. For most noarch packages, you can use the --libdir and --datadir configure switches to change the installation directory:
%configure2_5x --libdir=%{tcl_sitelib} --datadir=%{tcl_sitelib}
For noarch packages that aren't fixed by using --libdir, you can simply move the installation directory in the %install section of the spec file.
%install
rm -rf %{buildroot}
%makeinstall_std
install -d %{buildroot}%{tcl_sitelib}
mv %{buildroot}%{_datadir}/foobar%{version} %{buildroot}%{tcl_sitelib}/foobar%{version}
It may also be acceptable to patch upstream's configure script and Makefile to add additional flexibility for the install directory, but the packager is not required to do this.
arch-specific packages
The --libdir flag for the configure script can often be used to set the correct installation directory:
%build
%configure2_5x --libdir=%{tcl_sitearch}
For packages that do not respond properly to alternate values for --libdir, you can simply move the installation directory in the %install section of the spec file:
%install
rm -rf %{buildroot}
%makeinstall_std
install -d %{buildroot}%{tcl_sitearch}
mv %{buildroot}%{_libdir}/foobar%{version} %{buildroot}%{tcl_sitearch}/foobar%{version}
It may also be acceptable to patch upstream's configure script and Makefile to add additional flexibility for the install directory, but the packager is not required to do this.
arch-specific packages can be generally grouped into three categories: those that provide a shell, those that provide a fooConfig.sh file and a shared library for linking, and those that only provide a shared library for dlopen().
No shells
Very few Tcl extension packages provide a shell. Providing a shell for an extension is frowned upon. The extension's shared library can be dynamically loaded into a Tcl interpreter through the standard package require ... mechanism without providing a shell that automatically loads the shared library. The exceptions to this rule are the shells that are commonly expected to be present on a system, including Tk (wish) and Expect (expect, expectk).
-devel subpackage for fooConfig.sh
Some arch-specific Tcl extensions provide a shared library and a corresponding fooConfig.sh file with instructions for linking against the library. The shared library for such packages must be installed into %{_libdir} so that it can be found at runtime by applications that link against it. Unfortunately, the pkgIndex.tcl file in the package directory often references the shared library with a relative path. There are two ways to fix this. First, the maintainer can choose to keep the installation directory as %{_libdir}, and make a symlink to %{tcl_sitearch}. Second, the maintainer can choose to patch the pkgIndex.tcl file to contain an appropriate path to the shared library. Either solution is acceptable.
fooConfig.sh files must be placed in a -devel subpackage. This may require some sed magic to modify fooConfig.sh so that the paths to the libraries and headers are still correct.
No dlopen()'d libraries in %{_libdir}
If the extension does not provide a fooConfig.sh file, then the shared library must not be installed directly in %{_libdir} , but in the package-specific installation directory in %{tcl_sitearch} instead. This may require a patch to update the extension's pkgIndex.tcl file to look for the shared library in the correct location.
Stubs are OK if put in -devel subpackage
Some Tcl extensions provide a static 'stub' library. Stub libraries are a Tcl-ism to provide version-independent dynamic linking on a variety of platforms. These are not normal static libraries that provide the library's actual functionality, but instead provide a level of indirection pointing to the shared library. These stub libraries do not have the same static linking issues that are generally frowned upon, and thus are acceptable. If a package provides such a stub library, it must be placed in a -devel subpackage. More information on stubs can be found on the Tcl wiki.

