Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Feb 27, 2009, 2:13:29 PM (16 years ago)
Author:
rgrieder
Message:

Completed work on installation:

  • The CMake switch INSTALL_COPYABLE tells whether you will be able to move the installed directory or not. If TRUE then all folders, including log and config directory, will be put into the CMAKE_INSTALL_PREFIX. Furthermore, relative paths are used, which get resolved at run time.
  • If INSTALL_COPYABLE is set to FALSE, the standard operating system directories will be used. That also means on Windows files get written to the Application Data/.orxonox folder instead of Program Files/Orxonox
  • Default configuration is INSTALL_COPYABLE=TRUE for Windows and FALSE for Unix
  • Split OrxonoxConfig.h.in in two to avoid complete recompiles when changing only a path or INSTALL_COPYABLE
  • Added a global constant character: CP_SLASH which stands for cross platform slash, meaning '/' on Unix and '
    ' on Windows
  • Core class now has methods getFooPath(), getFooPathString() and getFooPathPOSIXString() where Foo can be Media, Log or Config
  • getFooPathPOSIXString() will always return a directory formatted with slashes, even on Windows
  • getFooPath() returns a reference to the boost::filesystem::path
  • boost/filesystem.hpp does not get included to Core.h because it has a very large rat tail
  • The platform specific directory stuff gets done in Core::postMainInitialisation()
  • Adjusted all classes using the media path
