10
0
mirror of https://github.com/LCPQ/quantum_package synced 2024-07-03 09:55:59 +02:00
quantum_package/setup_environment.py

418 lines
11 KiB
Python
Raw Normal View History

2015-06-08 12:35:40 +02:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import subprocess
import os
import sys
import pprint
from os.path import join
# __ _
# /__ | _ |_ _. | o ._ _|_ _
# \_| |_ (_) |_) (_| | | | | | (_)
#
2015-06-08 14:49:10 +02:00
QP_ROOT = os.getcwd()
QP_ROOT_BIN = join(QP_ROOT, "bin")
QP_ROOT_INSTALL = join(QP_ROOT, "install")
2015-06-08 12:35:40 +02:00
2015-06-09 11:02:45 +02:00
d_dependency = {
2015-06-08 12:35:40 +02:00
"ocaml": ["m4", "curl", "zlib", "patch", "gcc"],
2015-06-08 21:43:41 +02:00
"m4": ["make"],
"curl": ["make"],
"zlib": ["gcc", "make"],
"patch": ["make"],
2015-06-08 12:35:40 +02:00
"ezfio": ["irpf90"],
"irpf90": ["python"],
"docopt": ["python"],
"resultsFile": ["python"],
"emsl": ["python"],
"gcc": [],
"python": [],
2015-06-08 21:43:41 +02:00
"ninja": ["gcc", "python"],
"make": []
2015-06-08 12:35:40 +02:00
}
from collections import namedtuple
Info = namedtuple("Info", ["url", "description", "default_path"])
path_github = {"head": "http://github.com/", "tail": "archive/master.tar.gz"}
ocaml = Info(
url='http://raw.github.com/ocaml/opam/master/shell/opam_installer.sh',
2015-06-08 15:59:26 +02:00
description=' ocaml (it will take some time roughly 20min)',
2015-06-08 14:49:10 +02:00
default_path=join(QP_ROOT_BIN, "opam"))
2015-06-08 12:35:40 +02:00
m4 = Info(
url="http://ftp.gnu.org/gnu/m4/m4-latest.tar.gz",
description=" m4",
2015-06-08 14:49:10 +02:00
default_path=join(QP_ROOT_BIN, "m4"))
2015-06-08 12:35:40 +02:00
curl = Info(
url="http://qmcchem.ups-tlse.fr/files/scemama/curl-7.30.0.ermine.tar.bz2",
description=" curl",
2015-06-08 14:49:10 +02:00
default_path=join(QP_ROOT_BIN, "curl"))
2015-06-08 12:35:40 +02:00
zlib = Info(
url='http://zlib.net/zlib-1.2.8.tar.gz',
description=' zlib',
2015-06-08 14:49:10 +02:00
default_path=join(QP_ROOT_INSTALL, "zlib"))
2015-06-08 12:35:40 +02:00
path = Info(
url='ftp://ftp.gnu.org/gnu/patch/patch-2.7.5.tar.gz',
description=' path',
2015-06-09 15:05:06 +02:00
default_path=join(QP_ROOT, "lib", "libz.a"))
2015-06-08 12:35:40 +02:00
irpf90 = Info(
2015-06-08 20:46:36 +02:00
url='{head}/scemama/irpf90/archive/v1.6.6.tar.gz'.format(**path_github),
2015-06-08 12:35:40 +02:00
description=' irpf90',
2015-06-08 14:49:10 +02:00
default_path=join(QP_ROOT_BIN, "irpf90"))
2015-06-08 12:35:40 +02:00
docopt = Info(
url='{head}/docopt/docopt/{tail}'.format(**path_github),
description=' docop',
2015-06-08 14:49:10 +02:00
default_path=join(QP_ROOT_INSTALL, "docopt"))
2015-06-08 12:35:40 +02:00
resultsFile = Info(
url='{head}/LCPQ/resultsFile/{tail}'.format(**path_github),
description=' resultsFile',
2015-06-08 14:49:10 +02:00
default_path=join(QP_ROOT_INSTALL, "resultsFile"))
2015-06-08 12:35:40 +02:00
ninja = Info(
url='{head}/martine/ninja/{tail}'.format(**path_github),
description=' nina',
2015-06-08 14:49:10 +02:00
default_path=join(QP_ROOT_BIN, "ninja"))
2015-06-08 12:35:40 +02:00
emsl = Info(
url='{head}/LCPQ/EMSL_Basis_Set_Exchange_Local/{tail}'.format(**
path_github),
description=' emsl',
2015-06-08 14:49:10 +02:00
default_path=join(QP_ROOT_INSTALL, "emsl"))
2015-06-08 12:35:40 +02:00
ezfio = Info(
url='{head}/LCPQ/EZFIO/{tail}'.format(**path_github),
description=' EZFIO',
2015-06-08 14:49:10 +02:00
default_path=join(QP_ROOT_INSTALL, "EZFIO"))
2015-06-08 12:35:40 +02:00
d_info = dict()
for m in ["ocaml", "m4", "curl", "zlib", "path", "irpf90", "docopt",
"resultsFile", "ninja", "emsl", "ezfio"]:
exec ("d_info['{0}']={0}".format(m))
l_need = []
2015-06-08 14:49:10 +02:00
# _
# |_ ._ _ _|_ o _ ._
# | |_| | | (_ |_ | (_) | |
#
2015-06-08 12:35:40 +02:00
def check_output(*popenargs, **kwargs):
2015-06-08 15:06:49 +02:00
"""Run command with arguments and return its output as a byte string.
2015-06-08 12:35:40 +02:00
Backported from Python 2.7 as it's implemented as pure python on stdlib.
>>> check_output(['/usr/bin/python', '--version'])
Python 2.6.2
"""
process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
output, unused_err = process.communicate()
retcode = process.poll()
if retcode:
cmd = kwargs.get("args")
if cmd is None:
cmd = popenargs[0]
error = subprocess.CalledProcessError(retcode, cmd)
error.output = output
raise error
return output
def check_python():
req_version = (2, 6)
cur_version = sys.version_info
# Check python
if cur_version >= req_version:
l_installed["python"] = ""
else:
print "To old version (need >2.5). Abort"
sys.exit(1)
2015-06-09 11:02:45 +02:00
def check_availabiliy(binary):
2015-06-08 12:35:40 +02:00
if binary == "python":
check_python()
try:
2015-06-08 20:46:36 +02:00
return check_output(["which", binary])
2015-06-08 12:35:40 +02:00
except subprocess.CalledProcessError:
default_path = d_info[binary].default_path
if os.path.exists(default_path):
return default_path
else:
return 0
def splitext(path):
for ext in ['.tar.gz', '.tar.bz2']:
if path.endswith(ext):
return path[:-len(ext)], path[-len(ext):]
return os.path.splitext(path)
2015-06-10 13:29:11 +02:00
def find_path(bin_):
"""Use the global variable
* l_installed
* d_info
"""
try:
locate = l_installed[bin_]
except KeyError:
locate = d_info[bin_].default_path
return locate
def create_rule_ninja():
l_rules = [
"rule download", " command = wget ${url} -O ${out} -o /dev/null",
" description = Downloading ${descr}", "", "rule install",
" command = ./scripts/install_${target}.sh > _build/${target}.log 2>&1",
" description = Installing ${descr}", ""
]
return l_rules
def finalize():
path = join(QP_ROOT, "quantum_package.rc")
print "For more info on compiling the code, read the COMPILE_RUN.md file."
print ""
print "You can check {0} and run:".format(path)
print ""
print " source {0}".format(path)
print " qp_create_ninja.py --production $QP_ROOT/config/ifort.cfg"
print " ninja"
print " make -C ocaml"
print ""
sys.exit()
def get_list_need_child(l_need):
"""
Descendant a node reachable by repeated proceeding from parent to child.
"""
d_need_genealogy = dict()
for need in l_need:
d_need_genealogy[need] = None
for childen in d_dependency[need]:
if childen not in l_installed:
d_need_genealogy[childen] = None
return d_need_genealogy.keys()
return d_need_genealogy.keys()
2015-06-08 12:35:40 +02:00
print """
_
/ |_ _ _ | o ._ _
\_ | | (/_ (_ |< | | | (_|
_|
"""
2015-06-10 13:29:11 +02:00
l_installed = dict()
2015-06-08 12:35:40 +02:00
# Check all the other
2015-06-10 13:29:11 +02:00
length = max(map(len, d_dependency))
2015-06-09 11:02:45 +02:00
for i in d_dependency.keys():
2015-06-10 13:29:11 +02:00
print "Checking if {0:^{1}} is avalaible...".format(i, length),
2015-06-08 12:35:40 +02:00
2015-06-09 11:02:45 +02:00
r = check_availabiliy(i)
2015-06-08 12:35:40 +02:00
if r:
2015-06-09 11:02:45 +02:00
print "[ OK ]"
2015-06-08 12:35:40 +02:00
l_installed[i] = r.strip()
else:
2015-06-10 13:29:11 +02:00
print "[ will compile it ]"
2015-06-08 12:35:40 +02:00
l_need.append(i)
print """
__
(_ ._ _ ._ _ _. ._
__) |_| | | | | | | (_| | \/
/
"""
print "You have already installed :"
2015-06-10 13:29:11 +02:00
len_bin, len_path = [max(map(len, line))
for line in zip(*l_installed.iteritems())]
for bin, path in l_installed.iteritems():
print "{0:<{2}} : {1:<{3}}".format(bin, path, len_bin, len_path)
# Expend the need_stuff for all the genealogy
l_install_descendant = get_list_need_child(l_need)
2015-06-08 12:35:40 +02:00
print """
___
| ._ _ _|_ _. | | _. _|_ o _ ._
_|_ | | _> |_ (_| | | (_| |_ | (_) | |
"""
2015-06-10 13:29:11 +02:00
if l_install_descendant:
2015-06-09 11:02:45 +02:00
print "You need to install:"
2015-06-10 13:29:11 +02:00
pprint.pprint(l_install_descendant)
2015-06-08 12:35:40 +02:00
else:
2015-06-09 11:02:45 +02:00
print "Nothing to do."
finalize()
2015-06-08 12:35:40 +02:00
2015-06-10 13:29:11 +02:00
need_to_install_ninja = "ninja" in l_install_descendant
l_install_with_ninja = []
l_install_without_ninja = []
for need in l_install_descendant:
if need == "ocaml":
l_install_with_ninja.append(need)
else:
l_install_without_ninja.append(need)
if need_to_install_ninja:
2015-06-08 12:35:40 +02:00
print """
# ~#~#~#~#~#~#~#~#~#~#~#~#~ #
# I n s t a l l _ n i n j a #
# ~#~#~#~#~#~#~#~#~#~#~#~#~ #
"""
2015-06-10 13:29:11 +02:00
2015-06-08 12:35:40 +02:00
url = d_info["ninja"].url
extension = splitext(url)[1]
path_archive = "Downloads/{0}{1}".format("ninja", extension)
2015-06-08 15:38:37 +02:00
l_cmd = ["cd install &&",
"wget {0} -O {1} -o /dev/null &&".format(url, path_archive),
2015-06-08 15:59:26 +02:00
"./scripts/install_ninja.sh 2> /dev/null &&", "cd -"]
2015-06-08 12:35:40 +02:00
2015-06-08 15:09:36 +02:00
check_output(" ".join(l_cmd), shell=True)
2015-06-08 15:16:28 +02:00
print "Done"
2015-06-10 13:29:11 +02:00
l_install_with_ninja.remove("ninja")
2015-06-08 12:35:40 +02:00
2015-06-10 13:29:11 +02:00
if l_install_with_ninja:
print """
# ~#~#~#~#~#~#~#~#~#~#~#~#~#~ #
# C r e a t i n g _ n i n j a #
# ~#~#~#~#~#~#~#~#~#~#~#~#~#~ #
"""
2015-06-08 12:35:40 +02:00
2015-06-10 13:29:11 +02:00
l_string = create_rule_ninja()
2015-06-08 12:35:40 +02:00
2015-06-10 13:29:11 +02:00
l_build = []
2015-06-08 12:35:40 +02:00
2015-06-10 13:29:11 +02:00
for need in l_install_with_ninja:
2015-06-08 17:23:59 +02:00
2015-06-10 13:29:11 +02:00
url = d_info[need].url
extension = splitext(url)[1]
2015-06-08 12:35:40 +02:00
2015-06-10 13:29:11 +02:00
archive_path = "Downloads/{0}{1}".format(need, extension)
2015-06-08 12:35:40 +02:00
2015-06-10 13:29:11 +02:00
descr = d_info[need].description
2015-06-08 12:35:40 +02:00
2015-06-10 13:29:11 +02:00
# Build to dowload
l_build += ["build {0}: download".format(archive_path),
" url = {0}".format(url), " descr = {0}".format(descr),
""]
2015-06-08 12:35:40 +02:00
2015-06-10 13:29:11 +02:00
# Build to install
l_dependancy = [d_info[i].default_path for i in d_dependency[need]
if i in l_install_descendant]
2015-06-08 12:35:40 +02:00
2015-06-10 13:29:11 +02:00
l_build += ["build {0}: install {1} {2}".format(
d_info[need].default_path, archive_path, " ".join(l_dependancy)),
" target = {0}".format(need),
" descr = {0}".format(descr), ""]
2015-06-08 12:35:40 +02:00
2015-06-10 13:29:11 +02:00
l_string += l_build
2015-06-08 12:35:40 +02:00
2015-06-10 13:29:11 +02:00
path = join(QP_ROOT_INSTALL, "build.ninja")
with open(path, "w+") as f:
f.write("\n".join(l_string))
2015-06-08 12:35:40 +02:00
2015-06-10 13:29:11 +02:00
print "Done"
print "You can check {0}".format(path)
2015-06-08 12:35:40 +02:00
2015-06-10 13:29:11 +02:00
print """
# ~#~#~#~#~#~#~#~#~ #
# R u n _ n i n j a #
# ~#~#~#~#~#~#~#~#~ #
"""
2015-06-08 12:35:40 +02:00
2015-06-10 13:29:11 +02:00
if [i for i in l_install_descendant if i not in "ocaml"]:
subprocess.check_call("{0} -C install".format(find_path("ninja")),
shell=True)
2015-06-08 17:42:29 +02:00
2015-06-10 13:29:11 +02:00
print "Done"
2015-06-08 17:23:59 +02:00
2015-06-10 13:29:11 +02:00
if "ocaml" in l_install_without_ninja:
2015-06-08 17:23:59 +02:00
print """
# ~#~#~#~#~#~#~#~#~#~#~#~#~ #
# I n s t a l l _ o c a m l #
# ~#~#~#~#~#~#~#~#~#~#~#~#~ #
"""
2015-06-10 13:29:11 +02:00
2015-06-08 17:23:59 +02:00
url = d_info["ocaml"].url
extension = splitext(url)[1]
path_archive = "Downloads/{0}{1}".format("ocaml", extension)
l_cmd = ["cd install &&",
"wget {0} -O {1} -o /dev/null &&".format(url, path_archive),
2015-06-09 11:02:45 +02:00
"./scripts/install_ocaml.sh"]
2015-06-08 17:23:59 +02:00
os.system(" ".join(l_cmd))
print "Done"
2015-06-10 13:29:11 +02:00
l_install_descendant.remove("ocaml")
2015-06-08 12:35:40 +02:00
print """
# ~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~ #
# C r e a t e q u a n t u m _ p a c k a g e . r c
# ~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~ #
"""
2015-06-08 14:49:10 +02:00
python_path = [join(QP_ROOT, "scripts"), join(QP_ROOT, "install")]
2015-06-08 12:35:40 +02:00
2015-06-08 14:49:10 +02:00
l_python = [join(QP_ROOT, "scripts")]
2015-06-08 12:35:40 +02:00
for dir_ in python_path:
for folder in os.listdir(dir_):
path = join(dir_, folder)
if os.path.isdir(path):
l_python.append(path)
l_rc = [
2015-06-10 13:29:11 +02:00
'export QP_ROOT={0}'.format(QP_ROOT), 'export QP_EZFIO={0}'.format(
find_path('ezfio')), 'export IRPF90={0}'.format(find_path("irpf90")),
2015-06-08 12:35:40 +02:00
'export NINJA={0}'.format(find_path("ninja")),
2015-06-10 13:29:11 +02:00
'export QP_PYTHON={0}'.format(":".join(l_python)), "",
2015-06-08 14:49:10 +02:00
'export PYTHONPATH="${PYTHONPATH}":"${QP_PYTHON}"',
2015-06-08 21:43:41 +02:00
'export PATH="${PATH}":"${QP_PYTHON}":"${QP_ROOT}"/bin:"${QP_ROOT}"/ocaml',
2015-06-08 14:49:10 +02:00
'export LD_LIBRARY_PATH="${QP_ROOT}"/lib:"${LD_LIBRARY_PATH}"',
'export LIBRARY_PATH="${QP_ROOT}"/lib:"${LIBRARY_PATH}"', ""
2015-06-08 19:00:14 +02:00
'source ${HOME}/.opam/opam-init/init.sh > /dev/null 2> /dev/null || true',
2015-06-08 12:35:40 +02:00
""
]
2015-06-08 14:49:10 +02:00
path = join(QP_ROOT, "quantum_package.rc")
2015-06-08 12:35:40 +02:00
with open(path, "w+") as f:
f.write("\n".join(l_rc))
2015-06-09 11:02:45 +02:00
print "Done."
finalize()