From 16bc58ea49256b061c7308565fe41c446e748881 Mon Sep 17 00:00:00 2001 From: John Biddiscombe Date: Mon, 4 Dec 2023 17:53:06 +0100 Subject: Add EGL support to ParaView and Glew (#39800) * Add EGL support to ParaView and Glew add a package for egl that provides GL but also adds EGL libs and headers for projects that need them Fix a header problem with the opengl package Format files using black * better description for egl variant description Co-authored-by: Vicente Bolea * better check/setup of non egl variant dependencies Co-authored-by: Vicente Bolea * Add biddisco as maintainer * Fix unused var style warning * Add egl conflicts for other gl providers --------- Co-authored-by: Vicente Bolea --- var/spack/repos/builtin/packages/egl/package.py | 92 ++++++++++++++++++++++ var/spack/repos/builtin/packages/glew/package.py | 19 ++++- var/spack/repos/builtin/packages/opengl/package.py | 13 ++- .../repos/builtin/packages/paraview/package.py | 25 ++++-- 4 files changed, 137 insertions(+), 12 deletions(-) create mode 100644 var/spack/repos/builtin/packages/egl/package.py diff --git a/var/spack/repos/builtin/packages/egl/package.py b/var/spack/repos/builtin/packages/egl/package.py new file mode 100644 index 0000000000..d79f1e30db --- /dev/null +++ b/var/spack/repos/builtin/packages/egl/package.py @@ -0,0 +1,92 @@ +# Copyright 2013-2023 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 re +import sys + +from spack.package import * + + +class Egl(BundlePackage): + """Placeholder for external EGL(OpenGL) libraries from hardware vendors""" + + homepage = "https://www.khronos.org/egl" + maintainers("biddisco") + + version("1.5") + + # This should really be when='platform=linux' but can't because of a + # current bug in when and how ArchSpecs are constructed + if sys.platform.startswith("linux"): + provides("gl@4.5") + + # conflict with GLX + conflicts("glx") + + # not always available, but sometimes + executables = ["^eglinfo$"] + + @classmethod + def determine_version(cls, exe): + if exe: + output = Executable(exe)(output=str, error=str) + match = re.search(r"EGL version string: (\S+)", output) + return match.group(1) if match else None + else: + return None + + # Override the fetcher method to throw a useful error message; + # fixes GitHub issue (#7061) in which this package threw a + # generic, uninformative error during the `fetch` step, + @property + def fetcher(self): + msg = """This package is intended to be a placeholder for + system-provided EGL(OpenGL) libraries from hardware vendors. Please + download and install EGL drivers/libraries for your graphics + hardware separately, and then set that up as an external package. + An example of a working packages.yaml: + + packages: + egl: + buildable: False + externals: + - spec: egl@1.5.0 + prefix: /usr/ + + In that case, /usr/ should contain these two folders: + + include/EGL/ (egl headers, including "egl.h") + lib (egl libraries, including "libEGL.so") + + """ + raise InstallError(msg) + + @fetcher.setter # Since fetcher is read-write, must override both + def fetcher(self): + _ = self.fetcher + + @property + def headers(self): + return self.egl_headers + + @property + def libs(self): + return self.egl_libs + + @property + def egl_headers(self): + header_name = "GL/gl" + gl_header = find_headers(header_name, root=self.prefix, recursive=True) + header_name = "EGL/egl" + egl_header = find_headers(header_name, root=self.prefix, recursive=True) + return gl_header + egl_header + + @property + def egl_libs(self): + lib_name = "libGL" + gl_lib = find_libraries(lib_name, root=self.prefix, recursive=True) + lib_name = "libEGL" + egl_lib = find_libraries(lib_name, root=self.prefix, recursive=True) + return gl_lib + egl_lib diff --git a/var/spack/repos/builtin/packages/glew/package.py b/var/spack/repos/builtin/packages/glew/package.py index a5d8d1ef3e..38c2a9c322 100644 --- a/var/spack/repos/builtin/packages/glew/package.py +++ b/var/spack/repos/builtin/packages/glew/package.py @@ -15,6 +15,8 @@ class Glew(CMakePackage): url = "https://github.com/nigels-com/glew/releases/download/glew-2.1.0/glew-2.1.0.tgz" root_cmakelists_dir = "build/cmake" + maintainers("biddisco") + version("2.2.0", sha256="d4fc82893cfb00109578d0a1a2337fb8ca335b3ceccf97b97e5cc7f08e4353e1") version("2.1.0", sha256="04de91e7e6763039bc11940095cd9c7f880baba82196a7765f727ac05a993c95") version("2.0.0", sha256="c572c30a4e64689c342ba1624130ac98936d7af90c3103f9ce12b8a0c5736764") @@ -22,20 +24,26 @@ class Glew(CMakePackage): variant( "gl", default="glx" if sys.platform.startswith("linux") else "other", - values=("glx", "osmesa", "other"), + values=("glx", "osmesa", "egl", "other"), multi=False, description="The OpenGL provider to use", ) conflicts("^osmesa", when="gl=glx") + conflicts("^osmesa", when="gl=egl") conflicts("^osmesa", when="gl=other") conflicts("^glx", when="gl=osmesa") conflicts("^glx", when="gl=other") + conflicts("^glx", when="gl=egl") + conflicts("^egl", when="gl=glx") + conflicts("^egl", when="gl=osmesa") + conflicts("^egl", when="gl=other") depends_on("gl") depends_on("osmesa", when="gl=osmesa") depends_on("glx", when="gl=glx") depends_on("libx11", when="gl=glx") depends_on("xproto", when="gl=glx") + depends_on("egl", when="gl=egl") # glu is already forcibly disabled in the CMakeLists.txt. This prevents # it from showing up in the .pc file @@ -46,17 +54,22 @@ class Glew(CMakePackage): args = [ self.define("BUILD_UTILS", True), self.define("GLEW_REGAL", False), - self.define("GLEW_EGL", False), + self.define("GLEW_EGL", "gl=egl" in spec), self.define("OpenGL_GL_PREFERENCE", "LEGACY"), self.define("OPENGL_INCLUDE_DIR", spec["gl"].headers.directories[0]), self.define("OPENGL_gl_LIBRARY", spec["gl"].libs[0]), self.define("OPENGL_opengl_LIBRARY", "IGNORE"), self.define("OPENGL_glx_LIBRARY", "IGNORE"), - self.define("OPENGL_egl_LIBRARY", "IGNORE"), self.define("OPENGL_glu_LIBRARY", "IGNORE"), self.define("GLEW_OSMESA", "gl=osmesa" in spec), self.define("GLEW_X11", "gl=glx" in spec), self.define("CMAKE_DISABLE_FIND_PACKAGE_X11", "gl=glx" not in spec), ] + if "gl=egl" in spec: + args.append( + self.define("OPENGL_egl_LIBRARY", [spec["egl"].libs[0], spec["egl"].libs[1]]) + ) + else: + args.append(self.define("OPENGL_egl_LIBRARY", "IGNORE")) return args diff --git a/var/spack/repos/builtin/packages/opengl/package.py b/var/spack/repos/builtin/packages/opengl/package.py index 21cc3b8cd7..edc6577c3b 100644 --- a/var/spack/repos/builtin/packages/opengl/package.py +++ b/var/spack/repos/builtin/packages/opengl/package.py @@ -13,8 +13,8 @@ class Opengl(BundlePackage): """Placeholder for external OpenGL libraries from hardware vendors""" homepage = "https://www.opengl.org/" - version("4.5") + maintainers("biddisco") # This should really be when='platform=linux' but can't because of a # current bug in when and how ArchSpecs are constructed @@ -82,16 +82,21 @@ class Opengl(BundlePackage): def fetcher(self): _ = self.fetcher + @property + def headers(self): + return self.gl_headers + @property def libs(self): return self.gl_libs @property def gl_headers(self): - if "platform=darwin": - header_name = "OpenGL/gl.h" + spec = self.spec + if "platform=darwin" in spec: + header_name = "OpenGL/gl" else: - header_name = "GL/gl.h" + header_name = "GL/gl" return find_headers(header_name, root=self.prefix, recursive=True) @property diff --git a/var/spack/repos/builtin/packages/paraview/package.py b/var/spack/repos/builtin/packages/paraview/package.py index 1f3cd9a76f..333cc328f2 100644 --- a/var/spack/repos/builtin/packages/paraview/package.py +++ b/var/spack/repos/builtin/packages/paraview/package.py @@ -67,6 +67,7 @@ class Paraview(CMakePackage, CudaPackage, ROCmPackage): variant("fortran", default=False, description="Enable Fortran support") variant("mpi", default=True, description="Enable MPI support") variant("osmesa", default=False, description="Enable OSMesa support") + variant("egl", default=False, description="Enable EGL in the OpenGL library being used") variant("qt", default=False, description="Enable Qt (gui) support") variant("opengl2", default=True, description="Enable OpenGL2 backend") variant("examples", default=False, description="Build examples") @@ -186,12 +187,16 @@ class Paraview(CMakePackage, CudaPackage, ROCmPackage): depends_on("gl@3.2:", when="+opengl2") depends_on("gl@1.2:", when="~opengl2") - depends_on("glew") + depends_on("glew", when="~egl") + depends_on("glew gl=egl", when="+egl") + depends_on("osmesa", when="+osmesa") for p in ["linux", "cray"]: - depends_on("glx", when="~osmesa platform={}".format(p)) - depends_on("libxt", when="~osmesa platform={}".format(p)) + depends_on("glx", when="~egl ~osmesa platform={}".format(p)) + depends_on("libxt", when="~egl ~osmesa platform={}".format(p)) conflicts("+qt", when="+osmesa") + conflicts("+qt", when="+egl") + conflicts("+egl", when="+osmesa") depends_on("ospray@2.1:2", when="+raytracing") depends_on("openimagedenoise", when="+raytracing") @@ -419,13 +424,20 @@ class Paraview(CMakePackage, CudaPackage, ROCmPackage): """Negated ternary for spec variant to OFF/ON string""" return variant_bool(feature, on="OFF", off="ON") + def use_x11(): + """Return false if osmesa or egl are requested""" + if "+osmesa" in spec or "+egl" in spec: + return "OFF" + if spec.satisfies("platform=windows"): + return "OFF" + return "ON" + rendering = variant_bool("+opengl2", "OpenGL2", "OpenGL") includes = variant_bool("+development_files") - use_x11 = nvariant_bool("+osmesa") if not spec.satisfies("platform=windows") else "OFF" cmake_args = [ "-DVTK_OPENGL_HAS_OSMESA:BOOL=%s" % variant_bool("+osmesa"), - "-DVTK_USE_X:BOOL=%s" % use_x11, + "-DVTK_USE_X:BOOL=%s" % use_x11(), "-DPARAVIEW_INSTALL_DEVELOPMENT_FILES:BOOL=%s" % includes, "-DBUILD_TESTING:BOOL=OFF", "-DOpenGL_GL_PREFERENCE:STRING=LEGACY", @@ -433,6 +445,9 @@ class Paraview(CMakePackage, CudaPackage, ROCmPackage): self.define_from_variant("VISIT_BUILD_READER_Silo", "visitbridge"), ] + if "+egl" in spec: + cmake_args.append("-DVTK_OPENGL_HAS_EGL:BOOL=ON") + if spec.satisfies("@5.12:"): cmake_args.append("-DVTK_MODULE_USE_EXTERNAL_VTK_fast_float:BOOL=OFF") cmake_args.append("-DVTK_MODULE_USE_EXTERNAL_VTK_token:BOOL=OFF") -- cgit v1.2.3-60-g2f50