As of 2021-07-31, ncurses ships its own version of foot’s terminfo. Since: * It doesn’t have the non-standard Sync,Tc,setrgbf,setrgbb capabilities. * It doesn’t set hs,fsl,dsl (statusbar). * We want to be able to update our termminfo without waiting for an ncurses release. * Foot should be installable and usable on Linux systems that doesn’t have the latest ncurses. we still want to ship our own version. We can however not install it to the default terminfo location (e.g. /usr/share/terminfo), since it will collide with the ncurses provided files. Our options are to either rename our terminfo to something else, or to keep the name, but install our terminfo files somewhere else. The first option would be the easy one. However, I think it makes sense to use the same name. For example, a user that SSH’s into a remote system that does *not* have our own version installed, but *does* have the ncurses one, will gracefully fall back to that one, which is better than manually having to set e.g. TERM=xterm-256color. Now, if we want to use the same name, we need to install it somewhere else. But where? And how do we ensure our version is preferred over the ncurses one? I opted to $datadir/foot/terminfo (e.g. /usr/share/foot/terminfo) by default. It makes it namespaced to foot (i.e. we’re not introducing a new “standard” terminfo location), thus guaranteeing it wont collide with ncurses. To enable applications to find it, we export TERMINFO_DIRS. This is a list of *additional* directories to search for terminfo files. If it’s already defined, we *append* to it. The nice thing with this is, if there’s no terminfo in that location (e.g. when you SSH into a remote), the default terminfo location is *also* searched. But only *after* having searched through TERMINFO_DIRS. In short: our version is preferred, but the ncurses one (or an older version of our terminfo package!) will be used if ours cannot be found. To enable packagers full control over the new behavior, the existing meson command line options have been modified, and a new option added: -Dterminfo=disabled|enabled|auto: *build* and *install* the terminfo files. -Dcustom-terminfo-install-location=<path>: *where* the terminfo files are expected to be found. This *needs* to be set *even* if -Dterminfo=disabled. For example, if the packaging script builds and packages the terminfo files separate from the regular foot build. The path is *relative to $prefix*, and defaults to $datadir/foot/terminfo. This is the value that will be appended to TERMINFO_DIRS. Note that you can set it to ‘no’, in which case foot will *not* set/modify TERMINFO_DIRS. Only do this if you don’t intend to package foot’s terminfo files at all (i.e. you plan on using the ncurses ones only). -Ddefault-terminfo=foot. Allows overriding the default TERM value. This should only be changed if the target platform doesn’t support terminfo files. Closes #671
14 KiB
Installing
Overview
foot makes use of a couple of libraries I have developed: tllist and fcft. As such, they will most likely not have been installed already. You can either install them as system libraries or build them as subprojects in foot.
When building foot, they will first be searched for as system libraries. If found, foot will link dynamically against them. If not found, meson will attempt to download and build them as subprojects.
Requirements
Running
If you are packaging foot, you may also want to consider adding the following optional dependencies:
- libnotify: desktop notifications by default uses
notify-send. - xdg-utils: URLs are by default launched with
xdg-open. - bash-completion: If you want completion for positional arguments.
Building
In addition to the dev variant of the packages above, you need:
- meson
- ninja
- wayland protocols
- ncurses (needed to generate terminfo)
- scdoc (for man page generation, not needed if documentation is disabled)
- llvm (for PGO builds with Clang)
- tllist 1
A note on compilers; in general, foot runs much faster when compiled with gcc instead of clang. A profile-guided gcc build can be more than twice as fast as a clang build.
Note GCC 10.1 has a performance regression that severely affects
foot when doing PGO builds and building with -O2; it is about 30-40%
slower compared to GCC 9.3.
The work around is simple: make sure you build with -O3. This is the
default with meson --buildtype=release, but e.g. makepkg can
override it (makepkg uses -O2 by default).
Arch Linux
Install from AUR:
Or use makepkg to
build the bundled PKGBUILD (run makepkg in the source
root directory).
Unlike the AUR packages, the bundled PKGBUILD requires tllist and fcft to be installed as system libraries. If you do not want this, please edit the PKGBUILD file, or install manually (see Other below).
Note that it will do a profiling-guided build, and that this requires a running wayland session since it needs to run an intermediate build of foot.
Other
Foot uses meson. If you are unfamiliar with it, the official tutorial might be a good starting point.
I also recommend taking a look at the bundled Arch PKGBUILD file, to see how it builds foot. Especially so if you intend to install a release build of foot, in which case you might be interested in the compiler flags used there.
A note on terminfo; the terminfo database exposes terminal
capabilities to the applications running inside the terminal. As such,
it is important that the terminfo used reflects the actual
terminal. Using the xterm-256color terminfo will, in many cases,
work, but I still recommend using foot’s own terminfo. There are two
reasons for this:
- foot’s terminfo contains a couple of non-standard capabilities, used by e.g. tmux.
- New capabilities added to the
xterm-256colorterminfo could potentially break foot.
As of ncurses 2021-07-31, ncurses ships a version of foot’s terminfo. I still recommend building and installing the version shipped with foot, since:
- It will be more up to date (and more importantly, guaranteed to match the installed version of foot).
- The ncurses version is missing several of the non-standard capabilities.
Foot’s terminfo will by default be built, and installed along with foot itself. This can be disabled (for example, to simplify packaging when the terminfo definitions are packaged in a separate package). Instructions on how to do so is in terminfo.
I recommend packaging foot’s terminfo files in a separate package, to allow them to be installed on remote systems without having to install foot itself.
Setup
To build, first, create a build directory, and switch to it:
mkdir -p bld/release && cd bld/release
Options
Available compile-time options:
| Option | Type | Default | Description | Extra dependencies |
|---|---|---|---|---|
-Ddocs |
feature | auto |
Builds and install documentation | scdoc |
-Dime |
bool | true |
Enables IME support | None |
-Dgrapheme-clustering |
feature | auto |
Enables grapheme clustering | libutf8proc |
-Dterminfo |
feature | enabled |
Build and install terminfo files | tic (ncurses) |
-Ddefault-terminfo |
string | foot |
Default value of TERM |
none |
-Dcustom-terminfo-install-location |
string | ${datadir}/foot/terminfo |
Value to append to TERMINFO_DIRS |
None |
Documentation includes the man pages, the example foot.ini, readme,
changelog and license files.
-Ddefault-terminfo: I strongly recommend leaving the default
value. This option is meant to be used as a last resort on platforms
where individual terminfo files cannot easily be installed.
-Dcustom-terminfo-install-location enables foot’s terminfo to
co-exist with ncurses’ version. The idea is that you install foot’s
terminfo to a non-standard location, for example
/usr/share/foot/terminfo. Use -Dcustom-terminfo-install-location
to tell foot where the terminfo is. Foot will append this path to the
TERMINFO_DIRS environment variable in the client application’s
process. The value is relative to ${prefix}.
Conforming applications should look in TERMINFO_DIRS first, and
fallback to the builtin default (e.g. /usr/share/terminfo) if not
found. Thus, it will prefer foot’s version, if it exists (which it
typically will on localhost), and fallback to ncurses’ version if not
(e.g. on remote systems, where foot’s terminfo package has not been
installed).
If set to no, foot will not set or modify TERMINFO_DIRS at
all. Use this if you do not intend to use/support foot’s terminfo
definitions at all.
-Dterminfo can be used to disable building the terminfo definitions
in the meson build. It does not change the default value of
TERM, and it does not disable TERMINFO_DIRS.
Example:
meson --prefix=/usr -Dcustom-terminfo-install-location=lib/foot/terminfo
The above tells foot its terminfo definitions will be installed to
/usr/lib/foot/terminfo. This is the value foot will append to the
TERMINFO_DIRS environment variable.
If -Dterminfo is enabled (the default), then the terminfo files will
be built as part of the regular build process, and installed to the
specified location.
Packagers may want to set -Dterminfo=disabled, and manually build
and install the terminfo files instead:
tic -o <output-directory> -x -e foot,foot-direct foot.info
Release build
Below are instructions for building foot either size optimized, performance optimized, or performance optimized using PGO.
PGO - Profile Guided Optimization - is a way to optimize a program
better than -O3 can, and is done by compiling foot twice: first to
generate an instrumented version which is used to run a payload that
exercises the performance critical parts of foot, and then a second
time to rebuild foot using the generated profiling data to guide
optimization.
In addition to being faster, PGO builds also tend to be smaller than
regular -O3 builds.
Size optimized
To optimize for size (i.e. produce a small binary):
export CFLAGS="$CFLAGS -Os"
meson --buildtype=release --prefix=/usr -Db_lto=true ../..
ninja
ninja test
ninja install
Performance optimized, non-PGO
To do a regular, non-PGO build optimized for performance:
export CFLAGS="$CFLAGS -O3"
meson --buildtype=release --prefix=/usr -Db_lto=true ../..
ninja
ninja test
ninja install
Use -O2 instead of -O3 if you prefer a slightly smaller (and
slower!) binary.
Performance optimized, PGO
First, configure the build directory:
export CFLAGS="$CFLAGS -O3"
meson --buildtype=release --prefix=/usr -Db_lto=true ../..
It is very important -O3 is being used here, as GCC-10.1.x and
later have a regression where PGO with -O2 is much slower.
Clang users must add -Wno-ignored-optimization-argument to
CFLAGS.
Then, tell meson we want to generate profiling data, and build:
meson configure -Db_pgo=generate
ninja
ninja test
Next, we need to actually generate the profiling data.
There are two ways to do this: a partial PGO build using a PGO helper binary, or a full PGO build by running the real foot binary. The latter has slightly better results (i.e. results in a faster binary), but must be run in a Wayland session.
A full PGO build also tends to be smaller than a partial build.
Partial PGO
This method uses a PGO helper binary that links against the VT parser only. It is similar to a mock test; it instantiates a dummy terminal instance and then directly calls the VT parser with stimuli.
It explicitly does not include the Wayland backend and as such, it does not require a running Wayland session. The downside is that not all code paths in foot is exercised. In particular, the rendering code is not. As a result, the final binary built using this method is slightly slower than when doing a full PGO build.
We will use the pgo binary along with input corpus generated by
scripts/generate-alt-random-writes.py:
./footclient --version
./foot --version
tmp_file=$(mktemp)
../../scripts/generate-alt-random-writes \
--rows=67 \
--cols=135 \
--scroll \
--scroll-region \
--colors-regular \
--colors-bright \
--colors-256 \
--colors-rgb \
--attr-bold \
--attr-italic \
--attr-underline \
--sixel \
${tmp_file}
./pgo ${tmp_file} ${tmp_file} ${tmp_file}
rm ${tmp_file}
The first step, running ./foot --version and ./footclient --version might seem unnecessary, but is needed to ensure we have
some profiling data for functions not covered by the PGO helper
binary. Without this, the final link phase will fail.
The snippet above then creates an (empty) temporary file. Then, it
runs a script that generates random escape sequences (if you cat
${tmp_file} in a terminal, you’ll see random colored characters all
over the screen). Finally, we feed the randomly generated escape
sequences to the PGO helper. This is what generates the profiling data
used in the next step.
You are now ready to use the generated PGO data.
Full PGO
This method requires a running Wayland session.
We will use the script scripts/generate-alt-random-writes.py:
./footclient --version
foot_tmp_file=$(mktemp)
./foot --config=/dev/null --term=xterm sh -c "<path-to-generate-alt-random-writes.py> --scroll --scroll-region --colors-regular --colors-bright --colors-256 --colors-rgb --attr-bold --attr-italic --attr-underline --sixel ${foot_tmp_file} && cat ${foot_tmp_file}"
rm ${foot_tmp_file}
You should see a foot window open up, with random colored text. The window should close after ~1-2s.
The first step, ./footclient --version might seem unnecessary, but
is needed to ensure we have some profiling data for
footclient. Without this, the final link phase will fail.
Use the generated PGO data
Now that we have generated PGO data, we need to rebuild foot. This time telling meson (and ultimately gcc/clang) to use the PGO data.
If using Clang, now do (this requires llvm to have been installed):
llvm-profdata merge default_*profraw --output=default.profdata
Next, tell meson to use the profile data we just generated, and rebuild:
meson configure -Db_pgo=use
ninja
ninja test
Continue reading in Running the new build
Debug build
meson --buildtype=debug ../..
ninja
ninja test
Terminfo
By default, building foot also builds the terminfo files. If packaging the terminfo files in a separate package, it might be easier to simply disable the terminfo files in the regular build, and compile the terminfo files manually instead.
To build the terminfo files, run:
tic -o <output-directory> -x -e foot,foot-direct foot.info
Where ”output-directory” must match the value passed to
-Dcustom-terminfo-install-location in the foot build.
To compile and install directly (assuming the default
-Dcustom-terminfo-install-location):
sudo tic -o /usr/share/foot/terminfo ...
Or, if packaging:
tic -o ${DESTDIR}/usr/share/foot/terminfo ...
Running the new build
You can now run it directly from the build directory:
./foot
Or, if you did not install the terminfo definitions:
./foot --term xterm-256color
-
can also be built as subprojects, in which case they are statically linked. ↩︎