Installing solvers
Applications find solvers by name, never by path, so the library file has to sit in a directory FZnSO searches, under a file name it can read a name back from. The rules are in Discovery and Naming & versioning; this 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, even over a newer version further down, 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 problemA 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.
Listing and pinning
Section titled “Listing and pinning”Each binding enumerates the search path, and takes a version prefix of whole components to pin a series:
for found in fznso.Library.discover(): print(found.name, found.version, found.path)
fznso.Library.find("gecode", "6") # any 6.x.yfznso.Library.find("gecode", "6.2") # any 6.2.x, but not 6.1.0for found in fznso::Library::discover() { println!("{} {} {}", found.name, found.version, found.path.display());}
Library::find_version("gecode", "6"); // any 6.x.yLibrary::find_version("gecode", "6.2"); // any 6.2.x, but not 6.1.0for (const fznso::Library::Discovered& d : fznso::Library::discover()) { std::cout << d.name << ' ' << d.version << ' ' << d.path << '\n';}
fznso::Library::find_version("gecode", "6"); // any 6.x.yfznso::Library::find_version("gecode", "6.2"); // any 6.2.x, but not 6.1.0discover is a directory listing rather than a load, so it also shows solvers whose ABI version does not match.
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 list 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.