Hdf5 package: build on Windows (#31141)
* Enable hdf5 build (including +mpi) on Windows * This includes updates to hdf5 dependencies openssl (minor edit) and bzip2 (more-extensive edits) * Add binary-based installation of msmpi (this is currently the only supported MPI implementation in Spack for Windows). Note that this does not install to the Spack-specified prefix. This implementation will be replaced with a source-based implementation Co-authored-by: John Parent <john.parent@kitware.com>
This commit is contained in:
parent
6811651a0f
commit
381bedf369
6 changed files with 94 additions and 21 deletions
|
@ -1704,9 +1704,11 @@ dependencies or incompatible build tools like autoconf. Here are several
|
||||||
packages known to work on Windows:
|
packages known to work on Windows:
|
||||||
|
|
||||||
* abseil-cpp
|
* abseil-cpp
|
||||||
|
* bzip2
|
||||||
* clingo
|
* clingo
|
||||||
* cpuinfo
|
* cpuinfo
|
||||||
* cmake
|
* cmake
|
||||||
|
* hdf5
|
||||||
* glm
|
* glm
|
||||||
* nasm
|
* nasm
|
||||||
* netlib-lapack (requires Intel Fortran)
|
* netlib-lapack (requires Intel Fortran)
|
||||||
|
|
|
@ -1089,7 +1089,7 @@ def _libs_default_handler(descriptor, spec, cls):
|
||||||
home = getattr(spec.package, "home")
|
home = getattr(spec.package, "home")
|
||||||
|
|
||||||
# Avoid double 'lib' for packages whose names already start with lib
|
# Avoid double 'lib' for packages whose names already start with lib
|
||||||
if not name.startswith("lib"):
|
if not name.startswith("lib") and not spec.satisfies("platform=windows"):
|
||||||
name = "lib" + name
|
name = "lib" + name
|
||||||
|
|
||||||
# If '+shared' search only for shared library; if '~shared' search only for
|
# If '+shared' search only for shared library; if '~shared' search only for
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
from spack.package import *
|
from spack.package import *
|
||||||
|
|
||||||
|
@ -24,11 +25,23 @@ class Bzip2(Package, SourcewarePackage):
|
||||||
version("1.0.7", sha256="e768a87c5b1a79511499beb41500bcc4caf203726fff46a6f5f9ad27fe08ab2b")
|
version("1.0.7", sha256="e768a87c5b1a79511499beb41500bcc4caf203726fff46a6f5f9ad27fe08ab2b")
|
||||||
version("1.0.6", sha256="a2848f34fcd5d6cf47def00461fcb528a0484d8edef8208d6d2e2909dc61d9cd")
|
version("1.0.6", sha256="a2848f34fcd5d6cf47def00461fcb528a0484d8edef8208d6d2e2909dc61d9cd")
|
||||||
|
|
||||||
variant("shared", default=True, description="Enables the build of shared libraries.")
|
variant(
|
||||||
|
"shared",
|
||||||
|
default=(sys.platform != "win32"),
|
||||||
|
description="Enables the build of shared libraries.",
|
||||||
|
)
|
||||||
variant("pic", default=False, description="Build static libraries with PIC")
|
variant("pic", default=False, description="Build static libraries with PIC")
|
||||||
variant("debug", default=False, description="Enable debug symbols and disable optimization")
|
variant("debug", default=False, description="Enable debug symbols and disable optimization")
|
||||||
|
|
||||||
depends_on("diffutils", type="build")
|
# makefile.msc doesn't provide a shared recipe
|
||||||
|
conflicts(
|
||||||
|
"+shared",
|
||||||
|
when="platform=windows",
|
||||||
|
msg="Windows makefile has no recipe for shared builds, use ~shared.",
|
||||||
|
)
|
||||||
|
|
||||||
|
if sys.platform != "win32":
|
||||||
|
depends_on("diffutils", type="build")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def determine_version(cls, exe):
|
def determine_version(cls, exe):
|
||||||
|
@ -52,9 +65,10 @@ def flag_handler(self, name, flags):
|
||||||
|
|
||||||
def patch(self):
|
def patch(self):
|
||||||
if self.spec.satisfies("+debug"):
|
if self.spec.satisfies("+debug"):
|
||||||
for makefile in ["Makefile", "Makefile-libbz2_so"]:
|
for makefile in ["Makefile", "Makefile-libbz2_so", "makefile.msc"]:
|
||||||
filter_file(r"-O ", "-O0 ", makefile)
|
filter_file(r"-O ", "-O0 ", makefile)
|
||||||
filter_file(r"-O2 ", "-O0 ", makefile)
|
filter_file(r"-O2 ", "-O0 ", makefile)
|
||||||
|
filter_file(r"-Ox ", "-O0 ", makefile)
|
||||||
|
|
||||||
# bzip2 comes with two separate Makefiles for static and dynamic builds
|
# bzip2 comes with two separate Makefiles for static and dynamic builds
|
||||||
# Tell both to use Spack's compiler wrapper instead of GCC
|
# Tell both to use Spack's compiler wrapper instead of GCC
|
||||||
|
@ -82,13 +96,13 @@ def patch(self):
|
||||||
"$(CC) -dynamiclib -Wl,-install_name -Wl,@rpath/libbz2.{0}.dylib "
|
"$(CC) -dynamiclib -Wl,-install_name -Wl,@rpath/libbz2.{0}.dylib "
|
||||||
"-current_version {1} -compatibility_version {2} -o libbz2.{3}.dylib $(OBJS)"
|
"-current_version {1} -compatibility_version {2} -o libbz2.{3}.dylib $(OBJS)"
|
||||||
).format(v1, v2, v3, v3),
|
).format(v1, v2, v3, v3),
|
||||||
**kwargs
|
**kwargs,
|
||||||
)
|
)
|
||||||
|
|
||||||
mf.filter(
|
mf.filter(
|
||||||
"$(CC) $(CFLAGS) -o bzip2-shared bzip2.c libbz2.so.{0}".format(v3),
|
"$(CC) $(CFLAGS) -o bzip2-shared bzip2.c libbz2.so.{0}".format(v3),
|
||||||
"$(CC) $(CFLAGS) -o bzip2-shared bzip2.c libbz2.{0}.dylib".format(v3),
|
"$(CC) $(CFLAGS) -o bzip2-shared bzip2.c libbz2.{0}.dylib".format(v3),
|
||||||
**kwargs
|
**kwargs,
|
||||||
)
|
)
|
||||||
mf.filter(
|
mf.filter(
|
||||||
"rm -f libbz2.so.{0}".format(v2), "rm -f libbz2.{0}.dylib".format(v2), **kwargs
|
"rm -f libbz2.so.{0}".format(v2), "rm -f libbz2.{0}.dylib".format(v2), **kwargs
|
||||||
|
@ -96,7 +110,7 @@ def patch(self):
|
||||||
mf.filter(
|
mf.filter(
|
||||||
"ln -s libbz2.so.{0} libbz2.so.{1}".format(v3, v2),
|
"ln -s libbz2.so.{0} libbz2.so.{1}".format(v3, v2),
|
||||||
"ln -s libbz2.{0}.dylib libbz2.{1}.dylib".format(v3, v2),
|
"ln -s libbz2.{0}.dylib libbz2.{1}.dylib".format(v3, v2),
|
||||||
**kwargs
|
**kwargs,
|
||||||
)
|
)
|
||||||
|
|
||||||
def install(self, spec, prefix):
|
def install(self, spec, prefix):
|
||||||
|
@ -105,8 +119,23 @@ def install(self, spec, prefix):
|
||||||
make("-f", "Makefile-libbz2_so")
|
make("-f", "Makefile-libbz2_so")
|
||||||
|
|
||||||
# Build the static library and everything else
|
# Build the static library and everything else
|
||||||
make()
|
if self.spec.satisfies("platform=windows"):
|
||||||
make("install", "PREFIX={0}".format(prefix))
|
# Build step
|
||||||
|
nmake = Executable("nmake.exe")
|
||||||
|
nmake("-f", "makefile.msc")
|
||||||
|
# Install step
|
||||||
|
mkdirp(self.prefix.include)
|
||||||
|
mkdirp(self.prefix.lib)
|
||||||
|
mkdirp(self.prefix.bin)
|
||||||
|
mkdirp(self.prefix.man)
|
||||||
|
mkdirp(self.prefix.man.man1)
|
||||||
|
install("*.h", self.prefix.include)
|
||||||
|
install("*.lib", self.prefix.lib)
|
||||||
|
install("*.exe", self.prefix.bin)
|
||||||
|
install("*.1", self.prefix.man.man1)
|
||||||
|
else:
|
||||||
|
make()
|
||||||
|
make("install", "PREFIX={0}".format(prefix))
|
||||||
|
|
||||||
if "+shared" in spec:
|
if "+shared" in spec:
|
||||||
install("bzip2-shared", join_path(prefix.bin, "bzip2"))
|
install("bzip2-shared", join_path(prefix.bin, "bzip2"))
|
||||||
|
@ -124,7 +153,9 @@ def install(self, spec, prefix):
|
||||||
for libname in (lib, lib1, lib2):
|
for libname in (lib, lib1, lib2):
|
||||||
symlink(lib3, libname)
|
symlink(lib3, libname)
|
||||||
|
|
||||||
with working_dir(prefix.bin):
|
# These files won't be in a Windows installation
|
||||||
force_remove("bunzip2", "bzcat")
|
if not self.spec.satisfies("platform=windows"):
|
||||||
symlink("bzip2", "bunzip2")
|
with working_dir(prefix.bin):
|
||||||
symlink("bzip2", "bzcat")
|
force_remove("bunzip2", "bzcat")
|
||||||
|
symlink("bzip2", "bunzip2")
|
||||||
|
symlink("bzip2", "bzcat")
|
||||||
|
|
|
@ -196,13 +196,16 @@ class Hdf5(CMakePackage):
|
||||||
|
|
||||||
depends_on("cmake@3.12:", type="build")
|
depends_on("cmake@3.12:", type="build")
|
||||||
|
|
||||||
|
depends_on("msmpi", when="+mpi platform=windows")
|
||||||
depends_on("mpi", when="+mpi")
|
depends_on("mpi", when="+mpi")
|
||||||
depends_on("java", type=("build", "run"), when="+java")
|
depends_on("java", type=("build", "run"), when="+java")
|
||||||
depends_on("szip", when="+szip")
|
depends_on("szip", when="+szip")
|
||||||
depends_on("zlib@1.1.2:")
|
depends_on("zlib@1.1.2:")
|
||||||
|
|
||||||
# The compiler wrappers (h5cc, h5fc, etc.) run 'pkg-config'.
|
# The compiler wrappers (h5cc, h5fc, etc.) run 'pkg-config'.
|
||||||
depends_on("pkgconfig", type="run")
|
# Skip this on Windows since pkgconfig is autotools
|
||||||
|
for plat in ["cray", "darwin", "linux"]:
|
||||||
|
depends_on("pkgconfig", when="platform=%s" % plat, type="run")
|
||||||
|
|
||||||
conflicts("api=v114", when="@1.6:1.12", msg="v114 is not compatible with this release")
|
conflicts("api=v114", when="@1.6:1.12", msg="v114 is not compatible with this release")
|
||||||
conflicts("api=v112", when="@1.6:1.10", msg="v112 is not compatible with this release")
|
conflicts("api=v112", when="@1.6:1.10", msg="v112 is not compatible with this release")
|
||||||
|
@ -498,7 +501,7 @@ def cmake_args(self):
|
||||||
if api != "default":
|
if api != "default":
|
||||||
args.append(self.define("DEFAULT_API_VERSION", api))
|
args.append(self.define("DEFAULT_API_VERSION", api))
|
||||||
|
|
||||||
if "+mpi" in spec:
|
if "+mpi" in spec and "platform=windows" not in spec:
|
||||||
args.append(self.define("CMAKE_C_COMPILER", spec["mpi"].mpicc))
|
args.append(self.define("CMAKE_C_COMPILER", spec["mpi"].mpicc))
|
||||||
|
|
||||||
if "+cxx" in self.spec:
|
if "+cxx" in self.spec:
|
||||||
|
@ -567,7 +570,7 @@ def fix_package_config(self):
|
||||||
r"(Requires(?:\.private)?:.*)(hdf5[^\s,]*)(?:-[^\s,]*)(.*)",
|
r"(Requires(?:\.private)?:.*)(hdf5[^\s,]*)(?:-[^\s,]*)(.*)",
|
||||||
r"\1\2\3",
|
r"\1\2\3",
|
||||||
*pc_files,
|
*pc_files,
|
||||||
backup=False
|
backup=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create non-versioned symlinks to the versioned pkg-config files:
|
# Create non-versioned symlinks to the versioned pkg-config files:
|
||||||
|
|
42
var/spack/repos/builtin/packages/msmpi/package.py
Normal file
42
var/spack/repos/builtin/packages/msmpi/package.py
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
from spack.package import *
|
||||||
|
|
||||||
|
|
||||||
|
class Msmpi(Package):
|
||||||
|
"""A Windows-specced build of MPICH provided directly by
|
||||||
|
Microsoft Support Team
|
||||||
|
"""
|
||||||
|
|
||||||
|
homepage = "https://www.microsoft.com/en-us/download/default.aspx"
|
||||||
|
maintainers = ["jpopelar"]
|
||||||
|
|
||||||
|
executable = ["mpiexec.exe"]
|
||||||
|
|
||||||
|
version(
|
||||||
|
"10.0",
|
||||||
|
sha256="7dae13797627726f67fab9c1d251aec2df9ecd25939984645ec05748bdffd396",
|
||||||
|
extension="exe",
|
||||||
|
expand=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
provides("mpi")
|
||||||
|
|
||||||
|
conflicts("platform=linux")
|
||||||
|
conflicts("platform=darwin")
|
||||||
|
conflicts("platform=cray")
|
||||||
|
|
||||||
|
def url_for_version(self, version):
|
||||||
|
return "https://download.microsoft.com/download/A/E/0/AE002626-9D9D-448D-8197-1EA510E297CE/msmpisetup.exe"
|
||||||
|
|
||||||
|
def determine_version(self, exe):
|
||||||
|
output = Executable("mpiexec.exe")
|
||||||
|
ver_str = re.search("[Version ([0-9.]+)]", output)
|
||||||
|
return Version(ver_str.group(0)) if ver_str else None
|
||||||
|
|
||||||
|
def install(self, spec, prefix):
|
||||||
|
installer = Executable("msmpisetup.exe")
|
||||||
|
installer("-unattend")
|
|
@ -420,11 +420,6 @@ def install(self, spec, prefix):
|
||||||
# (e.g. gcc) will not accept them.
|
# (e.g. gcc) will not accept them.
|
||||||
filter_file(r"-arch x86_64", "", "Makefile")
|
filter_file(r"-arch x86_64", "", "Makefile")
|
||||||
|
|
||||||
if spec.satisfies("+dynamic"):
|
|
||||||
# This variant only makes sense for Windows
|
|
||||||
if spec.satisfies("platform=windows"):
|
|
||||||
filter_file(r"MT", "MD", "makefile")
|
|
||||||
|
|
||||||
if spec.satisfies("platform=windows"):
|
if spec.satisfies("platform=windows"):
|
||||||
host_make = nmake
|
host_make = nmake
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in a new issue