about summary refs log tree commit diff
path: root/nixpkgs/pkgs/tools/audio/yabridge/libyabridge-from-nix-profiles.patch
blob: 54125551e31532d5c7e8d8b267a022f526843a4e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
diff --git a/src/chainloader/utils.cpp b/src/chainloader/utils.cpp
index c43e5693..b8352adf 100644
--- a/src/chainloader/utils.cpp
+++ b/src/chainloader/utils.cpp
@@ -29,8 +29,10 @@
 namespace fs = ghc::filesystem;
 
 void* find_plugin_library(const std::string& name) {
+    Logger logger = Logger::create_exception_logger();
+
     // Just using a goto for this would probably be cleaner, but yeah...
-    const auto impl = [&name]() -> void* {
+    const auto impl = [&name, &logger]() -> void* {
         // If `name` exists right next to the Wine plugin host binary, then
         // we'll try loading that. Otherwise we'll fall back to regular
         // `dlopen()` for distro packaged versions of yabridge
@@ -52,27 +54,28 @@ void* find_plugin_library(const std::string& name) {
             }
         }
 
-        if (void* handle = dlopen(name.c_str(), RTLD_LAZY | RTLD_LOCAL)) {
-            return handle;
+        auto nix_profiles = getenv("NIX_PROFILES");
+        if (!nix_profiles || nix_profiles[0] == '\0') {
+            logger.log("");
+            logger.log("ERROR: 'NIX_PROFILES' environment variable is not set");
+            logger.log("");
+            return nullptr;
         }
 
-        // One last Hail Mary, in case ldconfig was not set up correctly. This
-        // might be relevant for some of the `/usr/local/*` locations (although
-        // you really, really shouldn't install yabridge there, please, thank
-        // you). Yabridgectl searches through these same directories.
-        for (const auto& lib_dir : {
-                 "/usr/lib",
-                 "/usr/lib/x86_64-linux-gnu",
-                 "/usr/lib64",
-                 "/usr/local/lib",
-                 "/usr/local/lib/x86_64-linux-gnu",
-                 "/usr/local/lib64",
-             }) {
-            const fs::path candidate = fs::path(lib_dir) / name;
-            if (void* handle =
-                    dlopen(candidate.c_str(), RTLD_LAZY | RTLD_LOCAL)) {
+        // NIX_PROFILES is iterated in reverse from the most specific (the
+        // user profile) to the least specific (the system profile).
+        const std::string_view nix_profiles_view = nix_profiles;
+        auto segment_end = nix_profiles_view.size();
+        while (segment_end != std::string::npos) {
+            const auto next_segment_end = nix_profiles_view.rfind(' ', segment_end - 1);
+            const auto segment_begin = next_segment_end + 1;
+            const auto profile = nix_profiles_view.substr(segment_begin, segment_end - segment_begin);
+            const auto candidate = fs::path(profile) / "lib" / name;
+            if (auto handle = dlopen(candidate.c_str(), RTLD_LAZY | RTLD_LOCAL)) {
                 return handle;
             }
+
+            segment_end = next_segment_end;
         }
 
         return nullptr;
@@ -82,8 +85,6 @@ void* find_plugin_library(const std::string& name) {
     if (!handle) {
         const fs::path this_plugin_path = get_this_file_location();
 
-        Logger logger = Logger::create_exception_logger();
-
         logger.log("");
         logger.log("Could not find '" + name + "'");
         logger.log("");