Tcl packaging guidelines
These conventions apply to Tcl packages in Fedora 9 and later. There are some aspects of Tcl in Fedora 7 and Fedora 8 that will conflict with these guidelines.
Naming Conventions
The name for all Tcl/Tk extensions must be prefixed with tcl-
. 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. 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).
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, as well as an explicit
Requires: tcl(abi) = 8.x
in the spec file.
Bad:
#!/usr/bin/tclsh8.5
Good:
#!/usr/bin/tclsh package require -exact Tcl 8.5
The same rules apply for Tk applications. The non-versioned wish
interpreter name must be used.
Extensions
Since Fedora 9, %{_libdir}
and %{_datadir}
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.
Both arch-specific and noarch
Tcl extensions must use
Requires: tcl(abi) = 8.6
to indicate which Tcl version (8.5 in F19 and F20, 8.6 in F21+) they were built against. This is necessary because the guidelines below require extensions to be installed into tcl-versioned directories, which are only used by a single version of Tcl. This does impose an inconvenience that all arch-specific and noarch extensions will need to be rebuilt for a new minor version of Tcl, but since new Tcl minor versions only appear once every few years, this should not be such a problematic inconvenience.
noarch packages
The following macros must be used at the top of the spec file to determine the correct installation paths:
%{!?tcl_version: %global tcl_version %(echo 'puts $tcl_version' | tclsh)} %{!?tcl_sitelib: %global tcl_sitelib %{_datadir}/tcl%{tcl_version}}
In order for the macros to work, the package must also BuildRequires:
tcl
either directly, or indirectly with BuildRequires: tcl-devel
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:
%configure --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 $RPM_BUILD_ROOT make install DESTDIR=$RPM_BUILD_ROOT install -d $RPM_BUILD_ROOT%{tcl_sitelib} mv $RPM_BUILD_ROOT%{_datadir}/foobar%{version} $RPM_BUILD_ROOT%{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 following macros must be used at the top of the spec file to determine the correct installation paths:
%{!?tcl_version: %global tcl_version %(echo 'puts $tcl_version' | tclsh)} %{!?tcl_sitearch: %global tcl_sitearch %{_libdir}/tcl%{tcl_version}}
In order for the macros to work, the package must also BuildRequires:
tcl
either directly, or indirectly with BuildRequires: tcl-devel
While %{tcl_sitearch}
is a symlink to %{tcl_sitelib}
in Fedora 8 and
earlier, in Fedora 9 it is an actual directory.
The --libdir
flag for the configure script can often be used to set the
correct installation directory:
%build %configure --libdir=%{tcl_sitearch}
For most arch-specific packages, the --libdir
flag for the configure
script is also used to locate tclConfig.sh. Some of these arch-specific
packages will break if --libdir
is redirected to
%{tcl_sitearch}
. For packages that can’t handle alternate values for
--libdir
, you can simply move the installation directory in the
%install
section of the spec file:
%install make install DESTDIR=$RPM_BUILD_ROOT install -d $RPM_BUILD_ROOT%{tcl_sitearch} mv $RPM_BUILD_ROOT%{_libdir}/foobar%{version} $RPM_BUILD_ROOT%{tcl_sitearch}/foobar%{version}
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 acceptible.
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 in Fedora, 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: http://wiki.tcl.tk/285