Merge pull request #6087 from YosysHQ/cat/windows-utf8

Accept UTF-8 filenames and terminal I/O on Windows.
This commit is contained in:
Miodrag Milanović 2026-08-06 12:28:04 +00:00 committed by GitHub
commit 25b06f428e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 45 additions and 20 deletions

View File

@ -426,7 +426,7 @@ if (NOT YOSYS_BUILD_PYTHON_ONLY)
yosys_link_components(yosys PRIVATE ${driver_components})
set_property(TARGET yosys PROPERTY ENABLE_EXPORTS ON)
if (MINGW)
target_link_options(yosys PRIVATE LINKER:--export-all-symbols)
target_link_options(yosys PRIVATE -municode LINKER:--export-all-symbols)
set_target_properties(yosys PROPERTIES
# Final name: `yosys.exe.a` (linked to explicitly)
IMPORT_PREFIX ""

View File

@ -48,6 +48,7 @@ namespace py = pybind11;
#include <string.h>
#include <limits.h>
#include <errno.h>
#include <fcntl.h>
#ifndef __STDC_FORMAT_MACROS
# define __STDC_FORMAT_MACROS
#endif
@ -112,8 +113,31 @@ namespace Yosys {
};
#endif
#ifdef _WIN32
int wmain(int argc, wchar_t **wargv)
{
// Configure ASCII functions like fopen() to use UTF-8 filenames.
// See https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?view=msvc-170#utf-8-support
#ifdef _UCRT
setlocale(LC_ALL, ".UTF-8");
#endif
// Configure the Win32 console to use UTF-8.
SetConsoleCP(CP_UTF8);
SetConsoleOutputCP(CP_UTF8);
std::vector<char*> uargs;
for (int i = 0; i < argc; i++) {
int usize = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, NULL, 0, NULL, NULL);
char *uarg = (char *)malloc(usize);
WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, uarg, usize, NULL, NULL);
uargs.push_back(uarg);
}
uargs.push_back(NULL);
char **argv = uargs.data();
#else
int main(int argc, char **argv)
{
#endif
auto wall_clock_start = std::chrono::steady_clock::now();
std::string frontend_command = "auto";
std::string backend_command = "auto";

View File

@ -155,13 +155,16 @@ std::string get_base_tmpdir()
}
#if defined(_WIN32)
char longpath[MAX_PATH + 1];
char shortpath[MAX_PATH + 1];
if (!GetTempPathA(MAX_PATH+1, longpath))
log_error("GetTempPath() failed.\n");
if (!GetShortPathNameA(longpath, shortpath, MAX_PATH + 1))
log_error("GetShortPathName() failed.\n");
tmpdir += shortpath;
std::wstring wtmppath(4096, L'\0');
// typically returns a 8.3 path, but this can be disabled via registry
if (!GetTempPathW(wtmppath.size(), wtmppath.data()))
log_error("GetTempPathW() failed.\n");
wtmppath.resize(wtmppath.find(L'\0'));
std::string utmppath;
utmppath.resize(WideCharToMultiByte(CP_UTF8, 0, wtmppath.data(), wtmppath.size(), NULL, 0, NULL, NULL));
if (WideCharToMultiByte(CP_UTF8, 0, wtmppath.data(), wtmppath.size(), utmppath.data(), utmppath.size(), NULL, NULL) == 0)
log_error("WideCharToMultiByte() failed.\n");
tmpdir += utmppath;
#else
char * var = std::getenv("TMPDIR");
if (var && strlen(var)!=0) {

View File

@ -537,18 +537,16 @@ std::string proc_self_dirname()
#elif defined(_WIN32)
std::string proc_self_dirname()
{
int i = 0;
char longpath[MAX_PATH + 1];
char shortpath[MAX_PATH + 1];
if (!GetModuleFileNameA(0, longpath, MAX_PATH+1))
log_error("GetModuleFileName() failed.\n");
if (!GetShortPathNameA(longpath, shortpath, MAX_PATH+1))
log_error("GetShortPathName() failed.\n");
while (shortpath[i] != 0)
i++;
while (i > 0 && shortpath[i-1] != '/' && shortpath[i-1] != '\\')
shortpath[--i] = 0;
return shortpath;
std::wstring wbinpath(4096, L'\0');
if (!GetModuleFileNameW(0, &wbinpath[0], wbinpath.size()))
fprintf(stderr, "GetModuleFileNameW() failed.\n");
wbinpath.resize(wbinpath.rfind(L'\\') + 1); // remove filename
std::string ubinpath;
ubinpath.resize(WideCharToMultiByte(CP_UTF8, 0, wbinpath.data(), wbinpath.size(), NULL, 0, NULL, NULL));
if (WideCharToMultiByte(CP_UTF8, 0, wbinpath.data(), wbinpath.size(), &ubinpath[0], ubinpath.size(), NULL, NULL) == 0)
fprintf(stderr, "WideCharToMultiByte() failed.\n");
return ubinpath;
}
#elif defined(__wasm)
std::string proc_self_dirname()