Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Fullpath or execution dir on widows/linux/mac[SOLVED]  (Read 29028 times)

0 Members and 2 Guests are viewing this topic.

wmbuRn

  • Jr. Member
  • **
  • Posts: 58
    • View Profile
    • Email
Re: Fullpath or execution dir on widows/linux/mac
« Reply #15 on: July 30, 2013, 05:22:16 pm »
Give me a minute to record a desktop. Becouse it is not working and i know it should work. I wont do whole linux/windows/mac defines if path like "Data/ images blah blah.jpg" works.

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: Fullpath or execution dir on widows/linux/mac
« Reply #16 on: July 30, 2013, 05:49:07 pm »
Quote
Hiura, but that defeats the whole purpose of relative paths. Isn't there a possibility to keep the working directory unchanged when using symbolic links?

It all depends on how you implement resources loading in your app. If it makes sense to use the working directory to load different files for different launch command, go ahead and you have nothing to do. I think it is useful for a marginal number of apps only.

Generally, you (the developer) create an app and its resources. Let's say you only need 'cat.png'. You will probably put that file in a subdirectory like 'res' and put you app (called 'lolcatz') in the same directory as 'res'. Let's assume we want to load that specific file and not another cat.png that could be relative to another working directory.

Then, in your code, you will do something like that:

sf::Texture cat;
cat.loadFromFile(resourcePath() + "cat.png");

(And check that the load command hasn't failed, of course.)

When you load the picture of cutty kitten, you don't care about absolute path. In fact, at this point, you don't want absolute path! You only know that the file is in the resources directory. So you call this 'resourcePath()' function that does the abstraction for you.

Now, you need the full path of your app to implement "correctly" (i.e. regarding the assumption made above) the 'resourcePath()' function.

There is another point to have this 'resourcePath' function which has nothing to do with working directory. So even if you're absolutely sure that using absolute path can always be avoided (on which I disagree ;-) you should still consider it for your app. Let me explain:

Assuming you want to load resource files depending on the current working directory but you know that all resource files are in a local folder called 'res'. Then your function can simply return './res/'. And remember that your function can return "./" (or something similar) if you don't need this yet.

So even if you disagree that absolute path are required, you do want (or at least you should want) to have a little bit of abstraction here.  :)

On Mac OS X we have 'bundle application'. That is, some kind of directory (that ends with .app) containing everything your app needs, or pretty much everything. From binary, to deps libs, and resources. With those application it make a lot of sense to use this 'resourcePath' function for the two reasons mentioned above (abstraction & full path).

Quote
I think
ln -s /full/path/to/my/program/exe MyShortcut
works as intended (and as on windows).
Nope, that doesn't work (at least on Mac, so I guess we can extend that to Unix). I didn't new symlink existed on Window, though.

ln -s /Users/m/Desktop/tmp/exe fulllnexe
m@mambp ~/D/t/inner> ./fulllnexe
Failed to load image "img.png". Reason : Unable to open file
Working directory: /Users/m/Desktop/tmp/inner~

BTW, I edited the code to use SFML in it. Just to convince you guys.  ;)

#include <unistd.h>
#include <iostream>
#include <SFML/Graphics.hpp>

int main(int, char**) {
    char* pwd = getwd(NULL);
    std::cout << "Working directory: " << pwd;
    free(pwd);

    sf::Image img;
    img.loadFromFile("img.png");
    return 0;
}

 

There might exist a way to create some kind of symlink on Unix that guarantee to use a specific working directoy. But that all depends on the user at the end: will he do something stupid and launch you lolcatz app without this neat symlink?

On a side note, some software comes with a launch script that do something like that:

cd $(dirname "$0")

in order to get always the same working directory (i.e. the one containing the shell script in this case).
« Last Edit: July 30, 2013, 05:50:58 pm by Hiura »
SFML / OS X developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11037
    • View Profile
    • development blog
    • Email
Re: Fullpath or execution dir on widows/linux/mac
« Reply #17 on: July 30, 2013, 05:55:30 pm »
I agree with Hiura.
In general relative path/working directory "works" and it's used widely in many application, but calling things with absolute path is not defeating any purpose.
With absolute path you can ensure, that the application will always look at the right location. So why give the end users the possibility to screw things up, when we can prevent it?

Personally I'd like to see SFML having such a feature built in, but I'm not sure if it would fit in SFML's scope.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

wmbuRn

  • Jr. Member
  • **
  • Posts: 58
    • View Profile
    • Email
