mirror of
https://github.com/wailsapp/wails.git
synced 2026-03-14 14:45:49 +01:00
* feat(linux): add libpath package for finding native library paths
Add a new internal/libpath package that locates shared libraries (.so files)
on Linux systems. Supports multiple distributions and package managers.
Features:
- Multi-tier search: pkg-config -> ldconfig -> filesystem scanning
- Parallel search using goroutines for faster lookups
- Cached dynamic path discovery for Flatpak, Snap, and Nix
- Support for Debian/Ubuntu, Fedora/RHEL, Arch, openSUSE, NixOS
- Context-aware cancellation for graceful shutdown
Performance:
- Library found: ~1.4ms (parallel search)
- Library not found: ~46ms (was 84ms sequential)
- Cached path discovery: 14ns (was 15ms uncached)
* feat(libpath): add multi-library parallel search functions
Add functions to search for multiple library candidates in parallel:
- FindFirstLibrary: Search multiple libs in parallel, return first found
- FindFirstLibraryOrdered: Search in order of preference (for version priority)
- FindAllLibraries: Find all available libraries from a list
Useful when the exact library version is unknown, e.g.:
match, _ := FindFirstLibrary("webkit2gtk-4.1", "webkit2gtk-4.0", "webkit2gtk-6.0")
Also adds findLibraryPathCtx for context-aware searching used by the
multi-library functions.
* refactor(libpath): split into separate files and fix race condition
Split libpath_linux.go into smaller, focused files:
- cache_linux.go: Path cache with thread-safe init/invalidate
- flatpak_linux.go: Flatpak runtime path discovery
- snap_linux.go: Snap package path discovery
- nix_linux.go: Nix/NixOS path discovery
- libpath_linux.go: Core search functions
Fixes:
- Fix data race between init() and invalidate() by holding mutex
during cache writes inside sync.Once.Do (CodeRabbit review)
- Fix FindLibraryPathWithOptions not searching dynamic paths
(Flatpak/Snap/Nix) - now uses GetAllLibPaths() (CodeRabbit review)
104 lines
3.5 KiB
Go
104 lines
3.5 KiB
Go
// Package libpath provides utilities for finding native library paths on Linux.
|
|
//
|
|
// # Overview
|
|
//
|
|
// This package helps locate shared libraries (.so files) on Linux systems,
|
|
// supporting multiple distributions and package managers. It's particularly
|
|
// useful for applications that need to link against libraries like GTK,
|
|
// WebKit2GTK, or other system libraries at runtime.
|
|
//
|
|
// # Search Strategy
|
|
//
|
|
// The package uses a multi-tier search strategy, trying each method in order
|
|
// until a library is found:
|
|
//
|
|
// 1. pkg-config: Queries the pkg-config database for library paths
|
|
// 2. ldconfig: Searches the dynamic linker cache
|
|
// 3. Filesystem: Scans common library directories
|
|
//
|
|
// # Supported Distributions
|
|
//
|
|
// The package includes default search paths for:
|
|
//
|
|
// - Debian/Ubuntu (multiarch paths like /usr/lib/x86_64-linux-gnu)
|
|
// - Fedora/RHEL/CentOS (/usr/lib64, /usr/lib64/gtk-*)
|
|
// - Arch Linux (/usr/lib/webkit2gtk-*, /usr/lib/gtk-*)
|
|
// - openSUSE (/usr/lib64/gcc/x86_64-suse-linux)
|
|
// - NixOS and Nix package manager
|
|
//
|
|
// # Package Manager Support
|
|
//
|
|
// Dynamic paths are discovered from:
|
|
//
|
|
// - Flatpak: Scans runtime directories via `flatpak --installations`
|
|
// - Snap: Globs /snap/*/current/usr/lib* directories
|
|
// - Nix: Checks ~/.nix-profile/lib and /run/current-system/sw/lib
|
|
//
|
|
// # Caching
|
|
//
|
|
// Dynamic path discovery (Flatpak, Snap, Nix) is cached for performance.
|
|
// The cache is populated on first access and persists for the process lifetime.
|
|
// Use [InvalidateCache] to force re-discovery if packages are installed/removed
|
|
// during runtime.
|
|
//
|
|
// # Security
|
|
//
|
|
// The current directory (".") is never included in search paths by default,
|
|
// as this is a security risk. Use [FindLibraryPathWithOptions] with
|
|
// IncludeCurrentDir if you explicitly need this behavior (not recommended
|
|
// for production).
|
|
//
|
|
// # Performance
|
|
//
|
|
// Typical lookup times (cached):
|
|
//
|
|
// - Found via pkg-config: ~2ms (spawns external process)
|
|
// - Found via ldconfig: ~1.3ms (spawns external process)
|
|
// - Found via filesystem: ~0.1ms (uses cached paths)
|
|
// - Not found (worst case): ~20ms (searches all paths)
|
|
//
|
|
// # Example Usage
|
|
//
|
|
// // Find a library by its pkg-config name
|
|
// path, err := libpath.FindLibraryPath("webkit2gtk-4.1")
|
|
// if err != nil {
|
|
// log.Fatal("WebKit2GTK not found:", err)
|
|
// }
|
|
// fmt.Println("Found at:", path)
|
|
//
|
|
// // Find a specific .so file
|
|
// soPath, err := libpath.FindLibraryFile("libgtk-3.so")
|
|
// if err != nil {
|
|
// log.Fatal("GTK3 library file not found:", err)
|
|
// }
|
|
// fmt.Println("Library file:", soPath)
|
|
//
|
|
// // Get all library search paths
|
|
// for _, p := range libpath.GetAllLibPaths() {
|
|
// fmt.Println(p)
|
|
// }
|
|
//
|
|
// # Multi-Library Search
|
|
//
|
|
// When you don't know which version of a library is installed, use the
|
|
// multi-library search functions:
|
|
//
|
|
// // Find any available WebKit2GTK version (first found wins)
|
|
// match, err := libpath.FindFirstLibrary("webkit2gtk-4.1", "webkit2gtk-4.0", "webkit2gtk-6.0")
|
|
// if err != nil {
|
|
// log.Fatal("No WebKit2GTK found")
|
|
// }
|
|
// fmt.Printf("Found %s at %s\n", match.Name, match.Path)
|
|
//
|
|
// // Prefer newer versions (ordered search)
|
|
// match, err := libpath.FindFirstLibraryOrdered("gtk4", "gtk+-3.0")
|
|
//
|
|
// // Discover all available versions
|
|
// matches := libpath.FindAllLibraries("gtk+-3.0", "gtk4", "webkit2gtk-4.0", "webkit2gtk-4.1")
|
|
// for _, m := range matches {
|
|
// fmt.Printf("Available: %s at %s\n", m.Name, m.Path)
|
|
// }
|
|
//
|
|
// On non-Linux platforms, stub implementations are provided that always
|
|
// return [LibraryNotFoundError].
|
|
package libpath
|