Windows: Support for Clingo and dependencies (#30690)

Make it possible to install the Clingo package on Windows; this
also provides a means to use Clingo with Spack on Windows.

This includes

* A new "winbison" package: Windows has a port of bison and flex where
  the two packages are grouped together. Clingo dependencies have been
  updated to use winbison on Windows and bison elsewhere (this avoids
  complicating the existin bison/flex packages until we can add support
  for implied virtuals).
* The CMake build system was incorrectly converting CMAKE_INSTALL_PREFIX
  to POSIX format.
* The re2c package has been modified to use CMake on Windows; for now
  this is done by overloading the configure/build/install methods to
  perform CMake-appropriate operations; the package should be refactored
  once support for multiple build systems in one Package is available.
This commit is contained in:
John W. Parent 2022-09-28 11:54:00 -04:00 committed by GitHub
parent db2565cb53
commit 650a668a9d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 130 additions and 16 deletions

View file

@ -46,6 +46,8 @@
#: Name of the file containing metadata about the bootstrapping source
METADATA_YAML_FILENAME = "metadata.yaml"
is_windows = sys.platform == "win32"
#: Map a bootstrapper type to the corresponding class
_bootstrap_methods = {}
@ -655,6 +657,8 @@ def _add_externals_if_missing():
# GnuPG
spack.repo.path.get_pkg_class("gawk"),
]
if is_windows:
search_list.extend(spack.repo.path.get_pkg_class("winbison"))
detected_packages = spack.detection.by_executable(search_list)
spack.detection.update_configuration(detected_packages, scope="bootstrap")

View file

@ -109,7 +109,14 @@
# Platform-specific library suffix.
dso_suffix = "dylib" if sys.platform == "darwin" else "so"
if sys.platform == "darwin":
dso_suffix = "dylib"
elif sys.platform == "win32":
dso_suffix = "dll"
else:
dso_suffix = "so"
stat_suffix = "lib" if sys.platform == "win32" else "a"
def should_set_parallel_jobs(jobserver_support=False):

View file

@ -19,7 +19,6 @@
import spack.build_environment
from spack.directives import conflicts, depends_on, variant
from spack.package_base import InstallError, PackageBase, run_after
from spack.util.path import convert_to_posix_path
# Regex to extract the primary generator from the CMake generator
# string.
@ -176,7 +175,7 @@ def _std_args(pkg):
args = [
"-G",
generator,
define("CMAKE_INSTALL_PREFIX", convert_to_posix_path(pkg.prefix)),
define("CMAKE_INSTALL_PREFIX", pkg.prefix),
define("CMAKE_BUILD_TYPE", build_type),
define("BUILD_TESTING", pkg.run_tests),
]

View file

@ -634,12 +634,11 @@ def configuration_dir(tmpdir_factory, linux_os):
# Slightly modify config.yaml and compilers.yaml
if is_windows:
solver = "original"
locks = False
else:
solver = os.environ.get("SPACK_TEST_SOLVER", "clingo")
locks = True
solver = os.environ.get("SPACK_TEST_SOLVER", "clingo")
config_yaml = test_config.join("config.yaml")
modules_root = tmpdir_factory.mktemp("share")
tcl_root = modules_root.ensure("modules", dir=True)

View file

@ -67,6 +67,8 @@ def setup_build_environment(self, env):
if "+static_libstdcpp" in self.spec:
# This is either linux or cray
opts = "-static-libstdc++ -static-libgcc -Wl,--exclude-libs,ALL"
elif "platform=windows" in self.spec:
pass
else:
msg = 'unexpected compiler for spec "{0}"'.format(self.spec)
raise RuntimeError(msg)

View file