Re: Fullpath or execution dir on widows/linux/mac
« Reply #18 on: July 30, 2013, 06:09:51 pm »
Relative paths wont work for me. Video is decoding, it takes time on my slo-mo cpu :)

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Fullpath or execution dir on widows/linux/mac
« Reply #19 on: July 30, 2013, 06:12:36 pm »
Hiura, thanks for the detailed explanation. Especially the Mac OS parts were new to me.

So why give the end users the possibility to screw things up, when we can prevent it?
Because it is a notable additional effort to work with absolute paths, with little gain for average cases. You have to call non-portable operating system functions and differentiate cases (or use an external library).

What about dynamic libraries that are loaded by the application (and that are not globally installed in the system)? On Windows, such DLLs are placed in the directory of the EXE, on Linux one can use the -rpath linker option to specify a relative path to SO files. Using a different working directory might introduce trouble here.
« Last Edit: July 30, 2013, 06:14:32 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11037
    • View Profile
    • development blog
    • Email
Re: Fullpath or execution dir on widows/linux/mac
« Reply #20 on: July 30, 2013, 06:28:41 pm »
Because it is a notable additional effort to work with absolute paths, with little gain for average cases. You have to call non-portable operating system functions and differentiate cases (or use an external library).
I kind of disagree. Just because there isn't a library that hides the abstraction, it doesn't automatically turn all the OS specific calls to evil. And given the example above from Hirua, it's no additional effort to work with absolute path at all.
What would your opinion be, if SFML had a function that returned the current working directory? Would it still be absurd?

What about dynamic libraries that are loaded by the application (and that are not globally installed in the system)? On Windows, such DLLs are placed in the directory of the EXE, on Linux one can use the -rpath linker option to specify a relative path to SO files. Using a different working directory might introduce trouble here.
Afaik libraries are a whole different topic. For instance the exe on Windows will look next to itself regardless from what working directory you call it. I don't know how that works on Linux though.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

wmbuRn

  • Jr. Member
  • **
  • Posts: 58
    • View Profile
    • Email
Re: Fullpath or execution dir on widows/linux/mac
« Reply #21 on: July 30, 2013, 06:29:55 pm »
Video is up
http://youtu.be/cmtO1mNgr_8

Low quality since my computer is so slow, but you can see that from terminal works, and starting app via double click doesnt work.

Anyway i used tgui in this project, if you want i can start new project without tgui.

Here is command what i used to display the "gangnam style" [ yeah lol i know :) ]
tgui::Picture::Ptr picture(*mainScreen);
    picture->load("Data/Backgrounds/loginBackground.png");  // equivalent of sf::Texture
    picture->setSize(800, 530);
 

Anyway that why i wanted to use execution path from
#ifdef _WIN32
#include <windows.h>

std::string getexepath()
  {
  char result[ MAX_PATH ];
  return std::string( result, GetModuleFileName( NULL, result, MAX_PATH ) );
  }
#endif

#ifdef __linux
#include <unistd.h>

std::string getexepath()
  {
  char result[ PATH_MAX ];
  ssize_t count = readlink( "/proc/self/exe", result, PATH_MAX );
  return std::string( result, (count > 0) ? count : 0 );

#endif
#ifdef __APPLE__
// nothing to do here [yet]
#endif
}
 
And  picture->load("Data/Backgrounds/loginBackground.png"); will look like this
...
std::string asd;
asd = getexepath();
picture->load(asd + "Data/Backgrounds/loginBackground.png");
 
« Last Edit: July 30, 2013, 06:45:51 pm by wmbuRn »

Lo-X

  • Hero Member
  • *****
  • Posts: 618
    • View Profile
    • My personal website, with CV, portfolio and projects
Re: Fullpath or execution dir on widows/linux/mac
« Reply #22 on: July 30, 2013, 06:49:47 pm »
I don't get it. I just done the same on my linux and it works well.
I don't know mac at all, but since it's unix based I don't understand why there are such differences. Perhaps as on windows there's an option in the executable properties that says "Launch as if it was in ... directory". ?

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: Fullpath or execution dir on widows/linux/mac
« Reply #23 on: July 30, 2013, 07:02:37 pm »
Quote from:  eXpl0it3r
What would your opinion be, if SFML had a function that returned the current working directory? Would it still be absurd?
If we're speaking or working directory I don't see a reason to add such function – the working directory is always './' so...

But if you were speaking of application directory (to give it another name), i.e. the directory containing the application binary, I'm not sure that it would fit well in SFML. For one reason, at least: on Mac with app bundle, it doesn't make much sense to have such function. You do want a function to get the resource directory, though.

So, basically, each operating system is based on different tradition / standard. It would be hard to find a perfect solution that make everybody happy.

But I agree, this is not a true argument against such function but only a limitation of the implementation.

