* windows: let V executables use paths past MAX_PATH
- Link a longPathAware manifest into Windows executables built with GCC or Clang
(skipped for tcc and MSVC; needs windres, otherwise the build continues without it).
- os.exists uses GetFileAttributesW: the CRT's _waccess cannot see long paths.
- Launch executables and working folders past MAX_PATH with the \\?\ prefix, and
let os.Process pass a \\?\ path to CreateProcessW unchanged.
- literal_output_gc_test: retry removing its root on Windows, because a just-run
executable can stay locked for a moment.
Not done: tcc.exe is not long-path aware, so tcc builds still fail past MAX_PATH.
Some \\?\ prefixes may now be redundant; not yet separated by test.
Co-Authored-By: WOZCODE <contact@withwoz.com>
* os: keep TMP/TEMP short enough for GetTempPathW on Windows
In a longPathAware process, GetTempPathW retries forever with a buffer
that stays one character too small once TMP (or TEMP/USERPROFILE, when
TMP is unset) is 261+ characters. CreateProcessW calls it for every
program it starts, so os.exec, os.Process, os.system and friends hang
at 100% CPU. GCC and llvm-mingw builds declare longPathAware, as does
cmd.exe, so a long TMP hangs V programs that start any child process.
Before each launch on Windows (os.exec/execute, os.Process, os.system,
popen, execvp/execve, open_uri), shorten the first temp variable that
GetTempPathW reads when it is too long: the folder's 8.3 short name,
else %LOCALAPPDATA%\Temp, else %SystemRoot%\Temp. An explicit child
environment (os.Process.env, execve envs) gets the same fix. Children
inherit the short value.
Tests: the platform-independent rule (boundary 260/261, UTF-16 length,
variable order, case-insensitive entries); the process environment
rewrite; and a regression test that runs a longPathAware helper with a
303-character TMP under a 30 s deadline (it hangs with the guard
disabled, passes in seconds with it).
Co-Authored-By: WOZCODE <contact@withwoz.com>
* driver: add the long-path manifest after linking; per-user short build root
Rework of 3c647c836c after an adversarial review:
- The longPathAware manifest is no longer a windres object linked into the
executable. On a Windows host it is added after linking with
UpdateResourceW, the way -icon adds an icon, and only when the executable
has no manifest yet. That needs no windres, cannot clash with a user's own
resource object under tcc ('__start_rsrc' defined twice), cannot duplicate
MinGW GCC's default manifest (which already declares longPathAware), and
works for every target architecture. tcc and llvm-mingw clang builds now
get it; GCC builds keep their own.
- MSVC builds stay without it: they load dbghelp.dll at startup, and its
DllMain calls GetTempPath2W, which loops forever on a TMP past MAX_PATH
in a longPathAware process before any V code can shorten it.
- Long build directories (240+ characters) move to %LOCALAPPDATA%\v3cc
instead of the shared %SystemDrive%\v3cc, under a 16-hex digest name, and
only when that makes them short enough. The C build directory stays put
when a C or linker flag holds a relative path that leaves it.
- cmdexec's \\?\ form: UNC paths use \\?\UNC\, paths that are not fully
qualified are left alone, `.` and `..` are resolved first, and the length
is counted in UTF-16 units.
- The long-path launch test skips when the test binary is not
longPathAware; new tests cover the 239/240 boundary, the per-user root,
the digest names, the manifest being added once and an existing manifest
being kept.
Co-Authored-By: WOZCODE <contact@withwoz.com>
* doc: document long paths on Windows
New doc/windows_long_paths.md, linked from README.md: which executables get
the longPathAware manifest (and why MSVC, -b fastc, shared libraries and
cross builds do not), the TMP/TEMP guard before launching programs, and
where long build directories move.
Co-Authored-By: WOZCODE <contact@withwoz.com>
---------
Co-authored-by: Richard Wheeler <18647491+PythonWillRule@users.noreply.github.com>
Co-authored-by: WOZCODE <contact@withwoz.com>