Skip to content

File tree

8 files changed

+149
-70
lines changed

8 files changed

+149
-70
lines changed
 

‎.github/workflows/linting.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
run: |
2424
pip install --upgrade pip
2525
# fix to this version for develop branch (to avoid needing to fix geant4.py)
26-
pip install --upgrade "flake8<7.1"
26+
pip install --upgrade "flake8"
2727
2828
- name: Run flake8 to verify PEP8-compliance of Python code
2929
run: flake8

‎easybuild/easyblocks/g/geant4.py

+55-55
Original file line numberDiff line numberDiff line change
@@ -96,102 +96,102 @@ def configure_step(self):
9696
"There exists a config.sh file. Shall I use it to set the defaults? [y]": "n",
9797
"Would you like to see the instructions? [n]": "",
9898
"[Type carriage return to continue]": "",
99-
"Definition of G4SYSTEM variable is Linux-g++. That stands for: 1) OS : Linux" \
100-
"2) Compiler : g++ To modify default settings, select number above (e.g. 2) " \
99+
"Definition of G4SYSTEM variable is Linux-g++. That stands for: 1) OS : Linux"
100+
"2) Compiler : g++ To modify default settings, select number above (e.g. 2) "
101101
"[Press [Enter] for default settings]": "2",
102102
"Which C++ compiler? [g++]": "$(GPP)",
103103
"Confirm your selection or set recommended 'g++'! [*]": "",
104-
"Definition of G4SYSTEM variable is Linux-icc. That stands for: 1) OS : Linux 2)" \
105-
"Compiler : icc To modify default settings, select number above (e.g. 2) " \
104+
"Definition of G4SYSTEM variable is Linux-icc. That stands for: 1) OS : Linux 2)"
105+
"Compiler : icc To modify default settings, select number above (e.g. 2) "
106106
"[Press [Enter] for default settings]": "",
107107
"Do you expect to run these scripts and binaries on multiple machines? [n]": "y",
108108
"Where is Geant4 source installed? [%s]" % pwd: "",
109-
"Specify the path where Geant4 libraries and source files should be installed." \
109+
"Specify the path where Geant4 libraries and source files should be installed."
110110
" [%s]" % pwd: dst,
111111
"Do you want to copy all Geant4 headers in one directory? [n]": "y",
112-
"Please, specify default directory where ALL the Geant4 data is installed:" \
113-
"G4LEVELGAMMADATA: %(pwd)s/data/PhotonEvaporation2.0 G4RADIOACTIVEDATA: " \
114-
"%(pwd)s/data/RadioactiveDecay3.2 G4LEDATA: %(pwd)s/data/G4EMLOW5.1 G4NEUTRONHPDATA: " \
115-
"%(pwd)s/data/G4NDL3.12 G4ABLADATA: %(pwd)s/data/G4ABLA3.0 You will be asked about " \
112+
"Please, specify default directory where ALL the Geant4 data is installed:"
113+
"G4LEVELGAMMADATA: %(pwd)s/data/PhotonEvaporation2.0 G4RADIOACTIVEDATA: "
114+
"%(pwd)s/data/RadioactiveDecay3.2 G4LEDATA: %(pwd)s/data/G4EMLOW5.1 G4NEUTRONHPDATA: "
115+
"%(pwd)s/data/G4NDL3.12 G4ABLADATA: %(pwd)s/data/G4ABLA3.0 You will be asked about "
116116
"customizing these next. [%(pwd)s/data]" % {'pwd': pwd}: "%s/data" % dst,
117117
"Directory %s/data doesn't exist. Use that name anyway? [n]" % dst: "y",
118-
"Please, specify default directory where the Geant4 data is installed: " \
119-
"1) G4LEVELGAMMADATA: %(dst)s/data/PhotonEvaporation2.0 2) G4RADIOACTIVEDATA: " \
120-
"%(dst)s/data/RadioactiveDecay3.2 3) G4LEDATA: %(dst)s/data/G4EMLOW5.1 4) G4NEUTRONHPDATA: " \
121-
"%(dst)s/data/G4NDL3.12 5) G4ABLADATA: %(dst)s/data/G4ABLA3.0 To modify default settings, " \
118+
"Please, specify default directory where the Geant4 data is installed: "
119+
"1) G4LEVELGAMMADATA: %(dst)s/data/PhotonEvaporation2.0 2) G4RADIOACTIVEDATA: "
120+
"%(dst)s/data/RadioactiveDecay3.2 3) G4LEDATA: %(dst)s/data/G4EMLOW5.1 4) G4NEUTRONHPDATA: "
121+
"%(dst)s/data/G4NDL3.12 5) G4ABLADATA: %(dst)s/data/G4ABLA3.0 To modify default settings, "
122122
"select number above (e.g. 2) [Press [Enter] for default settings]" % {'dst': dst}: "",
123123
"Please, specify where CLHEP is installed: CLHEP_BASE_DIR: ": clhepdir,
124124
"Please, specify where CLHEP is installed: CLHEP_BASE_DIR: [%s]" % clhepdir: "",
125-
"You can customize paths and library name of you CLHEP installation: 1) CLHEP_INCLUDE_DIR: " \
126-
"%(clhepdir)s/include 2) CLHEP_LIB_DIR: %(clhepdir)s/lib 3) CLHEP_LIB: CLHEP To modify " \
125+
"You can customize paths and library name of you CLHEP installation: 1) CLHEP_INCLUDE_DIR: "
126+
"%(clhepdir)s/include 2) CLHEP_LIB_DIR: %(clhepdir)s/lib 3) CLHEP_LIB: CLHEP To modify "
127127
"default settings, select number above (e.g. 2) [Press [Enter] for default settings]" %
128128
{'clhepdir': clhepdir}: "",
129-
"By default 'static' (.a) libraries are built. Do you want to build 'shared' (.so) " \
129+
"By default 'static' (.a) libraries are built. Do you want to build 'shared' (.so) "
130130
"libraries? [n]": "y",
131-
"You selected to build 'shared' (.so) libraries. Do you want to build 'static' (.a) " \
131+
"You selected to build 'shared' (.so) libraries. Do you want to build 'static' (.a) "
132132
"libraries too? [n]": "y",
133133
"Do you want to build 'global' compound libraries? [n]": "",
134134
"Do you want to compile libraries in DEBUG mode (-g)? [n]": "",
135-
"G4UI_NONE If this variable is set, no UI sessions nor any UI libraries are built. " \
136-
"This can be useful when running a pure batch job or in a user framework having its own " \
135+
"G4UI_NONE If this variable is set, no UI sessions nor any UI libraries are built. "
136+
"This can be useful when running a pure batch job or in a user framework having its own "
137137
"UI system. Do you want to set this variable ? [n]": "",
138-
"G4UI_BUILD_XAW_SESSION G4UI_USE_XAW Specifies to include and use the XAW interfaces in " \
139-
"the application to be built. The XAW (X11 Athena Widget set) extensions are required to " \
138+
"G4UI_BUILD_XAW_SESSION G4UI_USE_XAW Specifies to include and use the XAW interfaces in "
139+
"the application to be built. The XAW (X11 Athena Widget set) extensions are required to "
140140
"activate and build this driver. [n]": "",
141-
"G4UI_BUILD_XM_SESSION G4UI_USE_XM Specifies to include and use the XM Motif based user " \
141+
"G4UI_BUILD_XM_SESSION G4UI_USE_XM Specifies to include and use the XM Motif based user "
142142
"interfaces. The XM Motif extensions are required to activate and build this driver. [n]": "",
143-
"G4VIS_NONE If this variable is set, no visualization drivers will be built or used. Do " \
143+
"G4VIS_NONE If this variable is set, no visualization drivers will be built or used. Do "
144144
"you want to set this variable ? [n]": "n",
145-
"G4VIS_BUILD_OPENGLX_DRIVER G4VIS_USE_OPENGLX It is an interface to the de facto standard " \
146-
"3D graphics library, OpenGL. It is well suited for real-time fast visualization and " \
145+
"G4VIS_BUILD_OPENGLX_DRIVER G4VIS_USE_OPENGLX It is an interface to the de facto standard "
146+
"3D graphics library, OpenGL. It is well suited for real-time fast visualization and "
147147
"prototyping. The X11 version of the OpenGL libraries is required. [n]": "",
148-
"G4VIS_BUILD_OPENGLXM_DRIVER G4VIS_USE_OPENGLXM It is an interface to the de facto " \
149-
"standard 3D graphics library, OpenGL. It is well suited for real-time fast visualization " \
150-
"and prototyping. The X11 version of the OpenGL libraries and the Motif Xm extension is " \
148+
"G4VIS_BUILD_OPENGLXM_DRIVER G4VIS_USE_OPENGLXM It is an interface to the de facto "
149+
"standard 3D graphics library, OpenGL. It is well suited for real-time fast visualization "
150+
"and prototyping. The X11 version of the OpenGL libraries and the Motif Xm extension is "
151151
"required. [n]": "",
152-
"G4VIS_BUILD_DAWN_DRIVER G4VIS_USE_DAWN DAWN drivers are interfaces to the Fukui Renderer " \
153-
"DAWN. DAWN is a vectorized 3D PostScript processor suited to prepare technical high " \
152+
"G4VIS_BUILD_DAWN_DRIVER G4VIS_USE_DAWN DAWN drivers are interfaces to the Fukui Renderer "
153+
"DAWN. DAWN is a vectorized 3D PostScript processor suited to prepare technical high "
154154
"quality outputs for presentation and/or documentation. [n]": "",
155-
"G4VIS_BUILD_OIX_DRIVER G4VIS_USE_OIX The OpenInventor driver is based on OpenInventor tech" \
155+
"G4VIS_BUILD_OIX_DRIVER G4VIS_USE_OIX The OpenInventor driver is based on OpenInventor tech"
156156
"nology for scientific visualization. The X11 version of OpenInventor is required. [n]": "",
157-
"G4VIS_BUILD_RAYTRACERX_DRIVER G4VIS_USE_RAYTRACERX Allows for interactive ray-tracing " \
157+
"G4VIS_BUILD_RAYTRACERX_DRIVER G4VIS_USE_RAYTRACERX Allows for interactive ray-tracing "
158158
"graphics through X11. The X11 package is required. [n]": "",
159-
"G4VIS_BUILD_VRML_DRIVER G4VIS_USE_VRML These driver generate VRML files, which describe " \
159+
"G4VIS_BUILD_VRML_DRIVER G4VIS_USE_VRML These driver generate VRML files, which describe "
160160
"3D scenes to be visualized with a proper VRML viewer. [n]": "",
161-
"G4LIB_BUILD_GDML Setting this variable will enable building of the GDML plugin module " \
162-
"embedded in Geant4 for detector description persistency. It requires your system to have " \
161+
"G4LIB_BUILD_GDML Setting this variable will enable building of the GDML plugin module "
162+
"embedded in Geant4 for detector description persistency. It requires your system to have "
163163
"the XercesC library and headers installed. Do you want to set this variable? [n]": "",
164-
"G4LIB_BUILD_G3TOG4 The utility module 'g3tog4' will be built by setting this variable. " \
165-
"NOTE: it requires a valid FORTRAN compiler to be installed on your system and the " \
166-
"'cernlib' command in the path, in order to build the ancillary tools! Do you want to " \
164+
"G4LIB_BUILD_G3TOG4 The utility module 'g3tog4' will be built by setting this variable. "
165+
"NOTE: it requires a valid FORTRAN compiler to be installed on your system and the "
166+
"'cernlib' command in the path, in order to build the ancillary tools! Do you want to "
167167
"build 'g3tog4' ? [n]": "",
168-
"G4LIB_BUILD_ZLIB Do you want to activate compression for output files generated by the " \
168+
"G4LIB_BUILD_ZLIB Do you want to activate compression for output files generated by the "
169169
"HepRep visualization driver? [n]": "y",
170-
"G4ANALYSIS_USE Activates the configuration setup for allowing plugins to analysis tools " \
171-
"based on AIDA (Astract Interfaces for Data Analysis). In order to use AIDA features and " \
172-
"compliant analysis tools, the proper environment for these tools will have to be set " \
170+
"G4ANALYSIS_USE Activates the configuration setup for allowing plugins to analysis tools "
171+
"based on AIDA (Astract Interfaces for Data Analysis). In order to use AIDA features and "
172+
"compliant analysis tools, the proper environment for these tools will have to be set "
173173
"(see documentation for the specific analysis tools). [n]": "",
174174
"Press [Enter] to start installation or use a shell escape to edit config.sh: ": "",
175175
# extra questions and answers for version 9.2.p03
176176
"Directory %s doesn't exist. Use that name anyway? [n]" % dst: "y",
177-
"Specify the path where the Geant4 data libraries PhotonEvaporation%s " \
178-
"RadioactiveDecay%s G4EMLOW%s G4NDL%s G4ABLA%s are " \
179-
"installed. For now, a flat directory structure is assumed, and this can be customized " \
177+
"Specify the path where the Geant4 data libraries PhotonEvaporation%s "
178+
"RadioactiveDecay%s G4EMLOW%s G4NDL%s G4ABLA%s are "
179+
"installed. For now, a flat directory structure is assumed, and this can be customized "
180180
"at the next step if needed. [%s/data]" % (self.cfg['PhotonEvaporationVersion'],
181181
self.cfg['G4RadioactiveDecayVersion'],
182182
self.cfg['G4EMLOWVersion'],
183183
self.cfg['G4NDLVersion'],
184184
self.cfg['G4ABLAVersion'],
185185
pwd
186186
): "%s/data" % dst,
187-
"Please enter 1) Another path to search in 2) 'f' to force the use of the path " \
188-
"you entered previously (the data libraries are not needed to build Geant4, but " \
189-
"are needed to run applications later). 3) 'c' to customize the data paths, e.g. " \
187+
"Please enter 1) Another path to search in 2) 'f' to force the use of the path "
188+
"you entered previously (the data libraries are not needed to build Geant4, but "
189+
"are needed to run applications later). 3) 'c' to customize the data paths, e.g. "
190190
"if you have the data libraries installed in different locations. [f]": "",
191-
"G4UI_BUILD_QT_SESSION G4UI_USE_QT Setting these variables will enable the building " \
192-
"of the G4 Qt based user interface module and the use of this module in your " \
193-
"applications respectively. The Qt3 or Qt4 headers, libraries and moc application are " \
194-
"required to enable the building of this module. Do you want to enable build and use of " \
191+
"G4UI_BUILD_QT_SESSION G4UI_USE_QT Setting these variables will enable the building "
192+
"of the G4 Qt based user interface module and the use of this module in your "
193+
"applications respectively. The Qt3 or Qt4 headers, libraries and moc application are "
194+
"required to enable the building of this module. Do you want to enable build and use of "
195195
"this module? [n]": "",
196196
# extra questions and answers for version 9.4.po1
197197
"What is the path to the Geant4 source tree? [%s]" % pwd: "",
@@ -204,9 +204,9 @@ def configure_step(self):
204204
"Do you want to build libraries with debugging information? [n]": "",
205205
"Specify the path where the Geant4 data libraries are installed: [%s/data]" % pwd: "%s/data" % dst,
206206
"How many parallel jobs should make launch? [1]": "%s" % self.cfg['parallel'],
207-
"Please enter 1) Another path to search in 2) 'f' to force the use of the path you entered " \
208-
"previously (the data libraries are NOT needed to build Geant4, but are needed to run " \
209-
"applications later). 3) 'c' to customize the data paths, e.g. if you have the data " \
207+
"Please enter 1) Another path to search in 2) 'f' to force the use of the path you entered "
208+
"previously (the data libraries are NOT needed to build Geant4, but are needed to run "
209+
"applications later). 3) 'c' to customize the data paths, e.g. if you have the data "
210210
"libraries installed in different locations. [f]": "",
211211
"Enable building of User Interface (UI) modules? [y]": "",
212212
"Enable building of the XAW (X11 Athena Widget set) UI module? [n]": "",