I don't get it. I just done the same on my linux and it works well.
I don't know mac at all, but since it's unix based I don't understand why there are such differences. Perhaps as on windows there's an option in the executable properties that says "Launch as if it was in ... directory". ?

I remember something from a long time ago: on Windows XP, shortcuts had an optional setting for 'working directory'. But shortcuts are not symlinks. So I don't know.
SFML / OS X developer

wmbuRn

  • Jr. Member
  • **
  • Posts: 58
    • View Profile
    • Email
Re: Fullpath or execution dir on widows/linux/mac
« Reply #24 on: July 30, 2013, 07:06:56 pm »
I never used mac, barely used windows. Whole my life i spent using linux. So only thing i used from Windows family is windows 98 :)

I am curently using linux > elementary os luna beta 2, which looks like mac :)

And i have no idea why "Data/ images i need.png" wont work when started via double click.
« Last Edit: July 30, 2013, 07:11:55 pm by wmbuRn »

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Fullpath or execution dir on widows/linux/mac
« Reply #25 on: July 30, 2013, 07:14:56 pm »
Just because there isn't a library that hides the abstraction, it doesn't automatically turn all the OS specific calls to evil. And given the example above from Hirua, it's no additional effort to work with absolute path at all.
No surprise if he doesn't show the resourcePath() implementation :P

Using OS-specific functions doesn't only lead to more code, but it requires to have such all operating systems in order to test the functionality. You also have to lookup the corresponding APIs. Of course it's not impossible, but I wouldn't expect every developer to do it only to correct user's mistakes.
 
What would your opinion be, if SFML had a function that returned the current working directory?
That would be better.

Nevertheless, I wonder why absolute paths to resource directories are not that widespread, if they allegedly only have advantages? At least I just tested a game on Windows, after creating a shortcut with a different working directory. It simply crashed when starting.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Fullpath or execution dir on widows/linux/mac
« Reply #26 on: July 30, 2013, 07:21:38 pm »
Quote
At least I just tested a game on Windows, after creating a shortcut with a different working directory. It simply crashed when starting.
Some games do that on purpose, I think(I'm not sure now and I'm no longer using my win so I can't check easily) unreal engine 1 games mods are shortcuts that start exe with another working directory so it'll load different classes, assets, settings and levels.
Back to C++ gamedev with SFML in May 2023

wmbuRn

  • Jr. Member
  • **
  • Posts: 58
    • View Profile
    • Email
Re: Fullpath or execution dir on widows/linux/mac
« Reply #27 on: July 30, 2013, 07:25:52 pm »
Will this work on linux/ windows/ mac:

imagine these functions return path to application without programName[.exe or .out or .app]
#ifdef _WIN32
#include <windows.h>

std::string getexepath()
  {
  char result[ MAX_PATH ];
  return std::string( result, GetModuleFileName( NULL, result, MAX_PATH ) );
  }
#endif

#ifdef __linux
#include <unistd.h>

std::string getexepath()
  {
  char result[ PATH_MAX ];
  ssize_t count = readlink( "/proc/self/exe", result, PATH_MAX );
  return std::string( result, (count > 0) ? count : 0 );
  }
#endif
#ifdef __APPLE__
// imagine there is getexepath() function that return exe path on mac
#endif
 

so calling this code:
...
std::string asd;
asd = getexepath();
...
picture->load(asd + "Data/Backgrounds/loginBackground.png");
same code should work on windows/linux/mac?

Lo-X

  • Hero Member
  • *****
  • Posts: 618
    • View Profile
    • My personal website, with CV, portfolio and projects
Re: Fullpath or execution dir on widows/linux/mac
« Reply #28 on: July 30, 2013, 07:27:18 pm »
@wmbuRn :

What happen if you use Hiura code or the code below in your program when 1) you launch it by command line and 2) by double clicking

#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char **argv) {
    char the_path[256];

    getcwd(the_path, 255);

    printf("%s\n", the_path);

    return 0;
}


I really dont see what's happening here :/

For your full path question, if you have the executable path for each OS no reason it won't work

wmbuRn

  • Jr. Member
  • **
  • Posts: 58
    • View Profile
    • Email
Re: Fullpath or execution dir on widows/linux/mac
« Reply #29 on: July 30, 2013, 07:36:30 pm »
@wmbuRn :

What happen if you use Hiura code or the code below in your program when 1) you launch it by command line and 2) by double clicking

#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char **argv) {
    char the_path[256];

    getcwd(the_path, 255);

    printf("%s\n", the_path);

    return 0;
}
1. I moved application everywhere and start it from terminal, it does output the folder where the application is.
2. Nothing is shown, screen wont even blink. Like i havent double clicked on it.