@ -3,6 +3,7 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
from spack.compiler import UnsupportedCompilerFlag
from spack.package import *
@ -45,14 +46,22 @@ class Clingo(CMakePackage):
with when("@spack,master"):
depends_on("re2c@0.13:", type="build")
depends_on("bison@2.5:", type="build")
depends_on("bison@2.5:", type="build", when="platform=linux")
depends_on("bison@2.5:", type="build", when="platform=darwin")
depends_on("bison@2.5:", type="build", when="platform=cray")
with when("platform=windows"):
depends_on("re2c@0.13:", type="build")
depends_on("winbison@2.4.12:")
with when("+python"):
extends("python")
depends_on("python", type=("build", "link", "run"))
# Clingo 5.5.0 supports Python 3.6 or later and needs CFFI
depends_on("python@3.6.0:", type=("build", "link", "run"), when="@5.5.0:")
depends_on("py-cffi", type=("build", "run"), when="@5.5.0:")
depends_on("py-cffi", type=("build", "run"), when="@5.5.0: platform=darwin")
depends_on("py-cffi", type=("build", "run"), when="@5.5.0: platform=linux")
depends_on("py-cffi", type=("build", "run"), when="@5.5.0: platform=cray")
patch("python38.patch", when="@5.3:5.4.0")

View file

