Release v0.2.0: native GUI and managed KiCad libraries
This commit is contained in:
1 parent
0ed28c03fb
commit
c91f2ad67d
24 files changed
+9380
-527
No files matched your search
+308
@@ -0,0 +1,308 @@
|
||||
# UniLoader setup (Linux)
|
||||
|
||||
UniLoader imports component ZIPs or folders into global KiCad libraries or a
|
||||
portable project. It watches downloads during your graphical login session and
|
||||
asks where to import each component. It creates missing libraries and registers
|
||||
them in the selected scope automatically.
|
||||
|
||||
## Requirements and installation
|
||||
|
||||
Install Rust 1.95 or newer and your distribution's
|
||||
C build tools and `pkg-config`. Desktop dialogs use Rust
|
||||
[egui/eframe](https://docs.rs/eframe/latest/eframe/) with the OpenGL renderer and
|
||||
both Wayland and X11 support. File browsing uses
|
||||
[rfd's XDG desktop portal backend](https://docs.rs/rfd/latest/rfd/#linux--bsd-backends).
|
||||
Install `xdg-desktop-portal` and the backend appropriate for your desktop
|
||||
(for example, KDE or GTK). A working OpenGL driver, display session and session
|
||||
D-Bus are required. `notify-send` is optional for desktop notifications.
|
||||
|
||||
The UI is compiled into `uniloader`; there are no companion scripts to install.
|
||||
The watcher starts another instance of the same executable internally for each
|
||||
dialog, keeping the window event loop on its own main thread.
|
||||
|
||||
On Debian/Ubuntu, a starting set of build packages is `build-essential pkg-config
|
||||
libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libxkbcommon-dev
|
||||
libwayland-dev`; other distributions provide corresponding development packages.
|
||||
For optional notifications install `libnotify-bin` on Debian/Ubuntu or `libnotify`
|
||||
on Arch Linux. The portal backend can bring its own toolkit dependencies; UniLoader
|
||||
does not link a GTK UI. See the [upstream eframe build notes](https://github.com/emilk/eframe_template/#testing-locally)
|
||||
if compilation reports a missing system library.
|
||||
|
||||
Build from the repository directory:
|
||||
|
||||
```sh
|
||||
cargo build --release --locked
|
||||
install -Dm755 target/release/uniloader ~/.local/bin/uniloader
|
||||
~/.local/bin/uniloader --help
|
||||
```
|
||||
|
||||
Add `~/.local/bin` to your shell's `PATH` to use the shorter `uniloader` command.
|
||||
Do not run the importer as root.
|
||||
|
||||
The importer targets KiCad's modern `.kicad_sym`, `.kicad_mod` and `.kicad_pro`
|
||||
formats. It preserves source format versions; the installed KiCad must support
|
||||
those versions. Legacy `.lib` symbol conversion is not included. Verify your
|
||||
actual component in KiCad before relying on a library for a board design.
|
||||
|
||||
This release discovers possible open projects by inspecting Linux KiCad process
|
||||
arguments and working directories. These are **suggestions**, not an authoritative
|
||||
active-window selection: startup arguments can be stale, editor navigation can
|
||||
change documents, and some launchers hide the file argument. IPC discovery is a
|
||||
follow-up; no IPC configuration is required for this release. Always check the
|
||||
project path in the destination dialog, or use Browse / `--project`.
|
||||
|
||||
## Configuration
|
||||
|
||||
The default configuration is `${XDG_CONFIG_HOME:-~/.config}/uniloader/config.toml`.
|
||||
A missing configuration is generated with defaults on first launch. You can
|
||||
select another file with `--config /absolute/path/config.toml`. Existing
|
||||
`[libraries].path` and `[options]` settings remain supported. `~` expands in paths;
|
||||
relative configuration paths resolve from the process working directory, so use
|
||||
absolute or home-relative paths for a service.
|
||||
|
||||
A minimal setup is:
|
||||
|
||||
```toml
|
||||
[libraries]
|
||||
path = "~/KiCad/libraries"
|
||||
# Select your installed KiCad version for global library registration:
|
||||
kicad_config = "~/.config/kicad/9.0"
|
||||
```
|
||||
|
||||
Use your actual KiCad version directory. When a single installed configuration
|
||||
can be identified, UniLoader can discover it. If none or several are found,
|
||||
set `kicad_config` explicitly before importing globally. Project imports create
|
||||
project-local tables and do not require a global table.
|
||||
|
||||
The complete example is in `config/config_full.toml`. Available settings are:
|
||||
|
||||
```toml
|
||||
[libraries]
|
||||
path = "~/KiCad/libraries"
|
||||
kicad_config = "~/.config/kicad/9.0"
|
||||
search_paths = []
|
||||
model_search_paths = ["~/KiCad/models"]
|
||||
|
||||
# Optional KiCad variables not already supplied by your environment:
|
||||
[libraries.variables]
|
||||
# KICAD9_3DMODEL_DIR = "/usr/share/kicad/3dmodels"
|
||||
|
||||
[options]
|
||||
symbols = true
|
||||
footprints = true
|
||||
models = true
|
||||
preserve_source = true
|
||||
|
||||
[watch]
|
||||
directories = ["~/Downloads"]
|
||||
settle_seconds = 2
|
||||
retry_seconds = 60
|
||||
|
||||
[destination]
|
||||
policy = "ask" # ask, global, project
|
||||
# project = "/absolute/path/Board/Board.kicad_pro"
|
||||
portable = true
|
||||
|
||||
[matching]
|
||||
enabled = true
|
||||
exact = "reuse" # reuse, ask
|
||||
ambiguous = "ask" # ask, separate, skip
|
||||
# Pad-position comparison tolerance, in millimetres:
|
||||
tolerance = 0.15
|
||||
|
||||
[ui]
|
||||
enabled = true
|
||||
```
|
||||
|
||||
`destination.policy = "project"` requires a fixed `project` path. A fixed target
|
||||
can be used when KiCad is closed. The default `ask` offers detected projects,
|
||||
Global and Browse. Remembering a choice applies to the running session; restart
|
||||
UniLoader to clear it. Footprint reuse mappings are persisted by content; to clear
|
||||
those mappings, stop UniLoader and remove only the content-mapping JSON files in its data
|
||||
directory’s `decisions/` subdirectory, then restart. Explicit fixed configuration persists until edited.
|
||||
|
||||
Matching searches effective registered libraries and configured `search_paths`.
|
||||
Do not add an enormous recursive root such as your entire home directory.
|
||||
Missing/unreadable search locations are reported rather than silently treated
|
||||
as proof that no duplicate exists. Exact footprint reuse is conservative;
|
||||
similar footprints or conflicting names prompt for comparison. The preview
|
||||
shows both footprints at the same scale, numbered pads, bounds and differences.
|
||||
It approximates some shapes and omits text, drill holes and 3D geometry; the
|
||||
window reports limitations. Inspect source files in KiCad when necessary.
|
||||
`ambiguous = "separate"` or `"skip"` permits an explicit noninteractive policy;
|
||||
the default keeps unanswered choices pending.
|
||||
|
||||
## Foreground smoke test
|
||||
|
||||
Start with an expendable test project and a known downloaded component:
|
||||
|
||||
```sh
|
||||
uniloader discover
|
||||
uniloader import /path/to/component.zip --project /path/to/Test/Test.kicad_pro --dry-run
|
||||
uniloader import /path/to/component.zip --project /path/to/Test/Test.kicad_pro
|
||||
uniloader import /path/to/component.zip --global --dry-run
|
||||
uniloader watch
|
||||
```
|
||||
|
||||
A manual import also accepts an extracted component folder. No-argument startup
|
||||
runs the watcher. Dry run reports choices and intended library changes without
|
||||
writing libraries; unresolved decisions may need an interactive import.
|
||||
Use `--noninteractive` to avoid opening dialogs. A pending choice is not consent.
|
||||
|
||||
Project imports create `libraries/UniLoader.kicad_sym`,
|
||||
`libraries/UniLoader.pretty/`, and model storage as needed, and merge registration
|
||||
entries into `sym-lib-table` and `fp-lib-table` beside the `.kicad_pro` file.
|
||||
Project paths use `${KIPRJMOD}`. Portable mode copies selected external footprints
|
||||
and available referenced models into the project. Global imports use the
|
||||
configured library root and register entries in the selected KiCad configuration.
|
||||
Existing unrelated table entries are preserved. Existing schematic and PCB
|
||||
instances are not automatically replaced by a library import.
|
||||
|
||||
Open the imported symbol, footprint and model in KiCad. Refresh/reopen the
|
||||
library browser or editor if KiCad has cached the table/library. For an existing
|
||||
placed component, use KiCad's normal update-from-library operation when you want
|
||||
it updated. Copy the test project to another directory and verify its imported
|
||||
assets again to check portability.
|
||||
|
||||
The watcher handles component ZIP downloads (including common SamacSys,
|
||||
UltraLibrarian and SnapMagic layouts); use a manual folder import for extracted
|
||||
assets. Source archives are preserved by default. Incomplete or invalid ZIPs
|
||||
are retried for the configured period, then remain recoverable rather than
|
||||
stopping subsequent downloads.
|
||||
|
||||
## 3D models and broken paths
|
||||
|
||||
STEP (`.step`/`.stp`) and VRML (`.wrl`) models are copied when referenced by an
|
||||
imported footprint. Resolution tries existing paths, bundle files and configured
|
||||
model search roots. Windows/provider absolute paths and obsolete extraction
|
||||
roots can be repaired through unique relative suffixes or filenames. Different
|
||||
matching model files require a selection rather than an arbitrary choice.
|
||||
Model transforms remain attached to the reference. Project references point to
|
||||
`${KIPRJMOD}/libraries/models/...`; global references use absolute storage paths.
|
||||
|
||||
Missing models leave the usable component import available with warnings and
|
||||
retain the original reference. Such an import is not fully portable. Adding the
|
||||
missing model to a search root and deliberately reimporting with `--force` can
|
||||
repair the dependency. Disabling `options.models` may also leave external paths.
|
||||
UniLoader does not download models or convert CAD formats.
|
||||
|
||||
## Pending imports and recovery
|
||||
|
||||
```sh
|
||||
uniloader pending
|
||||
uniloader pending --all # include completed/skipped imports
|
||||
uniloader retry IMPORT_ID
|
||||
uniloader retry IMPORT_ID --dry-run --noninteractive
|
||||
```
|
||||
|
||||
Closing a dialog or choosing Later leaves a pending import; it does not choose
|
||||
Global, overwrite a file, or guess a model. Retry after fixing the configuration,
|
||||
restoring the display environment or obtaining a missing asset. Other downloads
|
||||
can continue through the queue. `--force` deliberately reimports a completed
|
||||
source when you need to revisit it.
|
||||
|
||||
Import state/history lives beneath `${XDG_DATA_HOME:-~/.local/share}/uniloader`;
|
||||
temporary extraction uses `${XDG_CACHE_HOME:-~/.cache}/uniloader`.
|
||||
Changed files have recovery backups recorded by the import result/history.
|
||||
Stop the watcher before manually restoring a backup, compare the current file
|
||||
with the backup, and copy back only the intended version. A backup may predate
|
||||
later manual edits; do not blindly restore every file. Restart KiCad or refresh
|
||||
its libraries afterwards. Automatic undo is not included.
|
||||
|
||||
## Run continuously with a systemd user unit
|
||||
|
||||
First verify the foreground test above, then install the shipped service:
|
||||
|
||||
```sh
|
||||
install -Dm644 systemd/uniloader.service ~/.config/systemd/user/uniloader.service
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now uniloader.service
|
||||
systemctl --user status uniloader.service
|
||||
journalctl --user -u uniloader.service -f
|
||||
```
|
||||
|
||||
The service uses `%h/.local/bin/uniloader watch` and the default configuration.
|
||||
It starts with `graphical-session.target`, stops with that target, and restarts
|
||||
after unexpected failure. “Always running” means while logged into your desktop.
|
||||
To use a nondefault config, run `systemctl --user edit uniloader.service` and add:
|
||||
|
||||
```ini
|
||||
[Service]
|
||||
ExecStart=
|
||||
ExecStart=%h/.local/bin/uniloader --config %h/.config/uniloader/work.toml watch
|
||||
```
|
||||
|
||||
Then reload/restart:
|
||||
|
||||
```sh
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user restart uniloader.service
|
||||
```
|
||||
|
||||
### Display/session troubleshooting
|
||||
|
||||
If imports remain pending and logs say dialogs are unavailable, try a manual
|
||||
interactive import from your desktop terminal and check the reported display or
|
||||
OpenGL error. Check the service manager environment with
|
||||
`systemctl --user show-environment`; it needs the real session's display variables
|
||||
and session D-Bus. File browsing also needs a running desktop portal and a backend
|
||||
that supports file selection; check `journalctl --user -u xdg-desktop-portal` if
|
||||
Browse fails. Never invent a `DISPLAY=:0` or copy another user's Xauthority.
|
||||
|
||||
Some window managers/compositors do not activate `graphical-session.target` or
|
||||
import display variables. Put this shell hook in your compositor's session-start
|
||||
configuration, after the graphical session exists:
|
||||
|
||||
```sh
|
||||
#!/bin/sh
|
||||
for variable in DISPLAY WAYLAND_DISPLAY XAUTHORITY XDG_RUNTIME_DIR XDG_CURRENT_DESKTOP XDG_SESSION_TYPE DBUS_SESSION_BUS_ADDRESS; do
|
||||
if printenv "$variable" >/dev/null 2>&1; then
|
||||
systemctl --user import-environment "$variable"
|
||||
fi
|
||||
done
|
||||
systemctl --user start uniloader.service
|
||||
```
|
||||
|
||||
If the service was already running with a stale environment, restart it after
|
||||
importing variables, then retry pending imports. For compositors without target
|
||||
lifecycle integration, add `systemctl --user stop uniloader.service` to your
|
||||
session-exit hook. Enabling a unit alone cannot supply a missing GUI session.
|
||||
The initial environment comes from the session startup hook, not a hardcoded
|
||||
service `Environment=` line.
|
||||
|
||||
Lingering (`loginctl enable-linger`) does not create a graphical session and is
|
||||
not needed here. Operation before login or after logout requires a configured
|
||||
noninteractive destination and explicit ambiguity policy; unanswered decisions
|
||||
will remain pending.
|
||||
|
||||
### Update, stop and remove
|
||||
|
||||
After updating the source:
|
||||
|
||||
```sh
|
||||
cargo build --release --locked
|
||||
systemctl --user stop uniloader.service
|
||||
install -Dm755 target/release/uniloader ~/.local/bin/uniloader
|
||||
systemctl --user start uniloader.service
|
||||
```
|
||||
|
||||
Keep your existing config; compare it with the updated complete example for new
|
||||
settings. A service restart reloads configuration.
|
||||
|
||||
To disable automatic startup:
|
||||
|
||||
```sh
|
||||
systemctl --user disable --now uniloader.service
|
||||
```
|
||||
|
||||
To remove the service and executable:
|
||||
|
||||
```sh
|
||||
rm ~/.config/systemd/user/uniloader.service
|
||||
systemctl --user daemon-reload
|
||||
rm ~/.local/bin/uniloader
|
||||
```
|
||||
|
||||
Remove any compositor hooks or service overrides you added as well. Imported
|
||||
libraries, configuration, source archives and history are retained. Only remove
|
||||
those separately when you are sure they are no longer needed.
|
||||
Reference in new issue
Block a user