summaryrefslogtreecommitdiff
path: root/var
diff options
context:
space:
mode:
Diffstat (limited to 'var')
-rw-r--r--var/spack/repos/builtin.mock/packages/ninja/package.py15
-rw-r--r--var/spack/repos/builtin/packages/cmake/package.py127
-rw-r--r--var/spack/repos/builtin/packages/nasm/msvc.mak.patch18
-rw-r--r--var/spack/repos/builtin/packages/nasm/package.py33
-rw-r--r--var/spack/repos/builtin/packages/netlib-lapack/package.py1
-rw-r--r--var/spack/repos/builtin/packages/openssl/package.py5
-rw-r--r--var/spack/repos/builtin/packages/perl/package.py107
-rw-r--r--var/spack/repos/builtin/packages/python/cpython-windows-externals.patch28
-rw-r--r--var/spack/repos/builtin/packages/python/package.py233
-rw-r--r--var/spack/repos/builtin/packages/ruby/package.py61
-rw-r--r--var/spack/repos/builtin/packages/zlib/package.py60
11 files changed, 549 insertions, 139 deletions
diff --git a/var/spack/repos/builtin.mock/packages/ninja/package.py b/var/spack/repos/builtin.mock/packages/ninja/package.py
new file mode 100644
index 0000000000..3ed308b3c0
--- /dev/null
+++ b/var/spack/repos/builtin.mock/packages/ninja/package.py
@@ -0,0 +1,15 @@
+# Copyright 2013-2021 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)
+
+from spack import *
+
+
+class Ninja(Package):
+ """Dummy Ninja Package"""
+
+ homepage = "https://ninja-build.org/"
+ url = "https://github.com/ninja-build/ninja/archive/v1.7.2.tar.gz"
+
+ version('1.10.2', sha256='ce35865411f0490368a8fc383f29071de6690cbadc27704734978221f25e2bed')
diff --git a/var/spack/repos/builtin/packages/cmake/package.py b/var/spack/repos/builtin/packages/cmake/package.py
index e91b6eacdc..e431dc62e5 100644
--- a/var/spack/repos/builtin/packages/cmake/package.py
+++ b/var/spack/repos/builtin/packages/cmake/package.py
@@ -3,9 +3,13 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+import os
import re
+import shutil
+import sys
import spack.build_environment
+from spack import *
class Cmake(Package):
@@ -141,6 +145,12 @@ class Cmake(Package):
# https://gitlab.kitware.com/cmake/cmake/merge_requests/4075
patch('fix-xlf-ninja-mr-4075.patch', sha256="42d8b2163a2f37a745800ec13a96c08a3a20d5e67af51031e51f63313d0dedd1", when="@3.15.5")
+ generator = "Unix Makefiles"
+
+ if sys.platform == 'win32':
+ generator = "Ninja"
+ depends_on('ninja')
+
# We default ownlibs to true because it greatly speeds up the CMake
# build, and CMake is built frequently. Also, CMake is almost always
# a build dependency, and its libs will not interfere with others in
@@ -149,7 +159,7 @@ class Cmake(Package):
variant('qt', default=False, description='Enables the build of cmake-gui')
variant('doc', default=False, description='Enables the generation of html and man page documentation')
variant('openssl', default=True, description="Enable openssl for curl bootstrapped by CMake when using +ownlibs")
- variant('ncurses', default=True, description='Enables the build of the ncurses gui')
+ variant('ncurses', default=os.name != 'nt', description='Enables the build of the ncurses gui')
# See https://gitlab.kitware.com/cmake/cmake/-/issues/21135
conflicts('%gcc platform=darwin', when='@:3.17',
@@ -241,36 +251,47 @@ class Cmake(Package):
flags.append(self.compiler.cxx11_flag)
return (flags, None, None)
- def bootstrap_args(self):
+ def setup_build_environment(self, env):
spec = self.spec
- args = [
- '--prefix={0}'.format(self.prefix),
- '--parallel={0}'.format(make_jobs)
- ]
+ if '+openssl' in spec:
+ env.set('OPENSSL_ROOT_DIR', spec['openssl'].prefix)
- if '+ownlibs' in spec:
- # Build and link to the CMake-provided third-party libraries
- args.append('--no-system-libs')
- else:
- # Build and link to the Spack-installed third-party libraries
- args.append('--system-libs')
-
- if spec.satisfies('@3.2:'):
- # jsoncpp requires CMake to build
- # use CMake-provided library to avoid circular dependency
- args.append('--no-system-jsoncpp')
-
- if '+qt' in spec:
- args.append('--qt-gui')
+ def bootstrap_args(self):
+ spec = self.spec
+ args = []
+ if not os.name == 'nt':
+ args.extend(
+ ['--prefix={0}'.format(self.prefix),
+ '--parallel={0}'.format(make_jobs)]
+ )
+
+ if '+ownlibs' in spec:
+ # Build and link to the CMake-provided third-party libraries
+ args.append('--no-system-libs')
+ else:
+ # Build and link to the Spack-installed third-party libraries
+ args.append('--system-libs')
+
+ if spec.satisfies('@3.2:'):
+ # jsoncpp requires CMake to build
+ # use CMake-provided library to avoid circular dependency
+ args.append('--no-system-jsoncpp')
+
+ if '+qt' in spec:
+ args.append('--qt-gui')
+ else:
+ args.append('--no-qt-gui')
+
+ if '+doc' in spec:
+ args.append('--sphinx-html')
+ args.append('--sphinx-man')
+
+ # Now for CMake arguments to pass after the initial bootstrap
+ args.append('--')
else:
- args.append('--no-qt-gui')
-
- if '+doc' in spec:
- args.append('--sphinx-html')
- args.append('--sphinx-man')
-
- # Now for CMake arguments to pass after the initial bootstrap
- args.append('--')
+ args.append('-DCMAKE_INSTALL_PREFIX=%s' % self.prefix)
+ if self.spec.satisfies('generator=Ninja'):
+ args.append('-GNinja')
args.append('-DCMAKE_BUILD_TYPE={0}'.format(
self.spec.variants['build_type'].value))
@@ -297,21 +318,61 @@ class Cmake(Package):
return args
+ def winbootcmake(self, spec):
+ from spack import fetch_strategy, stage
+ urls = {
+ '3': ('https://cmake.org/files/v3.21/cmake-3.21.2-windows-x86_64.zip', "f21e72ede9d15070602b60b2c14dc779"),
+ '2': ('https://cmake.org/files/v2.8/cmake-2.8.4-win32-x86.zip', "a2525342e495518101381203bf4484c4")
+ }
+ if spec.satisfies('@3.0.2:'):
+ bootstrap_url = urls['3']
+ else:
+ bootstrap_url = urls['2']
+ remote = fetch_strategy.URLFetchStrategy(url=bootstrap_url[0],
+ checksum=bootstrap_url[1])
+ bootstrap_stage_path = os.path.join(self.stage.path, "cmake-bootstraper")
+ with stage.Stage(remote, path=bootstrap_stage_path) as bootstrap_stage:
+ remote.stage = bootstrap_stage
+ remote.fetch()
+ remote.check()
+ remote.expand()
+ shutil.move(bootstrap_stage.source_path, self.stage.source_path)
+
+ def cmake_bootstrap(self):
+ exe_prefix = self.stage.source_path
+ relative_cmake_exe = os.path.join('spack-src', 'bin', 'cmake.exe')
+ return Executable(os.path.join(exe_prefix, relative_cmake_exe))
+
def bootstrap(self, spec, prefix):
- bootstrap = Executable('./bootstrap')
- bootstrap(*self.bootstrap_args())
+ bootstrap_args = self.bootstrap_args()
+ if os.name == 'nt':
+ self.winbootcmake(spec)
+ bootstrap = self.cmake_bootstrap()
+ bootstrap_args.extend(['.'])
+ else:
+ bootstrap = Executable('./bootstrap')
+ bootstrap(*bootstrap_args)
def build(self, spec, prefix):
- make()
+ if self.generator == "Ninja":
+ ninja()
+ else:
+ make()
@run_after('build')
@on_package_attributes(run_tests=True)
def build_test(self):
# Some tests fail, takes forever
- make('test')
+ if self.generator == "Ninja":
+ ninja('test')
+ else:
+ make('test')
def install(self, spec, prefix):
- make('install')
+ if self.generator == "Ninja":
+ ninja('install')
+ else:
+ make('install')
if spec.satisfies('%fj'):
for f in find(self.prefix, 'FindMPI.cmake', recursive=True):
diff --git a/var/spack/repos/builtin/packages/nasm/msvc.mak.patch b/var/spack/repos/builtin/packages/nasm/msvc.mak.patch
new file mode 100644
index 0000000000..cfc751c8cf
--- /dev/null
+++ b/var/spack/repos/builtin/packages/nasm/msvc.mak.patch
@@ -0,0 +1,18 @@
+diff --git a/Mkfiles/msvc.mak b/Mkfiles/msvc1.mak
+index 4f6121f..f0e6f4b 100644
+--- a/Mkfiles/msvc.mak
++++ b/Mkfiles/msvc1.mak
+@@ -228,10 +228,10 @@ WARNFILES = asm\warnings.c include\warnings.h doc\warnings.src
+
+ warnings:
+ $(RM_F) $(WARNFILES)
+- $(MAKE) asm\warnings.time
++# $(MAKE) asm\warnings.time
+
+-asm\warnings.time: $(ALLOBJ:.@OBJEXT@=.c)
+- : > asm\warnings.time
++# asm\warnings.time: $(ALLOBJ:.@OBJEXT@=.c)
++# : > asm\warnings.time
+ $(MAKE) $(WARNFILES)
+
+ asm\warnings.c: asm\warnings.pl asm\warnings.time
diff --git a/var/spack/repos/builtin/packages/nasm/package.py b/var/spack/repos/builtin/packages/nasm/package.py
index 2f0c747a52..6bfa36a660 100644
--- a/var/spack/repos/builtin/packages/nasm/package.py
+++ b/var/spack/repos/builtin/packages/nasm/package.py
@@ -5,17 +5,20 @@
from spack import *
+is_windows = str(spack.platforms.host()) == 'windows'
-class Nasm(AutotoolsPackage):
+
+class Nasm(Package):
"""NASM (Netwide Assembler) is an 80x86 assembler designed for
portability and modularity. It includes a disassembler as well."""
homepage = "https://www.nasm.us"
- url = "https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.xz"
+ url = "https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.gz"
list_url = "https://www.nasm.us/pub/nasm/releasebuilds"
list_depth = 1
+ a = '3caf6729c1073bf96629b57cee31eeb54f4f8129b01902c73428836550b30a3f'
- version('2.15.05', sha256='3caf6729c1073bf96629b57cee31eeb54f4f8129b01902c73428836550b30a3f')
+ version('2.15.05', sha256='9182a118244b058651c576baa9d0366ee05983c4d4ae1d9ddd3236a9f2304997')
version('2.14.02', sha256='e24ade3e928f7253aa8c14aa44726d1edf3f98643f87c9d72ec1df44b26be8f5')
version('2.13.03', sha256='812ecfb0dcbc5bd409aaa8f61c7de94c5b8752a7b00c632883d15b2ed6452573')
version('2.11.06', sha256='90f60d95a15b8a54bf34d87b9be53da89ee3d6213ea739fb2305846f4585868a')
@@ -24,9 +27,13 @@ class Nasm(AutotoolsPackage):
# https://bugzilla.nasm.us/show_bug.cgi?id=3392461
patch('https://src.fedoraproject.org/rpms/nasm/raw/0cc3eb244bd971df81a7f02bc12c5ec259e1a5d6/f/0001-Remove-invalid-pure_func-qualifiers.patch', level=1, sha256='ac9f315d204afa6b99ceefa1fe46d4eed2b8a23c7315d32d33c0f378d930e950', when='@2.13.03 %gcc@8:')
+ patch('msvc.mak.patch', when='platform=windows')
+
conflicts('%intel@:14', when='@2.14:',
msg="Intel 14 has immature C11 support")
+ phases = ['configure', 'build', 'install']
+
def patch(self):
# Remove flags not recognized by the NVIDIA compiler
if self.spec.satisfies('%nvhpc@:20.11'):
@@ -34,3 +41,23 @@ class Nasm(AutotoolsPackage):
'CFLAGS="$pa_add_cflags__old_cflags"', 'configure')
filter_file(r'CFLAGS="\$pa_add_flags__old_flags -Werror=.*"',
'CFLAGS="$pa_add_flags__old_flags"', 'configure')
+
+ def configure(self, spec, prefix):
+ with working_dir(self.stage.source_path, create=True):
+ if not is_windows:
+ configure(['--prefix={0}'.format(self.prefix)])
+
+ def build(self, spec, prefix):
+ with working_dir(self.stage.source_path):
+ if is_windows:
+ touch('asm\\warnings.time')
+ nmake('/f', 'Mkfiles\\msvc.mak')
+ else:
+ make(['V=1'])
+
+ def install(self, spec, prefix):
+ with working_dir(self.stage.source_path):
+ if is_windows:
+ pass
+ else:
+ make(['install'])
diff --git a/var/spack/repos/builtin/packages/netlib-lapack/package.py b/var/spack/repos/builtin/packages/netlib-lapack/package.py
index 5d527fedec..82af36426d 100644
--- a/var/spack/repos/builtin/packages/netlib-lapack/package.py
+++ b/var/spack/repos/builtin/packages/netlib-lapack/package.py
@@ -71,7 +71,6 @@ class NetlibLapack(CMakePackage):
depends_on('blas', when='+external-blas')
depends_on('netlib-xblas+fortran+plain_blas', when='+xblas')
depends_on('python@2.7:', type='test')
- depends_on('ninja@1.10.0:', when='platform=windows')
# We need to run every phase twice in order to get static and shared
# versions of the libraries. When ~shared, we run the default
diff --git a/var/spack/repos/builtin/packages/openssl/package.py b/var/spack/repos/builtin/packages/openssl/package.py
index f21b6b81a8..f57a65271a 100644
--- a/var/spack/repos/builtin/packages/openssl/package.py
+++ b/var/spack/repos/builtin/packages/openssl/package.py
@@ -5,6 +5,7 @@
import os
import re
+import sys
import llnl.util.tty as tty
@@ -96,6 +97,8 @@ class Openssl(Package): # Uses Fake Autotools, should subclass Package
depends_on('perl@5.14.0:', type=('build', 'test'))
depends_on('ca-certificates-mozilla', type=('build', 'run'), when='certs=mozilla')
+ conflicts('+dynamic', when=sys.platform != 'win32')
+
@classmethod
def determine_version(cls, exe):
output = Executable(exe)('version', output=str, error=str)
@@ -151,7 +154,7 @@ class Openssl(Package): # Uses Fake Autotools, should subclass Package
'CC=\"%s\"' % os.environ.get('SPACK_CC'),
'CXX=\"%s\"' % os.environ.get('SPACK_CXX'),
'%s' % shared_flag,
- 'VC-WIN64A')
+ 'VC-WIN64A', ignore_quotes=True)
else:
config = Executable('./config')
config('--prefix=%s' % prefix,
diff --git a/var/spack/repos/builtin/packages/perl/package.py b/var/spack/repos/builtin/packages/perl/package.py
index 0d666b41d3..714c7e3a7b 100644
--- a/var/spack/repos/builtin/packages/perl/package.py
+++ b/var/spack/repos/builtin/packages/perl/package.py
@@ -11,15 +11,20 @@
# Author: Justin Too <justin@doubleotoo.com>
# Date: September 6, 2015
#
+
import os
import re
from contextlib import contextmanager
from llnl.util.lang import match_predicate
+from llnl.util.symlink import symlink
from spack import *
from spack.operating_systems.mac_os import macos_version
+host = spack.platforms.host()
+is_windows = str(host) == 'windows'
+
class Perl(Package): # Perl doesn't use Autotools, it should subclass Package
"""Perl 5 is a highly capable, feature-rich programming language with over
@@ -64,15 +69,16 @@ class Perl(Package): # Perl doesn't use Autotools, it should subclass Package
extendable = True
- # Bind us below gdbm-1.20 due to API change: https://github.com/Perl/perl5/issues/18915
- depends_on('gdbm@:1.19')
- # :5.28 needs gdbm@:1:14.1: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=133295
- depends_on('gdbm@:1.14.1', when='@:5.28.0')
- depends_on('berkeley-db')
- depends_on('bzip2')
- depends_on('zlib')
- # :5.24.1 needs zlib@:1.2.8: https://rt.cpan.org/Public/Bug/Display.html?id=120134
- depends_on('zlib@:1.2.8', when='@5.20.3:5.24.1')
+ if not is_windows:
+ # Bind us below gdbm-1.20 due to API change: https://github.com/Perl/perl5/issues/18915
+ depends_on('gdbm@:1.19')
+ # :5.28 needs gdbm@:1:14.1: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=133295
+ depends_on('gdbm@:1.14.1', when='@:5.28.0')
+ depends_on('berkeley-db')
+ depends_on('bzip2')
+ depends_on('zlib')
+ # :5.24.1 needs zlib@:1.2.8: https://rt.cpan.org/Public/Bug/Display.html?id=120134
+ depends_on('zlib@:1.2.8', when='@5.20.3:5.24.1')
# there has been a long fixed issue with 5.22.0 with regard to the ccflags
# definition. It is well documented here:
@@ -181,6 +187,23 @@ class Perl(Package): # Perl doesn't use Autotools, it should subclass Package
perm = os.stat(filename).st_mode
os.chmod(filename, perm | 0o200)
+ @property
+ def nmake_arguments(self):
+ args = []
+ if self.spec.satisfies('%msvc'):
+ args.append('CCTYPE=%s' % self.compiler.msvc_version)
+ else:
+ raise RuntimeError("Perl unsupported for non MSVC compilers on Windows")
+ args.append('INST_TOP="%s"' % self.prefix.replace('/', '\\'))
+ args.append("INST_ARCH=\\$(ARCHNAME)")
+ if self.spec.satisfies('~shared'):
+ args.append("ALL_STATIC=%s" % "define")
+ if self.spec.satisfies('~threads'):
+ args.extend(["USE_MULTI=undef", "USE_ITHREADS=undef", "USE_IMP_SYS=undef"])
+ if not host.is_64bit():
+ args.append("WIN64=undef")
+ return args
+
def configure_args(self):
spec = self.spec
prefix = self.prefix
@@ -229,30 +252,69 @@ class Perl(Package): # Perl doesn't use Autotools, it should subclass Package
return config_args
def configure(self, spec, prefix):
+ if is_windows:
+ return
configure = Executable('./Configure')
configure(*self.configure_args())
def build(self, spec, prefix):
- make()
+ if is_windows:
+ pass
+ else:
+ make()
@run_after('build')
@on_package_attributes(run_tests=True)
def build_test(self):
- make('test')
+ if is_windows:
+ win32_dir = os.path.join(self.stage.source_path, "win32")
+ with working_dir(win32_dir):
+ nmake('test', ignore_quotes=True)
+ else:
+ make('test')
def install(self, spec, prefix):
- make('install')
+ if is_windows:
+ win32_dir = os.path.join(self.stage.source_path, "win32")
+ with working_dir(win32_dir):
+ nmake('install', *self.nmake_arguments, ignore_quotes=True)
+ else:
+ make('install')
+
+ @run_after('install')
+ def symlink_windows(self):
+ if not is_windows:
+ return
+ win_install_path = os.path.join(self.prefix.bin, "MSWin32")
+ if host.is_64bit():
+ win_install_path += "-x64"
+ else:
+ win_install_path += "-x86"
+ if self.spec.satisfies("+threads"):
+ win_install_path += "-multi-thread"
+ else:
+ win_install_path += "-perlio"
+
+ for f in os.listdir(os.path.join(self.prefix.bin, win_install_path)):
+ lnk_path = os.path.join(self.prefix.bin, f)
+ src_path = os.path.join(win_install_path, f)
+ if not os.path.exists(lnk_path):
+ symlink(src_path, lnk_path)
@run_after('install')
def install_cpanm(self):
spec = self.spec
-
+ maker = make
+ win_prefix = ''
+ if is_windows:
+ maker = nmake
+ win_prefix = self.stage.source_path
if '+cpanm' in spec:
- with working_dir(join_path('cpanm', 'cpanm')):
+ with working_dir(join_path(win_prefix, 'cpanm', 'cpanm')):
perl = spec['perl'].command
perl('Makefile.PL')
- make()
- make('install')
+ maker()
+ maker('install')
def _setup_dependent_env(self, env, dependent_spec, deptypes):
"""Set PATH and PERL5LIB to include the extension and
@@ -295,6 +357,9 @@ class Perl(Package): # Perl doesn't use Autotools, it should subclass Package
mkdirp(module.perl_lib_dir)
def setup_build_environment(self, env):
+ if is_windows:
+ return
+
spec = self.spec
if (spec.version <= Version('5.34.0')
@@ -321,7 +386,8 @@ class Perl(Package): # Perl doesn't use Autotools, it should subclass Package
frustrates filter_file on some filesystems (NFSv4), so make them
temporarily writable.
"""
-
+ if is_windows:
+ return
kwargs = {'ignore_absent': True, 'backup': False, 'string': False}
# Find the actual path to the installed Config.pm file.
@@ -409,8 +475,11 @@ class Perl(Package): # Perl doesn't use Autotools, it should subclass Package
Executable: the Perl command
"""
for ver in ('', self.spec.version):
- path = os.path.join(self.prefix.bin, '{0}{1}'.format(
- self.spec.name, ver))
+ ext = ''
+ if is_windows:
+ ext = '.exe'
+ path = os.path.join(self.prefix.bin, '{0}{1}{2}'.format(
+ self.spec.name, ver, ext))
if os.path.exists(path):
return Executable(path)
else:
diff --git a/var/spack/repos/builtin/packages/python/cpython-windows-externals.patch b/var/spack/repos/builtin/packages/python/cpython-windows-externals.patch
new file mode 100644
index 0000000000..c3bcce983f
--- /dev/null
+++ b/var/spack/repos/builtin/packages/python/cpython-windows-externals.patch
@@ -0,0 +1,28 @@
+diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat
+index b5a44e3..52941c7 100644
+--- a/PCbuild/get_externals.bat
++++ b/PCbuild/get_externals.bat
+@@ -76,7 +76,7 @@ for %%e in (%libraries%) do (
+ echo.Fetching external binaries...
+
+ set binaries=
+-if NOT "%IncludeLibffi%"=="false" set binaries=%binaries% libffi
++if NOT "%IncludeLibffi%"=="false" set binaries=%binaries% libffi-3.3.0
+ if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1k-1
+ if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.9.0
+ if NOT "%IncludeSSLSrc%"=="false" set binaries=%binaries% nasm-2.11.06
+diff --git a/PCbuild/python.props b/PCbuild/python.props
+index 419d5eb..c66fb07 100644
+--- a/PCbuild/python.props
++++ b/PCbuild/python.props
+@@ -59,8 +59,8 @@
+ <sqlite3Dir>$(ExternalsDir)sqlite-3.35.5.0\</sqlite3Dir>
+ <bz2Dir>$(ExternalsDir)bzip2-1.0.6\</bz2Dir>
+ <lzmaDir>$(ExternalsDir)xz-5.2.2\</lzmaDir>
+- <libffiDir>$(ExternalsDir)libffi\</libffiDir>
+- <libffiOutDir>$(ExternalsDir)libffi\$(ArchName)\</libffiOutDir>
++ <libffiDir>$(ExternalsDir)libffi-3.3.0\</libffiDir>
++ <libffiOutDir>$(ExternalsDir)libffi-3.3.0\$(ArchName)\</libffiOutDir>
+ <libffiIncludeDir>$(libffiOutDir)include</libffiIncludeDir>
+ <opensslDir>$(ExternalsDir)openssl-1.1.1k\</opensslDir>
+ <opensslOutDir>$(ExternalsDir)openssl-bin-1.1.1k-1\$(ArchName)\</opensslOutDir>
diff --git a/var/spack/repos/builtin/packages/python/package.py b/var/spack/repos/builtin/packages/python/package.py
index 2ce0510819..cd67ac4dc3 100644
--- a/var/spack/repos/builtin/packages/python/package.py
+++ b/var/spack/repos/builtin/packages/python/package.py
@@ -4,10 +4,14 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import glob
+import inspect
import json
import os
import re
+import subprocess
import sys
+from distutils.dir_util import copy_tree
+from shutil import copy
import llnl.util.tty as tty
from llnl.util.filesystem import get_filetype, path_contains_subdirectory
@@ -18,8 +22,12 @@ from spack.build_environment import dso_suffix
from spack.util.environment import is_system_path
from spack.util.prefix import Prefix
+arch_map = {"AMD64": "x64", "x86": "Win32",
+ "IA64": "Win32", "EM64T": "Win32"}
+is_windows = os.name == 'nt'
-class Python(AutotoolsPackage):
+
+class Python(Package):
"""The Python programming language."""
homepage = "https://www.python.org/"
@@ -29,11 +37,19 @@ class Python(AutotoolsPackage):
maintainers = ['adamjstewart', 'skosukhin', 'scheibelp', 'varioustoxins']
+
+ phases = ['configure', 'build', 'install']
+
+ #: phase
+ install_targets = ['install']
+ build_targets = []
+
version('3.10.2', sha256='3c0ede893011319f9b0a56b44953a3d52c7abf9657c23fb4bc9ced93b86e9c97')
version('3.10.1', sha256='b76117670e7c5064344b9c138e141a377e686b9063f3a8a620ff674fa8ec90d3')
version('3.10.0', sha256='c4e0cbad57c90690cb813fb4663ef670b4d0f587d8171e2c42bd4c9245bd2758')
version('3.9.10', sha256='1aa9c0702edbae8f6a2c95f70a49da8420aaa76b7889d3419c186bfc8c0e571e', preferred=True)
version('3.9.9', sha256='2cc7b67c1f3f66c571acc42479cdf691d8ed6b47bee12c9b68430413a17a44ea')
+ version('3.9.9', sha256='2cc7b67c1f3f66c571acc42479cdf691d8ed6b47bee12c9b68430413a17a44ea')
version('3.9.8', sha256='7447fb8bb270942d620dd24faa7814b1383b61fa99029a240025fd81c1db8283')
version('3.9.7', sha256='a838d3f9360d157040142b715db34f0218e535333696a5569dc6f854604eb9d1')
version('3.9.6', sha256='d0a35182e19e416fc8eae25a3dcd4d02d4997333e4ad1f2eee6010aadc3fe866')
@@ -146,12 +162,12 @@ class Python(AutotoolsPackage):
description='Enable expensive build-time optimizations, if available'
)
# See https://legacy.python.org/dev/peps/pep-0394/
- variant('pythoncmd', default=True,
+ variant('pythoncmd', default=not is_windows,
description="Symlink 'python3' executable to 'python' "
"(not PEP 394 compliant)")
# Optional Python modules
- variant('readline', default=True, description='Build readline module')
+ variant('readline', default=not is_windows, description='Build readline module')
variant('ssl', default=True, description='Build ssl module')
variant('sqlite3', default=True, description='Build sqlite3 module')
variant('dbm', default=True, description='Build dbm module')
@@ -166,33 +182,34 @@ class Python(AutotoolsPackage):
variant('tix', default=False, description='Build Tix module')
variant('ensurepip', default=True, description='Build ensurepip module', when='@2.7.9:2,3.4:')
- depends_on('pkgconfig@0.9.0:', type='build')
- depends_on('gettext +libxml2', when='+libxml2')
- depends_on('gettext ~libxml2', when='~libxml2')
-
- # Optional dependencies
- # See detect_modules() in setup.py for details
- depends_on('readline', when='+readline')
- depends_on('ncurses', when='+readline')
- depends_on('openssl', when='+ssl')
- # https://raw.githubusercontent.com/python/cpython/84471935ed2f62b8c5758fd544c7d37076fe0fa5/Misc/NEWS
- # https://docs.python.org/3.5/whatsnew/changelog.html#python-3-5-4rc1
- depends_on('openssl@:1.0.2z', when='@:2.7.13,3.0.0:3.5.2+ssl')
- depends_on('openssl@1.0.2:', when='@3.7:+ssl') # https://docs.python.org/3/whatsnew/3.7.html#build-changes
- depends_on('openssl@1.1.1:', when='@3.10:+ssl') # https://docs.python.org/3.10/whatsnew/3.10.html#build-changes
- depends_on('sqlite@3.0.8:', when='@:3.9+sqlite3')
- depends_on('sqlite@3.7.15:', when='@3.10:+sqlite3') # https://docs.python.org/3.10/whatsnew/3.10.html#build-changes
- depends_on('gdbm', when='+dbm') # alternatively ndbm or berkeley-db
- depends_on('libnsl', when='+nis')
- depends_on('zlib@1.1.3:', when='+zlib')
- depends_on('bzip2', when='+bz2')
- depends_on('xz', when='@3.3:+lzma')
- depends_on('expat', when='+pyexpat')
- depends_on('libffi', when='+ctypes')
- depends_on('tk', when='+tkinter')
- depends_on('tcl', when='+tkinter')
- depends_on('uuid', when='+uuid')
- depends_on('tix', when='+tix')
+ if os.name != 'nt':
+ depends_on('pkgconfig@0.9.0:', type='build')
+ depends_on('gettext +libxml2', when='+libxml2')
+ depends_on('gettext ~libxml2', when='~libxml2')
+
+ # Optional dependencies
+ # See detect_modules() in setup.py for details
+ depends_on('readline', when='+readline')
+ depends_on('ncurses', when='+readline')
+ depends_on('openssl', when='+ssl')
+ # https://raw.githubusercontent.com/python/cpython/84471935ed2f62b8c5758fd544c7d37076fe0fa5/Misc/NEWS
+ # https://docs.python.org/3.5/whatsnew/changelog.html#python-3-5-4rc1
+ depends_on('openssl@:1.0.2z', when='@:2.7.13,3.0.0:3.5.2+ssl')
+ depends_on('openssl@1.0.2:', when='@3.7:+ssl') # https://docs.python.org/3/whatsnew/3.7.html#build-changes
+ depends_on('openssl@1.1.1:', when='@3.10:+ssl') # https://docs.python.org/3.10/whatsnew/3.10.html#build-changes
+ depends_on('sqlite@3.0.8:', when='@:3.9+sqlite3')
+ depends_on('sqlite@3.7.15:', when='@3.10:+sqlite3') # https://docs.python.org/3.10/whatsnew/3.10.html#build-changes
+ depends_on('gdbm', when='+dbm') # alternatively ndbm or berkeley-db
+ depends_on('libnsl', when='+nis')
+ depends_on('zlib@1.1.3:', when='+zlib')
+ depends_on('bzip2', when='+bz2')
+ depends_on('xz', when='@3.3:+lzma')
+ depends_on('expat', when='+pyexpat')
+ depends_on('libffi', when='+ctypes')
+ depends_on('tk', when='+tkinter')
+ depends_on('tcl', when='+tkinter')
+ depends_on('uuid', when='+uuid')
+ depends_on('tix', when='+tix')
# Python needs to be patched to build extensions w/ mixed C/C++ code:
# https://github.com/NixOS/nixpkgs/pull/19585/files
@@ -211,6 +228,7 @@ class Python(AutotoolsPackage):
patch('python-3.7.3-distutils-C++.patch', when='@3.7.3')
patch('python-3.7.4+-distutils-C++.patch', when='@3.7.4:')
patch('python-3.7.4+-distutils-C++-testsuite.patch', when='@3.7.4:')
+ patch('cpython-windows-externals.patch', when='@:3.9.6 platform=windows')
patch('tkinter.patch', when='@:2.8,3.3:3.7 platform=darwin')
# Patch the setup script to deny that tcl/x11 exists rather than allowing
@@ -438,6 +456,70 @@ class Python(AutotoolsPackage):
# allow flags to be passed through compiler wrapper
return (flags, None, None)
+ @property
+ def configure_directory(self):
+ """Returns the directory where 'configure' resides.
+ :return: directory where to find configure
+ """
+ return self.stage.source_path
+
+ @property
+ def build_directory(self):
+ """Override to provide another place to build the package"""
+ return self.configure_directory
+
+ @property
+ def plat_arch(self):
+ arch = platform.machine()
+ if arch in arch_map:
+ arch = arch_map[arch]
+ return arch
+
+ @property
+ def win_build_params(self):
+ args = []
+ args.append("-p %s" % self.plat_arch)
+ if self.spec.satisfies('+debug'):
+ args.append('-d')
+ if self.spec.satisfies('~ctypes'):
+ args.append('--no-ctypes')
+ if self.spec.satisfies('~ssl'):
+ args.append('--no-ssl')
+ if self.spec.satisfies('~tkinter'):
+ args.append('--no-tkinter')
+ return args
+
+ def win_installer(self, prefix):
+ proj_root = self.stage.source_path
+ pcbuild_root = os.path.join(proj_root, "PCbuild")
+ build_root = os.path.join(pcbuild_root, platform.machine().lower())
+ include_dir = os.path.join(proj_root, "Include")
+ copy_tree(include_dir, prefix.include)
+ doc_dir = os.path.join(proj_root, "Doc")
+ copy_tree(doc_dir, prefix.Doc)
+ tools_dir = os.path.join(proj_root, "Tools")
+ copy_tree(tools_dir, prefix.Tools)
+ lib_dir = os.path.join(proj_root, "Lib")
+ copy_tree(lib_dir, prefix.Lib)
+ pyconfig = os.path.join(proj_root, "PC", "pyconfig.h")
+ copy(pyconfig, prefix.include)
+ shared_libraries = []
+ shared_libraries.extend(glob.glob("%s\\*.exe" % build_root))
+ shared_libraries.extend(glob.glob("%s\\*.dll" % build_root))
+ shared_libraries.extend(glob.glob("%s\\*.pyd" % build_root))
+ os.makedirs(prefix.DLLs)
+ for lib in shared_libraries:
+ file_name = os.path.basename(lib)
+ if file_name.endswith(".exe") or\
+ (file_name.endswith(".dll") and "python" in file_name)\
+ or "vcruntime" in file_name:
+ copy(lib, prefix)
+ else:
+ copy(lib, prefix.DLLs)
+ static_libraries = glob.glob("%s\\*.lib")
+ for lib in static_libraries:
+ copy(lib, prefix.libs)
+
def configure_args(self):
spec = self.spec
config_args = []
@@ -549,6 +631,54 @@ class Python(AutotoolsPackage):
return config_args
+ def configure(self, spec, prefix):
+ """Runs configure with the arguments specified in
+ :meth:`~spack.build_systems.autotools.AutotoolsPackage.configure_args`
+ and an appropriately set prefix.
+ """
+ with working_dir(self.build_directory, create=True):
+ if is_windows:
+ pass
+ else:
+ options = getattr(self, 'configure_flag_args', [])
+ options += ['--prefix={0}'.format(prefix)]
+ options += self.configure_args()
+ configure(*options)
+
+ def build(self, spec, prefix):
+ """Makes the build targets specified by
+ :py:attr:``~.AutotoolsPackage.build_targets``
+ """
+ # Windows builds use a batch script to drive
+ # configure and build in one step
+ with working_dir(self.build_directory):
+ if is_windows:
+ pcbuild_root = os.path.join(self.stage.source_path, "PCbuild")
+ builder_cmd = os.path.join(pcbuild_root, 'build.bat')
+ try:
+ subprocess.check_output( # novermin
+ " ".join([builder_cmd] + self.win_build_params),
+ stderr=subprocess.STDOUT
+ )
+ except subprocess.CalledProcessError as e:
+ raise ProcessError("Process exited with status %d" % e.returncode,
+ long_message=e.output.decode('utf-8'))
+ else:
+ # See https://autotools.io/automake/silent.html
+ params = ['V=1']
+ params += self.build_targets
+ inspect.getmodule(self).make(*params)
+
+ def install(self, spec, prefix):
+ """Makes the install targets specified by
+ :py:attr:``~.AutotoolsPackage.install_targets``
+ """
+ with working_dir(self.build_directory):
+ if is_windows:
+ self.win_installer(prefix)
+ else:
+ inspect.getmodule(self).make(*self.install_targets)
+
@run_after('install')
def filter_compilers(self):
"""Run after install to tell the configuration files and Makefiles
@@ -557,7 +687,8 @@ class Python(AutotoolsPackage):
If this isn't done, they'll have CC and CXX set to Spack's generic
cc and c++. We want them to be bound to whatever compiler
they were built with."""
-
+ if is_windows:
+ return
kwargs = {'ignore_absent': True, 'backup': False, 'string': True}
filenames = [
@@ -570,6 +701,8 @@ class Python(AutotoolsPackage):
@run_after('install')
def symlink(self):
+ if is_windows:
+ return
spec = self.spec
prefix = self.prefix
@@ -759,6 +892,26 @@ class Python(AutotoolsPackage):
Returns:
dict: variable definitions
"""
+ # Some values set by sysconfig may not always exist on Windows, so
+ # compute Windows alternatives
+ def repair_win_sysconf(conf):
+ if is_windows:
+ conf["LIBDIR"] = os.path.join(conf["LIBDEST"], "..", "libs")
+ conf["LIBPL"] = conf["LIBDIR"]
+ conf["PYTHONFRAMEWORKPREFIX"] = ""
+ conf["LDLIBRARY"] = "python" + conf["VERSION"] + ".dll"
+ conf["LIBRARY"] = "python" + conf["VERSION"] + ".lib"
+ conf["CC"] = ""
+ conf["CXX"] = ""
+ conf["LDSHARED"] = ""
+ conf["LDCXXSHARED"] = ""
+
+ return conf
+
+ # TODO: distutils is deprecated in Python 3.10 and will be removed in
+ # Python 3.12, find a different way to access this information.
+ # Also, calling the python executable disallows us from cross-compiling,
+ # so we want to try to avoid that if possible.
cmd = """
import json
from sysconfig import (
@@ -823,7 +976,7 @@ config.update(get_paths())
config.update(json.loads(self.command('-c', cmd, output=str)))
except (ProcessError, RuntimeError):
pass
- self._config_vars[dag_hash] = config
+ self._config_vars[dag_hash] = repair_win_sysconf(config)
return self._config_vars[dag_hash]
def get_sysconfigdata_name(self):
@@ -865,6 +1018,9 @@ config.update(get_paths())
# In Ubuntu 16.04.6 and python 2.7.12 from the system, lib could be
# in LBPL
# https://mail.python.org/pipermail/python-dev/2013-April/125733.html
+ # LIBPL does not exist in Windows, avoid uneccesary KeyError while allowing
+ # later failures.
+ # Return empty string rather than none so os.path doesn't complain
libpl = self.config_vars['LIBPL']
# The system Python installation on macOS and Homebrew installations
@@ -881,7 +1037,7 @@ config.update(get_paths())
if '+shared' in self.spec:
ldlibrary = self.config_vars['LDLIBRARY']
-
+ win_bin_dir = self.config_vars['BINDIR']
if os.path.exists(os.path.join(libdir, ldlibrary)):
return LibraryList(os.path.join(libdir, ldlibrary))
elif os.path.exists(os.path.join(libpl, ldlibrary)):
@@ -891,6 +1047,9 @@ config.update(get_paths())
elif macos_developerdir and \
os.path.exists(os.path.join(macos_developerdir, ldlibrary)):
return LibraryList(os.path.join(macos_developerdir, ldlibrary))
+ elif is_windows and \
+ os.path.exists(os.path.join(win_bin_dir, ldlibrary)):
+ return LibraryList(os.path.join(win_bin_dir, ldlibrary))
else:
msg = 'Unable to locate {0} libraries in {1}'
raise RuntimeError(msg.format(ldlibrary, libdir))
@@ -1075,7 +1234,7 @@ config.update(get_paths())
# fact that LDSHARED is set in the environment, therefore we export
# the variable only if the new value is different from what we got
# from the sysconfigdata file:
- if config_link != new_link:
+ if config_link != new_link and not is_windows:
env.set(link_var, new_link)
def setup_dependent_run_environment(self, env, dependent_spec):
@@ -1211,7 +1370,8 @@ config.update(get_paths())
))
def add_files_to_view(self, view, merge_map):
- bin_dir = self.spec.prefix.bin
+ bin_dir = self.spec.prefix.bin if os.name != 'nt'\
+ else self.spec.prefix
for src, dst in merge_map.items():
if not path_contains_subdirectory(src, bin_dir):
view.link(src, dst, spec=self.spec)
@@ -1243,7 +1403,8 @@ config.update(get_paths())
view.link(new_link_target, dst, spec=self.spec)
def remove_files_from_view(self, view, merge_map):
- bin_dir = self.spec.prefix.bin
+ bin_dir = self.spec.prefix.bin if os.name != 'nt'\
+ else self.spec.prefix
for src, dst in merge_map.items():
if not path_contains_subdirectory(src, bin_dir):
view.remove_file(src, dst)
diff --git a/var/spack/repos/builtin/packages/ruby/package.py b/var/spack/repos/builtin/packages/ruby/package.py
index 870a416283..b4ca1afaff 100644
--- a/var/spack/repos/builtin/packages/ruby/package.py
+++ b/var/spack/repos/builtin/packages/ruby/package.py
@@ -5,8 +5,12 @@
import re
+from spack import *
-class Ruby(AutotoolsPackage):
+is_windows = str(spack.platforms.host()) == 'windows'
+
+
+class Ruby(Package):
"""A dynamic, open source programming language with a focus on
simplicity and productivity."""
@@ -27,23 +31,22 @@ class Ruby(AutotoolsPackage):
version('2.5.3', sha256='9828d03852c37c20fa333a0264f2490f07338576734d910ee3fd538c9520846c')
version('2.2.0', sha256='7671e394abfb5d262fbcd3b27a71bf78737c7e9347fa21c39e58b0bb9c4840fc')
- variant('openssl', default=True, description="Enable OpenSSL support")
- variant('readline', default=False, description="Enable Readline support")
+ if not is_windows:
+ variant('openssl', default=True, description="Enable OpenSSL support")
+ variant('readline', default=False, description="Enable Readline support")
+ depends_on('pkgconfig', type=('build'))
+ depends_on('libffi')
+ depends_on('libx11', when='@:2.3')
+ depends_on('tcl', when='@:2.3')
+ depends_on('tk', when='@:2.3')
+ depends_on('readline', when='+readline')
+ depends_on('zlib')
+ with when('+openssl'):
+ depends_on('openssl@:1')
+ depends_on('openssl@:1.0', when='@:2.3')
extendable = True
-
- depends_on('pkgconfig', type=('build'))
- depends_on('libffi')
- depends_on('zlib')
- depends_on('libx11', when='@:2.3')
- depends_on('tcl', when='@:2.3')
- depends_on('tk', when='@:2.3')
- depends_on('readline', when='+readline')
-
- with when('+openssl'):
- depends_on('openssl@:1')
- depends_on('openssl@:1.0', when='@:2.3')
-
+ phases = ['autoreconf', 'configure', 'build', 'install']
# Known build issues when Avira antivirus software is running:
# https://github.com/rvm/rvm/issues/4313#issuecomment-374020379
# TODO: add check for this and warn user
@@ -116,6 +119,32 @@ class Ruby(AutotoolsPackage):
module.gem = Executable(self.prefix.bin.gem)
module.rake = Executable(self.prefix.bin.rake)
+ def configure(self, spec, prefix):
+ with working_dir(self.build_directory, create=True):
+ if is_windows:
+ Executable("win32\\configure.bat", "--prefix=%s" % self.prefix)
+ else:
+ options = getattr(self, 'configure_flag_args', [])
+ options += ['--prefix={0}'.format(prefix)]
+ options += self.configure_args()
+ configure(*options)
+
+ def build(self, spec, prefix):
+ with working_dir(self.build_directory):
+ if is_windows:
+ nmake()
+ else:
+ params = ['V=1']
+ params += self.build_targets
+ make(*params)
+
+ def install(self, spec, prefix):
+ with working_dir(self.build_directory):
+ if is_windows:
+ nmake('install')
+ else:
+ make(*self.install_targets)
+
@run_after('install')
def post_install(self):
""" RubyGems updated their SSL certificates at some point, so
diff --git a/var/spack/repos/builtin/packages/zlib/package.py b/var/spack/repos/builtin/packages/zlib/package.py
index 9a445b8173..3b6b1fd18d 100644
--- a/var/spack/repos/builtin/packages/zlib/package.py
+++ b/var/spack/repos/builtin/packages/zlib/package.py
@@ -6,7 +6,11 @@
# Although zlib comes with a configure script, it does not use Autotools
# The AutotoolsPackage causes zlib to fail to build with PGI
-class Zlib(CMakePackage):
+import glob
+import os
+
+
+class Zlib(Package):
"""A free, general-purpose, legally unencumbered lossless
data-compression library.
"""
@@ -37,16 +41,29 @@ class Zlib(CMakePackage):
['libz'], root=self.prefix, recursive=True, shared=shared
)
- def cmake_args(self):
- args = ['-DBUILD_SHARED_LIBS:BOOL=' +
- ('ON' if self._building_shared else 'OFF')]
- return args
+ def win_install(self):
+ build_dir = self.stage.source_path
+ install_tree = {}
+ install_tree["bin"] = glob.glob(os.path.join(build_dir, "*.dll"))
+ install_tree["lib"] = glob.glob(os.path.join(build_dir, "*.lib"))
+ compose_src_path = lambda x: os.path.join(build_dir, x)
+ install_tree["include"] = [compose_src_path("zlib.h"),
+ compose_src_path("zconf.h")]
+ install_tree["share"] = {"man": {"man3": [compose_src_path("zlib.3")]}}
- @property
- def build_directory(self):
- return join_path(self.stage.source_path,
- 'spack-build-shared' if self._building_shared
- else 'spack-build-static')
+ def installtree(dst, tree):
+ for inst_dir in tree:
+ if type(tree[inst_dir]) is list:
+ install_dst = getattr(dst, inst_dir)
+ try:
+ os.makedirs(install_dst)
+ except OSError:
+ pass
+ for file in tree[inst_dir]:
+ copy(file, install_dst)
+ else:
+ installtree(getattr(dst, inst_dir), tree[inst_dir])
+ installtree(self.prefix, install_tree)
def setup_build_environment(self, env):
if '+pic' in self.spec:
@@ -54,27 +71,10 @@ class Zlib(CMakePackage):
if '+optimize' in self.spec:
env.append_flags('CFLAGS', '-O2')
- # Build, install, and check both static and shared versions of the
- # libraries when +shared
- @when('+shared platform=windows')
- def cmake(self, spec, prefix):
- for self._building_shared in (False, True):
- super(Zlib, self).cmake(spec, prefix)
-
- @when('+shared platform=windows')
- def build(self, spec, prefix):
- for self._building_shared in (False, True):
- super(Zlib, self).build(spec, prefix)
-
- @when('+shared platform=windows')
- def check(self):
- for self._building_shared in (False, True):
- super(Zlib, self).check()
-
def install(self, spec, prefix):
- if 'platform=windows' in self.spec and '+shared' in self.spec:
- for self._building_shared in (False, True):
- super(Zlib, self).install(spec, prefix)
+ if 'platform=windows' in self.spec:
+ nmake('-f' 'win32\\Makefile.msc')
+ self.win_install()
else:
config_args = []
if '~shared' in spec: