From 717d4800e1a6355020e73d60039efad54462199e Mon Sep 17 00:00:00 2001 From: "John W. Parent" <45471568+johnwparent@users.noreply.github.com> Date: Mon, 7 Oct 2024 16:33:25 -0400 Subject: Qt package: Add Windows Port (#46788) Also adds support for Paraview and CMake to build with Qt support on Windows. The remaining edits are to enable building of Qt itself on Windows: * Several packages needed to update `.libs` to properly locate libraries on Windows * Qt needed a patch to allow it to build using a Python with a space in the path * Some Qt dependencies had not been ported to Windows yet (e.g. `harfbuzz` and `lcms`) This PR does not provide a sufficient GL for Qt to use Qt Quick2, as such Qt Quick2 is disabled on the Windows platform by this PR. --------- Co-authored-by: Dan Lipsa --- lib/spack/spack/compilers/msvc.py | 11 ++ var/spack/repos/builtin/packages/cmake/package.py | 42 ++++--- .../repos/builtin/packages/harfbuzz/package.py | 20 ++- var/spack/repos/builtin/packages/lcms/package.py | 25 +++- .../builtin/packages/libjpeg-turbo/package.py | 5 +- var/spack/repos/builtin/packages/libpng/package.py | 4 +- var/spack/repos/builtin/packages/meson/package.py | 10 +- var/spack/repos/builtin/packages/nasm/package.py | 5 + .../repos/builtin/packages/openssl/package.py | 9 +- .../repos/builtin/packages/paraview/package.py | 18 ++- var/spack/repos/builtin/packages/pcre/package.py | 4 + var/spack/repos/builtin/packages/pcre2/package.py | 54 +++++++-- var/spack/repos/builtin/packages/qt/package.py | 135 ++++++++++++++------- .../builtin/packages/qt/qt515_masm_python.patch | 22 ++++ var/spack/repos/builtin/packages/sqlite/package.py | 3 +- .../repos/builtin/packages/zlib-ng/package.py | 12 +- 16 files changed, 289 insertions(+), 90 deletions(-) create mode 100644 var/spack/repos/builtin/packages/qt/qt515_masm_python.patch diff --git a/lib/spack/spack/compilers/msvc.py b/lib/spack/spack/compilers/msvc.py index 0954d0b7d3..c3e9e13d71 100644 --- a/lib/spack/spack/compilers/msvc.py +++ b/lib/spack/spack/compilers/msvc.py @@ -293,6 +293,17 @@ class Msvc(Compiler): vs22_toolset = Version(toolset_ver) > Version("142") return toolset_ver if not vs22_toolset else "143" + @property + def visual_studio_version(self): + """The four digit Visual Studio version (i.e. 2019 or 2022) + + Note: This differs from the msvc version or toolset version as + those properties track the compiler and build tools version + respectively, whereas this tracks the VS release associated + with a given MSVC compiler. + """ + return re.search(r"[0-9]{4}", self.cc).group(0) + def _compiler_version(self, compiler): """Returns version object for given compiler""" # ignore_errors below is true here due to ifx's diff --git a/var/spack/repos/builtin/packages/cmake/package.py b/var/spack/repos/builtin/packages/cmake/package.py index 676fc26180..e4afbe2802 100644 --- a/var/spack/repos/builtin/packages/cmake/package.py +++ b/var/spack/repos/builtin/packages/cmake/package.py @@ -114,6 +114,23 @@ class Cmake(Package): values=("Debug", "Release", "RelWithDebInfo", "MinSizeRel"), ) + # 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 + # the build. + variant("ownlibs", default=True, description="Use CMake-provided third-party libraries") + variant( + "doc", + default=False, + description="Enables the generation of html and man page documentation", + ) + variant( + "ncurses", + default=sys.platform != "win32", + description="Enables the build of the ncurses gui", + ) + variant("qtgui", default=False, description="Enables the build of the Qt GUI") + # Revert the change that introduced a regression when parsing mpi link # flags, see: https://gitlab.kitware.com/cmake/cmake/issues/19516 patch("cmake-revert-findmpi-link-flag-list.patch", when="@3.15.0") @@ -139,21 +156,7 @@ class Cmake(Package): depends_on("gmake", when="platform=darwin") depends_on("gmake", when="platform=freebsd") - # 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 - # the build. - variant("ownlibs", default=True, description="Use CMake-provided third-party libraries") - variant( - "doc", - default=False, - description="Enables the generation of html and man page documentation", - ) - variant( - "ncurses", - default=sys.platform != "win32", - description="Enables the build of the ncurses gui", - ) + depends_on("qt", when="+qtgui") # See https://gitlab.kitware.com/cmake/cmake/-/issues/21135 conflicts( @@ -183,7 +186,7 @@ class Cmake(Package): with when("~ownlibs"): depends_on("expat") # expat/zlib are used in CMake/CTest, so why not require them in libarchive. - for plat in ["darwin", "linux"]: + for plat in ["darwin", "linux", "freebsd"]: with when("platform=%s" % plat): depends_on("libarchive@3.1.0: xar=expat compression=zlib") depends_on("libarchive@3.3.3:", when="@3.15.0:") @@ -311,12 +314,16 @@ class Cmake(Package): # Whatever +/~ownlibs, use system curl. args.append("--system-curl") - args.append("--no-qt-gui") if spec.satisfies("+doc"): args.append("--sphinx-html") args.append("--sphinx-man") + if spec.satisfies("+qtgui"): + args.append("--qt-gui") + else: + args.append("--no-qt-gui") + # Now for CMake arguments to pass after the initial bootstrap args.append("--") else: @@ -329,6 +336,7 @@ class Cmake(Package): # inside a ctest environment "-DCMake_TEST_INSTALL=OFF", f"-DBUILD_CursesDialog={'ON' if '+ncurses' in spec else 'OFF'}", + f"-DBUILD_QtDialog={'ON' if spec.satisfies('+qtgui') else 'OFF'}", ] ) diff --git a/var/spack/repos/builtin/packages/harfbuzz/package.py b/var/spack/repos/builtin/packages/harfbuzz/package.py index ca7db7be1f..d0ee982fb5 100644 --- a/var/spack/repos/builtin/packages/harfbuzz/package.py +++ b/var/spack/repos/builtin/packages/harfbuzz/package.py @@ -2,10 +2,14 @@ # Spack Project Developers. See the top-level COPYRIGHT file for details. # # SPDX-License-Identifier: (Apache-2.0 OR MIT) +import sys + import spack.build_systems.autotools import spack.build_systems.meson from spack.package import * +IS_WINDOWS = sys.platform == "win32" + class Harfbuzz(MesonPackage, AutotoolsPackage): """The Harfbuzz package contains an OpenType text shaping engine.""" @@ -84,12 +88,15 @@ class Harfbuzz(MesonPackage, AutotoolsPackage): description="Enable CoreText shaper backend on macOS", ) - depends_on("pkgconfig", type="build") - depends_on("glib") - depends_on("gobject-introspection") + for plat in ["linux", "darwin", "freebsd"]: + with when(f"platform={plat}"): + depends_on("pkgconfig", type="build") + depends_on("glib") + depends_on("gobject-introspection") + depends_on("cairo+pdf+ft") + depends_on("icu4c") depends_on("freetype") - depends_on("cairo+pdf+ft") depends_on("zlib-api") depends_on("graphite2", when="+graphite2") @@ -137,13 +144,16 @@ class MesonBuilder(spack.build_systems.meson.MesonBuilder, SetupEnvironment): def meson_args(self): graphite2 = "enabled" if self.pkg.spec.satisfies("+graphite2") else "disabled" coretext = "enabled" if self.pkg.spec.satisfies("+coretext") else "disabled" - return [ + config_args = [ # disable building of gtk-doc files following #9885 and #9771 "-Ddocs=disabled", "-Dfreetype=enabled", f"-Dgraphite2={graphite2}", f"-Dcoretext={coretext}", ] + if IS_WINDOWS: + config_args.extend(["-Dcairo=disabled", "-Dglib=disabled"]) + return config_args class AutotoolsBuilder(spack.build_systems.autotools.AutotoolsBuilder, SetupEnvironment): diff --git a/var/spack/repos/builtin/packages/lcms/package.py b/var/spack/repos/builtin/packages/lcms/package.py index 42ee9af89f..ce452131b2 100644 --- a/var/spack/repos/builtin/packages/lcms/package.py +++ b/var/spack/repos/builtin/packages/lcms/package.py @@ -3,10 +3,12 @@ # # SPDX-License-Identifier: (Apache-2.0 OR MIT) +import pathlib + from spack.package import * -class Lcms(AutotoolsPackage): +class Lcms(AutotoolsPackage, MSBuildPackage): """Little cms is a color management library. Implements fast transforms between ICC profiles. It is focused on speed, and is portable across several platforms (MIT license).""" @@ -35,6 +37,27 @@ class Lcms(AutotoolsPackage): depends_on("libtiff") depends_on("zlib-api") + build_system("autotools", "msbuild") + @property def libs(self): return find_libraries("liblcms2", root=self.prefix, recursive=True) + + +class MSBuildBuilder(spack.build_systems.msbuild.MSBuildBuilder): + @property + def build_directory(self): + return ( + pathlib.Path(self.pkg.stage.source_path) + / "Projects" + / f"VC{self.pkg.compiler.visual_studio_version}" + ) + + def setup_build_environment(self, env): + env.prepend_path( + "INCLUDE", + ";".join([dep.prefix.include for dep in self.spec.dependencies(deptype="link")]), + ) + + def msbuild_args(self): + return ["lcms2.sln"] diff --git a/var/spack/repos/builtin/packages/libjpeg-turbo/package.py b/var/spack/repos/builtin/packages/libjpeg-turbo/package.py index f5364a793c..d26fce407a 100644 --- a/var/spack/repos/builtin/packages/libjpeg-turbo/package.py +++ b/var/spack/repos/builtin/packages/libjpeg-turbo/package.py @@ -3,6 +3,8 @@ # # SPDX-License-Identifier: (Apache-2.0 OR MIT) +import sys + from spack.package import * @@ -111,7 +113,8 @@ class LibjpegTurbo(CMakePackage, AutotoolsPackage): @property def libs(self): shared = self.spec.satisfies("libs=shared") - return find_libraries("libjpeg*", root=self.prefix, shared=shared, recursive=True) + name = "jpeg" if sys.platform == "win32" else "libjpeg*" + return find_libraries(name, root=self.prefix, shared=shared, recursive=True, runtime=False) class CMakeBuilder(spack.build_systems.cmake.CMakeBuilder): diff --git a/var/spack/repos/builtin/packages/libpng/package.py b/var/spack/repos/builtin/packages/libpng/package.py index ef86a2e493..8db93426c5 100644 --- a/var/spack/repos/builtin/packages/libpng/package.py +++ b/var/spack/repos/builtin/packages/libpng/package.py @@ -49,7 +49,9 @@ class Libpng(CMakePackage): # v1.2 does not have a version-less symlink libraries = f"libpng{self.version.up_to(2).joined}" shared = "libs=shared" in self.spec - return find_libraries(libraries, root=self.prefix, shared=shared, recursive=True) + return find_libraries( + libraries, root=self.prefix, shared=shared, recursive=True, runtime=False + ) class CMakeBuilder(CMakeBuilder): diff --git a/var/spack/repos/builtin/packages/meson/package.py b/var/spack/repos/builtin/packages/meson/package.py index afad0e5672..e142fd0966 100644 --- a/var/spack/repos/builtin/packages/meson/package.py +++ b/var/spack/repos/builtin/packages/meson/package.py @@ -2,6 +2,8 @@ # Spack Project Developers. See the top-level COPYRIGHT file for details. # # SPDX-License-Identifier: (Apache-2.0 OR MIT) +import sys + from spack.package import * @@ -179,5 +181,11 @@ class Meson(PythonPackage): if self.spec.satisfies("platform=darwin"): env.set("STRIP", "strip -x") + def _meson_bin_dir(self): + bin_dir = self.spec.prefix.bin + if sys.platform == "win32": + bin_dir = self.spec.prefix.scripts + return bin_dir + def setup_dependent_package(self, module, dspec): - module.meson = Executable(self.spec.prefix.bin.meson) + module.meson = Executable(self._meson_bin_dir().meson) diff --git a/var/spack/repos/builtin/packages/nasm/package.py b/var/spack/repos/builtin/packages/nasm/package.py index c2dbee285f..c3d64e4757 100644 --- a/var/spack/repos/builtin/packages/nasm/package.py +++ b/var/spack/repos/builtin/packages/nasm/package.py @@ -86,3 +86,8 @@ class GenericBuilder(spack.build_systems.generic.GenericBuilder): for file in rdoff: install(file, self.prefix.rdoff) + + def setup_dependent_build_environment(self, env, dependent_spec): + # This is required as NASM installs its binaries into an + # atypical location (i.e. flat in the prefix) + env.prepend_path("PATH", self.pkg.prefix) diff --git a/var/spack/repos/builtin/packages/openssl/package.py b/var/spack/repos/builtin/packages/openssl/package.py index e21d427731..23711ba474 100644 --- a/var/spack/repos/builtin/packages/openssl/package.py +++ b/var/spack/repos/builtin/packages/openssl/package.py @@ -111,6 +111,7 @@ class Openssl(Package): # Uses Fake Autotools, should subclass Package root=self.prefix, recursive=True, shared=self.spec.variants["shared"].value, + runtime=False, ) def handle_fetch_error(self, error): @@ -159,9 +160,11 @@ class Openssl(Package): # Uses Fake Autotools, should subclass Package "--openssldir=%s" % join_path(prefix, "etc", "openssl"), ] if spec.satisfies("platform=windows"): - base_args.extend( - ['CC="%s"' % os.environ.get("CC"), 'CXX="%s"' % os.environ.get("CXX"), "VC-WIN64A"] - ) + if spec.satisfies("@:1"): + base_args.extend([f'CC="{self.compiler.cc}"', f'CXX="{self.compiler.cxx}"']) + else: + base_args.extend([f"CC={self.compiler.cc}", f"CXX={self.compiler.cxx}"]) + base_args.append("VC-WIN64A") else: base_args.extend( [ diff --git a/var/spack/repos/builtin/packages/paraview/package.py b/var/spack/repos/builtin/packages/paraview/package.py index b84f572055..92cbdb8991 100644 --- a/var/spack/repos/builtin/packages/paraview/package.py +++ b/var/spack/repos/builtin/packages/paraview/package.py @@ -11,6 +11,8 @@ from subprocess import Popen from spack.package import * +IS_WINDOWS = sys.platform == "win32" + class Paraview(CMakePackage, CudaPackage, ROCmPackage): """ParaView is an open-source, multi-platform data analysis and @@ -223,16 +225,23 @@ class Paraview(CMakePackage, CudaPackage, ROCmPackage): depends_on("tbb", when="+tbb") depends_on("mpi", when="+mpi") - depends_on("qt+opengl", when="@5.3.0:+qt+opengl2") - depends_on("qt~opengl", when="@5.3.0:+qt~opengl2") + depends_on("qt@:4", when="@:5.2.0+qt") + depends_on("qt+sql", when="+qt") + with when("+qt"): + depends_on("qt+opengl", when="@5.3.0:+opengl2") + depends_on("qt~opengl", when="@5.3.0:~opengl2") depends_on("gl@3.2:", when="+opengl2") depends_on("gl@1.2:", when="~opengl2") depends_on("glew") depends_on("libxt", when="platform=linux ^[virtuals=gl] glx") - requires("^[virtuals=gl] glx", when="+qt", msg="Qt support requires GLX") + for plat in ["linux", "darwin", "freebsd"]: + with when(f"platform={plat}"): + requires( + "^[virtuals=gl] glx", when="+qt", msg="Qt support requires GLX on non Windows" + ) depends_on("ospray@2.1:2", when="+raytracing") depends_on("openimagedenoise", when="+raytracing") @@ -568,6 +577,9 @@ class Paraview(CMakePackage, CudaPackage, ROCmPackage): # so explicitly specify which QT major version is actually being used if spec.satisfies("+qt"): cmake_args.extend(["-DPARAVIEW_QT_VERSION=%s" % spec["qt"].version[0]]) + if IS_WINDOWS: + # Windows does not currently support Qt Quick + cmake_args.append("-DVTK_MODULE_ENABLE_VTK_GUISupportQtQuick:STRING=NO") if "+fortran" in spec: cmake_args.append("-DPARAVIEW_USE_FORTRAN:BOOL=ON") diff --git a/var/spack/repos/builtin/packages/pcre/package.py b/var/spack/repos/builtin/packages/pcre/package.py index 4f7496f19c..e9b4606ce8 100644 --- a/var/spack/repos/builtin/packages/pcre/package.py +++ b/var/spack/repos/builtin/packages/pcre/package.py @@ -57,6 +57,10 @@ class Pcre(AutotoolsPackage, CMakePackage): variant("pic", default=True, description="Enable position-independent code (PIC)") requires("+pic", when="+shared build_system=autotools") + with when("build_system=cmake"): + depends_on("zlib") + depends_on("bzip2") + class AutotoolsBuilder(spack.build_systems.autotools.AutotoolsBuilder): def configure_args(self): diff --git a/var/spack/repos/builtin/packages/pcre2/package.py b/var/spack/repos/builtin/packages/pcre2/package.py index dd2c99f967..eb7186ed4f 100644 --- a/var/spack/repos/builtin/packages/pcre2/package.py +++ b/var/spack/repos/builtin/packages/pcre2/package.py @@ -6,7 +6,7 @@ from spack.package import * -class Pcre2(AutotoolsPackage): +class Pcre2(AutotoolsPackage, CMakePackage): """The PCRE2 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.""" @@ -31,7 +31,33 @@ class Pcre2(AutotoolsPackage): variant("multibyte", default=True, description="Enable support for 16 and 32 bit characters.") variant("jit", default=False, description="enable Just-In-Time compiling support") + # Building static+shared can cause naming colisions and other problems + # for dependents on Windows. It generally does not cause problems on + # other systems, so this variant is not exposed for non-Windows. + variant("shared", default=True, description="build shared pcre2", when="platform=windows") + build_system("autotools", "cmake", default="autotools") + with when("build_system=cmake"): + depends_on("zlib") + depends_on("bzip2") + + @property + def libs(self): + if "+multibyte" in self.spec: + name = "pcre2-32" + else: + name = "pcre2-8" + is_shared = self.spec.satisfies("+shared") + if not self.spec.satisfies("platform=windows"): + name = "lib" + name + if self.spec.satisfies("platform=windows") and not is_shared: + name += "-static" + return find_libraries( + name, root=self.prefix, recursive=True, shared=is_shared, runtime=False + ) + + +class AutotoolsBuilder(spack.build_systems.autotools.AutotoolsBuilder): def configure_args(self): args = [] @@ -44,11 +70,23 @@ class Pcre2(AutotoolsPackage): return args - @property - def libs(self): - if "+multibyte" in self.spec: - name = "libpcre2-32" - else: - name = "libpcre2-8" - return find_libraries(name, root=self.prefix, recursive=True) +class CMakeBuilder(spack.build_systems.cmake.CMakeBuilder): + def cmake_args(self): + args = [] + args.append(self.define_from_variant("PCRE2_BUILD_PCRE2_16", "multibyte")) + args.append(self.define_from_variant("PCRE2_BUILD_PCRE2_32", "multibyte")) + args.append(self.define_from_variant("PCRE2_SUPPORT_JIT", "jit")) + # Don't need to check for on or off, just if the variant is available + # If not specified, the build system will build both static and shared + # by default, this is in parity with the autotools build, so on + # linux and MacOS, the produced binaries are identical, Windows is the + # only outlier + if spec.satisfies("platform=windows"): + args.append(self.define_from_variant("BUILD_SHARED_LIBS", "shared")) + # PCRE allows building shared and static at the same time + # this is bad practice and a problem on some platforms + # Enforce mutual exclusivity here + args.append(self.define("BUILD_STATIC_LIBS", not self.spec.satisfies("+shared"))) + + return args diff --git a/var/spack/repos/builtin/packages/qt/package.py b/var/spack/repos/builtin/packages/qt/package.py index 442edd5d29..9412b9a3df 100644 --- a/var/spack/repos/builtin/packages/qt/package.py +++ b/var/spack/repos/builtin/packages/qt/package.py @@ -15,6 +15,7 @@ from spack.package import * MACOS_VERSION = macos_version() if sys.platform == "darwin" else None LINUX_VERSION = kernel_version() if platform.system() == "Linux" else None +IS_WINDOWS = sys.platform == "win32" class Qt(Package): @@ -69,14 +70,22 @@ class Qt(Package): ) variant("gtk", default=False, description="Build with gtkplus.") variant("gui", default=True, description="Build the Qt GUI module and dependencies") - variant("opengl", default=False, description="Build with OpenGL support.") - variant("location", default=False, when="+opengl", description="Build the Qt Location module.") + # Desktop only on Windows + variant("opengl", default=False, description="Build with OpenGL support") + for plat in ["linux", "darwin", "freebsd"]: + with when(f"platform={plat}"): + # webkit support requires qtquick2 which requires a GL implementation beyond what + # windows system gl provides. + # This is unavailable until we get a hardware accelerated option for EGL 2 on Windows + # We can use llvm or angle for this, but those are not hardware accelerated, so are not + # as useful for things like paraview + variant("webkit", default=False, description="Build the Webkit extension") + variant("location", default=False, description="Build the Qt Location module.") variant("phonon", default=False, description="Build with phonon support.") variant("shared", default=True, description="Build shared libraries.") variant("sql", default=True, description="Build with SQL support.") variant("ssl", default=True, description="Build with OpenSSL support.") variant("tools", default=True, description="Build tools, including Qt Designer.") - variant("webkit", default=False, description="Build the Webkit extension") provides("qmake") @@ -128,6 +137,9 @@ class Qt(Package): patch("qt514-isystem.patch", when="@5.14.2") # https://bugreports.qt.io/browse/QTBUG-84037 patch("qt515-quick3d-assimp.patch", when="@5.15:5+opengl") + # https://forum.qt.io/topic/130793/a-problem-with-python-path-when-i-try-to-build-qt-from-source-e-program-is-not-recognized-as-an-internal-or-external-command?_=1722965446110&lang=en-US + patch("qt515_masm_python.patch", when="@5.15 platform=windows") + # https://bugreports.qt.io/browse/QTBUG-90395 patch( "https://src.fedoraproject.org/rpms/qt5-qtbase/raw/6ae41be8260f0f5403367eb01f7cd8319779674a/f/qt5-qtbase-gcc11.patch", @@ -177,35 +189,65 @@ class Qt(Package): conflicts("%apple-clang@13:", when="@:5.13") # Build-only dependencies - depends_on("pkgconfig", type="build") + for plat in ["linux", "darwin", "freebsd"]: + with when(f"platform={plat}"): + depends_on("pkgconfig", type="build") + depends_on("libsm", when="@3") + depends_on("glib", when="@4:") + depends_on("libmng") + depends_on("assimp@5.0.0:5", when="@5.5:+opengl") + depends_on("sqlite+column_metadata", when="+sql", type=("build", "run")) + depends_on("inputproto", when="@:5.8") + for plat in ["linux", "freebsd"]: + with when(f"platform={plat} +gui"): + depends_on("fontconfig") + depends_on("libsm") + depends_on("libx11") + depends_on("libxcb") + depends_on("libxkbcommon") + depends_on("xcb-util-image") + depends_on("xcb-util-keysyms") + depends_on("xcb-util-renderutil") + depends_on("xcb-util-wm") + depends_on("libxext") + depends_on("libxrender") + + conflicts("+framework", msg="QT cannot be built as a framework except on macOS.") + + with when("platform=windows +sql"): + # Windows sqlite has no column_metadata variant unlike all other platforms + depends_on("sqlite", type=("build", "run")) + + with when("platform=darwin"): + conflicts("@:4.8.6", msg="QT 4 for macOS is only patched for 4.8.7") + conflicts( + "target=aarch64:", + when="@:5.15.3", + msg="Apple Silicon requires a very new version of qt", + ) + depends_on("python", when="@5.7.0:", type="build") # Dependencies, then variant- and version-specific dependencies depends_on("icu4c") depends_on("jpeg") - depends_on("libmng") depends_on("libtiff") depends_on("libxml2") depends_on("zlib-api") depends_on("freetype", when="+gui") depends_on("gtkplus", when="+gtk") - depends_on("sqlite+column_metadata", when="+sql", type=("build", "run")) depends_on("libpng@1.2.57", when="@3") - depends_on("libsm", when="@3") depends_on("pcre+multibyte", when="@5.0:5.8") - depends_on("inputproto", when="@:5.8") with when("+ssl"): depends_on("openssl") depends_on("openssl@:1.0", when="@4:5.9") depends_on("openssl@1.1.1:", when="@5.15.0:") - depends_on("glib", when="@4:") depends_on("libpng", when="@4:") depends_on("dbus", when="@4:+dbus") depends_on("gl", when="@4:+opengl") - depends_on("assimp@5.0.0:5", when="@5.5:+opengl") depends_on("harfbuzz", when="@5:") depends_on("double-conversion", when="@5.7:") @@ -261,32 +303,6 @@ class Qt(Package): conflicts("%oneapi", when="@:5.15.13") patch("qt51514-oneapi.patch", when="@5.15.14: %oneapi") - # Non-macOS dependencies and special macOS constraints - if MACOS_VERSION is None: - with when("+gui"): - depends_on("fontconfig") - depends_on("libsm") - depends_on("libx11") - depends_on("libxcb") - depends_on("libxkbcommon") - depends_on("xcb-util-image") - depends_on("xcb-util-keysyms") - depends_on("xcb-util-renderutil") - depends_on("xcb-util-wm") - depends_on("libxext") - depends_on("libxrender") - - conflicts("+framework", msg="QT cannot be built as a framework except on macOS.") - else: - conflicts( - "platform=darwin", when="@:4.8.6", msg="QT 4 for macOS is only patched for 4.8.7" - ) - conflicts( - "target=aarch64:", - when="@:5.15.3", - msg="Apple Silicon requires a very new version of qt", - ) - # Mapping for compilers/systems in the QT 'mkspecs' compiler_mapping = { "intel": ("icc",), @@ -300,7 +316,7 @@ class Qt(Package): "fj": ("clang",), "gcc": ("g++",), } - platform_mapping = {"darwin": ("macx")} + platform_mapping = {"darwin": ("macx"), "windows": ("win32")} def url_for_version(self, version): # URL keeps getting more complicated with every release @@ -350,7 +366,8 @@ class Qt(Package): return url def setup_build_environment(self, env): - env.set("MAKEFLAGS", "-j{0}".format(make_jobs)) + if not IS_WINDOWS: + env.set("MAKEFLAGS", "-j{0}".format(make_jobs)) if self.version >= Version("5.11"): # QDoc uses LLVM as of 5.11; remove the LLVM_INSTALL_DIR to # disable @@ -372,6 +389,10 @@ class Qt(Package): env.set("QTINC", self.prefix.inc) env.set("QTLIB", self.prefix.lib) env.prepend_path("QT_PLUGIN_PATH", self.prefix.plugins) + if IS_WINDOWS: + # Force Qt to use the desktop provided GL + # on Windows when dependencies are building against Qt + env.set("QT_OPENGL", "desktop") def setup_dependent_package(self, module, dependent_spec): module.qmake = Executable(self.spec.prefix.bin.qmake) @@ -562,18 +583,25 @@ class Qt(Package): self.prefix, "-v", "-opensource", - "-{0}opengl".format("" if "+opengl" in spec else "no-"), "-{0}".format("debug" if "+debug" in spec else "release"), "-confirm-license", "-optimized-qmake", "-no-pch", ] + # Windows currently only supports the desktop provider for opengl + if "+opengl" in spec: + config_args.append("-opengl") + if IS_WINDOWS: + config_args.append("desktop") + else: + config_args.append("-no-opengl") + use_spack_dep = self._dep_appender_factory(config_args) if "+gui" in spec: use_spack_dep("freetype") - if not MACOS_VERSION: + if spec.satisfies("platform=linux") or spec.satisfies("platform=freebsd"): config_args.append("-fontconfig") else: config_args.append("-no-freetype") @@ -716,7 +744,7 @@ class Qt(Package): # Errors on bluetooth even when bluetooth is disabled... # at least on apple-clang%12 config_args.extend(["-skip", "connectivity"]) - elif "+gui" in spec: + elif "+gui" in spec and not IS_WINDOWS: # Linux-only QT5 dependencies if version < Version("5.9.9"): config_args.append("-system-xcb") @@ -756,6 +784,9 @@ class Qt(Package): if version >= Version("5.15"): config_args.extend(["-skip", "qtlocation"]) + if IS_WINDOWS: + config_args.extend(["-skip", "qtspeech"]) + if "~opengl" in spec: config_args.extend(["-skip", "multimedia"]) config_args.extend(["-skip", "qt3d"]) @@ -773,10 +804,11 @@ class Qt(Package): # v5.9: user-selectable internal-vs-external via -assimp # v5.14: additional qtquick3d module uses -assimp # v5.15: qtquick3d switched to the -quick3d-assimp option - if version >= Version("5.9"): - use_spack_dep("assimp") - elif version >= Version("5.15"): - use_spack_dep("assimp", "quick3d-assimp") + if not IS_WINDOWS: + if version >= Version("5.9"): + use_spack_dep("assimp") + elif version >= Version("5.15"): + use_spack_dep("assimp", "quick3d-assimp") if MACOS_VERSION and "+opengl" in spec: # These options are only valid if 'multimedia' is enabled, i.e. @@ -789,13 +821,22 @@ class Qt(Package): # Not currently working for qt@5 config_args.extend(["-device-option", "QMAKE_APPLE_DEVICE_ARCHS=arm64"]) + if IS_WINDOWS: + global configure + configure = Executable("configure.bat") configure(*config_args) def build(self, spec, prefix): - make() + if IS_WINDOWS: + nmake() + else: + make() def install(self, spec, prefix): - make("install") + if IS_WINDOWS: + nmake("install") + else: + make("install") # Documentation generation requires the doc tools to be installed. # @when @run_after currently seems to ignore the 'when' restriction. diff --git a/var/spack/repos/builtin/packages/qt/qt515_masm_python.patch b/var/spack/repos/builtin/packages/qt/qt515_masm_python.patch new file mode 100644 index 0000000000..af599bd182 --- /dev/null +++ b/var/spack/repos/builtin/packages/qt/qt515_masm_python.patch @@ -0,0 +1,22 @@ +diff --git a/masm.pri b/masm-quote.pri +index b67ee79..b757ee5 100644 +--- a/qtdeclarative/src/3rdparty/masm/masm.pri ++++ b/qtdeclarative/src/3rdparty/masm/masm.pri +@@ -58,7 +58,7 @@ contains(DEFINES, WTF_USE_UDIS86=1) { + udis86.output = udis86_itab.h + udis86.input = ITAB + udis86.CONFIG += no_link +- udis86.commands = $$QMAKE_PYTHON $$PWD/disassembler/udis86/itab.py ${QMAKE_FILE_IN} ++ udis86.commands = "\"$$QMAKE_PYTHON\"" $$PWD/disassembler/udis86/itab.py ${QMAKE_FILE_IN} + QMAKE_EXTRA_COMPILERS += udis86 + + udis86_tab_cfile.target = $$OUT_PWD/udis86_itab.c +@@ -111,7 +111,7 @@ retgen.output = $$GENERATEDDIR/RegExpJitTables.h + retgen.script = $$PWD/yarr/create_regex_tables + retgen.input = retgen.script + retgen.CONFIG += no_link +-retgen.commands = $$QMAKE_PYTHON $$retgen.script > ${QMAKE_FILE_OUT} ++retgen.commands = "\"$$QMAKE_PYTHON\"" $$retgen.script > ${QMAKE_FILE_OUT} + QMAKE_EXTRA_COMPILERS += retgen + + # Taken from WebKit/Tools/qmake/mkspecs/features/unix/default_post.prf diff --git a/var/spack/repos/builtin/packages/sqlite/package.py b/var/spack/repos/builtin/packages/sqlite/package.py index 4b3b373489..57f1272801 100644 --- a/var/spack/repos/builtin/packages/sqlite/package.py +++ b/var/spack/repos/builtin/packages/sqlite/package.py @@ -218,7 +218,8 @@ class Sqlite(AutotoolsPackage, NMakePackage): @property def libs(self): - return find_libraries("libsqlite3", root=self.prefix.lib) + prefix = "lib" if sys.platform != "win32" else "" + return find_libraries(f"{prefix}sqlite3", root=self.prefix.lib, runtime=False) def test_example(self): """check example table dump""" diff --git a/var/spack/repos/builtin/packages/zlib-ng/package.py b/var/spack/repos/builtin/packages/zlib-ng/package.py index 45e7282e2f..2daba38d7a 100644 --- a/var/spack/repos/builtin/packages/zlib-ng/package.py +++ b/var/spack/repos/builtin/packages/zlib-ng/package.py @@ -3,6 +3,8 @@ # # SPDX-License-Identifier: (Apache-2.0 OR MIT) +import sys + from spack.build_systems import autotools, cmake from spack.package import * @@ -55,9 +57,15 @@ class ZlibNg(AutotoolsPackage, CMakePackage): @property def libs(self): - name = "libz" if self.spec.satisfies("+compat") else "libz-ng" + compat_name = "zlib" if sys.platform == "win32" else "libz" + non_compat_name = "zlib-ng" if sys.platform == "win32" else "libz-ng" + name = compat_name if self.spec.satisfies("+compat") else non_compat_name return find_libraries( - name, root=self.prefix, recursive=True, shared=self.spec.satisfies("+shared") + name, + root=self.prefix, + recursive=True, + shared=self.spec.satisfies("+shared"), + runtime=False, ) def flag_handler(self, name, flags): -- cgit v1.2.3-70-g09d2