Author: Andy Green Date: Fri Sep 11 05:19:33 2026 +0100 builder: windows: let spawned children inherit the builder's environment Since lws f92e831dd (C-328) the Windows spawn honours env_array as the child's entire environment, the way execve does. Before that it was silently ignored and children inherited the builder's environment. The builder hands every spawn its unix sanitizing set: a unix PATH, LANG and TERM, and nothing else. A Windows child given only that has no SystemRoot and none of the Visual Studio variables the service was started with, so after updating, every build died in cmake with "Running 'nmake' '-?' failed with: no such file or directory" and CMAKE_C_COMPILER not set. On Windows pass no env_array, so the child inherits ours as it always effectively did. Co-Authored-By: Claude Fable 5.1 diff --git a/src/builder/b-nspawn.c b/src/builder/b-nspawn.c index 9390658..e2d42a9 100644 --- a/src/builder/b-nspawn.c +++ b/src/builder/b-nspawn.c @@ -581,12 +581,14 @@ saib_spawn_script(struct sai_nspawn *ns) "/bin/ps", NULL }; +#if !defined(WIN32) const char *env[] = { "PATH=/usr/local/bin:/usr/bin:/bin", "LANG=en_US.UTF-8", "TERM=xterm-256color", NULL }; +#endif char one_step[4096]; char st[2048]; int fd, n; @@ -686,7 +688,18 @@ saib_spawn_script(struct sai_nspawn *ns) memset(&info, 0, sizeof(info)); info.vh = builder.vhost; +#if !defined(WIN32) info.env_array = (const char **)env; +#else + /* + * Since lws C-328 (f92e831dd) the Windows spawn honours env_array as + * the child's entire environment, as execve does; before it was + * ignored and the child inherited ours. The sanitizing set above is + * a unix PATH with no SystemRoot or Visual Studio variables, so a + * child given it cannot even find nmake or cl. Inherit instead. + */ + info.env_array = NULL; +#endif info.exec_array = cmd; info.protocol_name = "sai-stdxxx"; info.max_log_lines = 10000; @@ -866,12 +879,14 @@ saib_shell_spawn(struct sai_plat_server *spm, const char *task_uuid) struct lws_spawn_piped_info info; struct sai_shell *sh; const char *cmd[] = { "/bin/bash", "-i", NULL }; +#if !defined(WIN32) const char *env[] = { "PATH=/usr/local/bin:/usr/bin:/bin", "LANG=en_US.UTF-8", "TERM=xterm-256color", NULL }; +#endif sh = malloc(sizeof(*sh)); if (!sh) @@ -883,7 +898,18 @@ saib_shell_spawn(struct sai_plat_server *spm, const char *task_uuid) memset(&info, 0, sizeof(info)); info.vh = builder.vhost; +#if !defined(WIN32) info.env_array = (const char **)env; +#else + /* + * Since lws C-328 (f92e831dd) the Windows spawn honours env_array as + * the child's entire environment, as execve does; before it was + * ignored and the child inherited ours. The sanitizing set above is + * a unix PATH with no SystemRoot or Visual Studio variables, so a + * child given it cannot even find nmake or cl. Inherit instead. + */ + info.env_array = NULL; +#endif info.exec_array = cmd; info.protocol_name = "sai-saishell"; info.max_log_lines = 10000;