diff --git a/Cargo.toml b/Cargo.toml index c425cc7..373904f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sharun" -version = "0.2.6" +version = "0.2.7" readme = "README.md" license = "MIT" repository = "https://github.com/VHSgunzo/sharun" diff --git a/README.md b/README.md index b56bf80..d5d4784 100644 --- a/README.md +++ b/README.md @@ -91,42 +91,49 @@ cp ./target/$(uname -m)-unknown-linux-musl/release/sharun . * Additional env var can be specified in the `.env` file (see [dotenv](https://crates.io/crates/dotenv)). Env var can also be deleted using `unset ENV_VAR` in the end of the `.env` file. +* You can preload libraries using `.preload` file. Specify the necessary libraries in it from a new line. You can use the full paths to libraries or only their names if they are located in `shared/{lib,lib32}/` +This can be useful, for example, to use [ld-preload-open](https://github.com/fritzw/ld-preload-open) library to reassign paths. + * Also you can package the `sharun directory` with your applications into a single executable file using [wrappe](https://github.com/Systemcluster/wrappe) ## Screenshots: ![tree](img/tree.png) ## Environment variables that are set if sharun finds a directory or file: -* `PATH` -- `${SHARUN_DIR}/bin` -* `PYTHONHOME` and `PYTHONDONTWRITEBYTECODE` -- `${SHARUN_DIR}/shared/$LIB/python*` -* `PERLLIB` -- `${SHARUN_DIR}/shared/$LIB/perl*` -* `GCONV_PATH` -- `${SHARUN_DIR}/shared/$LIB/gconv` -* `GIO_MODULE_DIR` -- `${SHARUN_DIR}/shared/$LIB/gio/modules` -* `GTK_PATH`, `GTK_EXE_PREFIX` and `GTK_DATA_PREFIX` -- `${SHARUN_DIR}/shared/$LIB/gtk-*` -* `QT_PLUGIN_PATH` -- `${SHARUN_DIR}/shared/$LIB/qt*/plugins` -* `BABL_PATH` -- `${SHARUN_DIR}/shared/$LIB/babl-*` -* `GEGL_PATH` -- `${SHARUN_DIR}/shared/$LIB/gegl-*` -* `GIMP2_PLUGINDIR` -- `${SHARUN_DIR}/shared/$LIB/gimp/2.0` -* `TCL_LIBRARY` -- `${SHARUN_DIR}/shared/$LIB/tcl*` -* `TK_LIBRARY` -- `${SHARUN_DIR}/shared/$LIB/tk*` -* `GST_PLUGIN_PATH`, `GST_PLUGIN_SYSTEM_PATH`, `GST_PLUGIN_SYSTEM_PATH_1_0`, and `GST_PLUGIN_SCANNER` -- `${SHARUN_DIR}/shared/$LIB/gstreamer-*` -* `GDK_PIXBUF_MODULEDIR` and `GDK_PIXBUF_MODULE_FILE` -- `${SHARUN_DIR}/shared/$LIB/gdk-pixbuf-*` -* `LIBDECOR_PLUGIN_DIR` -- `${SHARUN_DIR}/shared/$LIB/libdecor/plugins-1` -* `GTK_IM_MODULE_FILE` -- `${SHARUN_DIR}/shared/$LIB/gtk-*/*/immodules.cache` -* `LIBGL_DRIVERS_PATH` -- `${SHARUN_DIR}/shared/$LIB/dri` -* `SPA_PLUGIN_DIR` -- `${SHARUN_DIR}/shared/$LIB/spa-*` -* `PIPEWIRE_MODULE_DIR` -- `${SHARUN_DIR}/shared/$LIB/pipewire-*` - -* `XDG_DATA_DIRS` -- `${SHARUN_DIR}/share` -* `VK_DRIVER_FILES` -- `${SHARUN_DIR}/share/vulkan/icd.d` -* `__EGL_VENDOR_LIBRARY_DIRS` -- `${SHARUN_DIR}/share/glvnd/egl_vendor.d` -* `XKB_CONFIG_ROOT` -- `${SHARUN_DIR}/share/X11/xkb` -* `GSETTINGS_SCHEMA_DIR` -- `${SHARUN_DIR}/share/glib-2.0/schemas` -* `GIMP2_DATADIR` -- `${SHARUN_DIR}/share/gimp/2.0` -* `TERMINFO` -- `${SHARUN_DIR}/share/terminfo` - -* `FONTCONFIG_FILE` -- `${SHARUN_DIR}/etc/fonts/fonts.conf` -* `GIMP2_SYSCONFDIR` -- `${SHARUN_DIR}/etc/gimp/2.0` +||| +|---|---| +|`PATH` | `${SHARUN_DIR}/bin` | +|`PYTHONHOME` and `PYTHONDONTWRITEBYTECODE` | `${SHARUN_DIR}/shared/$LIB/python*` | +|`PERLLIB` | `${SHARUN_DIR}/shared/$LIB/perl*` | +|`GCONV_PATH` | `${SHARUN_DIR}/shared/$LIB/gconv` | +|`GIO_MODULE_DIR` | `${SHARUN_DIR}/shared/$LIB/gio/modules`| +|`GTK_PATH`, `GTK_EXE_PREFIX` and `GTK_DATA_PREFIX` | `${SHARUN_DIR}/shared/$LIB/gtk-*`| +|`QT_PLUGIN_PATH` | `${SHARUN_DIR}/shared/$LIB/qt*/plugins`| +|`BABL_PATH` | `${SHARUN_DIR}/shared/$LIB/babl-*`| +|`GEGL_PATH` | `${SHARUN_DIR}/shared/$LIB/gegl-*`| +|`GIMP2_PLUGINDIR` | `${SHARUN_DIR}/shared/$LIB/gimp/2.0`| +|`TCL_LIBRARY` | `${SHARUN_DIR}/shared/$LIB/tcl*`| +|`TK_LIBRARY` | `${SHARUN_DIR}/shared/$LIB/tk*`| +|`GST_PLUGIN_PATH`, `GST_PLUGIN_SYSTEM_PATH`, `GST_PLUGIN_SYSTEM_PATH_1_0`, and `GST_PLUGIN_SCANNER` | `${SHARUN_DIR}/shared/$LIB/gstreamer-*`| +|`GDK_PIXBUF_MODULEDIR` and `GDK_PIXBUF_MODULE_FILE` | `${SHARUN_DIR}/shared/$LIB/gdk-pixbuf-*`| +|`LIBDECOR_PLUGIN_DIR` | `${SHARUN_DIR}/shared/$LIB/libdecor/plugins-1`| +|`GTK_IM_MODULE_FILE` | `${SHARUN_DIR}/shared/$LIB/gtk-*/*/immodules.cache`| +|`LIBGL_DRIVERS_PATH` | `${SHARUN_DIR}/shared/$LIB/dri`| +|`SPA_PLUGIN_DIR` | `${SHARUN_DIR}/shared/$LIB/spa-*`| +|`PIPEWIRE_MODULE_DIR` | `${SHARUN_DIR}/shared/$LIB/pipewire-*`| +||| +|---|---| +|`XDG_DATA_DIRS` | `${SHARUN_DIR}/share`| +|`VK_DRIVER_FILES` | `${SHARUN_DIR}/share/vulkan/icd.d`| +|`__EGL_VENDOR_LIBRARY_DIRS` | `${SHARUN_DIR}/share/glvnd/egl_vendor.d`| +|`XKB_CONFIG_ROOT` | `${SHARUN_DIR}/share/X11/xkb`| +|`GSETTINGS_SCHEMA_DIR` | `${SHARUN_DIR}/share/glib-2.0/schemas`| +|`GIMP2_DATADIR` | `${SHARUN_DIR}/share/gimp/2.0`| +|`TERMINFO` | `${SHARUN_DIR}/share/terminfo`| +||| +|---|---| +|`FONTCONFIG_FILE` | `${SHARUN_DIR}/etc/fonts/fonts.conf`| +|`GIMP2_SYSCONFDIR` | `${SHARUN_DIR}/etc/gimp/2.0`| ## Projects that use sharun: * [pelfCreator](https://github.com/xplshn/pelf/blob/pelf-ng/pelfCreator) @@ -137,6 +144,8 @@ cp ./target/$(uname -m)-unknown-linux-musl/release/sharun . * [mpv-AppImage](https://github.com/Samueru-sama/mpv-AppImage) * [OBS-Studio-AppImage](https://github.com/Samueru-sama/OBS-Studio-AppImage) * [GIMP-AppImage](https://github.com/Samueru-sama/GIMP-AppImage) +* [RMG](https://github.com/Rosalie241/RMG) +* [PrusaSlicer](https://github.com/probonopd/PrusaSlicer) ## References * [userland-execve](https://crates.io/crates/userland-execve) diff --git a/src/main.rs b/src/main.rs index e445e9d..a6ac0d4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -595,8 +595,29 @@ fn main() { CString::from_str(&interpreter.to_string_lossy()).unwrap(), CString::new("--library-path").unwrap(), CString::new(library_path).unwrap(), - CString::new(bin).unwrap() + CString::new("--argv0").unwrap(), + CString::new(arg0_path.to_str().unwrap()).unwrap() ]; + + let preload_path = PathBuf::from(format!("{sharun_dir}/.preload")); + if preload_path.exists() { + let data = read_to_string(&preload_path).unwrap_or_else(|err|{ + eprintln!("Failed to read .preload file: {}: {err}", preload_path.display()); + exit(1) + }); + let mut preload: Vec = vec![]; + for string in data.trim().split("\n") { + preload.push(string.trim().into()); + } + if !preload.is_empty() { + interpreter_args.append(&mut vec![ + CString::new("--preload").unwrap(), + CString::new(preload.join(" ")).unwrap() + ]) + } + } + + interpreter_args.push(CString::new(bin).unwrap()); for arg in exec_args { interpreter_args.push(CString::from_str(&arg).unwrap()) }