3

I am attempting to load some images into a very basic C++/SDL based program. The images are loaded using SDL_LoadBMP. I have the image loading and everything seems to work perfectly. My problem is that the image is loaded relative to where I call the program from.

So I have a directory structure that goes something like this.

project/
    src/
        source.cpp
    assets/
        image.bmp
    bin/
        program

When I execute the program from the project directory (./bin/program) it has to use a path of assets/image.bmp to load the image. Is there any way I can use a relative path of ../assets/image.bmp so the program can be executed from anywhere?

I think I need something that provides the absolute path to the program that I can then append my paths to.

genpfault
  • 51,148
  • 11
  • 85
  • 139
Olical
  • 39,703
  • 12
  • 54
  • 77

2 Answers2

3

On Linux, /proc/self/exe is a symbolic link to the executable of the current process. So you can use readlink to find its path. From there you can use usual path manipulation to find your resources. Perhaps you should cater for the case where the program executable is again a symlink to the location where your binary lies, i.e. do some more realink as long as the current path is a symlink.

There once was a question about finding current executable's path without /proc/self/exe which also asked about a portable interface, but no single solution that caters for all needs was given in the accepted answer.

Community
  • 1
  • 1
MvG
  • 57,380
  • 22
  • 148
  • 276
  • Wow, I didn't think it would be so difficult. So a simple relative path such as `../path` or `./path` won't do? I guess I will have to build or find a nice function that will work in most places. I aim for Linux but I would like to have the option to cross-compile later. – Olical Jul 02 '12 at 09:20
  • And what about `basename`? Any reason why that should not be used? http://stackoverflow.com/a/1019557/455137 – Olical Jul 02 '12 at 09:40
  • A relative path is always relative to the current working directory, which might be completely unrelated to the directory where your binary resides. If you are mainly targeting Linux, also read [section 1.14 of the Unix Programming Frequently Asked Questions](http://www.steve.org.uk/Reference/Unix/faq_2.html#SEC23). It advises against use of binary-relative paths. – MvG Jul 02 '12 at 09:46
  • `basename(path)` basically returns the part of `path` following the last occurrence of `'/'`. So you'd need a path to start with, and even then you are probably more interested in `dirname` than `basename`. Both fall into the category of “usual path manipulation” I mentioned in my answer. – MvG Jul 02 '12 at 09:50
2

In Windows:

  1. GetModuleFileName(NULL, ... gets you full path to your binary
  2. PathRemoveFileSpec(... leaves you directory only
  3. PathCombine(..., _T("..\\..\\image.bmp")) with result of item 2 above gets you fully qualified path to image
Roman R.
  • 68,205
  • 6
  • 94
  • 158