summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJared Popelar <jdpopelar@gmail.com>2023-09-27 09:58:12 -0600
committerGitHub <noreply@github.com>2023-09-27 09:58:12 -0600
commitd9724597eded17784b395b324d653305f3bf0e90 (patch)
treef09675ccc3cd6dd266d16dc014fd2a50a31f4908
parentc90c946d52615ea56eed2e5f16e00a6343f2572b (diff)
downloadspack-d9724597eded17784b395b324d653305f3bf0e90.tar.gz
spack-d9724597eded17784b395b324d653305f3bf0e90.tar.bz2
spack-d9724597eded17784b395b324d653305f3bf0e90.tar.xz
spack-d9724597eded17784b395b324d653305f3bf0e90.zip
Trilinos package: build on Windows (#34622)
Update Trilinos and dependencies to build a limited version of Trilinos on Windows. * Support trilinos~mpi~shared on Windows * superlu: force CMake build on Windows * boost: update to build on Windows (proper option formatting and build tool names) * pcre, openblas: add CMake-based build (keep prior build system as default on platforms other than Windows) * openblas: add patch when using Intel Fortran compiler (currently this is included as part of the hybrid %msvc compiler in Spack) Co-authored-by: John Parent <john.parent@kitware.com>
-rw-r--r--var/spack/repos/builtin/packages/boost/package.py39
-rw-r--r--var/spack/repos/builtin/packages/openblas/ifort-msvc.patch13
-rw-r--r--var/spack/repos/builtin/packages/openblas/package.py90
-rw-r--r--var/spack/repos/builtin/packages/pcre/package.py26
-rw-r--r--var/spack/repos/builtin/packages/superlu/package.py2
-rw-r--r--var/spack/repos/builtin/packages/trilinos/package.py19
6 files changed, 145 insertions, 44 deletions
diff --git a/var/spack/repos/builtin/packages/boost/package.py b/var/spack/repos/builtin/packages/boost/package.py
index efa8b2270b..58b836ac60 100644
--- a/var/spack/repos/builtin/packages/boost/package.py
+++ b/var/spack/repos/builtin/packages/boost/package.py
@@ -498,7 +498,9 @@ class Boost(Package):
with open("user-config.jam", "w") as f:
# Boost may end up using gcc even though clang+gfortran is set in
# compilers.yaml. Make sure this does not happen:
- f.write("using {0} : : {1} ;\n".format(boost_toolset_id, spack_cxx))
+ if not spec.satisfies("platform=windows"):
+ # Skip this on Windows since we don't have a cl.exe wrapper in spack
+ f.write("using {0} : : {1} ;\n".format(boost_toolset_id, spack_cxx))
if "+mpi" in spec:
# Use the correct mpi compiler. If the compiler options are
@@ -584,7 +586,7 @@ class Boost(Package):
options.extend(["link=%s" % ",".join(link_types), "--layout=%s" % layout])
- if not spec.satisfies("@:1.75 %intel"):
+ if not spec.satisfies("@:1.75 %intel") and not spec.satisfies("platform=windows"):
# When building any version >= 1.76, the toolset must be specified.
# Earlier versions could not specify Intel as the toolset
# as that was considered to be redundant/conflicting with
@@ -634,7 +636,7 @@ class Boost(Package):
return threading_opts
def add_buildopt_symlinks(self, prefix):
- with working_dir(prefix.lib):
+ with working_dir(prefix.lib, create=True):
for lib in os.listdir(os.curdir):
if os.path.isfile(lib):
prefix, remainder = lib.split(".", 1)
@@ -687,12 +689,15 @@ class Boost(Package):
# to make Boost find the user-config.jam
env["BOOST_BUILD_PATH"] = self.stage.source_path
- bootstrap = Executable("./bootstrap.sh")
-
bootstrap_options = ["--prefix=%s" % prefix]
self.determine_bootstrap_options(spec, with_libs, bootstrap_options)
- bootstrap(*bootstrap_options)
+ if self.spec.satisfies("platform=windows"):
+ bootstrap = Executable("cmd.exe")
+ bootstrap("/c", ".\\bootstrap.bat", *bootstrap_options)
+ else:
+ bootstrap = Executable("./bootstrap.sh")
+ bootstrap(*bootstrap_options)
# strip the toolchain to avoid double include errors (intel) or
# user-config being overwritten (again intel, but different boost version)
@@ -704,6 +709,8 @@ class Boost(Package):
# b2 used to be called bjam, before 1.47 (sigh)
b2name = "./b2" if spec.satisfies("@1.47:") else "./bjam"
+ if self.spec.satisfies("platform=windows"):
+ b2name = "b2.exe" if spec.satisfies("@1.47:") else "bjam.exe"
b2 = Executable(b2name)
jobs = make_jobs
@@ -711,11 +718,14 @@ class Boost(Package):
if jobs > 64 and spec.satisfies("@:1.58"):
jobs = 64
- b2_options = [
- "-j",
- "%s" % jobs,
- "--user-config=%s" % os.path.join(self.stage.source_path, "user-config.jam"),
- ]
+ # Windows just wants a b2 call with no args
+ b2_options = []
+ if not self.spec.satisfies("platform=windows"):
+ path_to_config = "--user-config=%s" % os.path.join(
+ self.stage.source_path, "user-config.jam"
+ )
+ b2_options = ["-j", "%s" % jobs]
+ b2_options.append(path_to_config)
threading_opts = self.determine_b2_options(spec, b2_options)
@@ -727,8 +737,11 @@ class Boost(Package):
# In theory it could be done on one call but it fails on
# Boost.MPI if the threading options are not separated.
- for threading_opt in threading_opts:
- b2("install", "threading=%s" % threading_opt, *b2_options)
+ if not self.spec.satisfies("platform=windows"):
+ for threading_opt in threading_opts:
+ b2("install", "threading=%s" % threading_opt, *b2_options)
+ else:
+ b2("install", *b2_options)
if "+multithreaded" in spec and "~taggedlayout" in spec:
self.add_buildopt_symlinks(prefix)
diff --git a/var/spack/repos/builtin/packages/openblas/ifort-msvc.patch b/var/spack/repos/builtin/packages/openblas/ifort-msvc.patch
new file mode 100644
index 0000000000..dd4c97fdd8
--- /dev/null
+++ b/var/spack/repos/builtin/packages/openblas/ifort-msvc.patch
@@ -0,0 +1,13 @@
+diff -ruN spack-src/cmake/fc.cmake spack-src-new/cmake/fc.cmake
+--- spack-src/cmake/fc.cmake 2023-04-01 14:18:01.000000000 -0600
++++ spack-src-new/cmake/fc.cmake 2023-06-06 09:34:12.921982500 -0600
+@@ -89,6 +89,9 @@
+
+ if (${F_COMPILER} STREQUAL "INTEL")
+ set(CCOMMON_OPT "${CCOMMON_OPT} -DF_INTERFACE_INTEL")
++ if (MSVC)
++ set(FCOMMON_OPT "${FCOMMON_OPT} -names:uppercase -assume:underscore")
++ endif ()
+ if (INTERFACE64)
+ set(FCOMMON_OPT "${FCOMMON_OPT} -i8")
+ endif ()
diff --git a/var/spack/repos/builtin/packages/openblas/package.py b/var/spack/repos/builtin/packages/openblas/package.py
index 8b00d2983c..e194a366e4 100644
--- a/var/spack/repos/builtin/packages/openblas/package.py
+++ b/var/spack/repos/builtin/packages/openblas/package.py
@@ -6,11 +6,13 @@
import os
import re
+import spack.build_systems.cmake
+import spack.build_systems.makefile
from spack.package import *
from spack.package_test import compare_output_file, compile_c_and_execute
-class Openblas(MakefilePackage):
+class Openblas(CMakePackage, MakefilePackage):
"""OpenBLAS: An optimized BLAS library"""
homepage = "https://www.openblas.net"
@@ -19,7 +21,7 @@ class Openblas(MakefilePackage):
)
git = "https://github.com/OpenMathLib/OpenBLAS.git"
- libraries = ["libopenblas"]
+ libraries = ["libopenblas", "openblas"]
version("develop", branch="develop")
version("0.3.24", sha256="ceadc5065da97bd92404cac7254da66cc6eb192679cf1002098688978d4d5132")
@@ -91,6 +93,9 @@ class Openblas(MakefilePackage):
provides("lapack@3.9.1:", when="@0.3.15:")
provides("lapack@3.7.0", when="@0.2.20")
+ # https://github.com/xianyi/OpenBLAS/pull/2519/files
+ patch("ifort-msvc.patch", when="%msvc")
+
# https://github.com/OpenMathLib/OpenBLAS/pull/3712
patch("cce.patch", when="@0.3.20 %cce")
@@ -213,6 +218,8 @@ class Openblas(MakefilePackage):
depends_on("perl", type="build")
+ build_system("makefile", "cmake", default="makefile")
+
def flag_handler(self, name, flags):
spec = self.spec
iflags = []
@@ -242,13 +249,37 @@ class Openblas(MakefilePackage):
# require both.
# As of 08/2022 (0.3.21), we can build purely with a C compiler using
# a f2c translated LAPACK version
- # https://github.com/OpenMathLib/OpenBLAS/releases/tag/v0.3.21
+ # https://github.com/xianyi/OpenBLAS/releases/tag/v0.3.21
if self.compiler.fc is None and "~fortran" not in self.spec:
raise InstallError(
self.compiler.cc
+ " has no Fortran compiler added in spack. Add it or use openblas~fortran!"
)
+ @property
+ def headers(self):
+ # The only public headers for cblas and lapacke in
+ # openblas are cblas.h and lapacke.h. The remaining headers are private
+ # headers either included in one of these two headers, or included in
+ # one of the source files implementing functions declared in these
+ # headers.
+ return find_headers(["cblas", "lapacke"], self.prefix.include)
+
+ @property
+ def libs(self):
+ spec = self.spec
+
+ # Look for openblas{symbol_suffix}
+ name = ["libopenblas", "openblas"]
+ search_shared = bool(spec.variants["shared"].value)
+ suffix = spec.variants["symbol_suffix"].value
+ if suffix != "none":
+ name += suffix
+
+ return find_libraries(name, spec.prefix, shared=search_shared, recursive=True)
+
+
+class MakefileBuilder(spack.build_systems.makefile.MakefileBuilder):
@staticmethod
def _read_targets(target_file):
"""Parse a list of available targets from the OpenBLAS/TargetList.txt
@@ -304,7 +335,7 @@ class Openblas(MakefilePackage):
if microarch.name in available_targets:
break
- if self.version >= Version("0.3"):
+ if self.spec.version >= Version("0.3"):
# 'ARCH' argument causes build errors in older OpenBLAS
# see https://github.com/spack/spack/issues/15385
arch_name = microarch.family.name
@@ -379,9 +410,9 @@ class Openblas(MakefilePackage):
if "~shared" in self.spec:
if "+pic" in self.spec:
- make_defs.append("CFLAGS={0}".format(self.compiler.cc_pic_flag))
+ make_defs.append("CFLAGS={0}".format(self.pkg.compiler.cc_pic_flag))
if "~fortran" not in self.spec:
- make_defs.append("FFLAGS={0}".format(self.compiler.f77_pic_flag))
+ make_defs.append("FFLAGS={0}".format(self.pkg.compiler.f77_pic_flag))
make_defs += ["NO_SHARED=1"]
# fix missing _dggsvd_ and _sggsvd_
if self.spec.satisfies("@0.2.16"):
@@ -443,28 +474,6 @@ class Openblas(MakefilePackage):
return make_defs
@property
- def headers(self):
- # As in netlib-lapack, the only public headers for cblas and lapacke in
- # openblas are cblas.h and lapacke.h. The remaining headers are private
- # headers either included in one of these two headers, or included in
- # one of the source files implementing functions declared in these
- # headers.
- return find_headers(["cblas", "lapacke"], self.prefix.include)
-
- @property
- def libs(self):
- spec = self.spec
-
- # Look for openblas{symbol_suffix}
- name = "libopenblas"
- search_shared = bool(spec.variants["shared"].value)
- suffix = spec.variants["symbol_suffix"].value
- if suffix != "none":
- name += suffix
-
- return find_libraries(name, spec.prefix, shared=search_shared, recursive=True)
-
- @property
def build_targets(self):
return ["-s"] + self.make_defs + ["all"]
@@ -499,3 +508,28 @@ class Openblas(MakefilePackage):
output = compile_c_and_execute(source_file, [include_flags], link_flags.split())
compare_output_file(output, blessed_file)
+
+
+class CMakeBuilder(spack.build_systems.cmake.CMakeBuilder):
+ def cmake_args(self):
+ cmake_defs = [self.define("TARGET", "GENERIC")]
+ if self.spec.satisfies("platform=windows"):
+ cmake_defs += [
+ self.define("DYNAMIC_ARCH", "OFF"),
+ self.define("BUILD_WITHOUT_LAPACK", "ON"),
+ ]
+
+ if "~fortran" in self.spec:
+ cmake_defs += [self.define("NOFORTRAN", "ON")]
+
+ if "+shared" in self.spec:
+ cmake_defs += [self.define("BUILD_SHARED_LIBS", "ON")]
+
+ if self.spec.satisfies("threads=openmp"):
+ cmake_defs += [self.define("USE_OPENMP", "ON"), self.define("USE_THREAD", "ON")]
+ elif self.spec.satisfies("threads=pthreads"):
+ cmake_defs += [self.define("USE_OPENMP", "OFF"), self.define("USE_THREAD", "ON")]
+ else:
+ cmake_defs += [self.define("USE_OPENMP", "OFF"), self.define("USE_THREAD", "OFF")]
+
+ return cmake_defs
diff --git a/var/spack/repos/builtin/packages/pcre/package.py b/var/spack/repos/builtin/packages/pcre/package.py
index 4e6e047335..4719f5ea37 100644
--- a/var/spack/repos/builtin/packages/pcre/package.py
+++ b/var/spack/repos/builtin/packages/pcre/package.py
@@ -3,10 +3,12 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+import spack.build_systems.autotools
+import spack.build_systems.cmake
from spack.package import *
-class Pcre(AutotoolsPackage):
+class Pcre(AutotoolsPackage, CMakePackage):
"""The PCRE package contains Perl Compatible Regular Expression
libraries. These are useful for implementing regular expression
pattern matching using the same syntax and semantics as Perl 5."""
@@ -26,6 +28,8 @@ class Pcre(AutotoolsPackage):
maintainers("drkennetz")
patch("intel.patch", when="@8.38")
+ build_system("autotools", "cmake", default="autotools")
+
variant("jit", default=False, description="Enable JIT support.")
variant("multibyte", default=True, description="Enable support for 16 and 32 bit characters.")
@@ -36,6 +40,8 @@ class Pcre(AutotoolsPackage):
description="Enable support for UTF-8/16/32, " "incompatible with EBCDIC.",
)
+
+class AutotoolsBuilder(spack.build_systems.autotools.AutotoolsBuilder):
def configure_args(self):
args = []
@@ -51,3 +57,21 @@ class Pcre(AutotoolsPackage):
args.append("--enable-unicode-properties")
return args
+
+
+class CMakeBuilder(spack.build_systems.cmake.CMakeBuilder):
+ def cmake_args(self):
+ args = []
+
+ if "+jit" in self.spec:
+ args.append("-DPCRE_SUPPORT_JIT:BOOL=ON")
+
+ if "+multibyte" in self.spec:
+ args.append("-DPCRE_BUILD_PCRE16:BOOL=ON")
+ args.append("-DPCRE_BUILD_PCRE32:BOOL=ON")
+
+ if "+utf" in self.spec:
+ args.append("-DPCRE_SUPPORT_UTF:BOOL=ON")
+ args.append("-DPCRE_SUPPORT_UNICODE_PROPERTIES:BOOL=ON")
+
+ return args
diff --git a/var/spack/repos/builtin/packages/superlu/package.py b/var/spack/repos/builtin/packages/superlu/package.py
index fd7f66d4d0..9ad86ab219 100644
--- a/var/spack/repos/builtin/packages/superlu/package.py
+++ b/var/spack/repos/builtin/packages/superlu/package.py
@@ -46,6 +46,8 @@ class Superlu(CMakePackage, Package):
conditional("cmake", when="@5:"), conditional("generic", when="@:4"), default="cmake"
)
+ requires("build_system=cmake", when="platform=windows")
+
variant("pic", default=True, description="Build with position independent code")
depends_on("blas")
diff --git a/var/spack/repos/builtin/packages/trilinos/package.py b/var/spack/repos/builtin/packages/trilinos/package.py
index 20a8d290e2..28f68b1b48 100644
--- a/var/spack/repos/builtin/packages/trilinos/package.py
+++ b/var/spack/repos/builtin/packages/trilinos/package.py
@@ -4,6 +4,7 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
+import pathlib
import sys
from spack.build_environment import dso_suffix
@@ -366,6 +367,18 @@ class Trilinos(CMakePackage, CudaPackage, ROCmPackage):
conflicts("+stokhos", when="%xl")
conflicts("+stokhos", when="%xl_r")
+ # Current Windows support, only have serial static builds
+ conflicts(
+ "+shared",
+ when="platform=windows",
+ msg="Only static builds are supported on Windows currently.",
+ )
+ conflicts(
+ "+mpi",
+ when="platform=windows",
+ msg="Only serial builds are supported on Windows currently.",
+ )
+
# ###################### Dependencies ##########################
# External Kokkos
@@ -393,7 +406,9 @@ class Trilinos(CMakePackage, CudaPackage, ROCmPackage):
depends_on("cgns", when="+exodus")
depends_on("cmake@3.23:", type="build", when="@14.0.0:")
depends_on("hdf5+hl", when="+hdf5")
- depends_on("hypre~internal-superlu~int64", when="+hypre")
+ for plat in ["cray", "darwin", "linux"]:
+ depends_on("hypre~internal-superlu~int64", when="+hypre platform=%s" % plat)
+ depends_on("hypre-cmake~int64", when="+hypre platform=windows")
depends_on("kokkos-nvcc-wrapper", when="+wrapper")
depends_on("lapack")
# depends_on('perl', type=('build',)) # TriBITS finds but doesn't use...
@@ -811,7 +826,7 @@ class Trilinos(CMakePackage, CudaPackage, ROCmPackage):
define("CMAKE_C_COMPILER", spec["mpi"].mpicc),
define("CMAKE_CXX_COMPILER", spec["mpi"].mpicxx),
define("CMAKE_Fortran_COMPILER", spec["mpi"].mpifc),
- define("MPI_BASE_DIR", spec["mpi"].prefix),
+ define("MPI_BASE_DIR", str(pathlib.PurePosixPath(spec["mpi"].prefix))),
]
)