Installing solvers
Applications find solvers by name, never by path. For that to work, the library file has to be in a directory FZnSO searches, with a file name it can read a name back from.
The rules are in Discovery and Naming & versioning; this page is the operational version.
Where to put it
Section titled “Where to put it”Pick the first that fits:
| Where | Directory | Use it for |
|---|---|---|
| Development | wherever you like, then set FZNSO_SOLVER_PATH | a solver you are building |
| Per user | ~/.local/share/fznso (Linux), ~/Library/Application Support/fznso (macOS), %LOCALAPPDATA%\fznso (Windows) | a solver you installed for yourself |
| System | /usr/local/lib/fznso, /usr/lib/fznso, or a fznso directory beside the executable on Windows | a packaged solver |
Earlier entries win outright — newer versions do not override the order — which is what makes the development case work.
export FZNSO_SOLVER_PATH="$PWD/target/debug/examples"FZNSO_SOLVER_PATH takes several directories, separated by : (or ; on Windows).
Naming the file
Section titled “Naming the file”The file name is where the solver’s name comes from, so it is not free-form:
libgecode.so ✓ name is `gecode`libgecode.6.2.1.so ✓ name is `gecode`, version 6.2.1libgecode.6.2.1.dylib ✓ same on macOSgecode.6.2.1.dll ✓ same on Windowslibgecode.so.6 ✓ a distribution-packaged version, also read as 6gecode-6.dll ✗ `-` cannot appear in a C identifierlibgecode-solver.so ✗ same problemSo: a valid C identifier that does not start with lib, then the version, then the extension — on
every platform, for reasons.
Several versions can live side by side; asking for gecode gets the newest.
Checking what is installed
Section titled “Checking what is installed”Each binding can enumerate the search path:
for found in fznso.Library.discover(): print(found.name, found.version, found.path)for found in fznso::Library::discover() { println!("{} {} {}", found.name, found.version, found.path.display());}for (const fznso::Library::Discovered& d : fznso::Library::discover()) { std::cout << d.name << ' ' << d.version << ' ' << d.path << '\n';}This is a directory listing, not a load, so it also shows solvers whose ABI version does not match.
Pinning a version
Section titled “Pinning a version”Asking for a name alone gets the newest installed version. To pin, name a prefix of whole components:
fznso.Library.find("gecode", "6") # any 6.x.yfznso.Library.find("gecode", "6.2") # any 6.2.x, but not 6.1.0Library::find_version("gecode", "6") // any 6.x.yLibrary::find_version("gecode", "6.2") // any 6.2.x, but not 6.1.0fznso::Library::find_version("gecode", "6"); // any 6.x.yfznso::Library::find_version("gecode", "6.2"); // any 6.2.x, but not 6.1.0Components are compared numerically, so 10 is newer than 9.
When it will not load
Section titled “When it will not load”| Symptom | Cause |
|---|---|
| Not found, though the file is there | The file name does not yield a valid name — check the table above. Or the directory is not on the search path. |
| Found, but rejected | The solver reports a different FZNSO_ABI_VERSION than your application. Rebuild it against matching headers. |
| A required symbol is missing | The solver does not export all thirteen entry points, or the name in the symbols does not match the file name. |
The last one is worth checking directly:
nm -gU libgecode.so | grep fznso_Every symbol must read fznso_gecode_….
If they say fznso_NAME_…, the template was copied but not renamed.