Installation, and requirements

LibCXX uses Linux-specific APIs. LibCXX targets the current generally-available version of gcc, and code that uses LibCXX should use -std=c++20 -fno-omit-frame-pointer -pthread options to compile. This is done automatically when using autotools.

LibCXX should be converted into an installable package instead of building and installing LibCXX directly. The source tarball contains build scripts for Fedora and Ubuntu (most likely works on Debian too, but untested.

RPM and DEB packages

Note

These packages use their own, generic, installation layout that may deviate slightly from the package installation conventions preferred by the distributions:

On Fedora: running rpmbuild -ta libcxx-version.tar.bz2 creates the following packages:

  • The main binary rpm package, with runtime libraries.

  • The ltdl and cups subpackages with additional runtime libraries that have additional dependencies.

  • The devel subpackage, containing header files and other supporting files used for developing applications that use the LibCXX.

  • An httpd subpackage containing an Apache configuration file. This subpackage only needs to be installed if Apache is also installed.

  • An selinux subpackage that installs an SELinux policy file for LibCXX.

Use the following process to build DEB packages:

  • Create an empty directory and copy/move the tarball into it:

    $ mkdir tmp
    $ mv libcxx-VERSION.tar.bz2 tmp
    $ cd tmp

    Unpack the tarball and cd into the unpacked subdirectory:

    $ tar xvf libcxx-VERSION.tar.bz2
    $ cd libcxx-VERSION
  • Run the debuild script in the current directory, which is a wrapper for the system debuild script, and it forwards its parameters to it:

    $ ./debuild -us -uc

    This creates DEB packages that use the default version of gcc (/usr/bin/g++). This is overriden by setting DEBGCC:

    $ DEBGCC=12 ./debuild -us -uc

    This uses /usr/bin/g++-12 to compile LibCXX.

Note

The above steps must be followed strictly. The debuild script expects the distributed tarball in its parent directory.

This eventually produces a deb subdirectory with .deb packages that can be installed with "dpkg -i".

Use the following documentation as a guide for preparing an installable LibCXX package on platforms other than Fedora and Ubuntu/Debian:

Requirements and prerequisites

  • A filesystem that implements extended file attributes. This is usually the case these days. Some older Linux systems, that have been upgraded for a long period of time, might be still on a filesystem without extended attribute support; but it's usually a simple command or two to enable this.

  • GNU make; if it's installed as gmake, use that in place of the make command.

  • The current generally-available version of GCC. As new GCC releases include support for new C++ standards, this library gets accordingly.

  • The CUPS libraries.

  • The Courier Unicode Library (and sysconftool if building from the git repository).

  • gnutls, libgcrypt (at least 1.6), libidn2, libxml2, libxslt, libyaml and pcre.

  • libtool, autoconf, automake, and gettext.

  • pkg-config.

  • An installed list of default certificate authorities, in /etc/pki/tls/cert.pem by default.

Configuring and building

As mentioned above, LibCXX should be built into a standalone, installable package. Use the following documentation as a guide to creating an installation script or a package.

Run the configure script, followed by make (or gmake). configure takes the usual options that specify non-default installation directories, for various files. Additional options are:

--with-pkgconfigdir=dir

Specifies where pkgconfig configuration file gets installed. The configure script goes through the list of some common directories, and checks if they exist.

This option may be needed to override the default even if configure finds it, and does not complain, if it ends up finding and installs its pkgconfig file into the wrong directory.

--with-cacerts=file

Specifies the file with a list of trusted certificate authorities. The configure script knows about some common locations, and will check them. If it can't find it, and complains, use this option to tell it where it is.

When building LibCXX, for the first time, it's also a good idea to run (g)make check, but that shouldn't be a part of an automated build script, since it may fail on a heavily loaded build server, due to some test scripts' timing.

Run (g)make install DESTDIR=/tmp/libcxx-install. This creates an installation image in the /tmp/libcxx-install directory, to use as a basis for creating an installable package. A plain (g)make install will do it for real, of course. However, using an installable package is strongly recommended.

Regenerating ephemeral DSA and RSA parameters

This is required by LibCXX's API for the GnuTLS library. Generating these parameters is often a time-consuming task, depending on the hardware, so LibCXX loads pregenerated parameters from a file. The files are located in localstatedir/tlsparams (usually /usr/local/var/tlsparams or /var/local/tlsparams). The installable package should have a cron entry that periodically regenerates the parameter files. The process for doing so is as follows:

The tlsparamsgen regenerates the parameter files in localstatedir/tlsparams. make install creates a tlsparams subdirectory in sysconfdir (usually /usr/local/etc or /etc). This directory contains files with options for the tlsparamsgen script. Then, the tlsparamsgen.sh wrapper script (installed in sbindir, which is /usr/sbin or /usr/local/sbin) reads these options, and runs tlsparamsgen to regenerate the ephemeral files. A regularly-scheduled job should be scheduled to run this script (a monthly frequency is fine).

make install runs a script that generates an initial set of ephemeral parameter files, making LibCXX immediately usable after installation. Include the pregenerated ephemeral parameter files in the installable package. Then, as part of the package installation, the package should make arrangements to execute tlsparamsgen.sh soon after installation, to replace the stock ephemeral parameters with randomly-generated ones.

This is taken care of by the Fedora and Ubuntu packages. No manual action is required with the Fedora and Ubuntu packages. All of this is described for documentation purposes only.

Furthermore, the Fedora and Ubuntu packages use a slightly more robust approach, as follows:

  • The INSTALL_TLSPARAM_SUFFIX=.dist parameter to make install installs the stock ephemeral parameter files with a .dist suffix. This is what goes into the RPM and DEB package.

  • A post-install script checks if each ephemeral parameter file already exists, or not, and only links the installed .dist file to the real one if it does not exist. Any existing ephemeral parameter files, from a previously-installed version of LibCXX, get preserved.

    Therefore, LibCXX is usable immediately after installation, and only a new install has the stock ephemeral parameters until the first reboot, because:

  • The startup script that runs at boot time, to start httportmap, checks if parameter files are the initial stock files, and runs tlsparamsgen in the background, immediately. The RPM/DEB packages also install a monthly cron job to generate new parameter files.

The final result is that LibCXX package gets installed without lengthy delays for generating ephemeral parameter files, at installation time. This happens in the background during the first reboot after installation. And going forward, the cron job in the package regenerates them monthly.

Installing and starting httportmapd

The httportmapd daemon is a part of LibCXX. A package that installs LibCXX needs to execute the properties command to configure httportmapd's property file. This is done by make install, however property files are stored in extended attributes, which are typically not preserved by binary package file formats. This usually needs to be done after LibCXX package's installation.

The property file is httportmapd.properties, and it gets installed in sysconfdir, which is usually /usr/local/etc, or /etc. httportmapd gets installed in sbindir, which is usually /usr/local/sbin, or /usr/sbin; and the properties command gets installed into bindir, which is usually /usr/local/bin, or /usr/bin:

/usr/bin/properties --set /usr/local/etc/httportmapd.properties /usr/local/sbin/httportmapd

Afterwards, arrangements must be made to have httportmapd started during system boot:

/usr/local/sbin/httportmapd --http --daemon start

This forks and runs the portmapper as a child process. The portmapper process opens and binds the HTTP port 80, to handle portmapper service requests. httportmapd stop may be added to the system shutdown script, to stop the daemon process.

Leave out the --http if there's already an HTTP server, such as Apache on port 80. In that case, the portmapper expects to be invoked as a CGI application for all http://hostname/portmap URLs (that is, in addition to the daemon instance which still needs to get started). In the source tarball, httportmap/apache.conf.in is a sample Apache configuration, with a placeholder for httportmapd's installation location. Additionally:

make install installs /etc/httportmaprc.dist (or what's specified by --with-httportmaprc option to configure).

The sysconftool and the sysinit scripts do not get installed, there is no good default location for them. These scripts are a blueprint for a typical start/stop procedure for httportmapd:

  • Add sysconftool and the sysinit to the installed package.

  • Have the package's installation script run sysconftool passing to it the full pathname of the httportmaprc.dist file (the make install-configure command executes this manually).

  • sysinit is a typical start/stop script that takes the start, stop, status, restart, and try-restart (restart httportmapd if it's running) parameters (reload does nothing and force-reload is equivalent to a restart).

    It should be possible to set up httportmapd running in a container. If so, prepending a container parameter to the script (sysinit container start, etc) should make the startup sequence more container-friendly.

Packaging different versions of LibCXX

LibCXX gets packaged in a way that makes it possible to install different versions at the same time. LibCXX is a heavily-templated C++ library. Minor maintenance releases of LibCXX preserve the same source and binary APIs. Regular releases introduce new or modified APIs, but it's possible to prepare concurrently-installable packages for multiple regular version releases of LibCXX. Only one minor maintenance release of the same version can be installed at the same time, but multiple regular version releases can coexist with each other.

This makes it possible to support compiling and running independently-maintained software packages until they get updated to the current LibCXX release, on their own schedules, and have an orderly migration, of some period of time, of all software packages to the new version:

  • The usual situation is to have the current version of LibCXX built normally. A normal version of LibCXX consists of runtime support tools (the properties and maillogs commands, and the httportmapd daemon), the header files, the runtime libraries, and autotools-related files and script.

  • Packages with older versions of LibCXX do not have the runtime support tools but have all other components. The runtime support tools' APIs with the LibCXX libraries will generally remain forwards and backwards compatible, for at least one major release, backwards and forwards and LibCXX-built code will remain compatible with runtime tools of at least one prior and one following major release. Any exceptions will be documented.

    This documentation uses compatibility package to refer to the older versions of LibCXX that get installed concurrently with the current version.

  • It's also possible to have a non-current version of LibCXX as the normal version, and newer versions of LibCXX as compatibility packages.

A compatibility package gets built the same way as a normal package: creating an installable image in a temporary directory, but then removing all runtime tools and runtime configuration files from the installable image. The only contents of an installable image are:

$libdir/libcxx-$version

This directory whose name includes the LibCXX API/ABI version contains the runtime libraries. Multiple concurrently-installed version of the LibCXX get installed into different directories in $libdir.

$includedir/libcxx-$version

This directory whose name includes the LibCXX API/ABI version contains the header files. Multiple concurrently-installed version of the LibCXX install their header files into different directories in $includedir.

$datadir/libcxx-$version

This directory whose name includes the LibCXX API/ABI version contains supporting scripts, macros, and other miscellaneous supporting files. Multiple concurrently-installed version of the LibCXX install their miscellaneous files into different directories in $datadir.

The pkgconf/pkg-config and aclocal autoconf macros

LibCXX installs a package configuration files and an autoconf macro files into the shared, global pkgconfig and aclocal directories. The names of these files include the LibCXX version, making it possible to install multiple versions of these files, corresponding to each installed version of LibCXX.

All other files in the temporary installation directory get removed before creating the installable compatibility package.

On Fedora, a compatibility package also gets built from the source tarball: rpmbuild --define 'compat 1' -ta libcxx-version.tar.bz2. This has the following results:

  • Normal RPM packages are named libcxxbase(-subpackage)-VERSION.

  • Compatibility RPM packages are named libcxxbaseNNN(-subpackage)-VERSION with the NNN part being the version digits, generally same digits as in the VERSION.

  • Since NNN is a part of the packages' names, rpm considers them as different packages that get independently installed on their own, and not related in any way to the current libcxxbase package set.

Re-targeting to a different version of LibCXX

Most code that uses the LibCXX should be using an autoconf-generated configure script. The LIBCXX_INIT checks that the same version of LibCXX is installed, and fail if the LibCXX version is different.

Concurrently installing an additional version of LibCXX is one option; but if it's determined that the software can be built correctly with the current LibCXX version, it should be possible to set the LIBCXX_VERSION environment variable before running the configure script.

LIBCXX_VERSION is not the full version number of the targeted LibCXX version. It's the API/ABI version number which is, generally, the LibCXX version without the minor release level. One way to obtain the API/ABI version number is that it gets included in the name of the lib subdirectory where LibCXX's runtime libraries get installed.