Skip to content

Commit 6f01e94

Browse files
committed
Add consvar for TEMPFILE encoding
Alternate approach to avoid decoding problems: don't try to guess how to encode the TEMPFILE. Leave it utf-8 unless TEMPFILEENCODING is set. Add comment to TEMPFILEDIR doc on the topic as well. Signed-off-by: Mats Wichmann <mats@linux.com>
1 parent 654a26d commit 6f01e94

4 files changed

Lines changed: 48 additions & 14 deletions

File tree

CHANGES.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
8383
Windows 11 and GitHub windows-2025.
8484

8585
From William Deegan:
86-
- Fix Issue #4746. TEMPFILE's are written with utf-8 encoding, this doesn't work
87-
for all situations. Change to use locale.getpreferredencoding(False), which should
88-
yield the encoding for the system.
86+
- Fix Issue #4746. TEMPFILE's are written with utf-8 encoding, In case
87+
of decoding errors, TEMPFILEENCODING can now be specified to give
88+
more explicit instructions to SCons.
8989

9090
From Edward Peek:
9191
- Fix the variant dir component being missing from generated source file

RELEASE.txt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,13 @@ FIXES
7676
- Fix a test problem on Windows where UNC tests failed due to incorrect path
7777
munging if a non-default %TEMP% was defined (as in moving to a Dev Drive).
7878

79-
- Fix Issue #4746. TEMPFILE's are written with utf-8 encoding, this doesn't work
80-
for all situations. Change to use locale.getpreferredencoding(False), which should
81-
yield the encoding for the system.
79+
- Fix Issue #4746. The TEMPFILE is written in utf-8 encoding by default.
80+
If the tempfile contents cannot be decoded by the command the
81+
tempfile is passed to, (new) TEMPPFILEENCODING can be used to speficy a
82+
different encoding to use. On Windows, the username may be a cause of this,
83+
as the default path for temporary files includes the username. Setting
84+
(existing) TEMPFILEDIR may also help in this case.
85+
8286

8387
IMPROVEMENTS
8488
------------

SCons/Platform/Platform.xml

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -395,9 +395,18 @@ Note this value is used literally and not expanded by the subst logic.
395395
<summary>
396396
<para>
397397
The directory to create the long-lines temporary file in.
398-
If unset, some suitable default should be chosen.
399-
The default tempfile object lets the &Python;
400-
<systemitem>tempfile</systemitem> module choose.
398+
If unset, the &Python;
399+
<systemitem>tempfile</systemitem> module chooses the directory
400+
based on the <envar>TMPDIR</envar>,
401+
<envar>TEMP</envar>
402+
or <envar>TMP</envar> environment variables.
403+
If the default path causes processing errors,
404+
set &cv-TEMPFILEDIR; to a safer alternative.
405+
For example, on Windows,
406+
the default temporary file path contains the username.
407+
If the username contains non-7-bit-ASCII characters,
408+
there may decoding errors opening the path to the temporary file.
409+
See also &cv-link-TEMPFILEENCODING;.
401410
</para>
402411
</summary>
403412
</cvar>
@@ -411,8 +420,8 @@ If you need to apply extra operations on a command argument
411420
(to fix Windows slashes, normalize paths, etc.)
412421
before writing to the temporary file,
413422
you can set the &cv-TEMPFILEARGESCFUNC; variable to a custom function.
414-
Such a function takes a single string argument and returns
415-
a new string with any modifications applied.
423+
The function must accept a single string argument and
424+
and return a new string with any modifications applied.
416425
Example:
417426
</para>
418427

@@ -435,4 +444,21 @@ env["TEMPFILEARGESCFUNC"] = tempfile_arg_esc_func
435444
</summary>
436445
</cvar>
437446

447+
<cvar name="TEMPFILEENCODING">
448+
<summary>
449+
<para>
450+
By default, the long-lines temporary file (aka "response file") created by the
451+
&cv-link-env-TEMPFILE; function will be encoded in the &Python;
452+
default encoding, UTF-8.
453+
If the external command which reads the response file
454+
encounters decoding errors
455+
(usually, if that command depends on Windows legacy code pages,
456+
and a pathname in the response file
457+
or the response file path itself cannot
458+
be represented in the 7-bit ASCII characer set),
459+
set this variable to the appropriate codec.
460+
See also &cv-link-TEMPFILEDIR;.
461+
</para>
462+
<para><emphasis>New in version NEXT_RELEASE</emphasis></para>
463+
438464
</sconsdoc>

SCons/Platform/__init__.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,13 @@
4747
import os
4848
import sys
4949
import tempfile
50-
import locale
5150

51+
import SCons.Action
5252
import SCons.Errors
53+
import SCons.Platform
5354
import SCons.Subst
5455
import SCons.Tool
56+
import SCons.Util
5557

5658

5759
def platform_default():
@@ -257,7 +259,8 @@ def __call__(self, target, source, env, for_signature):
257259
else:
258260
tempfile_dir = None
259261

260-
fd, tmp = tempfile.mkstemp(suffix, dir=tempfile_dir, text=True)
262+
# default is binary - encode the tempfile contents later
263+
fd, tmp = tempfile.mkstemp(suffix, dir=tempfile_dir)
261264
native_tmp = SCons.Util.get_native_path(tmp)
262265

263266
# arrange for cleanup on exit:
@@ -280,7 +283,8 @@ def tmpfile_cleanup(file) -> None:
280283
tempfile_esc_func = env.get('TEMPFILEARGESCFUNC', SCons.Subst.quote_spaces)
281284
args = [tempfile_esc_func(arg) for arg in cmd[1:]]
282285
join_char = env.get('TEMPFILEARGJOIN', ' ')
283-
os.write(fd, bytearray(join_char.join(args) + "\n", encoding=locale.getpreferredencoding(False)))
286+
encoding = env.get('TEMPFILEENCODING', 'utf-8')
287+
os.write(fd, bytes(join_char.join(args) + "\n", encoding=encoding))
284288
os.close(fd)
285289

286290
# XXX Using the SCons.Action.print_actions value directly

0 commit comments

Comments
 (0)