SDK Development: Working Path on MacOS?
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!
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?
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;
}
I used c74::min::path to get this working the way I need it. Thanks!