Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
- Testing: Increase the default timeout from 20 seconds to 60
seconds in the testing framework wait_for method. At present, the
wait_for method is only used for the interactive tests.
- GitHub: Remove the packaging tar xz test from the windows ci skip file.
- Testing: Update the packaging tar bz2 and xz tests on on Windows.
Detect if the tar bz2 and xz formats are supported for the windows
system tar executable using the reported version string. The packaging
tar bz2 and xz tests should be skipped on Windows 10 and GitHub
windows-2022. The packaging tar bz2 and xz tests should be run on
Windows 11 and GitHub windows-2025.

From Edward Peek:
- Fix the variant dir component being missing from generated source file
Expand Down
7 changes: 7 additions & 0 deletions RELEASE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ DEVELOPMENT

- GitHub: Enable the interactive tests on windows.

- GitHub: Enable the packaging tar xz test on windows.

- GitHub: Exclude two ninja tests that consistently fail on MacOS in
the experimental tests workflow.

Expand All @@ -165,6 +167,11 @@ DEVELOPMENT
in the testing framework wait_for method. The timeout was increased
during isolated experiments of the interactive tests on windows.

- Testing: Update the packaging tar bz2 and xz tests on on Windows.
The packaging tar bz2 and xz tests should be skipped on Windows 10
and GitHub windows-2022. The packaging tar bz2 and xz tests should
be run on Windows 11 and GitHub windows-2025.

- Ninja: Increase the number of generated source files in the
iterative speedup test from 200 to 250. Increasing the workload
should reduce the likelihood that the ninja tests are slower.
Expand Down
83 changes: 68 additions & 15 deletions test/packaging/tar/bz2_packaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

import os
import os.path
import subprocess
import sys

python = TestSCons.python
Expand All @@ -43,20 +44,75 @@
if not tar:
test.skip_test('tar not found, skipping test\n')

bz2 = test.where_is('bzip2')

if sys.platform == 'win32':
# windows 10 causes fresh problems by supplying a tar, not bzip2

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you ignoring the git tar? Which could be used in the case where the windows tar doesn't support bz2?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It shouldn't.

When either os.environ["SystemRoot"] or os.environ["windir"] is defined:

  • The test is performed if the tar.exe is not %SystemRoot%/system32/tar.exe.
  • The test may be performed if the tar.exe is %SystemRoot%/system32/tar.exe subject to the version string check.

One of these two environment variables should be defined.

If neither variables are defined, then the "--version" string is inspected for bsdtar, - libarchive and other fields. If there is not a match for the known fields, then the test is performed.

It should be unlikely that a bsdtar executable is used when the two Windows system environment variables are undefined.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which could be used in the case where the windows tar doesn't support bz2?

The test, as written prior to changes, only checks the first tar executable found on the path.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Locally annotated change (not pushed yet)

        windir = os.environ.get("SystemRoot")
        if not windir:
            windir = os.environ.get("windir")
        if not windir:  # <== ADDED
            windir = os.path.join(os.environ.get("SystemDrive", "C:") + os.path.sep, "Windows")  # <== ADDED
        expected = os.path.normcase(os.path.abspath(os.path.join(windir, "System32", "tar.exe")))
        if tar != expected:
            return False

Additional clause added to always test the target executable path against what should be the windows system32 path.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't windir always defined on windows?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be.

Depends on your level of paranoia:

(3.12.9) S:\SCons\Test-WinSkip>type test-env.bat
@setlocal
@python -c "import os; print([os.environ.get(var) for var in ['SystemDrive', 'SystemRoot', 'windir']])"
@set SystemDrive=
@set SystemRoot=
@set windir=
@python -c "import os; print([os.environ.get(var) for var in ['SystemDrive', 'SystemRoot', 'windir']])"
@endlocal

(3.12.9) S:\SCons\Test-WinSkip>test-env
['C:', 'C:\\Windows', 'C:\\Windows']
[None, None, None]