‎easybuild/easyblocks/generic/rpackage.py

+6
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
from easybuild.framework.easyconfig import CUSTOM
4141
from easybuild.framework.extensioneasyblock import ExtensionEasyBlock
4242
from easybuild.tools.build_log import EasyBuildError
43+
from easybuild.tools.environment import setvar
4344
from easybuild.tools.filetools import mkdir, copy_file
4445
from easybuild.tools.run import run_cmd, parse_log_for_error
4546

@@ -268,6 +269,11 @@ def prepare_r_ext_install(self):
268269
:return: Shell command to run + string to pass to stdin.
269270
"""
270271

272+
# set $R_LIBS_USER to non-existing path in build directory,
273+
# to avoid picking up on R packages installed in home directory of current user
274+
# (from ~/R/x86_64-pc-linux-gnu-library/<version>)
275+
setvar('R_LIBS_USER', os.path.join(self.builddir, 'r_libs'))
276+
271277
# determine location
272278
if isinstance(self.master, EB_R):
273279
# extension is being installed as part of an R installation/module

‎easybuild/easyblocks/i/impi.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
@author: Alex Domingo (Vrije Universiteit Brussel)
3535
"""
3636
import os
37+
import tempfile
3738
from easybuild.tools import LooseVersion
3839

3940
import easybuild.tools.toolchain as toolchain
@@ -244,6 +245,16 @@ def sanity_check_step(self):
244245
if build_option('mpi_tests'):
245246
if impi_ver >= LooseVersion('2017'):
246247
# Add minimal test program to sanity checks
248+
if build_option('sanity_check_only'):
249+
# When only running the sanity check we need to manually make sure that
250+
# variables for compilers and parallelism have been set
251+
self.set_parallel()
252+
self.prepare_step(start_dir=False)
253+
254+
impi_testexe = os.path.join(tempfile.mkdtemp(), 'mpi_test')
255+
else:
256+
impi_testexe = os.path.join(self.builddir, 'mpi_test')
257+
247258
if impi_ver >= LooseVersion('2021'):
248259
impi_testsrc = os.path.join(self.installdir, self.get_versioned_subdir('mpi'))
249260
if impi_ver >= LooseVersion('2021.11'):
@@ -252,7 +263,6 @@ def sanity_check_step(self):
252263
else:
253264
impi_testsrc = os.path.join(self.installdir, 'test', 'test.c')
254265

