Sign in to follow this  

Changing the working directory for Mac .app bundles

This topic is 3462 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey everyone, I'm new to the Mac world and realized that the ".app"-bundle for executables sets its working directory to program.app/Contents/Resources. The problem with that is, that I don't want to put my files there because non-Mac executables would need to have a separate data directory. I tried the "int chdir(const char* path)" function in <unistd.h> with the arguments "../../" and the absolute path "/Users/stefan/ProjectDir" but in both cases the Mac logging program tells me "Cant open". I'd be very thankful for any help I can get with this!

Share this post


Link to post
Share on other sites
Oh forget the part about the absoute path, that works (I guess I had a typo or something, my bad!). Still that is no good solution as it will break as soon as I move the directory or redistribute it :/

Share this post


Link to post
Share on other sites
Hi,

in the relative path case:
grap the current dir
for number of dir up in the director
-> create a sub string by removing everything after the last '/' (e.g. use strrchr)
then append the path you want to.


Most Applications let you choose during compile where to install your stuff via configure so a #define might do the job.

Hope this helps

Share this post


Link to post
Share on other sites
Okay I figured it out (cold showers work wonders for me when I'm stressed it seems).

In case anyone faces the same problem, here is how it works:

Directory structure:
DualJewel/
- Config.cfg (file I want to open)
- DualJewel.app/
-- Contents/
--- MacOS/
---- DualJewel (executable)
--- Resources/ (where the program will read from normally)

The program could be launched from different paths, which would break every file loading attempt, because it could wrongly assume to be in the project path (DualJewel/).

Situation #1:
cd DualJewel/
./DualJewel.app/Contents/MacOS/DualJewel
Works, "DualJewel/" is the project path.

Situation #2:
cd DualJewel/data/ (or some other sub directory)
../DualJewel.app/Contents/MacOS/DualJewel
Wouldn't work, current working directory is "DualJewel/data" and it wouldn't find the files there (e.g. "Config.cfg").

Situation #3:
Clicking the DualJewel.app with mouse.
Current working directory is root ("/"), at least that's what getcwd() reports. There seems to be some internal directory switching though, because it will find Config.wtf if it's put into "DualJewel.app/Contents/Resources/Config.wtf". That's what confused the hell out of me here.

Here's my little fix to alter this behaviour:

// How was this program called? e.g. "../DualJewel.app/Contents/MacOS/DualJewel"
string workdir = string(argv[0]);

// debug output: current working directory
/*
char* dir = getcwd(0, 0);
printf("cwd: %s\n", dir);
delete dir;
*/


// Removes 4 slashes from path. The 3 directories the binary is nested in
// and the binary name aswell.
// e.g. "/Users/me/DualJewel/DualJewel.app/Contents/MacOS/DualJewel"
// will only leave "/Users/me/DualJewel/".
size_t slashpos = workdir.length(); // start search at very end of path string
for(int i=0; i < 4; ++i) // remove until 4 slashes were found
slashpos = workdir.find_last_of("/\\", --slashpos);
workdir.erase(slashpos, workdir.length());

// switch to the project path, if called from outside of it
if (workdir != ".")
{
// cout << "Switching to working directory \"" << workdir << '\"' << endl;
chdir(workdir.c_str());
}





@dragon: Thanks for the hints! That's something I was thinking about too, but the "internal directory switching" to Contents/Resources/ was the reason I was so confused. I thought there's some special Mac function here or so.

Share this post


Link to post
Share on other sites
Sign in to follow this