2022-09-30 00:33:42 +02:00
|
|
|
import os
|
2022-09-30 00:43:29 +02:00
|
|
|
import glob
|
2022-09-30 00:33:42 +02:00
|
|
|
from lib.io import load_lib_data
|
|
|
|
|
|
|
|
def topological_sort(source):
|
|
|
|
pending = [(name, set(deps)) for name, deps in source]
|
|
|
|
emitted = []
|
|
|
|
while pending:
|
|
|
|
next_pending = []
|
|
|
|
next_emitted = []
|
|
|
|
for entry in pending:
|
|
|
|
name, deps = entry
|
|
|
|
deps.difference_update(set((name,)), emitted)
|
|
|
|
if deps:
|
|
|
|
next_pending.append(entry)
|
|
|
|
else:
|
|
|
|
yield name
|
|
|
|
emitted.append(name)
|
|
|
|
next_emitted.append(name)
|
|
|
|
if not next_emitted:
|
|
|
|
raise ValueError("cyclic dependancy detected: %s %r" % (name, (next_pending,)))
|
|
|
|
pending = next_pending
|
|
|
|
emitted = next_emitted
|
|
|
|
return emitted
|
|
|
|
|
|
|
|
|
|
|
|
def sort_libs_by_dependencies(selected_libs):
|
|
|
|
# no need for sorting in case of only one lib
|
|
|
|
if len(selected_libs) < 2:
|
|
|
|
return selected_libs
|
|
|
|
|
|
|
|
lib_names = []
|
|
|
|
for lib in selected_libs:
|
|
|
|
lib_names.append(lib['name'])
|
|
|
|
|
|
|
|
deplist = []
|
|
|
|
for lib in selected_libs:
|
|
|
|
name = lib['name']
|
|
|
|
# only sort after dependencies that are actually present to avoid cyclic dependencies
|
|
|
|
deps = []
|
|
|
|
for dep in lib['dependencies'].split(','):
|
|
|
|
if dep in lib_names:
|
|
|
|
deps.append(dep)
|
|
|
|
dependencies = set(deps)
|
|
|
|
if dependencies == {''}:
|
|
|
|
dependencies = {}
|
|
|
|
deplist.append([name, dependencies])
|
|
|
|
sorted_deplist = topological_sort(deplist)
|
|
|
|
|
|
|
|
sorted = []
|
|
|
|
for entry in sorted_deplist:
|
|
|
|
for lib in selected_libs:
|
|
|
|
if lib['name'] == entry:
|
|
|
|
sorted.append(lib)
|
|
|
|
return sorted
|
|
|
|
|
|
|
|
|
|
|
|
def load_dependencies(library, selected_libs, config_dir):
|
|
|
|
lib_names = []
|
|
|
|
for lib in selected_libs:
|
|
|
|
lib_names.append(lib['name'])
|
2022-09-30 15:56:20 +02:00
|
|
|
|
2022-09-30 00:33:42 +02:00
|
|
|
dependencies = library['dependencies'].split(',')
|
|
|
|
for dep in dependencies:
|
|
|
|
if len(dep) > 1:
|
|
|
|
if dep not in lib_names:
|
|
|
|
config_file = config_dir + "/" + dep + ".json"
|
|
|
|
if os.path.exists(config_file):
|
|
|
|
dep_data = load_lib_data(config_file)
|
|
|
|
dep_data['version'] = dep_data['default version']
|
|
|
|
selected_libs.append(dep_data)
|
|
|
|
else:
|
|
|
|
print("Warning - library " + lib['name'] + " depends on " + dep + " for which no configration file was found. Presence in LD_LIBRARY_PATH is assumed.")
|
|
|
|
|
|
|
|
|
|
|
|
# load library data from names in argparse result
|
|
|
|
def load_selected_libs(config_dir, arg_namespace, args, install_all_libs, ignore_deps):
|
|
|
|
selected_libs = []
|
|
|
|
if install_all_libs:
|
|
|
|
for config_file in glob.glob(config_dir+"/*.json"):
|
|
|
|
data = load_lib_data(config_file)
|
|
|
|
data['version'] = data['default version']
|
|
|
|
selected_libs.append(data)
|
|
|
|
else:
|
|
|
|
ignore_names = ["config", "mpi", "compiler", "prefix", "src", "work", "keep_work", "threads", "verbose", "version", "disable_shared", "ignore_deps"]
|
|
|
|
for lib_name in args:
|
|
|
|
if lib_name not in ignore_names and "version" not in lib_name:
|
|
|
|
install = getattr(arg_namespace, lib_name)
|
|
|
|
if install:
|
|
|
|
version = getattr(arg_namespace, lib_name + "_version")
|
|
|
|
lib_name = lib_name.replace('_','-')
|
|
|
|
config_file = config_dir + "/" + lib_name + ".json"
|
|
|
|
data = load_lib_data(config_file)
|
|
|
|
data['version'] = version
|
|
|
|
selected_libs.append(data)
|
2022-09-30 15:56:20 +02:00
|
|
|
|
2022-09-30 00:33:42 +02:00
|
|
|
if not ignore_deps:
|
|
|
|
# also add all dependencies to the install list
|
|
|
|
for lib in selected_libs:
|
|
|
|
load_dependencies(lib, selected_libs, config_dir)
|
2022-09-30 15:56:20 +02:00
|
|
|
|
2022-09-30 00:33:42 +02:00
|
|
|
return selected_libs
|