SDK Development: Working Path on MacOS?

Joe Kaplan's icon

Hi all,

I've built an external with MinDevkit on Windows using visual studio. Everything is working the way I like. I'd like to support MacOS as well, and I'm running into some challenges.

One thing I need to do is write and read a local file in order to persist some settings. My code contains

#include <fstream>
std::ofstream file
file.open("Mydata.dat");
if (file.is_open()) {
....write my file contents..
}

else {
cout << "could not open file" << endl;
}

On windows this works fine. It creates the file in the same folder as the external.
However on Mac, i get the "could not open file" error. I did some searching and one thing that was suggested was that maybe i didn't have write access to the working path.

When I try to get the working path with std::filesystem::current_path()  i just get back "/". That is, the system root?

On windows I get back the path to my external, as expected.


I suspect this is a clue to why I'm not able to write my file. But I'm not clear on the best way to fix it. Does anyone have any experience developing externals for Mac and have any advice on this one? Thanks!

Joe Kaplan's icon

Hm... I was able to get it to work by editing the schema and going to options and then forcing a custom working directory.

That's fine when I'm debugging. But when I load the external normally, and tell it to print the currentpath() to the max console, i see the working directory is still "/". So the files don't read/write.

How do I get the external to properly identify it's working path on MacOS?

JBG's icon

Hi Joe,

You can use the c74::min::path class to access various Max paths. It's behaviour is similar to the [absolutepath] object in Max. In your case, if Mydata.dat is in your Max path, you can simply do

auto my_data_path = path{"MyData.dat"};
file.open(static_cast<std::string>(my_data_path));

Note that the std::string operator throws std::runtime_error if not found.

If the name of your file is too generic, it might be a better idea to locate the external itself and backtrack to the relative folder of MyData.dat. You can get the path of the external itself through something like this (I haven't tried the .mxe64 part in a windows-only package, but I assume this would work)

try {
    auto p = path{static_cast<std::string>(box().classname()) + ".mxo"};
    if (!p)
        p = path{static_cast<std::string>(box().classname()) + ".mxe64"};
    cout << "full path to external: " << static_cast<std::string>(p) << endl;
} catch (std::runtime_error& e) {
    cerr << e.what() << endl;
}

Joe Kaplan's icon

I used c74::min::path to get this working the way I need it. Thanks!