Skip to content

Commit 9c67751

Browse files
author
Benedikt Hegner
committed
first test version of binary install procedures
1 parent 84de4be commit 9c67751

3 files changed

Lines changed: 80 additions & 13 deletions

File tree

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,64 @@
11
__author__ = "Benedikt Hegner (CERN)"
22

3+
import os
34
import platform
5+
import urllib2
46
from architecture import get_full_system_from_platform
7+
from spack.util.executable import which
8+
import spack.cmd
9+
import spack
10+
11+
def prepare():
12+
"""
13+
Install patchelf as pre-requisite to the required relocation of binary packages
14+
"""
15+
patchelf_spec = spack.cmd.parse_specs("patchelf", concretize=True)[0]
16+
patchelf = spack.repo.get(patchelf_spec)
17+
patchelf.do_install()
518

619
def tarball_name(spec):
720
"""
821
Return the name of the tarfile according to the convention
922
<architecture>-<os>-<name>-<dag_hash>.tar.gz
1023
"""
1124
return "%s-%s-%s.tar.gz" %(get_full_system_from_platform(),spec.name,spec.dag_hash())
25+
26+
def download_tarball(package):
27+
"""
28+
Download binary tarball for given package into stage area
29+
"""
30+
try:
31+
download_url = os.environ["DOWNLOAD_URL"]
32+
except KeyError:
33+
print "Please set the DOWNLOAD_URL environment variable for downloading pre-compiled packages!"
34+
raise KeyError()
35+
tarball = tarball_name(package.spec)
36+
remote_tarball = os.path.join(download_url, tarball)
37+
local_tarball = package.stage.path+"/"+tarball
38+
# TODO: handle failures
39+
f = urllib2.urlopen(remote_tarball)
40+
content = f.read()
41+
with open(local_tarball, "wb") as local:
42+
local.write(content)
43+
44+
def extract_tarball(package):
45+
"""
46+
extract binary tarball for given package into install area
47+
"""
48+
tarball = tarball_name(package.spec)
49+
tar = which("tar")
50+
local_tarball = package.stage.path+"/"+tarball
51+
tar("--strip-components=1","-C%s"%package.prefix,"-xf",local_tarball)
52+
53+
def relocate(package):
54+
# get location of previously installed patchelf
55+
patchelf_spec = spack.cmd.parse_specs("patchelf", concretize=True)[0]
56+
patchelf = spack.repo.get(patchelf_spec)
57+
patchelf_executable=os.path.join(patchelf.prefix,"bin","patchelf")
58+
rpath = ":".join(package.rpath)
59+
os.chdir(package.prefix)
60+
for root, dirs, files in os.walk(package.prefix):
61+
for file in files:
62+
if file.endswith("so"):
63+
fullname = os.path.join(root, file)
64+
os.system("%s --set-rpath %s %s"%(patchelf_executable,rpath,fullname) )

lib/spack/spack/cmd/install.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ def setup_parser(subparser):
5555
help="Fake install. Just remove the prefix and touch a fake file in it.")
5656
subparser.add_argument(
5757
'packages', nargs=argparse.REMAINDER, help="specs of packages to install")
58+
subparser.add_argument(
59+
'-p', '--install-policy', action='store', dest="install_policy",
60+
default="build", choices = ["build","download"],
61+
help="Install policy (build,download)")
5862

5963

6064
def install(parser, args):
@@ -78,4 +82,5 @@ def install(parser, args):
7882
ignore_deps=args.ignore_deps,
7983
make_jobs=args.jobs,
8084
verbose=args.verbose,
81-
fake=args.fake)
85+
fake=args.fake,
86+
install_policy=args.install_policy)

lib/spack/spack/package.py

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
import spack.mirror
5959
import spack.hooks
6060
import spack.directives
61+
import spack.binary_distribution
6162
import spack.build_environment
6263
import spack.url
6364
import spack.util.web
@@ -838,20 +839,21 @@ def _resource_stage(self, resource):
838839

839840
def do_install(self,
840841
keep_prefix=False, keep_stage=False, ignore_deps=False,
841-
skip_patch=False, verbose=False, make_jobs=None, fake=False):
842+
skip_patch=False, verbose=False, make_jobs=None, fake=False,install_policy="build"):
842843
"""Called by commands to install a package and its dependencies.
843844
844845
Package implementations should override install() to describe
845846
their build process.
846847
847848
Args:
848-
keep_prefix -- Keep install prefix on failure. By default, destroys it.
849-
keep_stage -- Keep stage on successful build. By default, destroys it.
850-
ignore_deps -- Do not install dependencies before installing this package.
851-
fake -- Don't really build -- install fake stub files instead.
852-
skip_patch -- Skip patch stage of build if True.
853-
verbose -- Display verbose build output (by default, suppresses it)
854-
make_jobs -- Number of make jobs to use for install. Default is ncpus.
849+
keep_prefix -- Keep install prefix on failure. By default, destroys it.
850+
keep_stage -- Keep stage on successful build. By default, destroys it.
851+
ignore_deps -- Do not install dependencies before installing this package.
852+
install_policy -- Whether to download a pre-compiled package or build from scratch
853+
fake -- Don't really build -- install fake stub files instead.
854+
skip_patch -- Skip patch stage of build if True.
855+
verbose -- Display verbose build output (by default, suppresses it)
856+
make_jobs -- Number of make jobs to use for install. Default is ncpus.
855857
"""
856858
if not self.spec.concrete:
857859
raise ValueError("Can only install concrete packages.")
@@ -865,11 +867,15 @@ def do_install(self,
865867
if not ignore_deps:
866868
self.do_install_dependencies(
867869
keep_prefix=keep_prefix, keep_stage=keep_stage, ignore_deps=ignore_deps,
868-
fake=fake, skip_patch=skip_patch, verbose=verbose,
870+
fake=fake, skip_patch=skip_patch, verbose=verbose, install_policy=install_policy,
869871
make_jobs=make_jobs)
870872

871873
start_time = time.time()
872-
if not fake:
874+
print install_policy
875+
if install_policy != "build":
876+
spack.binary_distribution.prepare()
877+
spack.binary_distribution.download_tarball(self)
878+
elif not fake:
873879
if not skip_patch:
874880
self.do_patch()
875881
else:
@@ -900,7 +906,10 @@ def real_work():
900906
spack.hooks.pre_install(self)
901907

902908
# Set up process's build environment before running install.
903-
if fake:
909+
if install_policy != "build":
910+
spack.binary_distribution.extract_tarball(self)
911+
spack.binary_distribution.relocate(self)
912+
elif fake:
904913
self.do_fake_install()
905914
else:
906915
# Do the real install in the source directory.
@@ -916,7 +925,7 @@ def real_work():
916925
self._sanity_check_install()
917926

918927
# Move build log into install directory on success
919-
if not fake:
928+
if install_policy == "build" and not fake:
920929
log_install_path = spack.install_layout.build_log_path(self.spec)
921930
install(log_path, log_install_path)
922931

0 commit comments

Comments
 (0)