File: _binwrapper.py

package info (click to toggle)
neuron 8.2.6-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 34,760 kB
  • sloc: cpp: 149,571; python: 58,465; ansic: 50,329; sh: 3,510; xml: 213; pascal: 51; makefile: 35; sed: 5
file content (123 lines) | stat: -rwxr-xr-x 4,554 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/usr/bin/env python
"""
A generic wrapper to access nrn binaries from a python installation
Please create a softlink with the binary name to be called.
"""
import os
import shutil
import subprocess
import sys
from pkg_resources import working_set
from setuptools.command.build_ext import new_compiler
from packaging.version import Version
from sysconfig import get_config_vars, get_config_var


def _customize_compiler(compiler):
    """Do platform-sepcific customizations of compilers on unix platforms."""
    if compiler.compiler_type == "unix":
        (cc, cxx, cflags) = get_config_vars("CC", "CXX", "CFLAGS")
        if "CC" in os.environ:
            cc = os.environ["CC"]
        if "CXX" in os.environ:
            cxx = os.environ["CXX"]
        if "CFLAGS" in os.environ:
            cflags = cflags + " " + os.environ["CFLAGS"]
        cc_cmd = cc + " " + cflags
        # We update executables in compiler to take advantage of distutils arg splitting
        compiler.set_executables(compiler=cc_cmd, compiler_cxx=cxx)


def _set_default_compiler():
    """Set (dont overwrite) CC/CXX so that apps dont use the build-time ones"""
    ccompiler = new_compiler()
    _customize_compiler(ccompiler)
    # xcrun wrapper must bring all args
    if ccompiler.compiler[0] == "xcrun":
        ccompiler.compiler[0] = get_config_var("CC")
        ccompiler.compiler_cxx[0] = get_config_var("CXX")
    os.environ.setdefault("CC", ccompiler.compiler[0])
    os.environ.setdefault("CXX", ccompiler.compiler_cxx[0])


def _check_cpp_compiler_version():
    """Check if GCC compiler is >= 9.0 otherwise show warning"""
    try:
        cpp_compiler = os.environ.get("CXX", "")
        version = subprocess.run(
            [cpp_compiler, "--version"], stdout=subprocess.PIPE
        ).stdout.decode("utf-8")
        if "GCC" in version:
            version = subprocess.run(
                [cpp_compiler, "-dumpversion"], stdout=subprocess.PIPE
            ).stdout.decode("utf-8")
            if Version(version) <= Version("9.0"):
                print(
                    "Warning: GCC >= 9.0 is required with this version of NEURON but found",
                    version,
                )
    except:
        pass


def _config_exe(exe_name):
    """Sets the environment to run the real executable (returned)"""

    package_name = "neuron"

    # determine package to find the install location
    if "neuron-gpu-nightly" in working_set.by_key:
        print("INFO : Using neuron-gpu-nightly Package (Alpha Developer Version)")
        package_name = "neuron-gpu-nightly"
    elif "neuron-gpu" in working_set.by_key:
        print("INFO : Using neuron-gpu Package (Alpha Version)")
        package_name = "neuron-gpu"
    elif "neuron-nightly" in working_set.by_key:
        print("INFO : Using neuron-nightly Package (Developer Version)")
        package_name = "neuron-nightly"
    elif "neuron" in working_set.by_key:
        package_name = "neuron"
    else:
        raise RuntimeError("NEURON package not found! Verify PYTHONPATH")

    NRN_PREFIX = os.path.join(
        working_set.by_key[package_name].location, "neuron", ".data"
    )
    os.environ["NEURONHOME"] = os.path.join(NRN_PREFIX, "share/nrn")
    os.environ["NRNHOME"] = NRN_PREFIX
    os.environ["CORENRNHOME"] = NRN_PREFIX
    os.environ["NRN_PYTHONEXE"] = sys.executable
    os.environ["CORENRN_PYTHONEXE"] = sys.executable
    os.environ["CORENRN_PERLEXE"] = shutil.which("perl")
    os.environ["NRNBIN"] = os.path.dirname(__file__)

    _set_default_compiler()
    return os.path.join(NRN_PREFIX, "bin", exe_name)


def _wrap_executable(output_name):
    """Create a wrapper for an executable in same dir. Requires renaming the original file.
    Executables are typically found under arch_name
    """
    release_dir = os.path.join(os.environ["NEURONHOME"], "demo/release")
    arch_name = next(os.walk(release_dir))[1][0]  # first dir
    file_path = os.path.join(arch_name, output_name)
    shutil.move(file_path, file_path + ".nrn")
    shutil.copy(__file__, file_path)


if __name__ == "__main__":
    exe = _config_exe(os.path.basename(sys.argv[0]))

    if exe.endswith("nrnivmodl"):
        # To create a wrapper for special (so it also gets ENV vars) we intercept nrnivmodl
        subprocess.check_call([exe, *sys.argv[1:]])
        _wrap_executable("special")
        sys.exit(0)

    if exe.endswith("special"):
        exe = os.path.join(
            sys.argv[0] + ".nrn"
        )  # original special is renamed special.nrn

    os.execv(exe, sys.argv)