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 <dan.lipsa@kitware.com>
This commit is contained in:
John W. Parent 2024-10-07 16:33:25 -04:00 committed by GitHub
parent c77916146c
commit 717d4800e1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 289 additions and 90 deletions

View File

@ -293,6 +293,17 @@ def platform_toolset_ver(self):
vs22_toolset = Version(toolset_ver) > Version("142") vs22_toolset = Version(toolset_ver) > Version("142")
return toolset_ver if not vs22_toolset else "143" 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): def _compiler_version(self, compiler):
"""Returns version object for given compiler""" """Returns version object for given compiler"""
# ignore_errors below is true here due to ifx's # ignore_errors below is true here due to ifx's

View File

@ -114,6 +114,23 @@ class Cmake(Package):
values=("Debug", "Release", "RelWithDebInfo", "MinSizeRel"), 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 # Revert the change that introduced a regression when parsing mpi link
# flags, see: https://gitlab.kitware.com/cmake/cmake/issues/19516 # flags, see: https://gitlab.kitware.com/cmake/cmake/issues/19516
patch("cmake-revert-findmpi-link-flag-list.patch", when="@3.15.0") 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=darwin")
depends_on("gmake", when="platform=freebsd") depends_on("gmake", when="platform=freebsd")
# We default ownlibs to true because it greatly speeds up the CMake depends_on("qt", when="+qtgui")
# 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",
)
# See https://gitlab.kitware.com/cmake/cmake/-/issues/21135 # See https://gitlab.kitware.com/cmake/cmake/-/issues/21135
conflicts( conflicts(
@ -183,7 +186,7 @@ class Cmake(Package):
with when("~ownlibs"): with when("~ownlibs"):
depends_on("expat") depends_on("expat")
# expat/zlib are used in CMake/CTest, so why not require them in libarchive. # 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): with when("platform=%s" % plat):
depends_on("libarchive@3.1.0: xar=expat compression=zlib") depends_on("libarchive@3.1.0: xar=expat compression=zlib")
depends_on("libarchive@3.3.3:", when="@3.15.0:") depends_on("libarchive@3.3.3:", when="@3.15.0:")
@ -311,12 +314,16 @@ def bootstrap_args(self):
# Whatever +/~ownlibs, use system curl. # Whatever +/~ownlibs, use system curl.
args.append("--system-curl") args.append("--system-curl")
args.append("--no-qt-gui")
if spec.satisfies("+doc"): if spec.satisfies("+doc"):
args.append("--sphinx-html") args.append("--sphinx-html")
args.append("--sphinx-man") 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 # Now for CMake arguments to pass after the initial bootstrap
args.append("--") args.append("--")
else: else:
@ -329,6 +336,7 @@ def bootstrap_args(self):
# inside a ctest environment # inside a ctest environment
"-DCMake_TEST_INSTALL=OFF", "-DCMake_TEST_INSTALL=OFF",
f"-DBUILD_CursesDialog={'ON' if '+ncurses' in spec else 'OFF'}", f"-DBUILD_CursesDialog={'ON' if '+ncurses' in spec else 'OFF'}",
f"-DBUILD_QtDialog={'ON' if spec.satisfies('+qtgui') else 'OFF'}",
] ]
) )

View File