# but if git is installed, there's a bzip2 there, but can't be used
if not bz2:
test.skip_test('tar found, but helper bzip2 not found, skipping test\n')
bz2 = os.path.splitdrive(bz2)[1]
tar = os.path.splitdrive(test.where_is('tar'))[1]
if tar[:8] != bz2[:8]: # catch one in \WINDOWS, one not
test.skip_test('tar found, but usable bzip2 not, skipping test\n')

bz2_path = os.path.dirname(bz2)
# Windows 10 and later supplies windows/system32/tar.exe (bsdtar).
# Not all versions support bz2 compression. Check the version string
# for bz2lib support.

def windows_system32_bsdtar_have_bz2(tar):

# Don't skip test if not confident this is the windows/system32/tar.exe (bsdtar).

tar = os.path.normcase(os.path.abspath(tar))

# windows tar.exe:
# %systemroot%/system32/tar.exe

windir = os.environ.get("SystemRoot")
if not windir:
windir = os.environ.get("windir")
if windir:
expected = os.path.normcase(os.path.abspath(os.path.join(windir, "System32", "tar.exe")))
if tar != expected:
return False

try:
result = subprocess.run([f"{tar}", "--version"], capture_output=True, text=True, check=True)
version_str = result.stdout.strip()
except:
version_str = None

if not version_str:
return False

# print(f"{tar} --version => {version_str!r}")

# tar.exe --version (Windows 10, GH windows-2022):
# bsdtar 3.5.2 - libarchive 3.5.2 zlib/1.2.5.f-ipp

# tar.exe --version (Windows 11):
# bsdtar 3.7.7 - libarchive 3.7.7 zlib/1.2.5.f-ipp liblzma/5.4.3 bz2lib/1.0.8 libzstd/1.5.4

# tar.exe --version (GH windows-2025):
# bsdtar 3.7.7 - libarchive 3.7.7 zlib/1.2.13.1-motley liblzma/5.4.3 bz2lib/1.0.8 libzstd/1.5.5

version_comps = version_str.split()
if len(version_comps) < 5:
return False

for indx, expected in [
(0, "bsdtar"), (2, "-"), (3, "libarchive"),
]:
if version_comps[indx].lower() != expected:
return False

# Reasonably confident this is the windows/system32/tar.exe (bsdtar).

# bsdtar_version = version_comps[1]
# libarchive_version = version_comps[4]

for component in version_comps[5:]:
if component.lower().startswith("bz2lib/"):
# Don't skip test: bz2/bz2lib appears to be supported.
return False

# Skip test: bz2/bz2lib appears to be unsupported.
return True

skip_test = windows_system32_bsdtar_have_bz2(tar)
if skip_test:
test.skip_test('windows tar found; bz2 not supported, skipping test\n')

test.subdir('src')

Expand All @@ -71,14 +127,11 @@
Program( 'src/main.c' )
env=Environment(tools=['packaging', 'filesystem', 'tar'])

# needed for windows to prevent picking up windows tar and thinking non-windows bzip2 would work.
env.PrependENVPath('PATH', r'%s')

env.Package( PACKAGETYPE = 'src_tarbz2',
target = 'src.tar.bz2',
PACKAGEROOT = 'test',
source = [ 'src/main.c', 'SConstruct' ] )
"""%bz2_path)
""")

test.run(arguments='', stderr=None)