255-
impi_testexe = os.path.join(self.builddir, 'mpi_test')
256266
self.log.info("Adding minimal MPI test program to sanity checks: %s", impi_testsrc)
257267

258268
# Build test program with appropriate compiler from current toolchain

‎easybuild/easyblocks/o/openfoam.py

+12
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,18 @@ def configure_step(self):
238238
regex_subs.append((r"^(CPP\s*(=|:=)\s*)/lib/cpp(.*)$", r"\1cpp\2"))
239239
apply_regex_substitutions(fullpath, regex_subs)
240240

241+
# use relative paths to object files when compiling shared libraries
242+
# in order to keep the build command short and to prevent "Argument list too long" errors
243+
wmake_makefile_general = os.path.join(self.builddir, self.openfoamdir, 'wmake', 'makefiles', 'general')
244+
if os.path.isfile(wmake_makefile_general):
245+
objects_relpath_regex = (
246+
# $(OBJECTS) is a list of absolute paths to all required object files
247+
r'(\$\(LINKLIBSO\) .*) \$\(OBJECTS\)',
248+
# we replace the absolute paths by paths relative to the current working directory
249+
r'\1 $(subst $(WM_PROJECT_DIR),$(shell realpath --relative-to=$(PWD) $(WM_PROJECT_DIR)),$(OBJECTS))',
250+
)
251+
apply_regex_substitutions(wmake_makefile_general, [objects_relpath_regex])
252+
241253
# enable verbose build for debug purposes
242254
# starting with openfoam-extend 3.2, PS1 also needs to be set
243255
env.setvar("FOAM_VERBOSE", '1')

