From 74cbe719b5cdc8bbf776ad72ee497b2ba16070df Mon Sep 17 00:00:00 2001 From: Ralf Habacker Date: Fri, 18 Nov 2022 10:43:07 +0100 Subject: [PATCH] Add function osgDB::executableFilePath() to find the executable path platform independent The implementation has been taken from the VulkanSceneGraph project. (cherry picked from commit 644f5521bd81e837fc8829a0df8581d8e253c6e6) --- include/osgDB/FileUtils | 3 ++ src/osgDB/FileUtils.cpp | 61 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/include/osgDB/FileUtils b/include/osgDB/FileUtils index 94b55fe070e..055b41b6928 100644 --- a/include/osgDB/FileUtils +++ b/include/osgDB/FileUtils @@ -43,6 +43,9 @@ extern OSGDB_EXPORT bool setCurrentWorkingDirectory( const std::string &newCurre /** return true if a file exists. */ extern OSGDB_EXPORT bool fileExists(const std::string& filename); +/** returns the path/filename of the currently executed program. */ +extern OSGDB_EXPORT std::string executableFilePath(); + enum FileType { FILE_NOT_FOUND, diff --git a/src/osgDB/FileUtils.cpp b/src/osgDB/FileUtils.cpp index 3c61dae629d..f99b25797fa 100644 --- a/src/osgDB/FileUtils.cpp +++ b/src/osgDB/FileUtils.cpp @@ -43,6 +43,11 @@ typedef char TCHAR; #ifndef F_OK #define F_OK 4 #endif +#ifdef _MSC_VER +#ifndef PATH_MAX + #define PATH_MAX MAX_PATH +#endif +#endif #else // unix @@ -50,6 +55,8 @@ typedef char TCHAR; // I'm not sure how we would handle this in raw Darwin // without the AvailablilityMacros. #include + #include + #include //>OSG_IOS //IOS includes @@ -116,6 +123,7 @@ typedef char TCHAR; #include #include +#include #include #include @@ -526,6 +534,59 @@ std::string osgDB::findFileInDirectory(const std::string& fileName,const std::st return ""; } +/* This function has be taken from the VSG project */ +std::string osgDB::executableFilePath() +{ + std::string path; + +#if defined(WIN32) + TCHAR buf[PATH_MAX + 1]; + DWORD result = GetModuleFileName(NULL, buf, static_cast(std::size(buf) - 1)); + if (result && result < std::size(buf)) + path = buf; +#elif defined(__linux__) + + std::vector buffer(1024); + ssize_t len = 0; + while ((len = ::readlink("/proc/self/exe", buffer.data(), buffer.size())) == static_cast(buffer.size())) + { + buffer.resize(buffer.size() * 2); + } + + // add terminator to string. + buffer[len] = '\0'; + + return buffer.data(); + +#elif defined(__APPLE__) +# if TARGET_OS_MAC + char realPathName[PATH_MAX + 1]; + char buf[PATH_MAX + 1]; + uint32_t size = (uint32_t)sizeof(buf); + + if (!_NSGetExecutablePath(buf, &size)) + { + realpath(buf, realPathName); + path = realPathName; + } +# elif TARGET_IPHONE_SIMULATOR + // iOS, tvOS, or watchOS Simulator + // Not currently implemented +# elif TARGET_OS_MACCATALYST + // Mac's Catalyst (ports iOS API into Mac, like UIKit). + // Not currently implemented +# elif TARGET_OS_IPHONE + // iOS, tvOS, or watchOS device + // Not currently implemented +# else +# error "Unknown Apple platform" +# endif +#elif defined(__ANDROID__) + // Not currently implemented +#endif + return path; +} + static void appendInstallationLibraryFilePaths(osgDB::FilePathList& filepath) { #ifdef OSG_DEFAULT_LIBRARY_PATH