@ -2,10 +2,14 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details. # Spack Project Developers. See the top-level COPYRIGHT file for details.
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import sys
import spack.build_systems.autotools import spack.build_systems.autotools
import spack.build_systems.meson import spack.build_systems.meson
from spack.package import * from spack.package import *
IS_WINDOWS = sys.platform == "win32"
class Harfbuzz(MesonPackage, AutotoolsPackage): class Harfbuzz(MesonPackage, AutotoolsPackage):
"""The Harfbuzz package contains an OpenType text shaping engine.""" """The Harfbuzz package contains an OpenType text shaping engine."""
@ -84,12 +88,15 @@ class Harfbuzz(MesonPackage, AutotoolsPackage):
description="Enable CoreText shaper backend on macOS", description="Enable CoreText shaper backend on macOS",
) )
depends_on("pkgconfig", type="build") for plat in ["linux", "darwin", "freebsd"]:
depends_on("glib") with when(f"platform={plat}"):
depends_on("gobject-introspection") depends_on("pkgconfig", type="build")
depends_on("glib")
depends_on("gobject-introspection")
depends_on("cairo+pdf+ft")
depends_on("icu4c") depends_on("icu4c")
depends_on("freetype") depends_on("freetype")
depends_on("cairo+pdf+ft")
depends_on("zlib-api") depends_on("zlib-api")
depends_on("graphite2", when="+graphite2") depends_on("graphite2", when="+graphite2")
@ -137,13 +144,16 @@ class MesonBuilder(spack.build_systems.meson.MesonBuilder, SetupEnvironment):
def meson_args(self): def meson_args(self):
graphite2 = "enabled" if self.pkg.spec.satisfies("+graphite2") else "disabled" graphite2 = "enabled" if self.pkg.spec.satisfies("+graphite2") else "disabled"
coretext = "enabled" if self.pkg.spec.satisfies("+coretext") 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 # disable building of gtk-doc files following #9885 and #9771
"-Ddocs=disabled", "-Ddocs=disabled",
"-Dfreetype=enabled", "-Dfreetype=enabled",
f"-Dgraphite2={graphite2}", f"-Dgraphite2={graphite2}",
f"-Dcoretext={coretext}", f"-Dcoretext={coretext}",
] ]
if IS_WINDOWS:
config_args.extend(["-Dcairo=disabled", "-Dglib=disabled"])
return config_args
class AutotoolsBuilder(spack.build_systems.autotools.AutotoolsBuilder, SetupEnvironment): class AutotoolsBuilder(spack.build_systems.autotools.AutotoolsBuilder, SetupEnvironment):

View File

@ -3,10 +3,12 @@
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import pathlib
from spack.package import * from spack.package import *
class Lcms(AutotoolsPackage): class Lcms(AutotoolsPackage, MSBuildPackage):
"""Little cms is a color management library. Implements fast """Little cms is a color management library. Implements fast
transforms between ICC profiles. It is focused on speed, and is transforms between ICC profiles. It is focused on speed, and is
portable across several platforms (MIT license).""" portable across several platforms (MIT license)."""
@ -35,6 +37,27 @@ def url_for_version(self, version):
depends_on("libtiff") depends_on("libtiff")
depends_on("zlib-api") depends_on("zlib-api")
build_system("autotools", "msbuild")
@property @property
def libs(self): def libs(self):
return find_libraries("liblcms2", root=self.prefix, recursive=True) 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"]

View File

@ -3,6 +3,8 @@
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import sys
from spack.package import * from spack.package import *
@ -111,7 +113,8 @@ class LibjpegTurbo(CMakePackage, AutotoolsPackage):
@property @property
def libs(self): def libs(self):
shared = self.spec.satisfies("libs=shared") 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): class CMakeBuilder(spack.build_systems.cmake.CMakeBuilder):

View File

@ -49,7 +49,9 @@ def libs(self):
# v1.2 does not have a version-less symlink # v1.2 does not have a version-less symlink
libraries = f"libpng{self.version.up_to(2).joined}" libraries = f"libpng{self.version.up_to(2).joined}"
shared = "libs=shared" in self.spec 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): class CMakeBuilder(CMakeBuilder):

View File

@ -2,6 +2,8 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details. # Spack Project Developers. See the top-level COPYRIGHT file for details.
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import sys
from spack.package import * from spack.package import *
@ -179,5 +181,11 @@ def setup_dependent_build_environment(self, env, dependent_spec):
if self.spec.satisfies("platform=darwin"): if self.spec.satisfies("platform=darwin"):
env.set("STRIP", "strip -x") 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): def setup_dependent_package(self, module, dspec):
module.meson = Executable(self.spec.prefix.bin.meson) module.meson = Executable(self._meson_bin_dir().meson)

View File

@ -86,3 +86,8 @@ def install(self, pkg, spec, prefix):
for file in rdoff: for file in rdoff:
install(file, self.prefix.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)

View File

