diff --git a/doc/interoperability/openxr.md b/doc/interoperability/openxr.md new file mode 100644 index 0000000000000..186b06d38c031 --- /dev/null +++ b/doc/interoperability/openxr.md @@ -0,0 +1,5 @@ +# OpenXR in NixOS + +OpenXR is a standard for eXtended Reality (XR) applications and drivers (providers). + +OpenXR runtime providers must ensure that the library path of the runtime's shared library can be loaded by Nix applications. If your OpenXR runtime provider runs in an FHSEnv, this means you may have to use `auto-patchelf` to link dependencies to the Nix store. diff --git a/pkgs/by-name/au/auto-patchelf/source/auto-patchelf.py b/pkgs/by-name/au/auto-patchelf/source/auto-patchelf.py index 2a1090302ee9e..f5c361841c006 100644 --- a/pkgs/by-name/au/auto-patchelf/source/auto-patchelf.py +++ b/pkgs/by-name/au/auto-patchelf/source/auto-patchelf.py @@ -320,6 +320,7 @@ def auto_patchelf( ignore_missing: list[str] = [], append_rpaths: list[Path] = [], keep_libc: bool = False, + add_existing: bool = True, extra_args: list[str] = []) -> None: if not paths_to_patch: @@ -327,7 +328,9 @@ def auto_patchelf( # Add all shared objects of the current output path to the cache, # before lib_dirs, so that they are chosen first in find_dependency. - populate_cache(paths_to_patch, recursive) + if add_existing: + populate_cache(paths_to_patch, recursive) + populate_cache(lib_dirs) dependencies = [] @@ -365,30 +368,46 @@ def main() -> None: "--ignore-missing", nargs="*", type=str, - help="Do not fail when some dependencies are not found.") + default=[], + help="Do not fail when some dependencies are not found." + ) parser.add_argument( "--no-recurse", dest="recursive", action="store_false", - help="Disable the recursive traversal of paths to patch.") + help="Disable the recursive traversal of paths to patch." + ) parser.add_argument( - "--paths", nargs="*", type=Path, + "--paths", + nargs="*", + type=Path, + required=True, help="Paths whose content needs to be patched." " Single files and directories are accepted." - " Directories are traversed recursively by default.") + " Directories are traversed recursively by default." + ) parser.add_argument( - "--libs", nargs="*", type=Path, + "--libs", + nargs="*", + type=Path, + default=[], help="Paths where libraries are searched for." " Single files and directories are accepted." - " Directories are not searched recursively.") + " Directories are not searched recursively." + ) parser.add_argument( - "--runtime-dependencies", nargs="*", type=Path, + "--runtime-dependencies", + nargs="*", + type=Path, + default=[], help="Paths to prepend to the runtime path of executable binaries." - " Subject to deduplication, which may imply some reordering.") + " Subject to deduplication, which may imply some reordering." + ) parser.add_argument( "--append-rpaths", nargs="*", type=Path, + default=[], help="Paths to append to all runtime paths unconditionally", ) parser.add_argument( @@ -397,6 +416,12 @@ def main() -> None: action="store_true", help="Attempt to search for and relink libc dependencies.", ) + parser.add_argument( + "--no-add-existing", + dest="add_existing", + action="store_false", + help="Do not add the existing rpaths of the patched files to the list of directories to search for dependencies.", + ) parser.add_argument( "--extra-args", # Undocumented Python argparse feature: consume all remaining arguments @@ -404,7 +429,8 @@ def main() -> None: # last. nargs="...", type=str, - help="Extra arguments to pass to patchelf. This argument should always come last." + default=[], + help="Extra arguments to pass to patchelf. This argument should always come last.", ) print("automatically fixing dependencies for ELF files") @@ -419,6 +445,7 @@ def main() -> None: args.ignore_missing, append_rpaths=args.append_rpaths, keep_libc=args.keep_libc, + add_existing=args.add_existing, extra_args=args.extra_args) diff --git a/pkgs/by-name/en/envision/autopatchelf.patch b/pkgs/by-name/en/envision/autopatchelf.patch new file mode 100644 index 0000000000000..d3063f74063d2 --- /dev/null +++ b/pkgs/by-name/en/envision/autopatchelf.patch @@ -0,0 +1,205 @@ +diff --git a/src/builders/build_basalt.rs b/src/builders/build_basalt.rs +index e67e081..0162e1d 100644 +--- a/src/builders/build_basalt.rs ++++ b/src/builders/build_basalt.rs +@@ -6,6 +6,7 @@ use crate::{ + util::file_utils::rm_rf, + }; + use std::collections::{HashMap, VecDeque}; ++use std::env; + + pub fn get_build_basalt_jobs(profile: &Profile, clean_build: bool) -> VecDeque { + let mut jobs = VecDeque::::new(); +@@ -101,6 +102,21 @@ pub fn get_build_basalt_jobs(profile: &Profile, clean_build: bool) -> VecDeque VecDeque { + let mut jobs = VecDeque::::new(); +@@ -71,6 +72,21 @@ pub fn get_build_libsurvive_jobs(profile: &Profile, clean_build: bool) -> VecDeq + } + jobs.push_back(cmake.get_build_job()); + jobs.push_back(cmake.get_install_job()); ++ jobs.push_back(WorkerJob::new_cmd( ++ None, ++ "auto-patchelf".into(), ++ Some( ++ [ ++ vec![ ++ "--no-add-existing", ++ "--paths".into(), ++ build_dir.into_os_string().into_string().unwrap(), ++ "--libs".into(), ++ ], ++ env::var("libs").unwrap_or_default().split(":").map(|s| s.to_string()).collect(), ++ ].concat() ++ ), ++ )); + + jobs + } +diff --git a/src/builders/build_monado.rs b/src/builders/build_monado.rs +index f379d6f..79d8fb9 100644 +--- a/src/builders/build_monado.rs ++++ b/src/builders/build_monado.rs +@@ -9,6 +9,7 @@ use std::{ + collections::{HashMap, VecDeque}, + path::Path, + }; ++use std::env; + + pub fn get_build_monado_jobs(profile: &Profile, clean_build: bool) -> VecDeque { + let mut jobs = VecDeque::::new(); +@@ -83,6 +84,21 @@ pub fn get_build_monado_jobs(profile: &Profile, clean_build: bool) -> VecDeque VecDeque { + let mut jobs = VecDeque::::new(); +@@ -48,6 +49,21 @@ pub fn get_build_opencomposite_jobs(profile: &Profile, clean_build: bool) -> Vec + jobs.push_back(cmake.get_prepare_job()); + } + jobs.push_back(cmake.get_build_job()); ++ jobs.push_back(WorkerJob::new_cmd( ++ None, ++ "auto-patchelf".into(), ++ Some( ++ [ ++ vec![ ++ "--no-add-existing", ++ "--paths".into(), ++ build_dir.into_os_string().into_string().unwrap(), ++ "--libs".into(), ++ ], ++ env::var("libs").unwrap_or_default().split(":").map(|s| s.to_string()).collect(), ++ ].concat() ++ ), ++ )); + + jobs + } +diff --git a/src/builders/build_openhmd.rs b/src/builders/build_openhmd.rs +index 1157eca..359f49c 100644 +--- a/src/builders/build_openhmd.rs ++++ b/src/builders/build_openhmd.rs +@@ -3,6 +3,7 @@ use crate::{ + util::file_utils::rm_rf, + }; + use std::{collections::VecDeque, path::Path}; ++use std::env; + + pub fn get_build_openhmd_jobs(profile: &Profile, clean_build: bool) -> VecDeque { + let mut jobs = VecDeque::::new(); +@@ -80,6 +81,22 @@ pub fn get_build_openhmd_jobs(profile: &Profile, clean_build: bool) -> VecDeque< + "install".into(), + ]), + )); ++ // autopatchelf job ++ jobs.push_back(WorkerJob::new_cmd( ++ None, ++ "auto-patchelf".into(), ++ Some( ++ [ ++ vec![ ++ "--no-add-existing", ++ "--paths".into(), ++ build_dir.into_os_string().into_string().unwrap(), ++ "--libs".into(), ++ ], ++ env::var("libs").unwrap_or_default().split(":").map(|s| s.to_string()).collect(), ++ ].concat() ++ ), ++ )); + + jobs + } +diff --git a/src/builders/build_wivrn.rs b/src/builders/build_wivrn.rs +index f2a415d..a160186 100644 +--- a/src/builders/build_wivrn.rs ++++ b/src/builders/build_wivrn.rs +@@ -9,6 +9,7 @@ use std::{ + collections::{HashMap, VecDeque}, + path::Path, + }; ++use std::env; + + pub fn get_build_wivrn_jobs(profile: &Profile, clean_build: bool) -> VecDeque { + let mut jobs = VecDeque::::new(); +@@ -60,6 +61,21 @@ pub fn get_build_wivrn_jobs(profile: &Profile, clean_build: bool) -> VecDeque