@ -20,7 +20,7 @@
)
from llnl.util.lang import dedupe, match_predicate
from spack.build_environment import dso_suffix
from spack.build_environment import dso_suffix, stat_suffix
from spack.package import *
from spack.util.environment import is_system_path
from spack.util.prefix import Prefix
@ -1105,10 +1105,12 @@ def config_vars(self):
)
dag_hash = self.spec.dag_hash()
lib_prefix = "lib" if not is_windows else ""
if dag_hash not in self._config_vars:
# Default config vars
version = self.version.up_to(2)
if is_windows:
version = str(version).split(".")[0]
config = {
# get_config_vars
"BINDIR": self.prefix.bin,
@ -1121,8 +1123,8 @@ def config_vars(self):
"LIBPL": self.prefix.lib.join("python{0}")
.join("config-{0}-{1}")
.format(version, sys.platform),
"LDLIBRARY": "libpython{}.{}".format(version, dso_suffix),
"LIBRARY": "libpython{}.a".format(version),
"LDLIBRARY": "{}python{}.{}".format(lib_prefix, version, dso_suffix),
"LIBRARY": "{}python{}.{}".format(lib_prefix, version, stat_suffix),
"LDSHARED": "cc",
"LDCXXSHARED": "c++",
"PYTHONFRAMEWORKPREFIX": "/System/Library/Frameworks",
@ -1210,8 +1212,16 @@ def find_library(self, library):
# Windows libraries are installed directly to BINDIR
win_bin_dir = self.config_vars["BINDIR"]
win_root_dir = self.config_vars["prefix"]
directories = [libdir, libpl, frameworkprefix, macos_developerdir, win_bin_dir]
directories = [
libdir,
libpl,
frameworkprefix,
macos_developerdir,
win_bin_dir,
win_root_dir,
]
# The Python shipped with Xcode command line tools isn't in any of these locations
for subdir in ["lib", "lib64"]:
@ -1226,17 +1236,19 @@ def find_library(self, library):
@property
def libs(self):
py_version = self.version.up_to(2)
if is_windows:
py_version = str(py_version).replace(".", "")
lib_prefix = "lib" if not is_windows else ""
# The values of LDLIBRARY and LIBRARY aren't reliable. Intel Python uses a
# static binary but installs shared libraries, so sysconfig reports
# libpythonX.Y.a but only libpythonX.Y.so exists. So we add our own paths, too.
shared_libs = [
self.config_vars["LDLIBRARY"],
"libpython{}.{}".format(py_version, dso_suffix),
"{}python{}.{}".format(lib_prefix, py_version, dso_suffix),
]
static_libs = [
self.config_vars["LIBRARY"],
"libpython{}.a".format(py_version),
"{}python{}.{}".format(lib_prefix, py_version, stat_suffix),
]
# The +shared variant isn't reliable, as `spack external find` currently can't
@ -1246,6 +1258,7 @@ def libs(self):
candidates = shared_libs + static_libs
else:
candidates = static_libs + shared_libs
candidates = dedupe(candidates)
for candidate in candidates:

View file

@ -3,10 +3,14 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import sys
from spack.package import *
is_windows = sys.platform == "win32"
class Re2c(AutotoolsPackage):
class Re2c(Package):
"""re2c: a free and open-source lexer generator for C and C++"""
homepage = "https://re2c.org/index.html"
@ -22,6 +26,15 @@ class Re2c(AutotoolsPackage):
version("1.3", sha256="f37f25ff760e90088e7d03d1232002c2c2672646d5844fdf8e0d51a5cd75a503")
version("1.2.1", sha256="1a4cd706b5b966aeffd78e3cf8b24239470ded30551e813610f9cd1a4e01b817")
phases = ["configure", "build", "install"]
@property
def make_tool(self):
if is_windows:
return ninja
else:
return make
def configure_args(self):
return [
"--disable-benchmarks",
@ -32,3 +45,21 @@ def configure_args(self):
"--disable-libs", # experimental
"--enable-golang",
]
def configure(self, spec, prefix):
with working_dir(self.stage.source_path, create=True):
configure("--prefix=" + prefix, *self.configure_args())
@when("platform=windows")
def configure(self, spec, prefix):
with working_dir(self.stage.source_path, create=True):
args = ["-G", "Ninja", "-DCMAKE_INSTALL_PREFIX=%s" % prefix]
cmake(*args)
def build(self, spec, prefix):
with working_dir(self.stage.source_path):
self.make_tool()
def install(self, spec, prefix):
with working_dir(self.stage.source_path):
self.make_tool("install")

View file

@ -0,0 +1,50 @@
# 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 os
import re
from spack.package import *
class Winbison(CMakePackage):
"""Bison is a general-purpose parser generator that converts
an annotated context-free grammar into a deterministic LR or
generalized LR (GLR) parser employing LALR(1) parser tables."""
homepage = "https://github.com/lexxmark/winflexbison#readme"
url = "https://github.com/lexxmark/winflexbison/archive/v2.5.25.tar.gz"
executables = [r"^bison(.*)?$"]
version("2.5.25", sha256="8e1b71e037b524ba3f576babb0cf59182061df1f19cd86112f085a882560f60b")
version("2.5.24", sha256="a49d6e310636e3487e1e066e411d908cfeae2d5b5fde1f3cf74fe1d6d4301062")
version("2.5.23", sha256="445bd1bcb90e0c84e97f6e44de76869f8e778c60ddbd7c39a7b2142f8ba43e61")
version("2.5.22", sha256="697c2c4af3308625605b75498bd63a9a294660f8e43a4c35452cf4334fa4a530")
version("2.5.21", sha256="41e31960cc7e8ccd4b95bd770a6279d31ab7dee156e6fb4e55834f8f220637f4")
version("2.5.20", sha256="cd29f888f167128c22211444c6e31b5f4823a7de0e23d8039559ee87b80349c9")
version("2.5.19", sha256="265f930e5b2e8e24d179d703668355550b226d033fdbe0a9232c671591ddfd0b")
version("2.5.18", sha256="1db991bebaded832427539b6b28a8f36948e5ce3db5701b5104f85b66b8484de")
version("2.5.17", sha256="2ab4c895f9baf03dfdfbb2dc4abe60e87bf46efe12ed1218c38fd7761f0f58fc")
version("2.5.16", sha256="39fe57de6a52dc83c8a9ece90b8484d8d2b764e24e22e30ba5dc018328019a4d")
version("2.5.15", sha256="a5ea5b98bb8d4054961f7bc82f458b4a9ef60c5e2dedcaba23a8e4363c2e6dfc")
version("2.5.14", sha256="2ace5c964fb4b45279544669950412dbe4e86908c03bd5ebc8c8d306e458e97d")
version("2.4.12", sha256="fcffc223897e14f2b5dce2db1c832f297cc43a1204e4b3fd713f1dc410e956e4")
build_directory = "spack-build"
cmake_dir = os.path.join(build_directory, "CMakeBuild")
variant(
"build_type",
default="Release",
description="CMake build type",
values=("Debug", "Release", "RelWithDebInfo", "MinSizeRel"),
)
@classmethod
def determine_version(cls, exe):
output = Executable(exe)("--version", output=str, error=str)
match = re.search(r"bison )\s+(\S+)", output)
return match.group(1) if match else None