From a2c712e5887f4cdb6dd4c6a27aa2b3a6a0fd3858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Venegas=20Arrab=C3=A9?= Date: Thu, 30 Jul 2026 16:18:36 +0200 Subject: [PATCH 1/2] lib: Win32 port of MemoryMappedFile lib/memory_mapped_file.cc used POSIX open/fstat/mmap, which does not exist under mingw-w64, blocking a native Windows build of the prjxray tools. Add an #ifdef _WIN32 branch using CreateFileA/CreateFileMappingA/MapViewOfFile; the POSIX path is byte-for-byte unchanged. One behavioural note: a zero-length file cannot be mapped on Windows, so that case returns an object with nullptr data and zero size to preserve the "file exists" contract of InitWithFile. --- lib/memory_mapped_file.cc | 46 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/lib/memory_mapped_file.cc b/lib/memory_mapped_file.cc index 0600c9b2..a5be18be 100644 --- a/lib/memory_mapped_file.cc +++ b/lib/memory_mapped_file.cc @@ -9,16 +9,56 @@ */ #include +#ifdef _WIN32 +#include +#else #include #include #include #include #include +#endif namespace prjxray { std::unique_ptr MemoryMappedFile::InitWithFile( const std::string& path) { +#ifdef _WIN32 + HANDLE file = CreateFileA(path.c_str(), GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, + NULL); + if (file == INVALID_HANDLE_VALUE) + return nullptr; + + LARGE_INTEGER file_size; + if (!GetFileSizeEx(file, &file_size)) { + CloseHandle(file); + return nullptr; + } + + // A zero-length file cannot be mapped; return an object (to indicate + // the file exists) with a nullptr and zero length. + if (file_size.QuadPart == 0) { + CloseHandle(file); + return std::unique_ptr( + new MemoryMappedFile(nullptr, 0)); + } + + HANDLE mapping = + CreateFileMappingA(file, NULL, PAGE_READONLY, 0, 0, NULL); + // The view keeps the file/mapping alive, so the handles can be closed. + CloseHandle(file); + if (mapping == NULL) + return nullptr; + + void* file_map = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0); + CloseHandle(mapping); + if (file_map == NULL) + return nullptr; + + return std::unique_ptr(new MemoryMappedFile( + file_map, static_cast(file_size.QuadPart))); +#else int fd = open(path.c_str(), O_RDONLY, 0); if (fd == -1) return nullptr; @@ -51,10 +91,16 @@ std::unique_ptr MemoryMappedFile::InitWithFile( return std::unique_ptr( new MemoryMappedFile(file_map, statbuf.st_size)); +#endif } MemoryMappedFile::~MemoryMappedFile() { +#ifdef _WIN32 + if (data_) + UnmapViewOfFile(data_); +#else munmap(data_, size_); +#endif } } // namespace prjxray From 78019690be3a0792fd185ad7a1ec5feed43772ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Venegas=20Arrab=C3=A9?= Date: Thu, 30 Jul 2026 16:18:36 +0200 Subject: [PATCH 2/2] lib: Win32 port of the Database segbits enumeration lib/database.cc used glob(3) to enumerate segbits files, which is unavailable on Windows. Add an #ifdef _WIN32 branch using FindFirstFileA/FindNextFileA; the POSIX glob path is unchanged. --- lib/database.cc | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib/database.cc b/lib/database.cc index e9d767bf..defa3325 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -9,7 +9,11 @@ */ #include +#ifdef _WIN32 +#include +#else #include +#endif #include @@ -23,6 +27,25 @@ std::vector> Database::segbits() const { std::vector> segbits; +#ifdef _WIN32 + const std::string pattern = + absl::StrCat(db_path_, "/", kSegbitsGlobPattern); + WIN32_FIND_DATAA find_data; + HANDLE handle = FindFirstFileA(pattern.c_str(), &find_data); + if (handle == INVALID_HANDLE_VALUE) { + return {}; + } + + do { + auto this_segbit = SegbitsFileReader::InitWithFile( + absl::StrCat(db_path_, "/", find_data.cFileName)); + if (this_segbit) { + segbits.emplace_back(std::move(this_segbit)); + } + } while (FindNextFileA(handle, &find_data)); + + FindClose(handle); +#else glob_t segbits_glob_results; int ret = glob(absl::StrCat(db_path_, "/", kSegbitsGlobPattern).c_str(), GLOB_NOSORT | GLOB_TILDE, NULL, &segbits_glob_results); @@ -39,6 +62,7 @@ std::vector> Database::segbits() } globfree(&segbits_glob_results); +#endif return segbits; }