Skip to content

Commit 4b47789

Browse files
committed
Add function osgDB::executableFilePath() to find the executable path platform independent
The implementation has been taken from the VulkanSceneGraph project.
1 parent 7fc36a5 commit 4b47789

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

include/osgDB/FileUtils

+3
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ extern OSGDB_EXPORT bool setCurrentWorkingDirectory( const std::string &newCurre
4343
/** return true if a file exists. */
4444
extern OSGDB_EXPORT bool fileExists(const std::string& filename);
4545

46+
/** returns the path/filename of the currently executed program. */
47+
extern OSGDB_EXPORT std::string executableFilePath();
48+
4649
enum FileType
4750
{
4851
FILE_NOT_FOUND,

src/osgDB/FileUtils.cpp

+60
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,20 @@ typedef char TCHAR;
4343
#ifndef F_OK
4444
#define F_OK 4
4545
#endif
46+
#ifdef _MSC_VER
47+
#ifndef PATH_MAX
48+
#define PATH_MAX MAX_PATH
49+
#endif
50+
#endif
4651

4752
#else // unix
4853

4954
#if defined( __APPLE__ )
5055
// I'm not sure how we would handle this in raw Darwin
5156
// without the AvailablilityMacros.
5257
#include <AvailabilityMacros.h>
58+
#include <libgen.h>
59+
#include <mach-o/dyld.h>
5360

5461
//>OSG_IOS
5562
//IOS includes
@@ -116,6 +123,7 @@ typedef char TCHAR;
116123
#include <osgDB/Registry>
117124

118125
#include <errno.h>
126+
#include <limits.h>
119127
#include <string.h>
120128

121129
#include <stack>
@@ -526,6 +534,58 @@ std::string osgDB::findFileInDirectory(const std::string& fileName,const std::st
526534
return "";
527535
}
528536

537+
std::string osgDB::executableFilePath()
538+
{
539+
std::string path;
540+
541+
#if defined(WIN32)
542+
TCHAR buf[PATH_MAX + 1];
543+
DWORD result = GetModuleFileName(NULL, buf, static_cast<DWORD>(std::size(buf) - 1));
544+
if (result && result < std::size(buf))
545+
path = buf;
546+
#elif defined(__linux__)
547+
548+
std::vector<char> buffer(1024);
549+
ssize_t len = 0;
550+
while ((len = ::readlink("/proc/self/exe", buffer.data(), buffer.size())) == static_cast<ssize_t>(buffer.size()))
551+
{
552+
buffer.resize(buffer.size() * 2);
553+
}
554+
555+
// add terminator to string.
556+
buffer[len] = '\0';
557+
558+
return buffer.data();
559+
560+
#elif defined(__APPLE__)
561+
# if TARGET_OS_MAC
562+
char realPathName[PATH_MAX + 1];
563+
char buf[PATH_MAX + 1];
564+
uint32_t size = (uint32_t)sizeof(buf);
565+
566+
if (!_NSGetExecutablePath(buf, &size))
567+
{
568+
realpath(buf, realPathName);
569+
path = realPathName;
570+
}
571+
# elif TARGET_IPHONE_SIMULATOR
572+
// iOS, tvOS, or watchOS Simulator
573+
// Not currently implemented
574+
# elif TARGET_OS_MACCATALYST
575+
// Mac's Catalyst (ports iOS API into Mac, like UIKit).
576+
// Not currently implemented
577+
# elif TARGET_OS_IPHONE
578+
// iOS, tvOS, or watchOS device
579+
// Not currently implemented
580+
# else
581+
# error "Unknown Apple platform"
582+
# endif
583+
#elif defined(__ANDROID__)
584+
// Not currently implemented
585+
#endif
586+
return path;
587+
}
588+
529589
static void appendInstallationLibraryFilePaths(osgDB::FilePathList& filepath)
530590
{
531591
#ifdef OSG_DEFAULT_LIBRARY_PATH

0 commit comments

Comments
 (0)