Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core7/src/libraries/core/ApplicationPaths.cc @ 10537

Last change on this file since 10537 was 10509, checked in by landauf, 9 years ago

moved static application paths (root, executable, modules) into new class named ApplicationPaths
moved configurable data paths (data, log, config) into new class named ConfigurablePaths
removed PathConfig

  • Property svn:eol-style set to native
File size: 6.8 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Reto Grieder
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "ApplicationPaths.h"
30
31#include <cassert>
32#include <cstdlib>
33#include <cstdio>
34#include <vector>
35#include <boost/filesystem.hpp>
36
37#ifdef ORXONOX_PLATFORM_WINDOWS
38#  ifndef WIN32_LEAN_AND_MEAN
39#    define WIN32_LEAN_AND_MEAN
40#  endif
41#  include <windows.h>
42#  undef min
43#  undef max
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"
53#include "util/Output.h"
54#include "util/Exception.h"
55
56// Differentiate Boost Filesystem v2 and v3
57#if (BOOST_FILESYSTEM_VERSION < 3)
58#  define BF_LEAF leaf
59#  define BF_GENERIC_STRING string
60#else
61#  define BF_LEAF path().filename().string
62#  define BF_GENERIC_STRING generic_string
63#endif
64
65namespace orxonox
66{
67    namespace bf = boost::filesystem;
68
69    //! Static pointer to the singleton
70    ApplicationPaths* ApplicationPaths::singletonPtr_s  = 0;
71
72    ApplicationPaths::ApplicationPaths()
73        : rootPath_(*(new bf::path()))
74        , executablePath_(*(new bf::path()))
75        , modulePath_(*(new bf::path()))
76        , bBuildDirectoryRun_(false)
77    {
78        //////////////////////////
79        // FIND EXECUTABLE PATH //
80        //////////////////////////
81
82#ifdef ORXONOX_PLATFORM_WINDOWS
83        // get executable module
84        TCHAR buffer[1024];
85        if (GetModuleFileName(NULL, buffer, 1024) == 0)
86            ThrowException(General, "Could not retrieve executable path.");
87
88#elif defined(ORXONOX_PLATFORM_APPLE)
89        char buffer[1024];
90        uint32_t path_len = 1023;
91        if (_NSGetExecutablePath(buffer, &path_len))
92            ThrowException(General, "Could not retrieve executable path.");
93
94#else /* Linux */
95        /* written by Nicolai Haehnle <prefect_@gmx.net> */
96
97        /* Get our PID and build the name of the link in /proc */
98        char linkname[64]; /* /proc/<pid>/exe */
99        if (snprintf(linkname, sizeof(linkname), "/proc/%i/exe", getpid()) < 0)
100        {
101            /* This should only happen on large word systems. I'm not sure
102               what the proper response is here.
103               Since it really is an assert-like condition, aborting the
104               program seems to be in order. */
105            assert(false);
106        }
107
108        /* Now read the symbolic link */
109        char buffer[1024];
110        int ret;
111        ret = readlink(linkname, buffer, 1024);
112        /* In case of an error, leave the handling up to the caller */
113        if (ret == -1)
114            ThrowException(General, "Could not retrieve executable path.");
115
116        /* Ensure proper NUL termination */
117        buffer[ret] = 0;
118#endif
119
120        // Remove executable filename
121        executablePath_ = bf::path(buffer).branch_path();
122
123        /////////////////////
124        // SET MODULE PATH //
125        /////////////////////
126
127        if (bf::exists(executablePath_ / "orxonox_dev_build.keep_me"))
128        {
129            orxout(internal_info) << "Running from the build tree." << endl;
130            ApplicationPaths::bBuildDirectoryRun_ = true;
131            modulePath_ = specialConfig::moduleDevDirectory;
132        }
133        else
134        {
135
136#ifdef INSTALL_COPYABLE // --> relative paths
137
138            // Also set the root path
139            bf::path relativeExecutablePath(specialConfig::defaultRuntimePath);
140            rootPath_ = executablePath_;
141            while (!bf::equivalent(rootPath_ / relativeExecutablePath, executablePath_) && !rootPath_.empty())
142                rootPath_ = rootPath_.branch_path();
143            if (rootPath_.empty())
144                ThrowException(General, "Could not derive a root directory. Might the binary installation directory contain '..' when taken relative to the installation prefix path?");
145
146            // Module path is fixed as well
147            modulePath_ = rootPath_ / specialConfig::defaultModulePath;
148
149#else
150
151            // There is no root path, so don't set it at all
152            // Module path is fixed as well
153            modulePath_ = specialConfig::moduleInstallDirectory;
154
155#endif
156        }
157    }
158
159    ApplicationPaths::~ApplicationPaths()
160    {
161        delete &rootPath_;
162        delete &executablePath_;
163        delete &modulePath_;
164    }
165
166    std::vector<std::string> ApplicationPaths::getModulePaths()
167    {
168        std::vector<std::string> modulePaths;
169
170        // We search for helper files with the following extension
171        const std::string& moduleextension = specialConfig::moduleExtension;
172        size_t moduleextensionlength = moduleextension.size();
173
174        // Make sure the path exists, otherwise don't load modules
175        if (!boost::filesystem::exists(modulePath_))
176            return modulePaths;
177
178        boost::filesystem::directory_iterator file(modulePath_);
179        boost::filesystem::directory_iterator end;
180
181        // Iterate through all files
182        while (file != end)
183        {
184            std::string filename = file->BF_LEAF();
185
186            // Check if the file ends with the extension in question
187            if (filename.size() > moduleextensionlength)
188            {
189                if (filename.substr(filename.size() - moduleextensionlength) == moduleextension)
190                {
191                    // We've found a helper file
192                    const std::string& library = filename.substr(0, filename.size() - moduleextensionlength);
193                    modulePaths.push_back(getModulePathString() + library);
194                }
195            }
196            ++file;
197        }
198
199        return modulePaths;
200    }
201
202    /*static*/ std::string ApplicationPaths::getRootPathString()
203    {
204        return getInstance().rootPath_.BF_GENERIC_STRING() + '/';
205    }
206
207    /*static*/ std::string ApplicationPaths::getExecutablePathString()
208    {
209        return getInstance().executablePath_.BF_GENERIC_STRING() + '/';
210    }
211
212    /*static*/ std::string ApplicationPaths::getModulePathString()
213    {
214        return getInstance().modulePath_.BF_GENERIC_STRING() + '/';
215    }
216}
Note: See TracBrowser for help on using the repository browser.