People aren't obligated to "comply" with the XDG specification either. It's not a bug to just use $HOME.
There is a difference between being cross-platform, and being Linux but mangling it so it technically works on other platforms.
https://stackoverflow.com/a/42700844/512904
> being Linux but mangling it so it technically works on other platforms
Sounds like the easiest way to solve this problem. I don't blame or shame developers for choosing it.
This is simple and works everywhere:
char * home = getenv("USERPROFILE");
if (home) {
// Use home directory
}
The answer demonstrating the Windows API way has the following code to accomplish the same thing: WCHAR profilePath[MAX_PATH];
HRESULT result = SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, profilePath);
if (SUCCEEDED(result)) {
// Use home directory
}
Yeah, I seriously doubt open source developers want to deal with this Windows bullshit. I sure don't. Maybe if you're getting paid.Just because you aren't used to it doesn't mean it's 'bullshit'. Might I provide a counterexample to the 'simplicity' of Linux? Developing video games natively on Linux is such a pain point that the industry has standardised around simply translating Windows syscalls and Direct3D shaders to their Linux equivalents, because the latter is so heavily fragmented to develop natively for. Also known as Proton.
Honestly I don't even disagree with you. I think POSIX sucks. I think even the libc sucks. However there is no way you can look at the Windows API mess above and think it's somehow better than the portable and clean getenv function call. Maybe you can "get used" to that cruft but I can't. If I had to deal with code like that the first thing I'd do is abstract it away so I don't have to deal with it anymore. That's exactly how Windows is and should be treated by everyone.
Video games, your counter example, are probably the most platform-specific software imaginable. There's a reason pretty much everybody uses an engine these days. There is no way you can compare that stuff to getting a user's home directory and writing files in there.
Also, for video games it ultimately doesn't matter how sucky the APIs are since it's all about market share anyway and people will use whatever they need to get it done. First parties don't put in effort into porting games to Linux because they don't see the money. Valve puts in effort because it gives them their own platform that they control and therefore leverage over Microsoft and its app store. Emulation and compatibility layers are a proven solution when first parties aren't playing ball. If they don't want to make it work on Linux, people will make it work whether they want it or not.
Also, you're comparing something it makes zero sense to compare. People are not saying 'you need to fetch $USERPROFILE without calling getenv'. People are saying 'you need to not store random garbage in $USERPROFILE'. Calling getenv("APPDATA") is a perfectly fine way of fetching FOLDERID_RoamingAppData, the same way you weren't going to bother calling getpwuid if $HOME was undefined.
It's just some example code. Real code will probably try a number of variables.
> Calling getenv("APPDATA") is a perfectly fine way of fetching FOLDERID_RoamingAppData
Okay then. Top level post said you needed a Win32 function for this. If you can do that without those functions, I suppose it's easy enough to support.
> calling getpwuid if $HOME was undefined
$HOME is set by login and ssh to whatever is in the passwd database. Can it ever be undefined? Seems like something is seriously wrong if it is.
int writeConfigFile(ConfigFile file) {
#if defined(_WIN32)
// Windows-specific function
#elif defined(__linux__)
// Linux-specific function
#elif defined(__APPLE__)
// macOS-specific function
With modern C++, there's probably a way to do this in a nicer manner, and achieve runtime polymorphism with virtual functions or a lambda (function pointer) table.As another sibling commenter wrote, .NET already has a platform-agnostic function to write to a `user program data` folder that nicely maps to the platform-specific directories. Other GC languages (Java, Go, etc) likely have similar abstractions.
As for scripting... A cross-platform project with scripts that also targets Windows should (in my opinion) have PowerShell `.ps1` scripts accompanying any `.sh` scripts. Better still, scripting should be done in a language that's truly platform-agnostic, like Python.
You proved my point. Creating an #ifdef mess with polymorphism, virtual methods and indirection is the very definition of going out of one's way to support something that really doesn't need any support.
This is just part of the cost of developing cross-platform, and I'm sorry, but to me, dismissing this as 'going out of one's way' is just being sloppy.
I felt a great disturbance in the source, as if hundreds of BSD users suddenly cried out in terror and were suddenly silenced.
I initially did think of simply letting the build system handle it (CMake can do this excellently, as can Meson, probably) by simply choosing different source files for different target OSs, but when typing out the parent comment, I forgot about it in my train of thought.
Come to think of it, this is far more elegant.
Linux doesn't hide anything. It's POSIX and GNU tools that choose not show anything that starts with a dot by default. As far as Linux is concerned they're just normal files on the file system.
It doesn't have to be that way. Personally I have my system configured so that all "hidden" files are shown because I hate the concept of hidden anything. I used to do this in Windows too.
> The specific functionality being used does not 'work just fine everywhere'.
It kind of does. "Program reads configuration from a file" seems like a really basic thing that every operating system supports. There really is no need to directly depend on any Windows API stuff. Even worse would be suggesting the use of the registry.
> It is not the case that Linux functionality is How Computing Works with every deviation being 'out of the way', not even in a hypothetical world where Linux isn't the drastic minority of machines by an order of magnitude.
And yet Windows is the system getting "half-baked ports of Unix-first software" here. Why should the developers be shamed for not going of their way to support Windows conventions for Unix software?
I would actually argue otherwise: the registry is the perfect place to put configuration data, provided Microsoft's guidelines[0] on registry key creation/deletion and hive use are followed. I would argue every OS should have its own 'registry' for a universal location to set configuration for programs.
On the other hand, if every application has its own configuration file, then every application shall have its own configuration file parsing/serialising/deserialising routine. It's also what has led to this explosion of 'config file formats': .json, .yaml, .ini, .conf, .cfg, .toml, .xml.
I guess this is why people dislike systemd so much: it reminds them too much of Windows.
[0]: https://learn.microsoft.com/en-us/windows/win32/sysinfo/regi...
You appear to have an attitude of UNIX/Linux > Windows, which is unfortunate. The two OS families are different, but I personally believe neither is superior to the other. Both OSs suck in their own ways, both OSs are better in their own ways (this conclusion after using Windows and Linux both on a 70:30 time ratio).
Windows is in every way as modern an OS as Linux is, but just like Linux, has inherited strange baggage from its 40-year-old past, like 'a file cannot have COM in its name'.
Few people follow that stuff. I wouldn't be surprised if Microsoft's own people didn't follow that stuff. The result is of course a mess that users have to clean up with software like CCleaner or whatever people use these days.
It sucks even if those guidelines are followed. Configuration is data and belongs to the users. I know people who really like portable applications that they can keep on a USB drive and use anywhere and this registry bullshit breaks that.
> I would argue every OS should have its own 'registry' for a universal location to set configuration for programs.
And I would argue otherwise. The Windows registry is essentially a poor excuse for a proper file system. I think at least one Linux desktop environment tried to reinvent this crap and it sucked just as hard.
> every application shall have its own configuration file parsing/serialising/deserialising routine
The Windows registry values are essentially memory dumps of C types. It's perfectly possible to simply dump raw bytes into binary files on Linux too if you don't care about stuff like endianness. The result would be strictly superior to the Windows registry because the files are being stored in a real file system.
> I guess this is why people dislike systemd so much: it reminds them too much of Windows.
I like systemd.
Windows is the system everyone actually uses - even developers!. I write software because I care about people using it.
> Why should the developers be shamed for not going of their way to support Windows conventions for Unix software?
Because it's wrong on Unix, and even wrong on Linux, and once you are doing the right thing on Linux it is no longer out of your way.
Btw, many native, no-linux windows apps, including Microsoft ones love to create their bs folders like “My Games”, “Microsoft Visual Studio (c)(tm) <yearname> Pile of Whatever” or “Android Projects” right in ~/Documents. This “way” is unenforceable even in OS’es own company.