We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
GTK+ check in OpenCV easyblock
https://github.com/easybuilders/easybuild-easyconfigs/pull/13900 and https://github.com/easybuilders/easybuild-easyconfigs/pull/13893 mean that newer `GTK+` are now either `GTK2` and `GTK3`. The OpenCV block checks (https://github.com/easybuilders/easybuild-easyblocks/blob/develop/easybuild/easyblocks/o/opencv.py#L152) for `GTK+` and sets `-DWITH_GTK=OFF` if this is not found. The check will need updating.

I do not know if OpenCV can build with both GTK2 and GTK3 at the same time.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `easybuild/easyblocks/o/opencv.py`
Content:
```
1 ##
2 # Copyright 2018-2021 Ghent University
3 #
4 # This file is part of EasyBuild,
5 # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),
6 # with support of Ghent University (http://ugent.be/hpc),
7 # the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),
8 # Flemish Research Foundation (FWO) (http://www.fwo.be/en)
9 # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).
10 #
11 # https://github.com/easybuilders/easybuild
12 #
13 # EasyBuild is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation v2.
16 #
17 # EasyBuild is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 # GNU General Public License for more details.
21 #
22 # You should have received a copy of the GNU General Public License
23 # along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.
24 ##
25 """
26 EasyBuild support for building and installing OpenCV, implemented as an easyblock
27 
28 @author: Kenneth Hoste (Ghent University)
29 """
30 import glob
31 import os
32 from distutils.version import LooseVersion
33 
34 from easybuild.easyblocks.generic.cmakemake import CMakeMake
35 from easybuild.easyblocks.generic.pythonpackage import det_pylibdir
36 from easybuild.framework.easyconfig import CUSTOM
37 from easybuild.tools.build_log import EasyBuildError
38 from easybuild.tools.config import build_option
39 from easybuild.tools.filetools import compute_checksum, copy
40 from easybuild.tools.modules import get_software_libdir, get_software_root, get_software_version
41 from easybuild.tools.systemtools import X86_64, get_cpu_architecture, get_cpu_features, get_shared_lib_ext
42 from easybuild.tools.toolchain.compiler import OPTARCH_GENERIC
43 
44 
45 class EB_OpenCV(CMakeMake):
46     """Support for building/installing OpenCV."""
47 
48     @staticmethod
49     def extra_options():
50         """Custom easyconfig parameters specific to OpenCV."""
51         extra_vars = CMakeMake.extra_options()
52         extra_vars.update({
53             'cpu_dispatch': ['NONE', "Value to pass to -DCPU_DISPATCH configuration option", CUSTOM],
54         })
55         extra_vars['separate_build_dir'][0] = True
56         return extra_vars
57 
58     def __init__(self, *args, **kwargs):
59         """Initialisation of custom class variables for OpenCV."""
60         super(EB_OpenCV, self).__init__(*args, **kwargs)
61 
62         # can't be set before prepare_step is run
63         self.pylibdir = None
64 
65     def prepare_step(self, *args, **kwargs):
66         """Prepare environment for installing OpenCV."""
67         super(EB_OpenCV, self).prepare_step(*args, **kwargs)
68 
69         self.pylibdir = det_pylibdir()
70 
71         if get_cpu_architecture() == X86_64:
72             # IPP are Intel's Integrated Performance Primitives - so only make sense on X86_64
73             ippicv_tgz = glob.glob(os.path.join(self.builddir, 'ippicv*.tgz'))
74             if ippicv_tgz:
75                 if len(ippicv_tgz) == 1:
76                     # copy ippicv tarball in the right place
77                     # expected location is 3rdparty/ippicv/downloads/linux-<md5sum>/
78                     ippicv_tgz = ippicv_tgz[0]
79                     ippicv_tgz_md5 = compute_checksum(ippicv_tgz, checksum_type='md5')
80                     target_subdir = os.path.join('3rdparty', 'ippicv', 'downloads', 'linux-%s' % ippicv_tgz_md5)
81                     copy([ippicv_tgz], os.path.join(self.cfg['start_dir'], target_subdir))
82 
83                     self.cfg.update('configopts', '-DWITH_IPP=ON')
84 
85                     # for recent OpenCV 3.x versions (and newer), we must also specify the download location
86                     # to prevent that the ippicv tarball is re-downloaded
87                     if LooseVersion(self.version) >= LooseVersion('3.4.4'):
88                         self.cfg.update('configopts', '-DOPENCV_DOWNLOAD_PATH=%s' % self.builddir)
89                 else:
90                     raise EasyBuildError("Found multiple ippicv*.tgz source tarballs in %s: %s",
91                                          self.builddir, ippicv_tgz)
92 
93     def configure_step(self):
94         """Custom configuration procedure for OpenCV."""
95 
96         # enable Python support if unspecified and Python is a dependency
97         if 'BUILD_PYTHON_SUPPORT' not in self.cfg['configopts']:
98             if get_software_root('Python'):
99                 self.cfg.update('configopts', "-DBUILD_PYTHON_SUPPORT=ON -DBUILD_NEW_PYTHON_SUPPORT=ON")
100 
101                 # recent OpenCV 3.x versions (and newer) use an alternative configure option to specify the location
102                 # where the OpenCV Python bindings should be installed
103                 py_pkgs_path = os.path.join(self.installdir, self.pylibdir)
104                 if LooseVersion(self.version) >= LooseVersion('3.4.4'):
105                     self.cfg.update('configopts', '-DOPENCV_PYTHON_INSTALL_PATH=%s' % py_pkgs_path)
106                 else:
107                     self.cfg.update('configopts', '-DPYTHON_PACKAGES_PATH=%s' % py_pkgs_path)
108             else:
109                 self.cfg.update('configopts', "-DBUILD_PYTHON_SUPPORT=OFF -DBUILD_NEW_PYTHON_SUPPORT=OFF")
110 
111         # enable CUDA support if CUDA is a dependency
112         if 'WITH_CUDA' not in self.cfg['configopts']:
113             if get_software_root('CUDA'):
114                 self.cfg.update('configopts', '-DWITH_CUDA=ON')
115             else:
116                 self.cfg.update('configopts', '-DWITH_CUDA=OFF')
117 
118         # disable bundled protobuf if it is a dependency
119         if 'BUILD_PROTOBUF' not in self.cfg['configopts']:
120             if get_software_root('protobuf'):
121                 self.cfg.update('configopts', '-DBUILD_PROTOBUF=OFF')
122             else:
123                 self.cfg.update('configopts', '-DBUILD_PROTOBUF=ON')
124 
125         # configure for dependency libraries
126         for dep in ['JasPer', 'libjpeg-turbo', 'libpng', 'LibTIFF', 'libwebp', 'OpenEXR', 'zlib']:
127             if dep in ['libpng', 'LibTIFF', 'libwebp']:
128                 # strip off 'lib'
129                 opt_name = dep[3:].upper()
130             elif dep == 'libjpeg-turbo':
131                 opt_name = 'JPEG'
132             else:
133                 opt_name = dep.upper()
134 
135             shlib_ext = get_shared_lib_ext()
136             if dep == 'zlib':
137                 lib_file = 'libz.%s' % shlib_ext
138             else:
139                 lib_file = 'lib%s.%s' % (opt_name.lower(), shlib_ext)
140 
141             dep_root = get_software_root(dep)
142             if dep_root:
143                 if dep == 'OpenEXR':
144                     self.cfg.update('configopts', '-D%s_ROOT=%s' % (opt_name, dep_root))
145                 else:
146                     inc_path = os.path.join(dep_root, 'include')
147                     self.cfg.update('configopts', '-D%s_INCLUDE_DIR=%s' % (opt_name, inc_path))
148                     libdir = get_software_libdir(dep, only_one=True)
149                     lib_path = os.path.join(dep_root, libdir, lib_file)
150                     self.cfg.update('configopts', '-D%s_LIBRARY=%s' % (opt_name, lib_path))
151 
152         # GTK+3 is used by default, use GTK+2 or none explicitely to avoid picking up a system GTK
153         if get_software_root('GTK+'):
154             if LooseVersion(get_software_version('GTK+')) < LooseVersion('3.0'):
155                 self.cfg.update('configopts', '-DWITH_GTK_2_X=ON')
156         else:
157             self.cfg.update('configopts', '-DWITH_GTK=OFF')
158 
159         # configure optimisation for CPU architecture
160         # see https://github.com/opencv/opencv/wiki/CPU-optimizations-build-options
161         if self.toolchain.options.get('optarch') and 'CPU_BASELINE' not in self.cfg['configopts']:
162             optarch = build_option('optarch')
163             if optarch is None:
164                 # optimize for host arch (let OpenCV detect it)
165                 self.cfg.update('configopts', '-DCPU_BASELINE=DETECT')
166             elif optarch == OPTARCH_GENERIC:
167                 # optimize for generic x86 architecture (lowest supported by OpenCV is SSE3)
168                 self.cfg.update('configopts', '-DCPU_BASELINE=SSE3')
169             else:
170                 raise EasyBuildError("Don't know how to configure OpenCV in accordance with --optarch='%s'", optarch)
171 
172         if self.cfg['cpu_dispatch']:
173             # using 'NONE' as value is equivalent with disabling the build of fat binaries (which is done by default)
174             self.cfg.update('configopts', '-DCPU_DISPATCH=%s' % self.cfg['cpu_dispatch'])
175 
176         # make sure that host CPU supports FP16 (unless -DCPU_BASELINE_DISABLE is already specified)
177         # Intel Sandy Bridge does not support FP16!
178         if 'CPU_BASELINE_DISABLE' not in self.cfg['configopts']:
179             avail_cpu_features = get_cpu_features()
180             if 'f16c' not in avail_cpu_features:
181                 self.cfg.update('configopts', '-DCPU_BASELINE_DISABLE=FP16')
182 
183         super(EB_OpenCV, self).configure_step()
184 
185     def install_step(self):
186         """
187         Custom installation procedure for OpenCV: also copy IPP library into lib subdirectory of installation directory.
188         """
189         super(EB_OpenCV, self).install_step()
190 
191         if 'WITH_IPP=ON' in self.cfg['configopts']:
192             common_dir = os.path.join('3rdparty', 'ippicv', 'ippicv_lnx')
193 
194             # for some recent OpenCV 3.x versions, libippicv.a is now in a subdirectory named 'icv'
195             if LooseVersion(self.version) >= LooseVersion('3.4.4'):
196                 ipp_libs = glob.glob(os.path.join(common_dir, 'icv', 'lib', 'intel64', 'libippicv.*'))
197             else:
198                 ipp_libs = glob.glob(os.path.join(common_dir, 'lib', 'intel64', 'libippicv.*'))
199 
200             copy(ipp_libs, os.path.join(self.installdir, 'lib'))
201 
202     def sanity_check_step(self):
203         """Custom sanity check for OpenCV."""
204         opencv_bins = ['annotation', 'interactive-calibration', 'version', 'visualisation']
205         if LooseVersion(self.version) < LooseVersion('4.0'):
206             opencv_bins.extend(['createsamples', 'traincascade'])
207 
208         libfile = 'libopencv_core.%s' % get_shared_lib_ext()
209         custom_paths = {
210             'files': [os.path.join('bin', 'opencv_%s' % x) for x in opencv_bins] + [os.path.join('lib64', libfile)],
211             'dirs': ['include'],
212         }
213         if 'WITH_IPP=ON' in self.cfg['configopts']:
214             custom_paths['files'].append(os.path.join('lib', 'libippicv.a'))
215 
216         custom_commands = []
217         if get_software_root('Python'):
218             custom_commands.append("python -c 'import cv2'")
219 
220         super(EB_OpenCV, self).sanity_check_step(custom_paths=custom_paths, custom_commands=custom_commands)
221 
222     def make_module_extra(self):
223         """Custom extra module file entries for OpenCV."""
224         txt = super(EB_OpenCV, self).make_module_extra()
225 
226         txt += self.module_generator.prepend_paths('CLASSPATH', os.path.join('share', 'OpenCV', 'java'))
227 
228         if os.path.exists(os.path.join(self.installdir, self.pylibdir)):
229             txt += self.module_generator.prepend_paths('PYTHONPATH', self.pylibdir)
230 
231         return txt
232
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/easybuild/easyblocks/o/opencv.py b/easybuild/easyblocks/o/opencv.py
--- a/easybuild/easyblocks/o/opencv.py
+++ b/easybuild/easyblocks/o/opencv.py
@@ -26,6 +26,7 @@
 EasyBuild support for building and installing OpenCV, implemented as an easyblock
 
 @author: Kenneth Hoste (Ghent University)
+@author: Simon Branford (University of Birmingham)
 """
 import glob
 import os
@@ -153,6 +154,10 @@
         if get_software_root('GTK+'):
             if LooseVersion(get_software_version('GTK+')) < LooseVersion('3.0'):
                 self.cfg.update('configopts', '-DWITH_GTK_2_X=ON')
+        elif get_software_root('GTK3'):
+            pass
+        elif get_software_root('GTK2'):
+            self.cfg.update('configopts', '-DWITH_GTK_2_X=ON')
         else:
             self.cfg.update('configopts', '-DWITH_GTK=OFF')

{"golden_diff": "diff --git a/easybuild/easyblocks/o/opencv.py b/easybuild/easyblocks/o/opencv.py\n--- a/easybuild/easyblocks/o/opencv.py\n+++ b/easybuild/easyblocks/o/opencv.py\n@@ -26,6 +26,7 @@\n EasyBuild support for building and installing OpenCV, implemented as an easyblock\n \n @author: Kenneth Hoste (Ghent University)\n+@author: Simon Branford (University of Birmingham)\n \"\"\"\n import glob\n import os\n@@ -153,6 +154,10 @@\n         if get_software_root('GTK+'):\n             if LooseVersion(get_software_version('GTK+')) < LooseVersion('3.0'):\n                 self.cfg.update('configopts', '-DWITH_GTK_2_X=ON')\n+        elif get_software_root('GTK3'):\n+            pass\n+        elif get_software_root('GTK2'):\n+            self.cfg.update('configopts', '-DWITH_GTK_2_X=ON')\n         else:\n             self.cfg.update('configopts', '-DWITH_GTK=OFF')\n", "issue": "GTK+ check in OpenCV easyblock\nhttps://github.com/easybuilders/easybuild-easyconfigs/pull/13900 and https://github.com/easybuilders/easybuild-easyconfigs/pull/13893 mean that newer `GTK+` are now either `GTK2` and `GTK3`. The OpenCV block checks (https://github.com/easybuilders/easybuild-easyblocks/blob/develop/easybuild/easyblocks/o/opencv.py#L152) for `GTK+` and sets `-DWITH_GTK=OFF` if this is not found. The check will need updating.\r\n\r\nI do not know if OpenCV can build with both GTK2 and GTK3 at the same time.\n", "before_files": [{"content": "##\n# Copyright 2018-2021 Ghent University\n#\n# This file is part of EasyBuild,\n# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),\n# with support of Ghent University (http://ugent.be/hpc),\n# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),\n# Flemish Research Foundation (FWO) (http://www.fwo.be/en)\n# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).\n#\n# https://github.com/easybuilders/easybuild\n#\n# EasyBuild is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation v2.\n#\n# EasyBuild is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.\n##\n\"\"\"\nEasyBuild support for building and installing OpenCV, implemented as an easyblock\n\n@author: Kenneth Hoste (Ghent University)\n\"\"\"\nimport glob\nimport os\nfrom distutils.version import LooseVersion\n\nfrom easybuild.easyblocks.generic.cmakemake import CMakeMake\nfrom easybuild.easyblocks.generic.pythonpackage import det_pylibdir\nfrom easybuild.framework.easyconfig import CUSTOM\nfrom easybuild.tools.build_log import EasyBuildError\nfrom easybuild.tools.config import build_option\nfrom easybuild.tools.filetools import compute_checksum, copy\nfrom easybuild.tools.modules import get_software_libdir, get_software_root, get_software_version\nfrom easybuild.tools.systemtools import X86_64, get_cpu_architecture, get_cpu_features, get_shared_lib_ext\nfrom easybuild.tools.toolchain.compiler import OPTARCH_GENERIC\n\n\nclass EB_OpenCV(CMakeMake):\n    \"\"\"Support for building/installing OpenCV.\"\"\"\n\n    @staticmethod\n    def extra_options():\n        \"\"\"Custom easyconfig parameters specific to OpenCV.\"\"\"\n        extra_vars = CMakeMake.extra_options()\n        extra_vars.update({\n            'cpu_dispatch': ['NONE', \"Value to pass to -DCPU_DISPATCH configuration option\", CUSTOM],\n        })\n        extra_vars['separate_build_dir'][0] = True\n        return extra_vars\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"Initialisation of custom class variables for OpenCV.\"\"\"\n        super(EB_OpenCV, self).__init__(*args, **kwargs)\n\n        # can't be set before prepare_step is run\n        self.pylibdir = None\n\n    def prepare_step(self, *args, **kwargs):\n        \"\"\"Prepare environment for installing OpenCV.\"\"\"\n        super(EB_OpenCV, self).prepare_step(*args, **kwargs)\n\n        self.pylibdir = det_pylibdir()\n\n        if get_cpu_architecture() == X86_64:\n            # IPP are Intel's Integrated Performance Primitives - so only make sense on X86_64\n            ippicv_tgz = glob.glob(os.path.join(self.builddir, 'ippicv*.tgz'))\n            if ippicv_tgz:\n                if len(ippicv_tgz) == 1:\n                    # copy ippicv tarball in the right place\n                    # expected location is 3rdparty/ippicv/downloads/linux-<md5sum>/\n                    ippicv_tgz = ippicv_tgz[0]\n                    ippicv_tgz_md5 = compute_checksum(ippicv_tgz, checksum_type='md5')\n                    target_subdir = os.path.join('3rdparty', 'ippicv', 'downloads', 'linux-%s' % ippicv_tgz_md5)\n                    copy([ippicv_tgz], os.path.join(self.cfg['start_dir'], target_subdir))\n\n                    self.cfg.update('configopts', '-DWITH_IPP=ON')\n\n                    # for recent OpenCV 3.x versions (and newer), we must also specify the download location\n                    # to prevent that the ippicv tarball is re-downloaded\n                    if LooseVersion(self.version) >= LooseVersion('3.4.4'):\n                        self.cfg.update('configopts', '-DOPENCV_DOWNLOAD_PATH=%s' % self.builddir)\n                else:\n                    raise EasyBuildError(\"Found multiple ippicv*.tgz source tarballs in %s: %s\",\n                                         self.builddir, ippicv_tgz)\n\n    def configure_step(self):\n        \"\"\"Custom configuration procedure for OpenCV.\"\"\"\n\n        # enable Python support if unspecified and Python is a dependency\n        if 'BUILD_PYTHON_SUPPORT' not in self.cfg['configopts']:\n            if get_software_root('Python'):\n                self.cfg.update('configopts', \"-DBUILD_PYTHON_SUPPORT=ON -DBUILD_NEW_PYTHON_SUPPORT=ON\")\n\n                # recent OpenCV 3.x versions (and newer) use an alternative configure option to specify the location\n                # where the OpenCV Python bindings should be installed\n                py_pkgs_path = os.path.join(self.installdir, self.pylibdir)\n                if LooseVersion(self.version) >= LooseVersion('3.4.4'):\n                    self.cfg.update('configopts', '-DOPENCV_PYTHON_INSTALL_PATH=%s' % py_pkgs_path)\n                else:\n                    self.cfg.update('configopts', '-DPYTHON_PACKAGES_PATH=%s' % py_pkgs_path)\n            else:\n                self.cfg.update('configopts', \"-DBUILD_PYTHON_SUPPORT=OFF -DBUILD_NEW_PYTHON_SUPPORT=OFF\")\n\n        # enable CUDA support if CUDA is a dependency\n        if 'WITH_CUDA' not in self.cfg['configopts']:\n            if get_software_root('CUDA'):\n                self.cfg.update('configopts', '-DWITH_CUDA=ON')\n            else:\n                self.cfg.update('configopts', '-DWITH_CUDA=OFF')\n\n        # disable bundled protobuf if it is a dependency\n        if 'BUILD_PROTOBUF' not in self.cfg['configopts']:\n            if get_software_root('protobuf'):\n                self.cfg.update('configopts', '-DBUILD_PROTOBUF=OFF')\n            else:\n                self.cfg.update('configopts', '-DBUILD_PROTOBUF=ON')\n\n        # configure for dependency libraries\n        for dep in ['JasPer', 'libjpeg-turbo', 'libpng', 'LibTIFF', 'libwebp', 'OpenEXR', 'zlib']:\n            if dep in ['libpng', 'LibTIFF', 'libwebp']:\n                # strip off 'lib'\n                opt_name = dep[3:].upper()\n            elif dep == 'libjpeg-turbo':\n                opt_name = 'JPEG'\n            else:\n                opt_name = dep.upper()\n\n            shlib_ext = get_shared_lib_ext()\n            if dep == 'zlib':\n                lib_file = 'libz.%s' % shlib_ext\n            else:\n                lib_file = 'lib%s.%s' % (opt_name.lower(), shlib_ext)\n\n            dep_root = get_software_root(dep)\n            if dep_root:\n                if dep == 'OpenEXR':\n                    self.cfg.update('configopts', '-D%s_ROOT=%s' % (opt_name, dep_root))\n                else:\n                    inc_path = os.path.join(dep_root, 'include')\n                    self.cfg.update('configopts', '-D%s_INCLUDE_DIR=%s' % (opt_name, inc_path))\n                    libdir = get_software_libdir(dep, only_one=True)\n                    lib_path = os.path.join(dep_root, libdir, lib_file)\n                    self.cfg.update('configopts', '-D%s_LIBRARY=%s' % (opt_name, lib_path))\n\n        # GTK+3 is used by default, use GTK+2 or none explicitely to avoid picking up a system GTK\n        if get_software_root('GTK+'):\n            if LooseVersion(get_software_version('GTK+')) < LooseVersion('3.0'):\n                self.cfg.update('configopts', '-DWITH_GTK_2_X=ON')\n        else:\n            self.cfg.update('configopts', '-DWITH_GTK=OFF')\n\n        # configure optimisation for CPU architecture\n        # see https://github.com/opencv/opencv/wiki/CPU-optimizations-build-options\n        if self.toolchain.options.get('optarch') and 'CPU_BASELINE' not in self.cfg['configopts']:\n            optarch = build_option('optarch')\n            if optarch is None:\n                # optimize for host arch (let OpenCV detect it)\n                self.cfg.update('configopts', '-DCPU_BASELINE=DETECT')\n            elif optarch == OPTARCH_GENERIC:\n                # optimize for generic x86 architecture (lowest supported by OpenCV is SSE3)\n                self.cfg.update('configopts', '-DCPU_BASELINE=SSE3')\n            else:\n                raise EasyBuildError(\"Don't know how to configure OpenCV in accordance with --optarch='%s'\", optarch)\n\n        if self.cfg['cpu_dispatch']:\n            # using 'NONE' as value is equivalent with disabling the build of fat binaries (which is done by default)\n            self.cfg.update('configopts', '-DCPU_DISPATCH=%s' % self.cfg['cpu_dispatch'])\n\n        # make sure that host CPU supports FP16 (unless -DCPU_BASELINE_DISABLE is already specified)\n        # Intel Sandy Bridge does not support FP16!\n        if 'CPU_BASELINE_DISABLE' not in self.cfg['configopts']:\n            avail_cpu_features = get_cpu_features()\n            if 'f16c' not in avail_cpu_features:\n                self.cfg.update('configopts', '-DCPU_BASELINE_DISABLE=FP16')\n\n        super(EB_OpenCV, self).configure_step()\n\n    def install_step(self):\n        \"\"\"\n        Custom installation procedure for OpenCV: also copy IPP library into lib subdirectory of installation directory.\n        \"\"\"\n        super(EB_OpenCV, self).install_step()\n\n        if 'WITH_IPP=ON' in self.cfg['configopts']:\n            common_dir = os.path.join('3rdparty', 'ippicv', 'ippicv_lnx')\n\n            # for some recent OpenCV 3.x versions, libippicv.a is now in a subdirectory named 'icv'\n            if LooseVersion(self.version) >= LooseVersion('3.4.4'):\n                ipp_libs = glob.glob(os.path.join(common_dir, 'icv', 'lib', 'intel64', 'libippicv.*'))\n            else:\n                ipp_libs = glob.glob(os.path.join(common_dir, 'lib', 'intel64', 'libippicv.*'))\n\n            copy(ipp_libs, os.path.join(self.installdir, 'lib'))\n\n    def sanity_check_step(self):\n        \"\"\"Custom sanity check for OpenCV.\"\"\"\n        opencv_bins = ['annotation', 'interactive-calibration', 'version', 'visualisation']\n        if LooseVersion(self.version) < LooseVersion('4.0'):\n            opencv_bins.extend(['createsamples', 'traincascade'])\n\n        libfile = 'libopencv_core.%s' % get_shared_lib_ext()\n        custom_paths = {\n            'files': [os.path.join('bin', 'opencv_%s' % x) for x in opencv_bins] + [os.path.join('lib64', libfile)],\n            'dirs': ['include'],\n        }\n        if 'WITH_IPP=ON' in self.cfg['configopts']:\n            custom_paths['files'].append(os.path.join('lib', 'libippicv.a'))\n\n        custom_commands = []\n        if get_software_root('Python'):\n            custom_commands.append(\"python -c 'import cv2'\")\n\n        super(EB_OpenCV, self).sanity_check_step(custom_paths=custom_paths, custom_commands=custom_commands)\n\n    def make_module_extra(self):\n        \"\"\"Custom extra module file entries for OpenCV.\"\"\"\n        txt = super(EB_OpenCV, self).make_module_extra()\n\n        txt += self.module_generator.prepend_paths('CLASSPATH', os.path.join('share', 'OpenCV', 'java'))\n\n        if os.path.exists(os.path.join(self.installdir, self.pylibdir)):\n            txt += self.module_generator.prepend_paths('PYTHONPATH', self.pylibdir)\n\n        return txt\n", "path": "easybuild/easyblocks/o/opencv.py"}], "after_files": [{"content": "##\n# Copyright 2018-2021 Ghent University\n#\n# This file is part of EasyBuild,\n# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),\n# with support of Ghent University (http://ugent.be/hpc),\n# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),\n# Flemish Research Foundation (FWO) (http://www.fwo.be/en)\n# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).\n#\n# https://github.com/easybuilders/easybuild\n#\n# EasyBuild is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation v2.\n#\n# EasyBuild is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.\n##\n\"\"\"\nEasyBuild support for building and installing OpenCV, implemented as an easyblock\n\n@author: Kenneth Hoste (Ghent University)\n@author: Simon Branford (University of Birmingham)\n\"\"\"\nimport glob\nimport os\nfrom distutils.version import LooseVersion\n\nfrom easybuild.easyblocks.generic.cmakemake import CMakeMake\nfrom easybuild.easyblocks.generic.pythonpackage import det_pylibdir\nfrom easybuild.framework.easyconfig import CUSTOM\nfrom easybuild.tools.build_log import EasyBuildError\nfrom easybuild.tools.config import build_option\nfrom easybuild.tools.filetools import compute_checksum, copy\nfrom easybuild.tools.modules import get_software_libdir, get_software_root, get_software_version\nfrom easybuild.tools.systemtools import X86_64, get_cpu_architecture, get_cpu_features, get_shared_lib_ext\nfrom easybuild.tools.toolchain.compiler import OPTARCH_GENERIC\n\n\nclass EB_OpenCV(CMakeMake):\n    \"\"\"Support for building/installing OpenCV.\"\"\"\n\n    @staticmethod\n    def extra_options():\n        \"\"\"Custom easyconfig parameters specific to OpenCV.\"\"\"\n        extra_vars = CMakeMake.extra_options()\n        extra_vars.update({\n            'cpu_dispatch': ['NONE', \"Value to pass to -DCPU_DISPATCH configuration option\", CUSTOM],\n        })\n        extra_vars['separate_build_dir'][0] = True\n        return extra_vars\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"Initialisation of custom class variables for OpenCV.\"\"\"\n        super(EB_OpenCV, self).__init__(*args, **kwargs)\n\n        # can't be set before prepare_step is run\n        self.pylibdir = None\n\n    def prepare_step(self, *args, **kwargs):\n        \"\"\"Prepare environment for installing OpenCV.\"\"\"\n        super(EB_OpenCV, self).prepare_step(*args, **kwargs)\n\n        self.pylibdir = det_pylibdir()\n\n        if get_cpu_architecture() == X86_64:\n            # IPP are Intel's Integrated Performance Primitives - so only make sense on X86_64\n            ippicv_tgz = glob.glob(os.path.join(self.builddir, 'ippicv*.tgz'))\n            if ippicv_tgz:\n                if len(ippicv_tgz) == 1:\n                    # copy ippicv tarball in the right place\n                    # expected location is 3rdparty/ippicv/downloads/linux-<md5sum>/\n                    ippicv_tgz = ippicv_tgz[0]\n                    ippicv_tgz_md5 = compute_checksum(ippicv_tgz, checksum_type='md5')\n                    target_subdir = os.path.join('3rdparty', 'ippicv', 'downloads', 'linux-%s' % ippicv_tgz_md5)\n                    copy([ippicv_tgz], os.path.join(self.cfg['start_dir'], target_subdir))\n\n                    self.cfg.update('configopts', '-DWITH_IPP=ON')\n\n                    # for recent OpenCV 3.x versions (and newer), we must also specify the download location\n                    # to prevent that the ippicv tarball is re-downloaded\n                    if LooseVersion(self.version) >= LooseVersion('3.4.4'):\n                        self.cfg.update('configopts', '-DOPENCV_DOWNLOAD_PATH=%s' % self.builddir)\n                else:\n                    raise EasyBuildError(\"Found multiple ippicv*.tgz source tarballs in %s: %s\",\n                                         self.builddir, ippicv_tgz)\n\n    def configure_step(self):\n        \"\"\"Custom configuration procedure for OpenCV.\"\"\"\n\n        # enable Python support if unspecified and Python is a dependency\n        if 'BUILD_PYTHON_SUPPORT' not in self.cfg['configopts']:\n            if get_software_root('Python'):\n                self.cfg.update('configopts', \"-DBUILD_PYTHON_SUPPORT=ON -DBUILD_NEW_PYTHON_SUPPORT=ON\")\n\n                # recent OpenCV 3.x versions (and newer) use an alternative configure option to specify the location\n                # where the OpenCV Python bindings should be installed\n                py_pkgs_path = os.path.join(self.installdir, self.pylibdir)\n                if LooseVersion(self.version) >= LooseVersion('3.4.4'):\n                    self.cfg.update('configopts', '-DOPENCV_PYTHON_INSTALL_PATH=%s' % py_pkgs_path)\n                else:\n                    self.cfg.update('configopts', '-DPYTHON_PACKAGES_PATH=%s' % py_pkgs_path)\n            else:\n                self.cfg.update('configopts', \"-DBUILD_PYTHON_SUPPORT=OFF -DBUILD_NEW_PYTHON_SUPPORT=OFF\")\n\n        # enable CUDA support if CUDA is a dependency\n        if 'WITH_CUDA' not in self.cfg['configopts']:\n            if get_software_root('CUDA'):\n                self.cfg.update('configopts', '-DWITH_CUDA=ON')\n            else:\n                self.cfg.update('configopts', '-DWITH_CUDA=OFF')\n\n        # disable bundled protobuf if it is a dependency\n        if 'BUILD_PROTOBUF' not in self.cfg['configopts']:\n            if get_software_root('protobuf'):\n                self.cfg.update('configopts', '-DBUILD_PROTOBUF=OFF')\n            else:\n                self.cfg.update('configopts', '-DBUILD_PROTOBUF=ON')\n\n        # configure for dependency libraries\n        for dep in ['JasPer', 'libjpeg-turbo', 'libpng', 'LibTIFF', 'libwebp', 'OpenEXR', 'zlib']:\n            if dep in ['libpng', 'LibTIFF', 'libwebp']:\n                # strip off 'lib'\n                opt_name = dep[3:].upper()\n            elif dep == 'libjpeg-turbo':\n                opt_name = 'JPEG'\n            else:\n                opt_name = dep.upper()\n\n            shlib_ext = get_shared_lib_ext()\n            if dep == 'zlib':\n                lib_file = 'libz.%s' % shlib_ext\n            else:\n                lib_file = 'lib%s.%s' % (opt_name.lower(), shlib_ext)\n\n            dep_root = get_software_root(dep)\n            if dep_root:\n                if dep == 'OpenEXR':\n                    self.cfg.update('configopts', '-D%s_ROOT=%s' % (opt_name, dep_root))\n                else:\n                    inc_path = os.path.join(dep_root, 'include')\n                    self.cfg.update('configopts', '-D%s_INCLUDE_DIR=%s' % (opt_name, inc_path))\n                    libdir = get_software_libdir(dep, only_one=True)\n                    lib_path = os.path.join(dep_root, libdir, lib_file)\n                    self.cfg.update('configopts', '-D%s_LIBRARY=%s' % (opt_name, lib_path))\n\n        # GTK+3 is used by default, use GTK+2 or none explicitely to avoid picking up a system GTK\n        if get_software_root('GTK+'):\n            if LooseVersion(get_software_version('GTK+')) < LooseVersion('3.0'):\n                self.cfg.update('configopts', '-DWITH_GTK_2_X=ON')\n        elif get_software_root('GTK3'):\n            pass\n        elif get_software_root('GTK2'):\n            self.cfg.update('configopts', '-DWITH_GTK_2_X=ON')\n        else:\n            self.cfg.update('configopts', '-DWITH_GTK=OFF')\n\n        # configure optimisation for CPU architecture\n        # see https://github.com/opencv/opencv/wiki/CPU-optimizations-build-options\n        if self.toolchain.options.get('optarch') and 'CPU_BASELINE' not in self.cfg['configopts']:\n            optarch = build_option('optarch')\n            if optarch is None:\n                # optimize for host arch (let OpenCV detect it)\n                self.cfg.update('configopts', '-DCPU_BASELINE=DETECT')\n            elif optarch == OPTARCH_GENERIC:\n                # optimize for generic x86 architecture (lowest supported by OpenCV is SSE3)\n                self.cfg.update('configopts', '-DCPU_BASELINE=SSE3')\n            else:\n                raise EasyBuildError(\"Don't know how to configure OpenCV in accordance with --optarch='%s'\", optarch)\n\n        if self.cfg['cpu_dispatch']:\n            # using 'NONE' as value is equivalent with disabling the build of fat binaries (which is done by default)\n            self.cfg.update('configopts', '-DCPU_DISPATCH=%s' % self.cfg['cpu_dispatch'])\n\n        # make sure that host CPU supports FP16 (unless -DCPU_BASELINE_DISABLE is already specified)\n        # Intel Sandy Bridge does not support FP16!\n        if 'CPU_BASELINE_DISABLE' not in self.cfg['configopts']:\n            avail_cpu_features = get_cpu_features()\n            if 'f16c' not in avail_cpu_features:\n                self.cfg.update('configopts', '-DCPU_BASELINE_DISABLE=FP16')\n\n        super(EB_OpenCV, self).configure_step()\n\n    def install_step(self):\n        \"\"\"\n        Custom installation procedure for OpenCV: also copy IPP library into lib subdirectory of installation directory.\n        \"\"\"\n        super(EB_OpenCV, self).install_step()\n\n        if 'WITH_IPP=ON' in self.cfg['configopts']:\n            common_dir = os.path.join('3rdparty', 'ippicv', 'ippicv_lnx')\n\n            # for some recent OpenCV 3.x versions, libippicv.a is now in a subdirectory named 'icv'\n            if LooseVersion(self.version) >= LooseVersion('3.4.4'):\n                ipp_libs = glob.glob(os.path.join(common_dir, 'icv', 'lib', 'intel64', 'libippicv.*'))\n            else:\n                ipp_libs = glob.glob(os.path.join(common_dir, 'lib', 'intel64', 'libippicv.*'))\n\n            copy(ipp_libs, os.path.join(self.installdir, 'lib'))\n\n    def sanity_check_step(self):\n        \"\"\"Custom sanity check for OpenCV.\"\"\"\n        opencv_bins = ['annotation', 'interactive-calibration', 'version', 'visualisation']\n        if LooseVersion(self.version) < LooseVersion('4.0'):\n            opencv_bins.extend(['createsamples', 'traincascade'])\n\n        libfile = 'libopencv_core.%s' % get_shared_lib_ext()\n        custom_paths = {\n            'files': [os.path.join('bin', 'opencv_%s' % x) for x in opencv_bins] + [os.path.join('lib64', libfile)],\n            'dirs': ['include'],\n        }\n        if 'WITH_IPP=ON' in self.cfg['configopts']:\n            custom_paths['files'].append(os.path.join('lib', 'libippicv.a'))\n\n        custom_commands = []\n        if get_software_root('Python'):\n            custom_commands.append(\"python -c 'import cv2'\")\n\n        super(EB_OpenCV, self).sanity_check_step(custom_paths=custom_paths, custom_commands=custom_commands)\n\n    def make_module_extra(self):\n        \"\"\"Custom extra module file entries for OpenCV.\"\"\"\n        txt = super(EB_OpenCV, self).make_module_extra()\n\n        txt += self.module_generator.prepend_paths('CLASSPATH', os.path.join('share', 'OpenCV', 'java'))\n\n        if os.path.exists(os.path.join(self.installdir, self.pylibdir)):\n            txt += self.module_generator.prepend_paths('PYTHONPATH', self.pylibdir)\n\n        return txt\n", "path": "easybuild/easyblocks/o/opencv.py"}]}