From e3ee579f929074e528f9ef3bb9f4394916a554e5 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Tue, 11 Feb 2025 13:31:53 -0800 Subject: [PATCH] Config: Correctly handle relative paths with portable It is desired that FEX_APP_CONFIG and FEX_APP_CONFIG_LOCATION support relative paths when portable is used. Support this. --- FEXCore/Scripts/config_generator.py | 6 ++++++ Source/Common/Config.cpp | 24 +++++++++++++++++++----- Source/Common/Config.h | 2 +- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/FEXCore/Scripts/config_generator.py b/FEXCore/Scripts/config_generator.py index 32468d5162..af755af048 100644 --- a/FEXCore/Scripts/config_generator.py +++ b/FEXCore/Scripts/config_generator.py @@ -193,6 +193,9 @@ def print_man_environment_tail(): "Allows the user to override where FEX looks for configuration files", "By default FEX will look in {$HOME, $XDG_CONFIG_HOME}/.fex-emu/", "This will override the full path", + "If FEX_PORTABLE is declared then relative paths are also supported", + "For FEXInterpreter: Relative to the FEXInterpreter binary", + "For WINE: Relative to %LOCALAPPDATA%" ], "''", True) @@ -204,6 +207,9 @@ def print_man_environment_tail(): "This will override this file location", "One must be careful with this option as it will override any applications that load with execve as well" "If you need to support applications that execve then use FEX_APP_CONFIG_LOCATION instead" + "If FEX_PORTABLE is declared then relative paths are also supported", + "For FEXInterpreter: Relative to the FEXInterpreter binary", + "For WINE: Relative to %LOCALAPPDATA%" ], "''", True) diff --git a/Source/Common/Config.cpp b/Source/Common/Config.cpp index dd433725fe..cc644a9927 100644 --- a/Source/Common/Config.cpp +++ b/Source/Common/Config.cpp @@ -108,7 +108,7 @@ class MainLoader final : public OptionMapper { public: explicit MainLoader(FEXCore::Config::LayerType Type); explicit MainLoader(fextl::string ConfigFile); - explicit MainLoader(FEXCore::Config::LayerType Type, const char* ConfigFile); + explicit MainLoader(FEXCore::Config::LayerType Type, std::string_view ConfigFile); void Load() override; @@ -168,7 +168,7 @@ MainLoader::MainLoader(fextl::string ConfigFile) , Config {std::move(ConfigFile)} {} -MainLoader::MainLoader(FEXCore::Config::LayerType Type, const char* ConfigFile) +MainLoader::MainLoader(FEXCore::Config::LayerType Type, std::string_view ConfigFile) : OptionMapper(Type) , Config {ConfigFile} {} @@ -259,7 +259,7 @@ fextl::unique_ptr CreateMainLayer(const fextl::string* F } } -fextl::unique_ptr CreateUserOverrideLayer(const char* AppConfig) { +fextl::unique_ptr CreateUserOverrideLayer(std::string_view AppConfig) { return fextl::make_unique(FEXCore::Config::LayerType::LAYER_USER_OVERRIDE, AppConfig); } @@ -418,8 +418,15 @@ void LoadConfig(fextl::unique_ptr ArgsLoader, fextl:: } const char* AppConfig = getenv("FEX_APP_CONFIG"); - if (AppConfig && FHU::Filesystem::Exists(AppConfig)) { - FEXCore::Config::AddLayer(CreateUserOverrideLayer(AppConfig)); + if (AppConfig) { + fextl::string AppConfigStr = AppConfig; + if (IsPortable && FHU::Filesystem::IsRelative(AppConfig)) { + AppConfigStr = PortableInfo.InterpreterPath + AppConfigStr; + } + + if (FHU::Filesystem::Exists(AppConfigStr)) { + FEXCore::Config::AddLayer(CreateUserOverrideLayer(AppConfigStr)); + } } FEXCore::Config::AddLayer(CreateEnvironmentLayer(envp)); @@ -503,6 +510,13 @@ fextl::string GetConfigDirectory(bool Global, const PortableInformation& Portabl const char* ConfigOverride = getenv("FEX_APP_CONFIG_LOCATION"); if (PortableInfo.IsPortable && (Global || !ConfigOverride)) { return fextl::fmt::format("{}/fex-emu/", PortableInfo.InterpreterPath); + } else if (PortableInfo.IsPortable && ConfigOverride && !Global) { + fextl::string AppConfigStr = ConfigOverride; + if (PortableInfo.IsPortable && FHU::Filesystem::IsRelative(AppConfigStr)) { + AppConfigStr = PortableInfo.InterpreterPath + AppConfigStr; + } + + return AppConfigStr; } fextl::string ConfigDir; diff --git a/Source/Common/Config.h b/Source/Common/Config.h index 5c13c210a7..d3f1e868cc 100644 --- a/Source/Common/Config.h +++ b/Source/Common/Config.h @@ -76,7 +76,7 @@ fextl::unique_ptr CreateGlobalMainLayer(); * @return unique_ptr for that layer */ fextl::unique_ptr CreateMainLayer(const fextl::string* File = nullptr); -fextl::unique_ptr CreateUserOverrideLayer(const char* AppConfig); +fextl::unique_ptr CreateUserOverrideLayer(std::string_view AppConfig); /** * @brief Create an application configuration loader