Location:
code/branches/buildsystem3/src/core
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • code/branches/buildsystem3/src/core/ArgumentCompletionFunctions.cc

    r2664 r2702  
    2727 */
    2828
     29#include "ArgumentCompletionFunctions.h"
     30
    2931#include <iostream>
    3032#include <map>
    31 
    3233#include <boost/filesystem.hpp>
    3334
    34 #include "ArgumentCompletionFunctions.h"
    3535#include "CoreIncludes.h"
    3636#include "Identifier.h"
     
    6868                    std::string dir = startdirectory.string();
    6969                    if (dir.size() > 0 && dir[dir.size() - 1] == ':')
    70                         startdirectory = dir + "/";
     70                        startdirectory = dir + CP_SLASH;
    7171                }
    7272#endif
     
    7878                {
    7979                    if (boost::filesystem::is_directory(*file))
    80                         dirlist.push_back(ArgumentCompletionListElement((*file).string() + "/", getLowercase((*file).string()) + "/", (*file).leaf() + "/"));
     80                        dirlist.push_back(ArgumentCompletionListElement((*file).string() + CP_SLASH, getLowercase((*file).string()) + "/", (*file).leaf() + "/"));
    8181                    else
    8282                        filelist.push_back(ArgumentCompletionListElement((*file).string(), getLowercase((*file).string()), (*file).leaf()));
  • code/branches/buildsystem3/src/core/CommandLine.cc

    r2687 r2702  
    302302
    303303        std::string filename = CommandLine::getValue("optionsFile").getString();
    304         boost::filesystem::path folder(Core::getConfigPath());
    305         boost::filesystem::path filepath(folder/filename);
     304        boost::filesystem::path filepath(Core::getConfigPath() / filename);
    306305
    307306        // look for additional arguments in given file or start.ini as default
  • code/branches/buildsystem3/src/core/ConfigFileManager.cc

    r2690 r2702  
    227227
    228228        // Get default file if necessary and available
    229         boost::filesystem::path filepath(Core::getConfigPath());
    230         filepath /= this->filename_;
     229        boost::filesystem::path filepath(Core::getConfigPath() / this->filename_);
    231230        if (!boost::filesystem::exists(filepath))
    232231        {
    233232            // Try to get default one from the media folder
    234             boost::filesystem::path defaultFilepath(Core::getMediaPath());
    235             defaultFilepath = defaultFilepath / "defaultConfig" / this->filename_;
     233            boost::filesystem::path defaultFilepath(Core::getMediaPath() / "defaultConfig" / this->filename_);
    236234            if (boost::filesystem::exists(defaultFilepath))
    237235            {
     
    345343    void ConfigFile::save() const
    346344    {
    347         boost::filesystem::path filepath(Core::getConfigPath());
    348         filepath /= this->filename_;
     345        boost::filesystem::path filepath(Core::getConfigPath() / this->filename_);
    349346
    350347        std::ofstream file;
  • code/branches/buildsystem3/src/core/Core.cc

    r2692 r2702  
    3333
    3434#include "Core.h"
     35
    3536#include <cassert>
    3637#include <fstream>
     38#include <cstdlib>
     39#include <cstdio>
    3740#include <boost/filesystem.hpp>
    3841
     42#ifdef ORXONOX_PLATFORM_WINDOWS
     43#  include <windows.h>
     44#elif defined(ORXONOX_PLATFORM_APPLE)
     45#  include <sys/param.h>
     46#  include <mach-o/dyld.h>
     47#else /* Linux */
     48#  include <sys/types.h>
     49#  include <unistd.h>
     50#endif
     51
     52#include "SpecialConfig.h"
    3953#include "util/Exception.h"
    4054#include "Language.h"
     
    4660namespace orxonox
    4761{
     62    //! Path to the parent directory of the ones above if program was installed with relativ pahts
     63    static boost::filesystem::path rootPath_g;
     64    static boost::filesystem::path executablePath_g;            //!< Path to the executable
     65    static boost::filesystem::path mediaPath_g;                 //!< Path to the media file folder
     66    static boost::filesystem::path configPath_g;                //!< Path to the config file folder
     67    static boost::filesystem::path logPath_g;                   //!< Path to the log file folder
     68
    4869    bool Core::bShowsGraphics_s = false;
    4970    bool Core::bHasServer_s     = false;
     
    5374
    5475    bool Core::isDevBuild_s     = false;
    55     std::string Core::configPath_s(ORXONOX_CONFIG_INSTALL_PATH); // from OrxonoxConfig.h
    56     std::string Core::logPath_s   (ORXONOX_LOG_INSTALL_PATH);    // from OrxonoxConfig.h
    57     std::string Core::mediaPath_s (ORXONOX_MEDIA_INSTALL_PATH);  // from OrxonoxConfig.h
    58 
    59     Core* Core::singletonRef_s = 0;
     76    Core* Core::singletonRef_s  = 0;
    6077
    6178    SetCommandLineArgument(mediaPath, "").information("PATH");
     
    7693
    7794        // Set the correct log path. Before this call, /tmp (Unix) or %TEMP% was used
    78         OutputHandler::getOutStream().setLogPath(Core::logPath_s);
     95        OutputHandler::getOutStream().setLogPath(Core::getLogPathString());
    7996
    8097        // Possible media path override by the command line
    8198        if (!CommandLine::getArgument("mediaPath")->hasDefaultValue())
    8299        {
    83             std::string mediaPath = CommandLine::getValue("mediaPath");
    84             Core::tsetMediaPath(mediaPath);
     100            //std::string mediaPath = CommandLine::getValue("mediaPath");
     101            Core::tsetMediaPath(CommandLine::getValue("mediaPath"));
    85102        }
    86103    }
     
    119136        SetConfigValue(bInitializeRandomNumberGenerator_, true).description("If true, all random actions are different each time you start the game").callback(this, &Core::initializeRandomNumberGenerator);
    120137
    121         // Media path (towards config and log path) is ini-configurable
    122         const char* defaultMediaPath = ORXONOX_MEDIA_INSTALL_PATH;
    123         if (Core::isDevBuild())
    124             defaultMediaPath = ORXONOX_MEDIA_DEV_PATH;
    125 
    126         SetConfigValue(mediaPath_s, defaultMediaPath)
     138        SetConfigValue(mediaPathString_, Core::getMediaPathPOSIXString())
    127139            .description("Relative path to the game data.").callback(this, &Core::mediaPathChanged);
    128 
    129140    }
    130141
     
    162173    void Core::mediaPathChanged()
    163174    {
    164         if (mediaPath_s != "" && mediaPath_s[mediaPath_s.size() - 1] != '/')
    165         {
    166             ModifyConfigValue(mediaPath_s, set, mediaPath_s + "/");
    167         }
    168 
    169         if (mediaPath_s == "")
    170         {
    171             ModifyConfigValue(mediaPath_s, set, "/");
    172             COUT(2) << "Warning: Data path set to \"/\", is that really correct?" << std::endl;
    173         }
     175        mediaPath_g = boost::filesystem::path(this->mediaPathString_);
    174176    }
    175177
     
    248250    void Core::_tsetMediaPath(const std::string& path)
    249251    {
    250         if (*path.end() != '/' && *path.end() != '\\')
    251         {
    252             ModifyConfigValue(mediaPath_s, tset, path + "/");
    253         }
    254         else
    255         {
    256             ModifyConfigValue(mediaPath_s, tset, path);
    257         }
     252        ModifyConfigValue(mediaPathString_, tset, path);
     253    }
     254
     255    /*static*/ const boost::filesystem::path& Core::getMediaPath()
     256    {
     257        return mediaPath_g;
     258    }
     259    /*static*/ std::string Core::getMediaPathString()
     260    {
     261        return mediaPath_g.directory_string() + CP_SLASH;
     262    }
     263    /*static*/ std::string Core::getMediaPathPOSIXString()
     264    {
     265        return mediaPath_g.string() + '/';
     266       
     267    }
     268
     269    /*static*/ const boost::filesystem::path& Core::getConfigPath()
     270    {
     271        return configPath_g;
     272    }
     273    /*static*/ std::string Core::getConfigPathString()
     274    {
     275        return configPath_g.directory_string() + CP_SLASH;
     276    }
     277    /*static*/ std::string Core::getConfigPathPOSIXString()
     278    {
     279        return configPath_g.string() + '/';
     280    }
     281
     282    /*static*/ const boost::filesystem::path& Core::getLogPath()
     283    {
     284        return logPath_g;
     285    }
     286    /*static*/ std::string Core::getLogPathString()
     287    {
     288        return logPath_g.directory_string() + CP_SLASH;
     289    }
     290    /*static*/ std::string Core::getLogPathPOSIXString()
     291    {
     292        return logPath_g.string() + '/';
    258293    }
    259294
     
    271306    /**
    272307    @brief
    273         Checks for "orxonox_dev_build.keep_me" in the working diretory.
     308        Performs the rather lower level operations just after
     309        int main() has been called.
     310    @remarks
     311        This gets called AFTER pre-main stuff like AddFactory,
     312        SetConsoleCommand, etc.
     313    */
     314    /*static*/ void Core::postMainInitialisation()
     315    {
     316        // set location of the executable
     317        Core::setExecutablePath();
     318
     319        // Determine whether we have an installed or a binary dir run
     320        // The latter occurs when simply running from the build directory
     321        Core::checkDevBuild();
     322
     323        // Make sure the directories we write in exist or else make them
     324        Core::createDirectories();
     325    }
     326
     327    /**
     328    @brief
     329        Compares the executable path with the working directory
     330    */
     331    /*static*/ void Core::setExecutablePath()
     332    {
     333#ifdef ORXONOX_PLATFORM_WINDOWS
     334        // get executable module
     335        TCHAR buffer[1024];
     336        if (GetModuleFileName(NULL, buffer, 1024) == 0)
     337            ThrowException(General, "Could not retrieve executable path.");
     338
     339#elif defined(ORXONOX_PLATFORM_APPLE)
     340        char buffer[1024];
     341        unsigned long path_len = 1023;
     342        if (_NSGetExecutablePath(buffer, &path_len))
     343            ThrowException(General, "Could not retrieve executable path.");
     344
     345#else /* Linux */
     346        /* written by Nicolai Haehnle <prefect_@gmx.net> */
     347
     348        /* Get our PID and build the name of the link in /proc */
     349        char linkname[64]; /* /proc/<pid>/exe */
     350        if (snprintf(linkname, sizeof(linkname), "/proc/%i/exe", getpid()) < 0)
     351        {
     352            /* This should only happen on large word systems. I'm not sure
     353               what the proper response is here.
     354               Since it really is an assert-like condition, aborting the
     355               program seems to be in order. */
     356            assert(false);
     357        }
     358
     359        /* Now read the symbolic link */
     360        char buffer[1024];
     361        int ret;
     362        ret = readlink(linkname, buffer, 1024);
     363        /* In case of an error, leave the handling up to the caller */
     364        if (ret == -1)
     365            ThrowException(General, "Could not retrieve executable path.");
     366
     367        /* Ensure proper NUL termination */
     368        buf[ret] = 0;
     369#endif
     370
     371        executablePath_g = boost::filesystem::path(buffer);
     372#ifndef ORXONOX_PLATFORM_APPLE
     373        executablePath_g = executablePath_g.branch_path(); // remove executable name
     374#endif
     375    }
     376
     377    /**
     378    @brief
     379        Checks for "orxonox_dev_build.keep_me" in the executable diretory.
    274380        If found it means that this is not an installed run, hence we
    275381        don't write the logs and config files to ~/.orxonox
     
    277383    /*static*/ void Core::checkDevBuild()
    278384    {
    279         std::ifstream probe;
    280         probe.open("orxonox_dev_build.keep_me");
    281         if (probe)
    282         {
     385        if (boost::filesystem::exists(executablePath_g / "orxonox_dev_build.keep_me"))
     386        {
     387            COUT(1) << "Running from the build tree." << std::endl;
    283388            Core::isDevBuild_s = true;
    284             // Constants are taken from OrxonoxConfig.h
    285             Core::configPath_s = ORXONOX_CONFIG_DEV_PATH;
    286             Core::logPath_s    = ORXONOX_LOG_DEV_PATH;
    287             Core::mediaPath_s  = ORXONOX_MEDIA_DEV_PATH;
    288             probe.close();
     389            mediaPath_g  = ORXONOX_MEDIA_DEV_PATH;
     390            configPath_g = ORXONOX_CONFIG_DEV_PATH;
     391            logPath_g    = ORXONOX_LOG_DEV_PATH;
     392        }
     393        else
     394        {
     395#ifdef INSTALL_COPYABLE // --> relative paths
     396            // Also set the root path
     397            boost::filesystem::path relativeExecutablePath(ORXONOX_RUNTIME_INSTALL_PATH);
     398            rootPath_g = executablePath_g;
     399            while (!boost::filesystem::equivalent(rootPath_g / relativeExecutablePath, executablePath_g) || rootPath_g.empty())
     400                rootPath_g = rootPath_g.branch_path();
     401            if (rootPath_g.empty())
     402                ThrowException(General, "Could not derive a root directory. Might the binary installation directory contain '..' when taken relative to the installation prefix path?");
     403
     404            // Using paths relative to the install prefix, complete them
     405            mediaPath_g  = rootPath_g / ORXONOX_MEDIA_INSTALL_PATH;
     406            configPath_g = rootPath_g / ORXONOX_CONFIG_INSTALL_PATH;
     407            logPath_g    = rootPath_g / ORXONOX_LOG_INSTALL_PATH;
     408#else
     409            // There is no root path, so don't set it at all
     410
     411            mediaPath_g  = ORXONOX_MEDIA_INSTALL_PATH;
     412
     413            // Get user directory
     414#  ifdef ORXONOX_PLATFORM_UNIX /* Apple? */
     415            char* userDataPathPtr(getenv("HOME"));
     416#  else
     417            char* userDataPathPtr(getenv("APPDATA"));
     418#  endif
     419            if (userDataPathPtr == NULL)
     420                ThrowException(General, "Could not retrieve user data path.");
     421            boost::filesystem::path userDataPath(userDataPathPtr);
     422            userDataPath /= ".orxonox";
     423
     424            configPath_g = userDataPath / ORXONOX_CONFIG_INSTALL_PATH;
     425            logPath_g    = userDataPath / ORXONOX_LOG_INSTALL_PATH;
     426#endif
    289427        }
    290428    }
     
    299437        std::vector<std::pair<boost::filesystem::path, std::string> > directories;
    300438        directories.push_back(std::pair<boost::filesystem::path, std::string>
    301             (boost::filesystem::path(Core::configPath_s), "config"));
     439            (boost::filesystem::path(configPath_g), "config"));
    302440        directories.push_back(std::pair<boost::filesystem::path, std::string>
    303             (boost::filesystem::path(Core::logPath_s),    "log"));
     441            (boost::filesystem::path(logPath_g),    "log"));
    304442
    305443        for (std::vector<std::pair<boost::filesystem::path, std::string> >::iterator it = directories.begin();
  • code/branches/buildsystem3/src/core/Core.h

    r2690 r2702  
    4444#include "util/OutputHandler.h"
    4545
    46 // Only allow main to access setDevBuild, so we need a forward declaration
     46// Only allow main to access postMainInitialisation, so we need a forward declaration
    4747int main(int, char**);
     48// boost::filesystem header has quite a large tail, use forward declaration
     49namespace boost { namespace filesystem
     50{
     51    struct path_traits;
     52    template<class String, class Traits> class basic_path;
     53    typedef basic_path< std::string, path_traits> path;
     54} }
    4855
    4956namespace orxonox
     
    7077            static void tsetMediaPath(const std::string& path)
    7178            { assert(singletonRef_s); singletonRef_s->_tsetMediaPath(path); }
    72             static const std::string& getMediaPath()  { return mediaPath_s; }
    73             static const std::string& getConfigPath() { return configPath_s; }
    74             static const std::string& getLogPath()    { return logPath_s; }
     79            static const boost::filesystem::path& getMediaPath();
     80            static const boost::filesystem::path& getConfigPath();
     81            static const boost::filesystem::path& getLogPath();
     82            static std::string getMediaPathString();
     83            static std::string getConfigPathString();
     84            static std::string getLogPathString();
     85            static std::string getMediaPathPOSIXString();
     86            static std::string getConfigPathPOSIXString();
     87            static std::string getLogPathPOSIXString();
    7588
    7689            // fast access global variables.
     
    95108            void _tsetMediaPath(const std::string& path);
    96109
     110            static void postMainInitialisation();
     111            static void checkDevBuild();
     112            static void setExecutablePath();
    97113            static void createDirectories();
    98             static void checkDevBuild();
    99114
    100115            int softDebugLevel_;                            //!< The debug level
     
    104119            std::string language_;                          //!< The language
    105120            bool bInitializeRandomNumberGenerator_;         //!< If true, srand(time(0)) is called
     121            std::string mediaPathString_;                   //!< Path to the data/media file folder as string
    106122
    107123            static bool bShowsGraphics_s;                   //!< global variable that tells whether to show graphics
     
    112128
    113129            static bool isDevBuild_s;                       //!< True for builds in the build directory (not installed)
    114             static std::string configPath_s;                //!< Path to the config file folder
    115             static std::string logPath_s;                   //!< Path to the log file folder
    116             static std::string mediaPath_s;                 //!< Path to the data/media file folder
    117130
    118131            static Core* singletonRef_s;
  • code/branches/buildsystem3/src/core/Language.cc

    r2687 r2702  
    206206        COUT(4) << "Read default language file." << std::endl;
    207207
    208         boost::filesystem::path folder(Core::getConfigPath());
    209         boost::filesystem::path filepath(folder/getFilename(this->defaultLanguage_));
     208        boost::filesystem::path filepath(Core::getConfigPath() / getFilename(this->defaultLanguage_));
    210209
    211210        // This creates the file if it's not existing
     
    258257        COUT(4) << "Read translated language file (" << Core::getLanguage() << ")." << std::endl;
    259258
    260         boost::filesystem::path folder(Core::getConfigPath());
    261         boost::filesystem::path filepath(folder/getFilename(Core::getLanguage()));
     259        boost::filesystem::path filepath(Core::getConfigPath() / getFilename(Core::getLanguage()));
    262260
    263261        // Open the file
     
    315313        COUT(4) << "Language: Write default language file." << std::endl;
    316314
    317         boost::filesystem::path folder(Core::getConfigPath());
    318         boost::filesystem::path filepath(folder/getFilename(this->defaultLanguage_));
     315        boost::filesystem::path filepath(Core::getConfigPath() / getFilename(this->defaultLanguage_));
    319316
    320317        // Open the file
  • code/branches/buildsystem3/src/core/LuaBind.cc

    r2687 r2702  
    5353    LuaBind::singletonRef_s = this;
    5454
    55     this->includePath_ = Core::getMediaPath();
     55    this->includePath_ = Core::getMediaPathPOSIXString();
    5656
    5757    luaState_ = lua_open();
  • code/branches/buildsystem3/src/core/TclBind.cc

    r1792 r2702  
    6262    void TclBind::setDataPath(const std::string& datapath)
    6363    {
    64         this->tclLibPath_ = datapath + "/tcl" + TCL_VERSION + "/";
     64        // String has POSIX slashes
     65        this->tclLibPath_ = datapath + "tcl" + TCL_VERSION + '/';
    6566        this->bSetTclLibPath_ = true;
    6667
Note: See TracChangeset for help on using the changeset viewer.