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 <vicente.bolea@gmail.com>

* better check/setup of non egl variant dependencies

Co-authored-by: Vicente Bolea <vicente.bolea@gmail.com>

* Add biddisco as maintainer

* Fix unused var style warning

* Add egl conflicts for other gl providers

---------

Co-authored-by: Vicente Bolea <vicente.bolea@gmail.com>
This commit is contained in:
John Biddiscombe 2023-12-04 17:53:06 +01:00 committed by GitHub
parent 6028ce8bc1
commit 16bc58ea49
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 137 additions and 12 deletions

View file

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

View file

@ -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" url = "https://github.com/nigels-com/glew/releases/download/glew-2.1.0/glew-2.1.0.tgz"
root_cmakelists_dir = "build/cmake" root_cmakelists_dir = "build/cmake"
maintainers("biddisco")
version("2.2.0", sha256="d4fc82893cfb00109578d0a1a2337fb8ca335b3ceccf97b97e5cc7f08e4353e1") version("2.2.0", sha256="d4fc82893cfb00109578d0a1a2337fb8ca335b3ceccf97b97e5cc7f08e4353e1")
version("2.1.0", sha256="04de91e7e6763039bc11940095cd9c7f880baba82196a7765f727ac05a993c95") version("2.1.0", sha256="04de91e7e6763039bc11940095cd9c7f880baba82196a7765f727ac05a993c95")
version("2.0.0", sha256="c572c30a4e64689c342ba1624130ac98936d7af90c3103f9ce12b8a0c5736764") version("2.0.0", sha256="c572c30a4e64689c342ba1624130ac98936d7af90c3103f9ce12b8a0c5736764")
@ -22,20 +24,26 @@ class Glew(CMakePackage):
variant( variant(
"gl", "gl",
default="glx" if sys.platform.startswith("linux") else "other", default="glx" if sys.platform.startswith("linux") else "other",
values=("glx", "osmesa", "other"), values=("glx", "osmesa", "egl", "other"),
multi=False, multi=False,
description="The OpenGL provider to use", description="The OpenGL provider to use",
) )
conflicts("^osmesa", when="gl=glx") conflicts("^osmesa", when="gl=glx")
conflicts("^osmesa", when="gl=egl")
conflicts("^osmesa", when="gl=other") conflicts("^osmesa", when="gl=other")
conflicts("^glx", when="gl=osmesa") conflicts("^glx", when="gl=osmesa")
conflicts("^glx", when="gl=other") 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("gl")
depends_on("osmesa", when="gl=osmesa") depends_on("osmesa", when="gl=osmesa")
depends_on("glx", when="gl=glx") depends_on("glx", when="gl=glx")
depends_on("libx11", when="gl=glx") depends_on("libx11", when="gl=glx")
depends_on("xproto", 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 # glu is already forcibly disabled in the CMakeLists.txt. This prevents
# it from showing up in the .pc file # it from showing up in the .pc file
@ -46,17 +54,22 @@ def cmake_args(self):
args = [ args = [
self.define("BUILD_UTILS", True), self.define("BUILD_UTILS", True),
self.define("GLEW_REGAL", False), 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_GL_PREFERENCE", "LEGACY"),
self.define("OPENGL_INCLUDE_DIR", spec["gl"].headers.directories[0]), self.define("OPENGL_INCLUDE_DIR", spec["gl"].headers.directories[0]),
self.define("OPENGL_gl_LIBRARY", spec["gl"].libs[0]), self.define("OPENGL_gl_LIBRARY", spec["gl"].libs[0]),
self.define("OPENGL_opengl_LIBRARY", "IGNORE"), self.define("OPENGL_opengl_LIBRARY", "IGNORE"),
self.define("OPENGL_glx_LIBRARY", "IGNORE"), self.define("OPENGL_glx_LIBRARY", "IGNORE"),
self.define("OPENGL_egl_LIBRARY", "IGNORE"),
self.define("OPENGL_glu_LIBRARY", "IGNORE"), self.define("OPENGL_glu_LIBRARY", "IGNORE"),
self.define("GLEW_OSMESA", "gl=osmesa" in spec), self.define("GLEW_OSMESA", "gl=osmesa" in spec),
self.define("GLEW_X11", "gl=glx" in spec), self.define("GLEW_X11", "gl=glx" in spec),
self.define("CMAKE_DISABLE_FIND_PACKAGE_X11", "gl=glx" not 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 return args

View file

@ -13,8 +13,8 @@ class Opengl(BundlePackage):
"""Placeholder for external OpenGL libraries from hardware vendors""" """Placeholder for external OpenGL libraries from hardware vendors"""
homepage = "https://www.opengl.org/" homepage = "https://www.opengl.org/"
version("4.5") version("4.5")
maintainers("biddisco")
# This should really be when='platform=linux' but can't because of a # This should really be when='platform=linux' but can't because of a
# current bug in when and how ArchSpecs are constructed # current bug in when and how ArchSpecs are constructed
@ -82,16 +82,21 @@ def fetcher(self):
def fetcher(self): def fetcher(self):
_ = self.fetcher _ = self.fetcher
@property
def headers(self):
return self.gl_headers
@property @property
def libs(self): def libs(self):
return self.gl_libs return self.gl_libs
@property @property
def gl_headers(self): def gl_headers(self):
if "platform=darwin": spec = self.spec
header_name = "OpenGL/gl.h" if "platform=darwin" in spec:
header_name = "OpenGL/gl"
else: else:
header_name = "GL/gl.h" header_name = "GL/gl"
return find_headers(header_name, root=self.prefix, recursive=True) return find_headers(header_name, root=self.prefix, recursive=True)
@property @property

View file

@ -67,6 +67,7 @@ class Paraview(CMakePackage, CudaPackage, ROCmPackage):
variant("fortran", default=False, description="Enable Fortran support") variant("fortran", default=False, description="Enable Fortran support")
variant("mpi", default=True, description="Enable MPI support") variant("mpi", default=True, description="Enable MPI support")
variant("osmesa", default=False, description="Enable OSMesa 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("qt", default=False, description="Enable Qt (gui) support")
variant("opengl2", default=True, description="Enable OpenGL2 backend") variant("opengl2", default=True, description="Enable OpenGL2 backend")
variant("examples", default=False, description="Build examples") 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@3.2:", when="+opengl2")
depends_on("gl@1.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") depends_on("osmesa", when="+osmesa")
for p in ["linux", "cray"]: for p in ["linux", "cray"]:
depends_on("glx", when="~osmesa platform={}".format(p)) depends_on("glx", when="~egl ~osmesa platform={}".format(p))
depends_on("libxt", when="~osmesa platform={}".format(p)) depends_on("libxt", when="~egl ~osmesa platform={}".format(p))
conflicts("+qt", when="+osmesa") conflicts("+qt", when="+osmesa")
conflicts("+qt", when="+egl")
conflicts("+egl", when="+osmesa")
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")
@ -419,13 +424,20 @@ def nvariant_bool(feature):
"""Negated ternary for spec variant to OFF/ON string""" """Negated ternary for spec variant to OFF/ON string"""
return variant_bool(feature, on="OFF", off="ON") 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") rendering = variant_bool("+opengl2", "OpenGL2", "OpenGL")
includes = variant_bool("+development_files") includes = variant_bool("+development_files")
use_x11 = nvariant_bool("+osmesa") if not spec.satisfies("platform=windows") else "OFF"
cmake_args = [ cmake_args = [
"-DVTK_OPENGL_HAS_OSMESA:BOOL=%s" % variant_bool("+osmesa"), "-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, "-DPARAVIEW_INSTALL_DEVELOPMENT_FILES:BOOL=%s" % includes,
"-DBUILD_TESTING:BOOL=OFF", "-DBUILD_TESTING:BOOL=OFF",
"-DOpenGL_GL_PREFERENCE:STRING=LEGACY", "-DOpenGL_GL_PREFERENCE:STRING=LEGACY",
@ -433,6 +445,9 @@ def nvariant_bool(feature):
self.define_from_variant("VISIT_BUILD_READER_Silo", "visitbridge"), 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:"): 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_fast_float:BOOL=OFF")
cmake_args.append("-DVTK_MODULE_USE_EXTERNAL_VTK_token:BOOL=OFF") cmake_args.append("-DVTK_MODULE_USE_EXTERNAL_VTK_token:BOOL=OFF")