@ -111,6 +111,7 @@ def libs(self):
root=self.prefix, root=self.prefix,
recursive=True, recursive=True,
shared=self.spec.variants["shared"].value, shared=self.spec.variants["shared"].value,
runtime=False,
) )
def handle_fetch_error(self, error): def handle_fetch_error(self, error):
@ -159,9 +160,11 @@ def install(self, spec, prefix):
"--openssldir=%s" % join_path(prefix, "etc", "openssl"), "--openssldir=%s" % join_path(prefix, "etc", "openssl"),
] ]
if spec.satisfies("platform=windows"): if spec.satisfies("platform=windows"):
base_args.extend( if spec.satisfies("@:1"):
['CC="%s"' % os.environ.get("CC"), 'CXX="%s"' % os.environ.get("CXX"), "VC-WIN64A"] 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: else:
base_args.extend( base_args.extend(
[ [

View File

@ -11,6 +11,8 @@
from spack.package import * from spack.package import *
IS_WINDOWS = sys.platform == "win32"
class Paraview(CMakePackage, CudaPackage, ROCmPackage): class Paraview(CMakePackage, CudaPackage, ROCmPackage):
"""ParaView is an open-source, multi-platform data analysis and """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("tbb", when="+tbb")
depends_on("mpi", when="+mpi") 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@: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@3.2:", when="+opengl2")
depends_on("gl@1.2:", when="~opengl2") depends_on("gl@1.2:", when="~opengl2")
depends_on("glew") depends_on("glew")
depends_on("libxt", when="platform=linux ^[virtuals=gl] glx") 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("ospray@2.1:2", when="+raytracing")
depends_on("openimagedenoise", when="+raytracing") depends_on("openimagedenoise", when="+raytracing")
@ -568,6 +577,9 @@ def use_x11():
# so explicitly specify which QT major version is actually being used # so explicitly specify which QT major version is actually being used
if spec.satisfies("+qt"): if spec.satisfies("+qt"):
cmake_args.extend(["-DPARAVIEW_QT_VERSION=%s" % spec["qt"].version[0]]) 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: if "+fortran" in spec:
cmake_args.append("-DPARAVIEW_USE_FORTRAN:BOOL=ON") cmake_args.append("-DPARAVIEW_USE_FORTRAN:BOOL=ON")

View File

@ -57,6 +57,10 @@ class Pcre(AutotoolsPackage, CMakePackage):
variant("pic", default=True, description="Enable position-independent code (PIC)") variant("pic", default=True, description="Enable position-independent code (PIC)")
requires("+pic", when="+shared build_system=autotools") 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): class AutotoolsBuilder(spack.build_systems.autotools.AutotoolsBuilder):
def configure_args(self): def configure_args(self):

View File

@ -6,7 +6,7 @@
from spack.package import * from spack.package import *
class Pcre2(AutotoolsPackage): class Pcre2(AutotoolsPackage, CMakePackage):
"""The PCRE2 package contains Perl Compatible Regular Expression """The PCRE2 package contains Perl Compatible Regular Expression
libraries. These are useful for implementing regular expression libraries. These are useful for implementing regular expression
pattern matching using the same syntax and semantics as Perl 5.""" 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("multibyte", default=True, description="Enable support for 16 and 32 bit characters.")
variant("jit", default=False, description="enable Just-In-Time compiling support") 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): def configure_args(self):
args = [] args = []
@ -44,11 +70,23 @@ def configure_args(self):
return args 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

View File

@ -15,6 +15,7 @@
MACOS_VERSION = macos_version() if sys.platform == "darwin" else None MACOS_VERSION = macos_version() if sys.platform == "darwin" else None
LINUX_VERSION = kernel_version() if platform.system() == "Linux" else None LINUX_VERSION = kernel_version() if platform.system() == "Linux" else None
IS_WINDOWS = sys.platform == "win32"
class Qt(Package): class Qt(Package):
@ -69,14 +70,22 @@ class Qt(Package):
) )
variant("gtk", default=False, description="Build with gtkplus.") variant("gtk", default=False, description="Build with gtkplus.")
variant("gui", default=True, description="Build the Qt GUI module and dependencies") variant("gui", default=True, description="Build the Qt GUI module and dependencies")
variant("opengl", default=False, description="Build with OpenGL support.") # Desktop only on Windows
variant("location", default=False, when="+opengl", description="Build the Qt Location module.") 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("phonon", default=False, description="Build with phonon support.")
variant("shared", default=True, description="Build shared libraries.") variant("shared", default=True, description="Build shared libraries.")
variant("sql", default=True, description="Build with SQL support.") variant("sql", default=True, description="Build with SQL support.")
variant("ssl", default=True, description="Build with OpenSSL support.") variant("ssl", default=True, description="Build with OpenSSL support.")
variant("tools", default=True, description="Build tools, including Qt Designer.") variant("tools", default=True, description="Build tools, including Qt Designer.")
variant("webkit", default=False, description="Build the Webkit extension")
provides("qmake") provides("qmake")
@ -128,6 +137,9 @@ class Qt(Package):
patch("qt514-isystem.patch", when="@5.14.2") patch("qt514-isystem.patch", when="@5.14.2")
# https://bugreports.qt.io/browse/QTBUG-84037 # https://bugreports.qt.io/browse/QTBUG-84037
patch("qt515-quick3d-assimp.patch", when="@5.15:5+opengl") 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 # https://bugreports.qt.io/browse/QTBUG-90395
patch( patch(
"https://src.fedoraproject.org/rpms/qt5-qtbase/raw/6ae41be8260f0f5403367eb01f7cd8319779674a/f/qt5-qtbase-gcc11.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") conflicts("%apple-clang@13:", when="@:5.13")
# Build-only dependencies # 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") depends_on("python", when="@5.7.0:", type="build")
# Dependencies, then variant- and version-specific dependencies # Dependencies, then variant- and version-specific dependencies
depends_on("icu4c") depends_on("icu4c")
depends_on("jpeg") depends_on("jpeg")
depends_on("libmng")
depends_on("libtiff") depends_on("libtiff")
depends_on("libxml2") depends_on("libxml2")
depends_on("zlib-api") depends_on("zlib-api")
depends_on("freetype", when="+gui") depends_on("freetype", when="+gui")
depends_on("gtkplus", when="+gtk") 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("libpng@1.2.57", when="@3")
depends_on("libsm", when="@3")
depends_on("pcre+multibyte", when="@5.0:5.8") depends_on("pcre+multibyte", when="@5.0:5.8")
depends_on("inputproto", when="@:5.8")
with when("+ssl"): with when("+ssl"):
depends_on("openssl") depends_on("openssl")
depends_on("openssl@:1.0", when="@4:5.9") depends_on("openssl@:1.0", when="@4:5.9")
depends_on("openssl@1.1.1:", when="@5.15.0:") depends_on("openssl@1.1.1:", when="@5.15.0:")
depends_on("glib", when="@4:")
depends_on("libpng", when="@4:") depends_on("libpng", when="@4:")
depends_on("dbus", when="@4:+dbus") depends_on("dbus", when="@4:+dbus")
depends_on("gl", when="@4:+opengl") depends_on("gl", when="@4:+opengl")
depends_on("assimp@5.0.0:5", when="@5.5:+opengl")
depends_on("harfbuzz", when="@5:") depends_on("harfbuzz", when="@5:")
depends_on("double-conversion", when="@5.7:") depends_on("double-conversion", when="@5.7:")
@ -261,32 +303,6 @@ class Qt(Package):
conflicts("%oneapi", when="@:5.15.13") conflicts("%oneapi", when="@:5.15.13")
patch("qt51514-oneapi.patch", when="@5.15.14: %oneapi") 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' # Mapping for compilers/systems in the QT 'mkspecs'
compiler_mapping = { compiler_mapping = {
"intel": ("icc",), "intel": ("icc",),
@ -300,7 +316,7 @@ class Qt(Package):
"fj": ("clang",), "fj": ("clang",),
"gcc": ("g++",), "gcc": ("g++",),
} }
platform_mapping = {"darwin": ("macx")} platform_mapping = {"darwin": ("macx"), "windows": ("win32")}
def url_for_version(self, version): def url_for_version(self, version):
# URL keeps getting more complicated with every release # URL keeps getting more complicated with every release
@ -350,7 +366,8 @@ def url_for_version(self, version):
return url return url
def setup_build_environment(self, env): 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"): if self.version >= Version("5.11"):
# QDoc uses LLVM as of 5.11; remove the LLVM_INSTALL_DIR to # QDoc uses LLVM as of 5.11; remove the LLVM_INSTALL_DIR to
# disable # disable
@ -372,6 +389,10 @@ def setup_dependent_build_environment(self, env, dependent_spec):
env.set("QTINC", self.prefix.inc) env.set("QTINC", self.prefix.inc)
env.set("QTLIB", self.prefix.lib) env.set("QTLIB", self.prefix.lib)
env.prepend_path("QT_PLUGIN_PATH", self.prefix.plugins) 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): def setup_dependent_package(self, module, dependent_spec):
module.qmake = Executable(self.spec.prefix.bin.qmake) module.qmake = Executable(self.spec.prefix.bin.qmake)
@ -562,18 +583,25 @@ def common_config_args(self):
self.prefix, self.prefix,
"-v", "-v",
"-opensource", "-opensource",
"-{0}opengl".format("" if "+opengl" in spec else "no-"),
"-{0}".format("debug" if "+debug" in spec else "release"), "-{0}".format("debug" if "+debug" in spec else "release"),
"-confirm-license", "-confirm-license",
"-optimized-qmake", "-optimized-qmake",
"-no-pch", "-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) use_spack_dep = self._dep_appender_factory(config_args)
if "+gui" in spec: if "+gui" in spec:
use_spack_dep("freetype") use_spack_dep("freetype")
if not MACOS_VERSION: if spec.satisfies("platform=linux") or spec.satisfies("platform=freebsd"):
config_args.append("-fontconfig") config_args.append("-fontconfig")
else: else:
config_args.append("-no-freetype") config_args.append("-no-freetype")
@ -716,7 +744,7 @@ def configure(self, spec, prefix):
# Errors on bluetooth even when bluetooth is disabled... # Errors on bluetooth even when bluetooth is disabled...
# at least on apple-clang%12 # at least on apple-clang%12
config_args.extend(["-skip", "connectivity"]) config_args.extend(["-skip", "connectivity"])
elif "+gui" in spec: elif "+gui" in spec and not IS_WINDOWS:
# Linux-only QT5 dependencies # Linux-only QT5 dependencies
if version < Version("5.9.9"): if version < Version("5.9.9"):
config_args.append("-system-xcb") config_args.append("-system-xcb")
@ -756,6 +784,9 @@ def configure(self, spec, prefix):
if version >= Version("5.15"): if version >= Version("5.15"):
config_args.extend(["-skip", "qtlocation"]) config_args.extend(["-skip", "qtlocation"])
if IS_WINDOWS:
config_args.extend(["-skip", "qtspeech"])
if "~opengl" in spec: if "~opengl" in spec:
config_args.extend(["-skip", "multimedia"]) config_args.extend(["-skip", "multimedia"])
config_args.extend(["-skip", "qt3d"]) config_args.extend(["-skip", "qt3d"])
@ -773,10 +804,11 @@ def configure(self, spec, prefix):
# v5.9: user-selectable internal-vs-external via -assimp # v5.9: user-selectable internal-vs-external via -assimp
# v5.14: additional qtquick3d module uses -assimp # v5.14: additional qtquick3d module uses -assimp
# v5.15: qtquick3d switched to the -quick3d-assimp option # v5.15: qtquick3d switched to the -quick3d-assimp option
if version >= Version("5.9"): if not IS_WINDOWS:
use_spack_dep("assimp") if version >= Version("5.9"):
elif version >= Version("5.15"): use_spack_dep("assimp")
use_spack_dep("assimp", "quick3d-assimp") elif version >= Version("5.15"):
use_spack_dep("assimp", "quick3d-assimp")
if MACOS_VERSION and "+opengl" in spec: if MACOS_VERSION and "+opengl" in spec:
# These options are only valid if 'multimedia' is enabled, i.e. # These options are only valid if 'multimedia' is enabled, i.e.
@ -789,13 +821,22 @@ def configure(self, spec, prefix):
# Not currently working for qt@5 # Not currently working for qt@5
config_args.extend(["-device-option", "QMAKE_APPLE_DEVICE_ARCHS=arm64"]) config_args.extend(["-device-option", "QMAKE_APPLE_DEVICE_ARCHS=arm64"])
if IS_WINDOWS:
global configure
configure = Executable("configure.bat")
configure(*config_args) configure(*config_args)
def build(self, spec, prefix): def build(self, spec, prefix):
make() if IS_WINDOWS:
nmake()
else:
make()
def install(self, spec, prefix): def install(self, spec, prefix):
make("install") if IS_WINDOWS:
nmake("install")
else:
make("install")
# Documentation generation requires the doc tools to be installed. # Documentation generation requires the doc tools to be installed.
# @when @run_after currently seems to ignore the 'when' restriction. # @when @run_after currently seems to ignore the 'when' restriction.

View File

@ -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

View File

@ -218,7 +218,8 @@ def url_for_version(self, version):
@property @property
def libs(self): 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): def test_example(self):
"""check example table dump""" """check example table dump"""

View File

@ -3,6 +3,8 @@
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import sys
from spack.build_systems import autotools, cmake from spack.build_systems import autotools, cmake
from spack.package import * from spack.package import *
@ -55,9 +57,15 @@ class ZlibNg(AutotoolsPackage, CMakePackage):
@property @property
def libs(self): 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( 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): def flag_handler(self, name, flags):