‎easybuild/easyblocks/p/python.py

+44-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
from easybuild.framework.easyconfig import CUSTOM
4646
from easybuild.framework.easyconfig.templates import TEMPLATE_CONSTANTS
4747
from easybuild.tools.build_log import EasyBuildError, print_warning
48-
from easybuild.tools.config import build_option, log_path
48+
from easybuild.tools.config import build_option, ERROR, log_path
4949
from easybuild.tools.modules import get_software_libdir, get_software_root, get_software_version
5050
from easybuild.tools.filetools import apply_regex_substitutions, change_dir, mkdir
5151
from easybuild.tools.filetools import read_file, remove_dir, symlink, write_file
@@ -192,6 +192,33 @@ def patch_step(self, *args, **kwargs):
192192
# Ignore user site dir. -E ignores PYTHONNOUSERSITE, so we have to add -s
193193
apply_regex_substitutions('configure', [(r"(PYTHON_FOR_BUILD=.*-E)'", r"\1 -s'")])
194194

195+
# If we filter out LD_LIBRARY_PATH (not unusual when using rpath), ctypes is not able to dynamically load
196+
# libraries installed with EasyBuild (see https://github.com/EESSI/software-layer/issues/192).
197+
# ctypes is using GCC (and therefore LIBRARY_PATH) to figure out the full location but then only returns the
198+
# soname, instead let's return the full path in this particular scenario
199+
filtered_env_vars = build_option('filter_env_vars') or []
200+
if 'LD_LIBRARY_PATH' in filtered_env_vars and 'LIBRARY_PATH' not in filtered_env_vars:
201+
ctypes_util_py = os.path.join("Lib", "ctypes", "util.py")
202+
orig_gcc_so_name = None
203+
# Let's do this incrementally since we are going back in time
204+
if LooseVersion(self.version) >= "3.9.1":
205+
# From 3.9.1 to at least v3.12.4 there is only one match for this line
206+
orig_gcc_so_name = "_get_soname(_findLib_gcc(name)) or _get_soname(_findLib_ld(name))"
207+
if orig_gcc_so_name:
208+
orig_gcc_so_name_regex = r'(\s*)' + re.escape(orig_gcc_so_name) + r'(\s*)'
209+
# _get_soname() takes the full path as an argument and uses objdump to get the SONAME field from
210+
# the shared object file. The presence or absence of the SONAME field in the ELF header of a shared
211+
# library is influenced by how the library is compiled and linked. For manually built libraries we
212+
# may be lacking this field, this approach also solves that problem.
213+
updated_gcc_so_name = (
214+
"_findLib_gcc(name) or _findLib_ld(name)"
215+
)
216+
apply_regex_substitutions(
217+
ctypes_util_py,
218+
[(orig_gcc_so_name_regex, r'\1' + updated_gcc_so_name + r'\2')],
219+
on_missing_match=ERROR
220+
)
221+
195222
# if we're installing Python with an alternate sysroot,
196223
# we need to patch setup.py which includes hardcoded paths like /usr/include and /lib64;
197224
# this fixes problems like not being able to build the _ssl module ("Could not build the ssl module")
@@ -245,6 +272,22 @@ def patch_step(self, *args, **kwargs):
245272

