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/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.
prjxray/util.py imported fcntl at module level, so merely importing
prjxray (e.g. from fasm2frames) failed on Windows, where fcntl does
not exist. The only user is OpenSafeFile's advisory flock, whose
timeout also relies on SIGALRM — equally POSIX-only.
Guard the import and skip the locking when fcntl is unavailable:
OpenSafeFile degrades to a plain open on Windows, while POSIX
behaviour is unchanged.
The temporary bits file was created with NamedTemporaryFile() and kept
open while the bitread subprocess wrote to it by name. On Windows that
is a sharing violation (the open handle blocks the child's write), so
bit2fasm always failed there. Create the file with delete=False, close
it immediately, and unlink it via the ExitStack instead.
No behaviour change on POSIX beyond the file being closed while
bitread runs.
The fn_out argument defaulted to the literal path '/dev/stdout', which
does not exist on Windows, so running fasm2frames without an output
file (the common shell-redirect invocation) failed there. Default to
None and fall back to sys.stdout.
configuration.cc explicitly specializes
Configuration<Spartan6>::createType2ConfigurationPacketData and
Configuration<...>::createConfigurationPackage (Spartan6, Series7,
UltraScale, UltraScalePlus), but none of those specializations were
declared in configuration.h. The standard requires an explicit
specialization to be declared in every translation unit that uses it
([temp.expl.spec]); without the declaration, a TU calling
createType2ConfigurationPacketData for Spartan6 instantiates the
primary template — which is defined in this header — and emits its own
COMDAT copy of the symbol.
That copy collides with the strong definition from configuration.cc
when linking xc7frames2bit/xc7patch with mingw-w64 ld ("multiple
definition of ...createType2ConfigurationPacketData..."), which is why
Windows builds needed -Wl,--allow-multiple-definition. ELF linkers
happen to resolve the collision silently in favour of the strong
symbol, so Linux builds never noticed.
Declare all five specializations in the header so every user
references the single definition in configuration.cc. Verified with a
mingw-w64 cross build: the tools now link without the workaround
linker flag. No behaviour change on ELF.