From 28cfa89970d2d747c54236d0f0a476aa1203462d Mon Sep 17 00:00:00 2001 From: jcm <6864788+jcm93@users.noreply.github.com> Date: Tue, 12 Nov 2024 07:02:37 -0600 Subject: [PATCH] nall, desktop-ui: Account for other *nix data locations (#1688) ### Context https://github.com/ares-emulator/ares/pull/1575 ended up defining the `sharedData` directory on Unix-like systems as `~/.local/share` if a build prefix was not defined. This is not exactly correct; the meaning of a "shared data" directory on a Unix-like system is variously `/usr/share`, `/usr/local/share`, or else the `share` directory of a given install prefix. ### Changes This PR allows us to respect normal Unix conventions while also respecting the option to build and install with a given prefix. This is done by defining two more functions in nall's `path`: * `localSharedData()` for `/usr/local/share` * `prefixSharedData()` for `${ARES_PREFIX}/share` `sharedData()` is changed back to the old behavior and returns `/usr/share`. Then, the `locate` logic in desktop-ui (and uh, mia) is adjusted to now search (in order): 1. the prefix's shared data if the prefix exists 2. local shared data 3. system shared data --- desktop-ui/desktop-ui.cpp | 12 ++++++++++++ mia/mia.cpp | 12 ++++++++++++ nall/path.cpp | 17 +++++++++++++++++ nall/path.hpp | 15 ++++++++++++--- 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/desktop-ui/desktop-ui.cpp b/desktop-ui/desktop-ui.cpp index cbc7c7010a..3ab0a30eb4 100644 --- a/desktop-ui/desktop-ui.cpp +++ b/desktop-ui/desktop-ui.cpp @@ -19,6 +19,18 @@ auto locate(const string& name) -> string { if(inode::exists(location)) return location; // 3. The shared data directory +#if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD) + /// Unix-like systems have multiple notions of a 'shared data' directory. First, check for + /// an install prefix, as would be used by package managers that do not use `/usr/share`. + /// Secondly, look in `/usr/local/share` to cover software compiled by the user. + /// Lastly, look in the 'global' shared data directory, `/usr/share`. + location = {Path::prefixSharedData(), "ares/", name}; + if(inode::exists(location)) return location; + + location = {Path::localSharedData(), "ares/", name}; + if(inode::exists(location)) return location; +#endif + location = {Path::sharedData(), "ares/", name}; if(inode::exists(location)) return location; diff --git a/mia/mia.cpp b/mia/mia.cpp index ca9b73c9d0..9aca07f323 100644 --- a/mia/mia.cpp +++ b/mia/mia.cpp @@ -21,6 +21,18 @@ auto locate(const string &name) -> string { if (inode::exists(location)) return location; // 3. The shared data directory +#if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD) + /// Unix-like systems have multiple notions of a 'shared data' directory. First, check for + /// an install prefix, as would be used by package managers that do not use `/usr/share`. + /// Secondly, look in `/usr/local/share` to cover software compiled by the user. + /// Lastly, look in the 'global' shared data directory, `/usr/share`. + location = {Path::prefixSharedData(), "ares/", name}; + if (inode::exists(location)) return location; + + location = {Path::localSharedData(), "ares/", name}; + if (inode::exists(location)) return location; +#endif + location = {Path::sharedData(), "ares/", name}; if (inode::exists(location)) return location; diff --git a/nall/path.cpp b/nall/path.cpp index 96adaa0fd4..40b3824a29 100644 --- a/nall/path.cpp +++ b/nall/path.cpp @@ -151,6 +151,23 @@ NALL_HEADER_INLINE auto sharedData() -> string { return result; } +#if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD) +NALL_HEADER_INLINE auto prefixSharedData() -> string { + string result; + #if defined(ARES_PREFIX) + string result = stringize(ARES_PREFIX/share/); + #endif + if(!result) result = "."; + if(!result.endsWith("/")) result.append("/"); + return result; +} + +NALL_HEADER_INLINE auto localSharedData() -> string { + string result = "/usr/local/share/"; + return result; +} +#endif + NALL_HEADER_INLINE auto temporary() -> string { #if defined(PLATFORM_WINDOWS) wchar_t path[PATH_MAX] = L""; diff --git a/nall/path.hpp b/nall/path.hpp index 6218110050..109efc3bf9 100644 --- a/nall/path.hpp +++ b/nall/path.hpp @@ -38,19 +38,19 @@ auto root() -> string; // c:/users/username/ auto user() -> string; -// /home/username/Desktop/ +// ~/Desktop/ // c:/users/username/Desktop/ auto desktop(string_view name = {}) -> string; //todo: MacOS uses the same location for userData() and userSettings() //... is there a better option here? -// /home/username/.config/ +// ~/.config/ // ~/Library/Application Support/ // c:/users/username/appdata/roaming/ auto userSettings() -> string; -// /home/username/.local/share/ +// ~/.local/share/ // ~/Library/Application Support/ // c:/users/username/appdata/local/ auto userData() -> string; @@ -60,6 +60,15 @@ auto userData() -> string; // c:/ProgramData/ auto sharedData() -> string; +#if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD) +// ARES_PREFIX/share +auto prefixSharedData() -> string; + +// /usr/local/share +auto localSharedData() -> string; +#endif + + // /tmp // c:/users/username/AppData/Local/Temp/ auto temporary() -> string;