Expand Down
83 changes: 72 additions & 11 deletions test/packaging/tar/xz_packaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@
This tests the SRC xz packager, which does the following:
- create a tar package from the specified files
"""
import os
import os.path
import subprocess
import sys
import TestSCons

python = TestSCons.python
Expand All @@ -38,14 +41,75 @@
if not tar:
test.skip_test('tar not found, skipping test\n')

# Windows 10 now supplies tar, but doesn't support xz compression
# assume it's just okay to check for an xz command, because don't
# want to probe the command itself to see what it supports
xz = test.where_is('xz')
if not xz:
test.skip_test('tar found, but helper xz not found, skipping test\n')
if sys.platform == 'win32':

xz_path = os.path.dirname(xz)
# Windows 10 and later supplies windows/system32/tar.exe (bsdtar).
# Not all versions support xz compression. Check the version string

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probable makes sense to move this logic into TestSCons?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After copy/pasting/modifying from the xz source code it seemed like it would be a good idea to have only one parameterized implementation.

Wasn't sure where or what name to use.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to move common windows system tar code in bz2 and xz scripts to a private common module in the packaging/tar folder.

It should be easier now to move somewhere else if desired. At present, only used in two places.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well that didn't work as I had hoped. The source file test/packaging/tar/_windows_tar.py was "run" as a test (which passes) which is undesirable.

Seems unfortunate to have to add to TestSCons for two tests.

@bdbaddog bdbaddog Jul 6, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

# for liblzma support.

def windows_system32_bsdtar_have_xz(tar):

# Don't skip test if not confident this is the windows/system32/tar.exe (bsdtar).

tar = os.path.normcase(os.path.abspath(tar))

# windows tar.exe:
# %systemroot%/system32/tar.exe

windir = os.environ.get("SystemRoot")
if not windir:
windir = os.environ.get("windir")
if windir:
expected = os.path.normcase(os.path.abspath(os.path.join(windir, "System32", "tar.exe")))
if tar != expected:
return False

try:
result = subprocess.run([f"{tar}", "--version"], capture_output=True, text=True, check=True)
version_str = result.stdout.strip()
except:
version_str = None

if not version_str:
return False

# print(f"{tar} --version => {version_str!r}")

# tar.exe --version (Windows 10, GH windows-2022):
# bsdtar 3.5.2 - libarchive 3.5.2 zlib/1.2.5.f-ipp

# tar.exe --version (Windows 11):
# bsdtar 3.7.7 - libarchive 3.7.7 zlib/1.2.5.f-ipp liblzma/5.4.3 bz2lib/1.0.8 libzstd/1.5.4

# tar.exe --version (GH windows-2025):
# bsdtar 3.7.7 - libarchive 3.7.7 zlib/1.2.13.1-motley liblzma/5.4.3 bz2lib/1.0.8 libzstd/1.5.5

version_comps = version_str.split()
if len(version_comps) < 5:
return False

for indx, expected in [
(0, "bsdtar"), (2, "-"), (3, "libarchive"),
]:
if version_comps[indx].lower() != expected:
return False

# Reasonably confident this is the windows/system32/tar.exe (bsdtar).

# bsdtar_version = version_comps[1]
# libarchive_version = version_comps[4]

for component in version_comps[5:]:
if component.lower().startswith("liblzma/"):
# Don't skip test: xz/liblzma appears to be supported.
return False

# Skip test: xz/liblzma appears to be unsupported.
return True

skip_test = windows_system32_bsdtar_have_xz(tar)
if skip_test:
test.skip_test('windows tar found; xz not supported, skipping test\n')

test.subdir('src')

Expand All @@ -60,14 +124,11 @@
Program( 'src/main.c' )
env=Environment(tools=['packaging', 'filesystem', 'tar'])

# needed for windows to prevent picking up windows tar and thinking non-windows bzip2 would work.
env.PrependENVPath('PATH', r'%s')

env.Package( PACKAGETYPE = 'src_tarxz',
target = 'src.tar.xz',
PACKAGEROOT = 'test',
source = [ 'src/main.c', 'SConstruct' ] )
"""%xz_path)
""")

test.run(arguments='', stderr=None)

Expand Down
1 change: 0 additions & 1 deletion testing/ci/windows_ci_skip.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ test/CPPDEFINES/pkg-config.py
test/packaging/msi/explicit-target.py
test/packaging/msi/file-placement.py
test/packaging/msi/package.py
test/packaging/tar/xz_packaging.py
test/scons-time/run/config/python.py
test/scons-time/run/option/python.py
test/sconsign/script/no-SConsignFile.py
Expand Down