Workaround for opening file streams using wide string paths on old versions of MinGW
On old MinGW versions, opening file streams using wide string paths is not supported. This basically makes it impossible to use ghc::filesystem's streams for opening files with a Unicode character in the path since, by default, the narrow path string (UTF-8 encoded) gets interpreted by Windows using the system codepage (unless you force the program to use UTF-8 via a manifest file).
Example:
#include <iostream>
#include <Windows.h>
#include "ghc/filesystem.hpp"
namespace fs = ghc::filesystem;
constexpr auto path_str = L"αρχείο.txt";
auto main() -> int {
std::cout << "System codepage: " << GetACP() << std::endl;
const auto path = fs::path{ path_str };
{
fs::ofstream ofs{ path, std::ios::binary };
ofs << "hello world!" << std::endl;
}
std::cout << "File exists: " << std::boolalpha << fs::exists( path ) << std::endl;
}
Output:
However, old versions of MinGW might support the _wsopen_s function, a Microsoft extension that allows opening a file using a wide C string path. This, together with an internal function of libstdc++ (__gnu_cxx::stdio_filebuf), can be used to implement a workaround.
The workaround is used only if libstdc++ doesn't natively support opening file streams using wide string paths (https://github.com/gulrak/filesystem/pull/172), which is the preferred way on recent versions of MinGW.
Output with the workaround:
I tested it with both MinGW 7 and 8, which do not support GHC_HAS_FSTREAM_OPEN_WITH_WCHAR, but support _wsopen_s.
As a side note, I had to modify the CMake files so that the -Wa,-mbig-obj parameter is passed to all the test targets; otherwise, MinGW fails while linking the executables.
I hope everything is ok!