No wanting re-event the wheel, is there already a function to do this?
-
When I build an application on the iMAC using Qt Creator the app is actually a folder with the following structure:
Contents (folder) MacOS (folder) application executable file here info.plist PkgInfo Resources. (folder) empty.lproj
When calling:
QCoreApplication::applicationFilePath()
The actual path returned contains now everything including the path of the compressed above structure:
/Users/sy/XMLMPAM/build-mdFileIO-Desktop_Qt_5_15_2_clang_64bit-Debug/mdFileIO.app/Contents/MacOS/mdFileIO
Where in the above path the file created by Qt Creator is mdFileIO.app. I have written a routine which returns just the file path to the application:
const quint8 cuint8Delimiters = 3; QString strAppName = QCoreApplication::applicationFilePath(), strPath; if ( strAppName.isEmpty() == true ) { //Cannot do anything without application path and name return; } //Locate last delimiter in path int intIdx = strAppName.lastIndexOf(QDir::separator()); if ( intIdx == -1 ) { //Cannot locate path seperator! return; } //Go back to the location of the actual file path quint8 uint8Found = 0; for( int i=intIdx-1; i>=0; i-- ) { if ( strAppName[i] == QDir::separator() ) { if ( ++uint8Found == cuint8Delimiters ) { //Extract just the path strPath = strAppName.mid(0, i); break; } } } if ( strPath.isEmpty() == true ) { //Path not found return; }
Is there something that already exists to do the same?
-
@SPlatten I don't quite follow,
you want the following returned ?
/Users/sy/XMLMPAM/build-mdFileIO-Desktop_Qt_5_15_2_clang_64bit-Debug/mdFileIO.app/Contents/MacOS/mdFileIO
? than you can use QCoreApplication::applicationDirPath() for that,
if you want only the path of the app bundle, I'm using the following function myself:static const QString &ApplicationFolder (){ #ifdef Q_OS_MACOS auto getStringPath = []()->QString{ CFURLRef url =(CFURLRef)CFAutorelease((CFURLRef)CFBundleCopyBundleURL(CFBundleGetMainBundle())); QDir d(QUrl::fromCFURL(url).path()); d.cdUp(); return d.absolutePath(); }; static const QString path = getStringPath(); #else static const QString path = QCoreApplication::applicationDirPath(); #endif return path; }
Not sure if there exists something for that in Qt, I never really found anything 🤷♂️
-
@SPlatten said in No wanting re-event the wheel, is there already a function to do this?:
Is there something that already exists to do the same?
Sometimes reading doc can help:
QString QCoreApplication::applicationDirPath()Returns the directory that contains the application executable.
For example, if you have installed Qt in the C:\Qt directory, and you run the regexp example, this function will return "C:/Qt/examples/tools/regexp".
On macOS and iOS this will point to the directory actually containing the executable, which may be inside an application bundle (if the application is bundled). -
@KroMignon , actually, having just tried it, its not what I'm after, calling:
QCoreApplication::applicationDirPath();
Gives:
/Users/sy/XMLMPAM/build-mdFileIO-Desktop_Qt_5_15_2_clang_64bit-Debug/mdFileIO.app/Contents/MacOS
What I want is:
/Users/sy/XMLMPAM/build-mdFileIO-Desktop_Qt_5_15_2_clang_64bit-Debug/
-
@SPlatten said in No wanting re-event the wheel, is there already a function to do this?:
What I want is:
Again, found in Qt documentation:
https://doc.qt.io/qt-5/macos-issues.html#macos-native-api-access -
@SPlatten said in No wanting re-event the wheel, is there already a function to do this?:
does this mean that on different platforms (Linux and Windows) that the application is stored differently?
Yes, these are very different operating systems.
-
@SPlatten said in No wanting re-event the wheel, is there already a function to do this?:
actually Linux is very similar at the command line level with macOS
But not if it comes to packaging software...
-
@SPlatten said in No wanting re-event the wheel, is there already a function to do this?:
so I guess what I want now is a multipatform fool proof way of getting the application path not including any OS specific additions.
QString QCoreApplication::applicationDirPath()
Returns the directory that contains the application executable.
For example, if you have installed Qt in the C:\Qt directory, and you run the regexp example, this function will return "C:/Qt/examples/tools/regexp".
On macOS and iOS this will point to the directory actually containing the executable, which may be inside an application bundle (if the application is bundled). -
Hi,
That's why it's usual to have an
#ifdef Q_OS_MACOS
which contains the code to move up two folders from what is returned byQCoreApplication::applicationDirPath()
. -
@SPlatten said in No wanting re-event the wheel, is there already a function to do this?:
@KroMignon, Thank you, does this mean that on different platforms (Linux and Windows) that the application is stored differently?
Yes, application bundles is specific to macOS. In a sense QCoreApplication::applicationDirPath() does the right thing because an app bundle might also have some additional executables in a different subfolder. applicationDirPath() would return these for those additional executables instead.
To my knowledge Windows does not have anything comparable. So, on Windows applicationDirPath() will always return the correct path.
Linux in general behaves the same as Windows in this respect. However, we started using AppImage to bundle our application for Linux. It is similar to macOS' app bundle, but it uses a disk image instead of a folder. Running the application mounts the image to a temporary directory (which is not a subdirectory of where the actual AppImage is located). There is an environment variable to get the directory of the AppImage. linuxdeployqt (the equivalent to macdeployqt) will generate such an AppImage.
So, in summary only on Windows does applicationDirPath() give you what you want (also on Linux if you don't create an AppImage). Everything else you need to handle by yourself. I don't know of any library - let alone one wildly used - which would do exactly that.