Factor out forking logic to build_environment.py.
This commit is contained in:
parent
614c22fc1b
commit
e6b2c27011
@ -28,6 +28,7 @@
|
|||||||
calls you can make from within the install() function.
|
calls you can make from within the install() function.
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import shutil
|
import shutil
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
import platform
|
import platform
|
||||||
@ -212,3 +213,58 @@ def setup_package(pkg):
|
|||||||
for dep_spec in pkg.spec.traverse(root=False):
|
for dep_spec in pkg.spec.traverse(root=False):
|
||||||
dep_spec.package.setup_dependent_environment(
|
dep_spec.package.setup_dependent_environment(
|
||||||
pkg.module, dep_spec, pkg.spec)
|
pkg.module, dep_spec, pkg.spec)
|
||||||
|
|
||||||
|
|
||||||
|
def fork(pkg, function):
|
||||||
|
"""Fork a child process to do part of a spack build.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
pkg -- pkg whose environemnt we should set up the
|
||||||
|
forked process for.
|
||||||
|
function -- arg-less function to run in the child process.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
def child_fun():
|
||||||
|
# do stuff
|
||||||
|
build_env.fork(pkg, child_fun)
|
||||||
|
|
||||||
|
Forked processes are run with the build environemnt set up by
|
||||||
|
spack.build_environment. This allows package authors to have
|
||||||
|
full control over the environment, etc. without offecting
|
||||||
|
other builds that might be executed in the same spack call.
|
||||||
|
|
||||||
|
If something goes wrong, the child process is expected toprint
|
||||||
|
the error and the parent process will exit with error as
|
||||||
|
well. If things go well, the child exits and the parent
|
||||||
|
carries on.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
pid = os.fork()
|
||||||
|
except OSError, e:
|
||||||
|
raise InstallError("Unable to fork build process: %s" % e)
|
||||||
|
|
||||||
|
if pid == 0:
|
||||||
|
# Give the child process the package's build environemnt.
|
||||||
|
setup_package(pkg)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# call the forked function.
|
||||||
|
function()
|
||||||
|
|
||||||
|
# Use os._exit here to avoid raising a SystemExit exception,
|
||||||
|
# which interferes with unit tests.
|
||||||
|
os._exit(0)
|
||||||
|
except:
|
||||||
|
# Child doesn't raise or return to main spack code.
|
||||||
|
# Just runs default exception handler and exits.
|
||||||
|
sys.excepthook(*sys.exc_info())
|
||||||
|
os._exit(1)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Parent process just waits for the child to complete. If the
|
||||||
|
# child exited badly, assume it already printed an appropriate
|
||||||
|
# message. Just make the parent exit with an error code.
|
||||||
|
pid, returncode = os.waitpid(pid, 0)
|
||||||
|
if returncode != 0:
|
||||||
|
sys.exit(1)
|
||||||
|
@ -804,32 +804,21 @@ def do_install(self, **kwargs):
|
|||||||
if not fake_install:
|
if not fake_install:
|
||||||
self.do_patch()
|
self.do_patch()
|
||||||
|
|
||||||
# Fork a child process to do the build. This allows each
|
# create the install directory. The install layout
|
||||||
# package authors to have full control over their environment,
|
# handles this in case so that it can use whatever
|
||||||
# etc. without offecting other builds that might be executed
|
# package naming scheme it likes.
|
||||||
# in the same spack call.
|
spack.install_layout.make_path_for_spec(self.spec)
|
||||||
try:
|
|
||||||
pid = os.fork()
|
|
||||||
except OSError, e:
|
|
||||||
raise InstallError("Unable to fork build process: %s" % e)
|
|
||||||
|
|
||||||
if pid == 0:
|
def real_work():
|
||||||
try:
|
try:
|
||||||
tty.msg("Building %s." % self.name)
|
tty.msg("Building %s." % self.name)
|
||||||
|
|
||||||
# create the install directory. The install layout
|
|
||||||
# handles this in case so that it can use whatever
|
|
||||||
# package naming scheme it likes.
|
|
||||||
spack.install_layout.make_path_for_spec(self.spec)
|
|
||||||
|
|
||||||
# Run the pre-install hook in the child process after
|
# Run the pre-install hook in the child process after
|
||||||
# the directory is created.
|
# the directory is created.
|
||||||
spack.hooks.pre_install(self)
|
spack.hooks.pre_install(self)
|
||||||
|
|
||||||
# Set up process's build environment before running install.
|
# Set up process's build environment before running install.
|
||||||
self.stage.chdir_to_source()
|
self.stage.chdir_to_source()
|
||||||
build_env.setup_package(self)
|
|
||||||
|
|
||||||
if fake_install:
|
if fake_install:
|
||||||
self.do_fake_install()
|
self.do_fake_install()
|
||||||
else:
|
else:
|
||||||
@ -852,10 +841,6 @@ def do_install(self, **kwargs):
|
|||||||
% (_hms(self._fetch_time), _hms(build_time), _hms(self._total_time)))
|
% (_hms(self._fetch_time), _hms(build_time), _hms(self._total_time)))
|
||||||
print_pkg(self.prefix)
|
print_pkg(self.prefix)
|
||||||
|
|
||||||
# Use os._exit here to avoid raising a SystemExit exception,
|
|
||||||
# which interferes with unit tests.
|
|
||||||
os._exit(0)
|
|
||||||
|
|
||||||
except:
|
except:
|
||||||
if not keep_prefix:
|
if not keep_prefix:
|
||||||
# If anything goes wrong, remove the install prefix
|
# If anything goes wrong, remove the install prefix
|
||||||
@ -865,24 +850,14 @@ def do_install(self, **kwargs):
|
|||||||
"Spack will think this package is installed." +
|
"Spack will think this package is installed." +
|
||||||
"Manually remove this directory to fix:",
|
"Manually remove this directory to fix:",
|
||||||
self.prefix)
|
self.prefix)
|
||||||
|
raise
|
||||||
|
|
||||||
# Child doesn't raise or return to main spack code.
|
build_env.fork(self, real_work)
|
||||||
# Just runs default exception handler and exits.
|
|
||||||
sys.excepthook(*sys.exc_info())
|
|
||||||
os._exit(1)
|
|
||||||
|
|
||||||
# Parent process just waits for the child to complete. If the
|
|
||||||
# child exited badly, assume it already printed an appropriate
|
|
||||||
# message. Just make the parent exit with an error code.
|
|
||||||
pid, returncode = os.waitpid(pid, 0)
|
|
||||||
if returncode != 0:
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Once everything else is done, run post install hooks
|
# Once everything else is done, run post install hooks
|
||||||
spack.hooks.post_install(self)
|
spack.hooks.post_install(self)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _sanity_check_install(self):
|
def _sanity_check_install(self):
|
||||||
installed = set(os.listdir(self.prefix))
|
installed = set(os.listdir(self.prefix))
|
||||||
installed.difference_update(spack.install_layout.hidden_file_paths)
|
installed.difference_update(spack.install_layout.hidden_file_paths)
|
||||||
|
Loading…
Reference in New Issue
Block a user