Config: Move path generation to the frontend

This lets all the path generation for the config to be in the frontend.
This then informs FEXCore where things should live.

This is for llvm-mingw. While paths aren't quite generated correctly,
this gets the code closer to compiling.
This commit is contained in:
Ryan Houdek 2023-04-12 11:04:02 -07:00
parent 27c03f98d8
commit d853de39ff
13 changed files with 156 additions and 182 deletions

View File

@ -1,7 +1,6 @@
set (MAN_DIR ${CMAKE_INSTALL_PREFIX}/share/man CACHE PATH "MAN_DIR")
set (FEXCORE_BASE_SRCS
Common/Paths.cpp
Interface/Config/Config.cpp
Utils/Allocator.cpp
Utils/Allocator/64BitAllocator.cpp

View File

@ -1,87 +0,0 @@
#include "Common/Paths.h"
#include <FEXCore/Utils/Allocator.h>
#include <FEXCore/Utils/LogManager.h>
#include <FEXCore/fextl/memory.h>
#include <FEXCore/fextl/string.h>
#include <FEXHeaderUtils/Filesystem.h>
#include <cstdlib>
#include <filesystem>
#include <memory>
#include <pwd.h>
#include <system_error>
#include <sys/stat.h>
#include <unistd.h>
namespace FEXCore::Paths {
fextl::string CachePath{};
fextl::string EntryCache{};
char const* FindUserHomeThroughUID() {
auto passwd = getpwuid(geteuid());
if (passwd) {
return passwd->pw_dir;
}
return nullptr;
}
const char *GetHomeDirectory() {
char const *HomeDir = getenv("HOME");
// Try to get home directory from uid
if (!HomeDir) {
HomeDir = FindUserHomeThroughUID();
}
// try the PWD
if (!HomeDir) {
HomeDir = getenv("PWD");
}
// Still doesn't exit? You get local
if (!HomeDir) {
HomeDir = ".";
}
return HomeDir;
}
void InitializePaths() {
char const *HomeDir = getenv("HOME");
if (!HomeDir) {
HomeDir = getenv("PWD");
}
if (!HomeDir) {
HomeDir = ".";
}
char *XDGDataDir = getenv("XDG_DATA_DIR");
if (XDGDataDir) {
CachePath = XDGDataDir;
}
else {
if (HomeDir) {
CachePath = HomeDir;
}
}
CachePath += "/.fex-emu/";
EntryCache = CachePath + "/EntryCache/";
// Ensure the folder structure is created for our Data
if (!FHU::Filesystem::Exists(EntryCache) &&
!FHU::Filesystem::CreateDirectories(EntryCache)) {
LogMan::Msg::DFmt("Couldn't create EntryCache directory: '{}'", EntryCache);
}
}
fextl::string GetCachePath() {
return CachePath;
}
fextl::string GetEntryCachePath() {
return EntryCache;
}
}

View File

@ -1,12 +0,0 @@
#pragma once
#include <FEXCore/fextl/string.h>
namespace FEXCore::Paths {
void InitializePaths();
void ShutdownPaths();
const char *GetHomeDirectory();
fextl::string GetCachePath();
fextl::string GetEntryCachePath();
}

View File

@ -1,6 +1,5 @@
#include "Common/StringConv.h"
#include "Common/StringUtils.h"
#include "Common/Paths.h"
#include <FEXCore/Config/Config.h>
#include <FEXCore/Utils/Allocator.h>
@ -109,71 +108,41 @@ namespace JSON {
}
}
fextl::string GetDataDirectory() {
fextl::string DataDir{};
enum Paths {
PATH_DATA_DIR = 0,
PATH_CONFIG_DIR_LOCAL,
PATH_CONFIG_DIR_GLOBAL,
PATH_CONFIG_FILE_LOCAL,
PATH_CONFIG_FILE_GLOBAL,
PATH_LAST,
};
static std::array<fextl::string, Paths::PATH_LAST> Paths;
char const *HomeDir = Paths::GetHomeDirectory();
char const *DataXDG = getenv("XDG_DATA_HOME");
char const *DataOverride = getenv("FEX_APP_DATA_LOCATION");
if (DataOverride) {
// Data override will override the complete directory
DataDir = DataOverride;
}
else {
DataDir = DataXDG ?: HomeDir;
DataDir += "/.fex-emu/";
}
return DataDir;
void SetDataDirectory(const std::string_view Path) {
Paths[PATH_DATA_DIR] = Path;
}
fextl::string GetConfigDirectory(bool Global) {
fextl::string ConfigDir;
if (Global) {
ConfigDir = GLOBAL_DATA_DIRECTORY;
}
else {
char const *HomeDir = Paths::GetHomeDirectory();
char const *ConfigXDG = getenv("XDG_CONFIG_HOME");
char const *ConfigOverride = getenv("FEX_APP_CONFIG_LOCATION");
if (ConfigOverride) {
// Config override completely overrides the config directory
ConfigDir = ConfigOverride;
}
else {
ConfigDir = ConfigXDG ? ConfigXDG : HomeDir;
ConfigDir += "/.fex-emu/";
}
// Ensure the folder structure is created for our configuration
if (!FHU::Filesystem::Exists(ConfigDir) &&
!FHU::Filesystem::CreateDirectories(ConfigDir)) {
// Let's go local in this case
return "./";
}
}
return ConfigDir;
void SetConfigDirectory(const std::string_view Path, bool Global) {
Paths[PATH_CONFIG_DIR_LOCAL + Global] = Path;
}
fextl::string GetConfigFileLocation(bool Global) {
fextl::string ConfigFile{};
if (Global) {
ConfigFile = GetConfigDirectory(true) + "Config.json";
}
else {
const char *AppConfig = getenv("FEX_APP_CONFIG");
if (AppConfig) {
// App config environment variable overwrites only the config file
ConfigFile = AppConfig;
}
else {
ConfigFile = GetConfigDirectory(false) + "Config.json";
}
}
return ConfigFile;
void SetConfigFileLocation(const std::string_view Path, bool Global) {
Paths[PATH_CONFIG_FILE_LOCAL + Global] = Path;
}
fextl::string GetApplicationConfig(const fextl::string &Filename, bool Global) {
fextl::string const& GetDataDirectory() {
return Paths[PATH_DATA_DIR];
}
fextl::string const& GetConfigDirectory(bool Global) {
return Paths[PATH_CONFIG_DIR_LOCAL + Global];
}
fextl::string const& GetConfigFileLocation(bool Global) {
return Paths[PATH_CONFIG_FILE_LOCAL + Global];
}
fextl::string GetApplicationConfig(const std::string_view Program, bool Global) {
fextl::string ConfigFile = GetConfigDirectory(Global);
if (!Global &&
@ -181,7 +150,7 @@ namespace JSON {
!FHU::Filesystem::CreateDirectories(ConfigFile)) {
LogMan::Msg::DFmt("Couldn't create config directory: '{}'", ConfigFile);
// Let's go local in this case
return "./" + Filename + ".json";
return fextl::fmt::format("./{}.json", Program);
}
ConfigFile += "AppConfig/";
@ -191,11 +160,10 @@ namespace JSON {
!FHU::Filesystem::Exists(ConfigFile) &&
!FHU::Filesystem::CreateDirectories(ConfigFile)) {
// Let's go local in this case
return "./" + Filename + ".json";
return fextl::fmt::format("./{}.json", Program);
}
ConfigFile += Filename + ".json";
return ConfigFile;
return fextl::fmt::format("{}{}.json", ConfigFile, Program);
}
void SetConfig(FEXCore::Context::Context *CTX, ConfigOption Option, uint64_t Config) {

View File

@ -1,4 +1,3 @@
#include "Common/Paths.h"
#include "Interface/Context/Context.h"
#include "Interface/Core/Core.h"
#include "Interface/Core/OpcodeDispatcher.h"
@ -19,7 +18,6 @@ namespace FEXCore::HLE {
namespace FEXCore::Context {
void InitializeStaticTables(OperatingMode Mode) {
FEXCore::Paths::InitializePaths();
X86Tables::InitializeInfoTables(Mode);
IR::InstallOpcodeHandlers(Mode);
}

View File

@ -1,11 +0,0 @@
#pragma once
#include <FEXCore/Utils/CompilerDefs.h>
#include <FEXCore/fextl/string.h>
namespace FEXCore::Paths {
FEX_DEFAULT_VISIBILITY const char *GetHomeDirectory();
FEX_DEFAULT_VISIBILITY fextl::string GetCachePath();
FEX_DEFAULT_VISIBILITY fextl::string GetEntryCachePath();
}

View File

@ -102,10 +102,14 @@ namespace Type {
#undef P
}
FEX_DEFAULT_VISIBILITY fextl::string GetDataDirectory();
FEX_DEFAULT_VISIBILITY fextl::string GetConfigDirectory(bool Global);
FEX_DEFAULT_VISIBILITY fextl::string GetConfigFileLocation(bool Global = false);
FEX_DEFAULT_VISIBILITY fextl::string GetApplicationConfig(const fextl::string &Filename, bool Global);
FEX_DEFAULT_VISIBILITY void SetDataDirectory(std::string_view Path);
FEX_DEFAULT_VISIBILITY void SetConfigDirectory(const std::string_view Path, bool Global);
FEX_DEFAULT_VISIBILITY void SetConfigFileLocation(std::string_view Path, bool Global);
FEX_DEFAULT_VISIBILITY fextl::string const& GetDataDirectory();
FEX_DEFAULT_VISIBILITY fextl::string const& GetConfigDirectory(bool Global);
FEX_DEFAULT_VISIBILITY fextl::string const& GetConfigFileLocation(bool Global = false);
FEX_DEFAULT_VISIBILITY fextl::string GetApplicationConfig(const std::string_view Program, bool Global);
using LayerValue = fextl::list<fextl::string>;
using LayerOptions = fextl::unordered_map<ConfigOption, LayerValue>;

View File

@ -11,6 +11,7 @@
#include <cstring>
#include <linux/limits.h>
#include <list>
#include <pwd.h>
#include <utility>
#include <json-maker.h>
@ -117,6 +118,7 @@ namespace FEX::Config {
char **const envp,
bool ExecFDInterp,
const std::string_view ProgramFDFromEnv) {
FEX::Config::InitializeConfigs();
FEXCore::Config::Initialize();
FEXCore::Config::AddLayer(FEXCore::Config::CreateGlobalMainLayer());
FEXCore::Config::AddLayer(FEXCore::Config::CreateMainLayer());
@ -197,4 +199,105 @@ namespace FEX::Config {
}
return {};
}
char const* FindUserHomeThroughUID() {
auto passwd = getpwuid(geteuid());
if (passwd) {
return passwd->pw_dir;
}
return nullptr;
}
const char *GetHomeDirectory() {
char const *HomeDir = getenv("HOME");
// Try to get home directory from uid
if (!HomeDir) {
HomeDir = FindUserHomeThroughUID();
}
// try the PWD
if (!HomeDir) {
HomeDir = getenv("PWD");
}
// Still doesn't exit? You get local
if (!HomeDir) {
HomeDir = ".";
}
return HomeDir;
}
fextl::string GetDataDirectory() {
fextl::string DataDir{};
char const *HomeDir = GetHomeDirectory();
char const *DataXDG = getenv("XDG_DATA_HOME");
char const *DataOverride = getenv("FEX_APP_DATA_LOCATION");
if (DataOverride) {
// Data override will override the complete directory
DataDir = DataOverride;
}
else {
DataDir = DataXDG ?: HomeDir;
DataDir += "/.fex-emu/";
}
return DataDir;
}
fextl::string GetConfigDirectory(bool Global) {
fextl::string ConfigDir;
if (Global) {
ConfigDir = GLOBAL_DATA_DIRECTORY;
}
else {
char const *HomeDir = GetHomeDirectory();
char const *ConfigXDG = getenv("XDG_CONFIG_HOME");
char const *ConfigOverride = getenv("FEX_APP_CONFIG_LOCATION");
if (ConfigOverride) {
// Config override completely overrides the config directory
ConfigDir = ConfigOverride;
}
else {
ConfigDir = ConfigXDG ? ConfigXDG : HomeDir;
ConfigDir += "/.fex-emu/";
}
// Ensure the folder structure is created for our configuration
if (!FHU::Filesystem::Exists(ConfigDir) &&
!FHU::Filesystem::CreateDirectories(ConfigDir)) {
// Let's go local in this case
return "./";
}
}
return ConfigDir;
}
fextl::string GetConfigFileLocation(bool Global) {
fextl::string ConfigFile{};
if (Global) {
ConfigFile = GetConfigDirectory(true) + "Config.json";
}
else {
const char *AppConfig = getenv("FEX_APP_CONFIG");
if (AppConfig) {
// App config environment variable overwrites only the config file
ConfigFile = AppConfig;
}
else {
ConfigFile = GetConfigDirectory(false) + "Config.json";
}
}
return ConfigFile;
}
void InitializeConfigs() {
FEXCore::Config::SetDataDirectory(GetDataDirectory());
FEXCore::Config::SetConfigDirectory(GetConfigDirectory(false), false);
FEXCore::Config::SetConfigDirectory(GetConfigDirectory(true), true);
FEXCore::Config::SetConfigFileLocation(GetConfigFileLocation(false), false);
FEXCore::Config::SetConfigFileLocation(GetConfigFileLocation(true), true);
}
}

View File

@ -47,4 +47,12 @@ namespace FEX::Config {
bool ExecFDInterp,
const std::string_view ProgramFDFromEnv
);
const char *GetHomeDirectory();
fextl::string GetDataDirectory();
fextl::string GetConfigDirectory(bool Global);
fextl::string GetConfigFileLocation(bool Global);
void InitializeConfigs();
}

View File

@ -972,6 +972,8 @@ int main(int argc, char **argv) {
GlobalTime = std::chrono::high_resolution_clock::now();
FEX::Config::InitializeConfigs();
// Attempt to open the config passed in
if (argc > 1) {
if (OpenFile(argv[1], true)) {

View File

@ -8,6 +8,7 @@ $end_info$
#include "AOT/AOTGenerator.h"
#include "Common/ArgumentLoader.h"
#include "Common/FEXServerClient.h"
#include "Common/Config.h"
#include "ELFCodeLoader.h"
#include "VDSO_Emulation.h"
#include "LinuxSyscalls/LinuxAllocator.h"

View File

@ -83,6 +83,7 @@ PRIVATE
target_link_libraries(LinuxEmulation
PRIVATE
Common
FEXCore
FEX_Utils
)

View File

@ -5,6 +5,7 @@ desc: Rootfs overlay logic
$end_info$
*/
#include "Common/Config.h"
#include "Common/FDUtils.h"
#include "FEXCore/Config/Config.h"
@ -13,7 +14,6 @@ $end_info$
#include "LinuxSyscalls/Syscalls.h"
#include "LinuxSyscalls/x64/Syscalls.h"
#include <FEXCore/Common/Paths.h>
#include <FEXCore/Utils/LogManager.h>
#include <FEXCore/fextl/fmt.h>
#include <FEXCore/fextl/list.h>
@ -116,7 +116,7 @@ static void LoadThunkDatabase(fextl::unordered_map<fextl::string, ThunkDBObject>
return;
}
std::string_view HomeDirectory = FEXCore::Paths::GetHomeDirectory();
std::string_view HomeDirectory = FEX::Config::GetHomeDirectory();
for( json_t const* Library = json_getChild( DB ); Library != nullptr; Library = json_getSibling( Library )) {
// Get the user defined name for the library