2 Commits
Author SHA1 Message Date
Alexander Medvednikov ebec02a8aa windows: preserve external executable manifests (#31012) 2026-10-23 10:18:49 +03:00
768cdd695c windows: long paths in the build pipeline; fix the GetTempPathW hang on long TMP (#30777)
* 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>
2026-10-18 01:28:12 +03:00