246273
apply_regex_substitutions(setup_py_fn, regex_subs)
247274

275+
# The path to ldconfig is hardcoded in cpython.util._findSoname_ldconfig(name) as /sbin/ldconfig.
276+
# This is incorrect if a custom sysroot is used
277+
if sysroot is not None:
278+
# Have confirmed for all versions starting with this one that _findSoname_ldconfig hardcodes /sbin/ldconfig
279+
if LooseVersion(self.version) >= "3.9.1":
280+
orig_ld_config_call = "with subprocess.Popen(['/sbin/ldconfig', '-p'],"
281+
if orig_ld_config_call:
282+
ctypes_util_py = os.path.join("Lib", "ctypes", "util.py")
283+
orig_ld_config_call_regex = r'(\s*)' + re.escape(orig_ld_config_call) + r'(\s*)'
284+
updated_ld_config_call = "with subprocess.Popen(['%s/sbin/ldconfig', '-p']," % sysroot
285+
apply_regex_substitutions(
286+
ctypes_util_py,
287+
[(orig_ld_config_call_regex, r'\1' + updated_ld_config_call + r'\2')],
288+
on_missing_match=ERROR
289+
)
290+
248291
def prepare_for_extensions(self):
249292
"""
250293
Set default class and filter for Python packages

‎easybuild/easyblocks/t/tkinter.py

+16-10
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
from easybuild.easyblocks.generic.pythonpackage import det_pylibdir
4040
from easybuild.easyblocks.python import EB_Python
4141
from easybuild.tools.build_log import EasyBuildError
42-
from easybuild.tools.filetools import copy, move_file, remove_dir
42+
from easybuild.tools.filetools import move_file, remove_dir
4343
from easybuild.tools.modules import get_software_root
4444
from easybuild.tools.systemtools import get_shared_lib_ext
4545

@@ -75,27 +75,33 @@ def configure_step(self):
7575
env.setvar('XDG_CACHE_HOME', tempfile.gettempdir())
7676
self.log.info("Using %s as pip cache directory", os.environ['XDG_CACHE_HOME'])
7777

78+
# Use a temporary install directory, as we only want the Tkinter part of the full install.
79+
self.orig_installdir = self.installdir
80+
self.installdir = tempfile.mkdtemp(dir=self.builddir)
7881
super(EB_Tkinter, self).configure_step()
7982

8083
def install_step(self):
8184
"""Install python but only keep the bits we need"""
8285
super(EB_Tkinter, self).install_step()
8386

84-
tmpdir = tempfile.mkdtemp(dir=self.builddir)
85-
86-
self.tkinter_so_basename = self.get_tkinter_so_basename(False)
8787
if LooseVersion(self.version) >= LooseVersion('3'):
88-
tkparts = ["tkinter", os.path.join("lib-dynload", self.tkinter_so_basename)]
88+
tklibdir = "tkinter"
8989
else:
90-
tkparts = ["lib-tk", os.path.join("lib-dynload", self.tkinter_so_basename)]
90+
tklibdir = "lib-tk"
9191

92-
pylibdir = os.path.join(self.installdir, det_pylibdir())
93-
copy([os.path.join(os.path.dirname(pylibdir), x) for x in tkparts], tmpdir)
92+
self.tkinter_so_basename = self.get_tkinter_so_basename(False)
93+
source_pylibdir = os.path.dirname(os.path.join(self.installdir, det_pylibdir()))
9494

95+
# Reset the install directory and remove it if it already exists. It will not have been removed automatically
96+
# at the start of the install step, as self.installdir pointed at the temporary install directory.
97+
self.installdir = self.orig_installdir
9598
remove_dir(self.installdir)
9699

97-
move_file(os.path.join(tmpdir, tkparts[0]), os.path.join(pylibdir, tkparts[0]))
98-
move_file(os.path.join(tmpdir, self.tkinter_so_basename), os.path.join(pylibdir, self.tkinter_so_basename))
100+
dest_pylibdir = os.path.join(self.installdir, det_pylibdir())
101+
102+
move_file(os.path.join(source_pylibdir, tklibdir), os.path.join(dest_pylibdir, tklibdir))
103+
move_file(os.path.join(source_pylibdir, "lib-dynload", self.tkinter_so_basename),
104+
os.path.join(dest_pylibdir, self.tkinter_so_basename))
99105

100106
def get_tkinter_so_basename(self, in_final_dir):
101107
pylibdir = os.path.join(self.installdir, det_pylibdir())

‎easybuild/easyblocks/w/wps.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,9 @@ def build_step(self):
237237
"""Build in install dir using compile script."""
238238
cmd = ' '.join([
239239
self.cfg['prebuildopts'],
240-
'./' + self.compile_script,
240+
# compile script rely on /bin/csh
241+
# Better call csh command to allow tcsh build dependency
242+
'csh ./' + self.compile_script,
241243
self.cfg['buildopts'],
242244
])
243245
run_cmd(cmd, log_all=True, simple=True)
@@ -342,7 +344,7 @@ def run_wps_cmd(cmdname, mpi_cmd=True):
342344
raise EasyBuildError("Could not find Vtable file to use for testing ungrib")
343345

344346
# run link_grib.csh script
345-
cmd = "%s %s*" % (os.path.join(wpsdir, "link_grib.csh"), grib_file_prefix)
347+
cmd = "csh %s %s*" % (os.path.join(wpsdir, "link_grib.csh"), grib_file_prefix)
346348
run_cmd(cmd, log_all=True, simple=True)
347349

348350
# run ungrib.exe

0 commit comments

Comments
 (0)
Please sign in to comment.