diff --git a/CMakeLists.txt b/CMakeLists.txt index 06fbdd22..28b0c84f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -230,7 +230,10 @@ option(DEV_BUILD "Enable development build (enables some debugging tools, local # PLEASE DO NOT USE ON UNOFFICIAL BUILDS. Thanks. option(OFFICIAL_COLOBOT_BUILD "Official build (changes crash screen text)" OFF) -# Portable build - load all data from current directory +# Hardcode relative paths instead of absolute paths +option(USE_RELATIVE_PATHS "Generate relative paths from absolute paths" OFF) + +# Portable build - load all data from the base directory option(PORTABLE "Portable build" OFF) # Portable saves - suitable for e.g. putting the whole game on external storage and moving your saves with it @@ -392,39 +395,44 @@ endif() # Installation paths defined before compiling sources if(PORTABLE OR (PLATFORM_WINDOWS AND MXE)) # We need to use STRING because PATH doesn't accept relative paths - set(COLOBOT_INSTALL_BIN_DIR ./ CACHE STRING "Colobot binary directory") - set(COLOBOT_INSTALL_LIB_DIR ./ CACHE STRING "Colobot libraries directory") - set(COLOBOT_RELATIVE_DATA_DIR data CACHE STRING "Colobot shared data directory (relative)") - set(COLOBOT_RELATIVE_I18N_DIR lang CACHE STRING "Colobot translations directory (relative)") - set(COLOBOT_INSTALL_DATA_DIR ./data CACHE STRING "Colobot shared data directory") - set(COLOBOT_INSTALL_I18N_DIR ./lang CACHE STRING "Colobot translations directory") - set(COLOBOT_INSTALL_DOC_DIR ./doc CACHE STRING "Colobot documentation directory") + set(COLOBOT_INSTALL_BIN_DIR ${CMAKE_INSTALL_PREFIX}/ CACHE STRING "Colobot binary directory") + set(COLOBOT_INSTALL_LIB_DIR ${CMAKE_INSTALL_PREFIX}/ CACHE STRING "Colobot libraries directory") + set(COLOBOT_INSTALL_DATA_DIR ${CMAKE_INSTALL_PREFIX}/data CACHE STRING "Colobot shared data directory") + set(COLOBOT_INSTALL_I18N_DIR ${CMAKE_INSTALL_PREFIX}/lang CACHE STRING "Colobot translations directory") + set(COLOBOT_INSTALL_DOC_DIR ${CMAKE_INSTALL_PREFIX}/doc CACHE STRING "Colobot documentation directory") + set(USE_RELATIVE_PATHS ON) elseif(PLATFORM_WINDOWS) set(COLOBOT_INSTALL_BIN_DIR ${CMAKE_INSTALL_PREFIX}/ CACHE PATH "Colobot binary directory") set(COLOBOT_INSTALL_LIB_DIR ${CMAKE_INSTALL_PREFIX}/ CACHE PATH "Colobot libraries directory") - set(COLOBOT_RELATIVE_DATA_DIR data CACHE STRING "Colobot shared data directory (relative)") - set(COLOBOT_RELATIVE_I18N_DIR lang CACHE STRING "Colobot translations directory (relative)") set(COLOBOT_INSTALL_DATA_DIR ${CMAKE_INSTALL_PREFIX}/data CACHE PATH "Colobot shared data directory") set(COLOBOT_INSTALL_I18N_DIR ${CMAKE_INSTALL_PREFIX}/lang CACHE PATH "Colobot translations directory") set(COLOBOT_INSTALL_DOC_DIR ${CMAKE_INSTALL_PREFIX}/doc CACHE PATH "Colobot documentation directory") elseif(PLATFORM_MACOSX) set(COLOBOT_INSTALL_BIN_DIR ../MacOS CACHE STRING "Colobot binary directory") set(COLOBOT_INSTALL_LIB_DIR ../MacOS CACHE STRING "Colobot libraries directory") - set(COLOBOT_RELATIVE_DATA_DIR . CACHE STRING "Colobot shared data directory (relative)") - set(COLOBOT_RELATIVE_I18N_DIR i18n CACHE STRING "Colobot translations directory (relative)") set(COLOBOT_INSTALL_DATA_DIR . CACHE STRING "Colobot shared data directory") set(COLOBOT_INSTALL_I18N_DIR i18n CACHE SRING "Colobot translations directory") set(COLOBOT_INSTALL_DOC_DIR doc CACHE STRING "Colobot documentation directory") else() set(COLOBOT_INSTALL_BIN_DIR ${CMAKE_INSTALL_PREFIX}/games CACHE PATH "Colobot binary directory") set(COLOBOT_INSTALL_LIB_DIR ${CMAKE_INSTALL_PREFIX}/lib/colobot CACHE PATH "Colobot libraries directory") - set(COLOBOT_RELATIVE_DATA_DIR ../share/games/colobot CACHE STRING "Colobot shared data directory (relative)") - set(COLOBOT_RELATIVE_I18N_DIR ../share/locale CACHE STRING "Colobot translations directory (relative)") set(COLOBOT_INSTALL_DATA_DIR ${CMAKE_INSTALL_PREFIX}/share/games/colobot CACHE PATH "Colobot shared data directory") set(COLOBOT_INSTALL_I18N_DIR ${CMAKE_INSTALL_PREFIX}/share/locale CACHE PATH "Colobot translations directory") set(COLOBOT_INSTALL_DOC_DIR ${CMAKE_INSTALL_PREFIX}/share/doc/colobot CACHE PATH "Colobot documentation directory") endif() +# Generate relative paths from absolute paths +if(USE_RELATIVE_PATHS) + message(STATUS "Generating relative paths") + file(RELATIVE_PATH COLOBOT_DATA_DIR ${COLOBOT_INSTALL_BIN_DIR} ${COLOBOT_INSTALL_DATA_DIR}) + file(RELATIVE_PATH COLOBOT_I18N_DIR ${COLOBOT_INSTALL_BIN_DIR} ${COLOBOT_INSTALL_I18N_DIR}) + + add_definitions(-DUSE_RELATIVE_PATHS) +else() + set(COLOBOT_DATA_DIR ${COLOBOT_INSTALL_DATA_DIR}) + set(COLOBOT_I18N_DIR ${COLOBOT_INSTALL_I18N_DIR}) +endif() + # Subdirectory with sources add_subdirectory(src) diff --git a/src/common/config.h.cmake b/src/common/config.h.cmake index 6100d7dc..556e067e 100644 --- a/src/common/config.h.cmake +++ b/src/common/config.h.cmake @@ -18,5 +18,5 @@ #cmakedefine PORTABLE_SAVES @PORTABLE_SAVES@ -#define COLOBOT_DEFAULT_DATADIR "@COLOBOT_RELATIVE_DATA_DIR@" -#define COLOBOT_I18N_DIR "@COLOBOT_RELATIVE_I18N_DIR@" +#define COLOBOT_DEFAULT_DATADIR "@COLOBOT_DATA_DIR@" +#define COLOBOT_I18N_DIR "@COLOBOT_I18N_DIR@" diff --git a/src/common/system/system.cpp b/src/common/system/system.cpp index b22d0771..d69fbf6c 100644 --- a/src/common/system/system.cpp +++ b/src/common/system/system.cpp @@ -190,28 +190,28 @@ std::string CSystemUtils::GetBasePath() std::string CSystemUtils::GetDataPath() { -#if DEV_BUILD - return std::string{"./"} + COLOBOT_DEFAULT_DATADIR; -#else +#ifdef USE_RELATIVE_PATHS return GetBasePath() + COLOBOT_DEFAULT_DATADIR; +#else + return COLOBOT_DEFAULT_DATADIR; #endif } std::string CSystemUtils::GetLangPath() { -#if DEV_BUILD - return std::string{"./"} + COLOBOT_I18N_DIR; -#else +#ifdef USE_RELATIVE_PATHS return GetBasePath() + COLOBOT_I18N_DIR; +#else + return COLOBOT_I18N_DIR; #endif } std::string CSystemUtils::GetSaveDir() { - return "./saves"; + return GetBasePath() + "saves"; } -std::string CSystemUtils::GetEnvVar(const std::string& str) +std::string CSystemUtils::GetEnvVar(const std::string& name) { - return std::string(); + return ""; } diff --git a/src/common/system/system.h b/src/common/system/system.h index 431ddd41..95901390 100644 --- a/src/common/system/system.h +++ b/src/common/system/system.h @@ -127,7 +127,7 @@ public: /** The difference is \a after - \a before. */ virtual long long TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after) = 0; - //! Returns the path where the executable binary is located + //! Returns the path where the executable binary is located (ends with the path separator) virtual std::string GetBasePath(); //! Returns the data path (containing textures, levels, helpfiles, etc) @@ -139,8 +139,8 @@ public: //! Returns the save dir location virtual std::string GetSaveDir(); - //! Returns environment variable - virtual std::string GetEnvVar(const std::string &str); + //! Returns the environment variable with the given name or an empty string if it does not exist + virtual std::string GetEnvVar(const std::string &name); //! Sleep for given amount of microseconds virtual void Usleep(int usecs) = 0; diff --git a/src/common/system/system_linux.cpp b/src/common/system/system_linux.cpp index b71befe5..69551bce 100644 --- a/src/common/system/system_linux.cpp +++ b/src/common/system/system_linux.cpp @@ -102,23 +102,23 @@ std::string CSystemUtilsLinux::GetSaveDir() std::string savegameDir; // Determine savegame dir according to XDG Base Directory Specification - char *envXDG_DATA_HOME = getenv("XDG_DATA_HOME"); - if (envXDG_DATA_HOME == nullptr) + auto envXDG_DATA_HOME = GetEnvVar("XDG_DATA_HOME"); + if (envXDG_DATA_HOME.empty()) { - char *envHOME = getenv("HOME"); - if (envHOME == nullptr) + auto envHOME = GetEnvVar("HOME"); + if (envHOME.empty()) { - GetLogger()->Warn("Unable to find directory for saves - using current directory"); - savegameDir = "./saves"; + GetLogger()->Warn("Unable to find directory for saves - using default directory"); + savegameDir = CSystemUtils::GetSaveDir(); } else { - savegameDir = std::string(envHOME) + "/.local/share/colobot"; + savegameDir = envHOME + "/.local/share/colobot"; } } else { - savegameDir = std::string(envXDG_DATA_HOME) + "/colobot"; + savegameDir = envXDG_DATA_HOME + "/colobot"; } GetLogger()->Trace("Saved game files are going to %s\n", savegameDir.c_str()); @@ -131,7 +131,6 @@ std::string CSystemUtilsLinux::GetEnvVar(const std::string& name) char* envVar = getenv(name.c_str()); if (envVar != nullptr) { - GetLogger()->Trace("Detected environment variable %s = %s\n", name.c_str(), envVar); return std::string(envVar); } diff --git a/src/common/system/system_macosx.h b/src/common/system/system_macosx.h index 708d26fc..c8ea607a 100644 --- a/src/common/system/system_macosx.h +++ b/src/common/system/system_macosx.h @@ -36,7 +36,7 @@ public: std::string GetLangPath() override; std::string GetSaveDir() override; - std::string GetEnvVar(const std::string& str) override; + std::string GetEnvVar(const std::string& name) override; void Usleep(int usec) override; diff --git a/src/common/system/system_windows.cpp b/src/common/system/system_windows.cpp index 5254db83..9a8e6833 100644 --- a/src/common/system/system_windows.cpp +++ b/src/common/system/system_windows.cpp @@ -115,15 +115,15 @@ std::string CSystemUtilsWindows::GetSaveDir() #else std::string savegameDir; - wchar_t* envUSERPROFILE = _wgetenv(L"USERPROFILE"); - if (envUSERPROFILE == nullptr) + auto envUSERPROFILE = GetEnvVar("USERPROFILE"); + if (envUSERPROFILE.empty()) { - GetLogger()->Warn("Unable to find directory for saves - using current directory"); - savegameDir = "./saves"; + GetLogger()->Warn("Unable to find directory for saves - using default directory"); + savegameDir = CSystemUtils::GetSaveDir(); } else { - savegameDir = UTF8_Encode(std::wstring(envUSERPROFILE)) + "\\colobot"; + savegameDir = envUSERPROFILE + "\\colobot"; } GetLogger()->Trace("Saved game files are going to %s\n", savegameDir.c_str());