# Support precompiled (.qlf) libraries

**URL:** <https://swi-prolog.discourse.group/t/support-precompiled-qlf-libraries/8887>\
**Category:** Announce\
**Tags:** qlf, install\
**Created:** [March 20, 2025, 10:55am UTC](https://swi-prolog.discourse.group/t/support-precompiled-qlf-libraries/8887 "2025-03-20T10:55:20Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [March 20, 2025, 10:55am UTC](https://swi-prolog.discourse.group/t/support-precompiled-qlf-libraries/8887/1 "2025-03-20T10:55:20Z")

</div>

I’ve pushed a lot of patches to facilitate compiling the entire library to `.qlf` (Quick Load Format` files. This was proposed by @maren. Thanks! This has several advantages

- .qlf files load about 20 times faster. That notably affects applications that load a lot of libraries. For example, loading s(CASP) from source on my dev machine drops from 0.45 sec to 0.17 sec. Loading big libraries such as `clpfd` and `chr`. E.g., `use_module(library(clpfd))` drops from 0.11 to 0.006 sec.
- .qlf files are about 50% smaller. SWI-Prolog now also supports installing **only .qlf** files. That is good news for e.g., the WASM version. Of course, the price is that source-level tracing through the libraries no longer works and it is harder to inspect the implementation.

These new features are still experimental. It they interest you, pick the latest git version and run `cmake` with these additional flags

- `-DINSTALL_QLF=ON`   
 Build and install the library .qlf files.
- `-DINSTALL_PROLOG_SRC=OFF`   
 Install **only** the .qlf files

If you install both (probably recommended for most purposes), you can run SWI-Prolog like below to make it load the source rather than the .qlf files.

```
swipl -Dsource ...

```

Alternatively, you can use `?- set_prolog_flag(source, true).` to achieve the same result for each file loaded after changing this flag. Loading the source may be useful to verify that unexpected behaviour is due to issues with the .qlf files. In addition if can be used to improve debugging libraries because the precompiled libraries are compiled with optimization enabled and debug/3 and assertion/1 statements removed.

Once this proofs stable, `INSTALL_QLF` will be changed to default to `ON`.

Please share your experience.

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [March 26, 2025, 12:17am UTC](https://swi-prolog.discourse.group/t/support-precompiled-qlf-libraries/8887/2 "2025-03-26T00:17:29Z")

</div>

I don’t know if this is related to the .qlf files, but I noticed that the `install_manifest.txt` is now empty or missing; when I build with `CMAKE_INSTALL_MODE=ABS_SYMLINK`, only the `.qlf` files are listed in that file. (And when I build with `-DINSTALL_QLF=OFF`, it seems to have most of the files, but is missing `bin/swipl`, etc.) I’m seeing a bit of instability in that file, but it takes a long time to re-try the various options.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [March 26, 2025, 9:24am UTC](https://swi-prolog.discourse.group/t/support-precompiled-qlf-libraries/8887/3 "2025-03-26T09:24:18Z")

</div>

Weird. I do not use `CMAKE_INSTALL_MODE=ABS_SYMLINK` and the install manifest looks ok in all variations. Looks like a feature/bug of this CMake option? Why do you care though?

The tricks I use to manage a lot of different installations is

- Set the environment variable `SWIPL_INSTALL_PREFIX=/home/jan/cmake/@builddir@`. This causes `ninja install` to install in `~/cmake/<builddir>`. Once installed, you can run it from there or activate it from the build dir using `../scripts/swipl-activate --installed`.
- For every build type, create a directory named `build.feat1-feat2-...`
- Run `../scripts/configure`. Align the _feat_ terms with the keywords used in this script. Install the `direnv` utility to have a local environment.
- Build using `ninja`. Normally I simply run `src/swipl` to play with this particular version. You can connect `swipl` to the version in this build dir using `../scripts/swipl-activate`.

That makes it all easy to manage. The source directories are unaffected. You can ditch a build version simply by removing the build directory and an installed version by removing the directory from `~/cmake`. Best, you can quickly switch from the normal release version to the debug version or the ASAN version to analyse issues.

By running the versions from the source dir your Prolog library files are symlinks to the sources, so you can edit them comfortably and test the changes without rebuilding or installing. You should not use the qlf build for that or run Prolog as `src/swipl -Dsource`.

Currently my default version is built in `build.qlf-nosrc` and installed (the non-installed version still has the sources). That is a little uncomfortable as you cannot quickly look at the library source. It seems to run quite well though.

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [March 26, 2025, 7:11pm UTC](https://swi-prolog.discourse.group/t/support-precompiled-qlf-libraries/8887/4 "2025-03-26T19:11:35Z")

</div>

> [@jan](#):
>
> Why do you care though? [that `install_manifest.txt` has the correct contents]

If I want to ensure a clean install, I could do `rm -rf $(cat install_manifest.txt)`. (E.g., when switching between `INSTALL_QLF` settings.) As it is, I can delete a few directories and the binaries, so it’s not a big deal … my suspicion is that it’s a bug in cmake because the manifest used to be correct. (FWIW, I run cmake with `-DCMAKE_INSTALL_PREFIX=$HOME/.local`)

---

<div class="post-metadata">

**Author:** ![jamesnvc](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jamesnvc/32/14_2.png) [@jamesnvc](https://swi-prolog.discourse.group/u/jamesnvc)\
**Post date:** [April 28, 2025, 7:01pm UTC](https://swi-prolog.discourse.group/t/support-precompiled-qlf-libraries/8887/5 "2025-04-28T19:01:09Z")

</div>

I guess since this change, I get the following error that kills the swipl process when doing `use_module(library(pengines))`:

```prolog
[FATAL ERROR: at Mon Apr 28 14:52:20 2025
	/Users/james/lib/swipl/library/ext/pengines/pengines.qlf: QLF format error at index = 22 (/Users/james/src/swipl-devel/src/pl-qlf.c:2121)]

```

edit: deleted the pengines.qlf file and re-ran `ninja install` and things seem okay now 🤷

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [April 29, 2025, 6:44am UTC](https://swi-prolog.discourse.group/t/support-precompiled-qlf-libraries/8887/6 "2025-04-29T06:44:18Z")

</div>

Thanks for reporting. Yes, there are (still) occasional issues with incremental compilation of .qlf files. I’m still not entirely happy with how that works as is. Ideally, this should probably be fully integrated into `cmake` using a Prolog equivalent of `makedepend`. As is, the compilation is done by qlf\_make/0, which tries to take dependencies and incompatible .qlf files into account. This apparently is not flawless ☹

If a build fails, run `swipl qlf clean -ra` in the build dir to clean all .qlf files and retry the build. Or, if you have no working `swipl` anymore,

```
find . -name '*.qlf' | xargs rm

```
