Update decompression support on Windows (#25185)
Most package installations include compressed source files. This adds support for common archive types on Windows: * Add support for using system 7zip functionality to decompress .Z files when available (and on Windows, use 7zip for .xz archives) * Default to using built-in Python support for tar/bz2 decompression (note that Python tar documentation mentions preservation of file permissions) * Add tests for decompression support * Extract logic for handling exploding archives (i.e. compressed archives that expand to more than one base file) into an exploding_archive_catch context manager in the filesystem module
This commit is contained in:
16
var/spack/repos/builtin/packages/7zip/noexcept_typedef.patch
Normal file
16
var/spack/repos/builtin/packages/7zip/noexcept_typedef.patch
Normal file
@@ -0,0 +1,16 @@
|
||||
diff --git a/CPP/7zip/UI/Common/Update.cpp b/CPP/7zip/UI/Common/Update.prev.cpp
|
||||
index 451b12c..3be3781 100644
|
||||
--- a/CPP/7zip/UI/Common/Update.cpp
|
||||
+++ b/CPP/7zip/UI/Common/Update.prev.cpp
|
||||
@@ -1075,11 +1075,7 @@ static HRESULT EnumerateInArchiveItems(
|
||||
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
|
||||
-#pragma push_macro("WIN_NOEXCEPT")
|
||||
-#undef WIN_NOEXCEPT
|
||||
-#define WIN_NOEXCEPT
|
||||
#include <MAPI.h>
|
||||
-#pragma pop_macro("WIN_NOEXCEPT")
|
||||
|
||||
#endif
|
||||
|
94
var/spack/repos/builtin/packages/7zip/package.py
Normal file
94
var/spack/repos/builtin/packages/7zip/package.py
Normal file
@@ -0,0 +1,94 @@
|
||||
# Copyright 2013-2022 Lawrence Livermore National Security, LLC and other
|
||||
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
|
||||
import glob
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import shutil
|
||||
|
||||
from spack.package import *
|
||||
|
||||
|
||||
class _7zip(SourceforgePackage, Package):
|
||||
"""7-Zip is a file archiver for Windows"""
|
||||
|
||||
homepage = "https://sourceforge.net/projects/sevenzip"
|
||||
sourceforge_mirror_path = 'sevenzip/files/7z2107-src.tar.xz'
|
||||
|
||||
executables = ['7z']
|
||||
|
||||
version('21.07', sha256='213d594407cb8efcba36610b152ca4921eda14163310b43903d13e68313e1e39')
|
||||
|
||||
variant('link_type', default='shared',
|
||||
description='build shared and/or static libraries',
|
||||
values=('static', 'shared'), multi=True)
|
||||
|
||||
phases = ['build', 'install']
|
||||
|
||||
conflicts('platform=linux')
|
||||
conflicts('platform=darwin')
|
||||
conflicts('platform=cray')
|
||||
|
||||
# TODO: Patch on WinSDK version 10.0.20348.0 when SDK is introduced to Spack
|
||||
# This patch solves a known bug in that SDK version on the 7zip side
|
||||
# right now patch for all versions to prevent build errors
|
||||
patch('noexcept_typedef.patch', when='platform=windows')
|
||||
|
||||
@classmethod
|
||||
def determine_version(cls, exe):
|
||||
output = Executable(exe)('--help', output=str, error=str)
|
||||
match = re.search(r'7-Zip ([0-9][0-9]*.[0-9][0-9])', output)
|
||||
return match.group(1) if match else None
|
||||
|
||||
def url_version(self, version):
|
||||
ver_str = str(version).replace('.', '')
|
||||
return '7z' + ver_str
|
||||
|
||||
@property
|
||||
def _7z_src_dir(self):
|
||||
return os.path.join(self.stage.source_path, 'CPP', '7zip')
|
||||
|
||||
@property
|
||||
def plat_arch(self):
|
||||
"""
|
||||
String referencing platform architecture
|
||||
filtered through 7zip's Windows build file
|
||||
"""
|
||||
arch = platform.machine()
|
||||
if arch.lower() == 'amd64':
|
||||
arch = 'x64'
|
||||
elif arch.lower() == 'i386':
|
||||
arch = 'x86'
|
||||
return arch
|
||||
|
||||
def is_64bit(self):
|
||||
return platform.machine().endswith('64')
|
||||
|
||||
def build(self, spec, prefix):
|
||||
link_type = '1' if 'static' in spec.variants['link_type'].value else '0'
|
||||
nmake_args = ['PLATFORM=%s' % self.plat_arch,
|
||||
'MY_STATIC_LINK=%s' % link_type,
|
||||
'NEW_COMPILER=1']
|
||||
# 7zips makefile is configured in such as way that if this value is set
|
||||
# compiler paths with spaces are incorrectly parsed. Compiler will be infered
|
||||
# from VCVARs on Windows
|
||||
os.environ.pop('CC', None)
|
||||
with working_dir(self._7z_src_dir):
|
||||
nmake(*nmake_args)
|
||||
|
||||
def install(self, spec, prefix):
|
||||
"""7Zip exports no install target so we must hand install"""
|
||||
arch_prefix = 'x64' if self.is_64bit() else 'x86'
|
||||
path_roots = ['Bundles', 'UI']
|
||||
exts = ['*.exe', '*.dll']
|
||||
with working_dir(self._7z_src_dir):
|
||||
for root in path_roots:
|
||||
pth = os.path.join(root, '*', arch_prefix)
|
||||
for ext in exts:
|
||||
glob_str = os.path.join(pth, ext)
|
||||
files = glob.glob(glob_str)
|
||||
[shutil.copy(os.path.join(self._7z_src_dir, x),
|
||||
os.path.join(prefix, os.path.basename(x))) for x in files]
|
Reference in New Issue
Block a user