setup.py 9.04 KB
Newer Older
Robert McGibbon's avatar
Robert McGibbon committed
1
__author__ = "Peter Eastman"
2
3
__version__ = "1.0"

4
5
6
7
8
import ast
import re
import os
import sys
import platform
9
10
from distutils.core import setup

11
12
13
MAJOR_VERSION_NUM='@OPENMM_MAJOR_VERSION@'
MINOR_VERSION_NUM='@OPENMM_MINOR_VERSION@'
BUILD_INFO='@OPENMM_BUILD_VERSION@'
14
15
IS_RELEASED = False

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

def reportError(message):
    sys.stdout.write("ERROR: ")
    sys.stdout.write(message)
    sys.stdout.write("\nExiting\n")
    sys.exit(1)

def removeRecursive(dir):
    for file in os.listdir(dir):
        path = os.path.join(dir, file)
        if os.path.isdir(path):
            removeRecursive(path)
        else:
            os.remove(path)
    os.rmdir(dir)

def removePackage(mod, verbose):
        try:
            pathList = mod.__path__
        except AttributeError:
            return
        if len(pathList) > 1:
           raise Exception("more than one item in simtk.__path__")
        simtkInstallPath = pathList[0]
        if os.path.exists(simtkInstallPath):
            if verbose:
                sys.stdout.write('REMOVING "%s"\n' % simtkInstallPath)
            removeRecursive(simtkInstallPath)

def uninstall(verbose=True):
    save_path=sys.path[:]
    sys.path=[]
    for item in save_path:
        if item!='.' and item!=os.getcwd():
            sys.path.append(item)
    try:
52
        import simtk.openmm as openmm
53
54
55
56
57
58
59
60
61
62
63
64
        removePackage(openmm, verbose)
    except ImportError:
        pass

    try:
        import simtk.unit as unit
        removePackage(unit, verbose)
    except ImportError:
        pass
    sys.path=save_path


65
def writeVersionPy(filename="simtk/openmm/version.py", major_version_num=MAJOR_VERSION_NUM,
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
                     minor_version_num=MINOR_VERSION_NUM, build_info=BUILD_INFO):
    """Write a version.py file into the python source directory before installation.
    If a version.py file already exists, we assume that it contains only the git_revision
    information, since from within this python session in the python staging directory, we're
    not in the version controlled directory hierarchy.

    When cmake is copying files into the PYTHON_STAGING_DIRECTORY, it will write the
    git revision to version.py. We read that, and then overwrite it.
    """

    cnt = """
# THIS FILE IS GENERATED FROM OPENMM SETUP.PY
short_version = '%(version)s'
version = '%(version)s'
full_version = '%(full_version)s'
git_revision = '%(git_revision)s'
release = %(isrelease)s
Robert T. McGibbon's avatar
Robert T. McGibbon committed
83
openmm_library_path = r'%(path)s'
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

if not release:
    version = full_version
"""

    if os.path.exists(filename):
        # git_revision is written to the file by cmake
        with open(filename) as f:
            text = f.read()
            match = re.search(r"git_revision\s+=\s+(.*)", text, re.MULTILINE)
        try:
            git_revision = ast.literal_eval(match.group(1))
        except:
            # except anything, including no re match or
            # literal_eval failing
            git_revision = 'Unknown'
    else:
        git_revision = 'Unknown'

    version = full_version = '%s.%s.%s' % (major_version_num, minor_version_num, build_info)
    if not IS_RELEASED:
        full_version += '.dev-' + git_revision[:7]

    a = open(filename, 'w')
    try:
        a.write(cnt % {'version': version,
                       'full_version' : full_version,
                       'git_revision' : git_revision,
112
113
                       'isrelease': str(IS_RELEASED),
                       'path': os.getenv('OPENMM_LIB_PATH')})
114
115
116
117
    finally:
        a.close()


118
119
120
121
122
def buildKeywordDictionary(major_version_num=MAJOR_VERSION_NUM,
                           minor_version_num=MINOR_VERSION_NUM,
                           build_info=BUILD_INFO):
    from distutils.core import Extension
    setupKeywords = {}
Peter Eastman's avatar
Peter Eastman committed
123
124
125
126
127
    try:
        from distutils.command.build_py import build_py_2to3 as build_py
    except ImportError:
        from distutils.command.build_py import build_py
    setupKeywords["cmdclass"]          = {'build_py': build_py}
128
129
130
131
132
133
134
135
136
137
138
139
    setupKeywords["name"]              = "OpenMM"
    setupKeywords["version"]           = "%s.%s.%s" % (major_version_num,
                                                       minor_version_num,
                                                       build_info)
    setupKeywords["author"]            = "Randall J. Radmer"
    setupKeywords["author_email"]      = "radmer@stanford.edu"
    setupKeywords["license"]           = \
    "Python Software Foundation License (BSD-like)"
    setupKeywords["url"]               = "https://simtk.org/home/openmm"
    setupKeywords["download_url"]      = "https://simtk.org/home/openmm"
    setupKeywords["packages"]          = ["simtk",
                                          "simtk.unit",
140
141
                                          "simtk.openmm",
                                          "simtk.openmm.app",
Jason Swails's avatar
Jason Swails committed
142
                                          "simtk.openmm.app.internal",
143
                                          "simtk.openmm.app.internal.charmm",
peastman's avatar
Bug fix  
peastman committed
144
                                          "simtk.openmm.app.internal.pdbx",
145
146
                                          "simtk.openmm.app.internal.pdbx.reader",
                                          "simtk.openmm.app.internal.pdbx.writer"]
147
148
149
    setupKeywords["data_files"]        = []
    setupKeywords["package_data"]      = {"simtk" : [],
                                          "simtk.unit" : [],
150
                                          "simtk.openmm" : [],
Peter Eastman's avatar
Peter Eastman committed
151
                                          "simtk.openmm.app" : ['data/*.xml', 'data/*.pdb'],
152
                                          "simtk.openmm.app.internal" : []}
153
154
155
156
    setupKeywords["platforms"]         = ["Linux", "Mac OS X", "Windows"]
    setupKeywords["description"]       = \
    "Python wrapper for OpenMM (a C++ MD package)"
    setupKeywords["long_description"]  = \
Robert McGibbon's avatar
Robert McGibbon committed
157
158
159
160
161
    """OpenMM is a toolkit for molecular simulation. It can be used either as a
    stand-alone application for running simulations, or as a library you call
    from your own code. It provides a combination of extreme flexibility
    (through custom forces and integrators), openness, and high performance
    (especially on recent GPUs) that make it truly unique among simulation codes.
162
163
164
165
166
167
168
    """

    define_macros = [('MAJOR_VERSION', major_version_num),
                     ('MINOR_VERSION', minor_version_num)]

    libraries=['OpenMM',
               'OpenMMAmoeba',
169
               'OpenMMRPMD',
170
               'OpenMMDrude',
171
172
173
174
175
176
177
178
179
              ]
    if 'OPENMM_USE_DEBUG_LIBS' in os.environ:
        if platform.system() == "Windows":
            raise Exception("use of OpenMM debug libs not supported on Win OS")
        else:
            sys.stdout.write("WARNING: using debug libs:\n")
            for ii in range(len(libraries)):
                libraries[ii]="%s_d" % libraries[ii]
                sys.stdout.write("%s\n" % libraries[ii])
Robert McGibbon's avatar
Robert McGibbon committed
180

181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
    openmm_include_path = os.getenv('OPENMM_INCLUDE_PATH')
    if not openmm_include_path:
        reportError("Set OPENMM_INCLUDE_PATH to point to the include directory for OpenMM")
    openmm_lib_path = os.getenv('OPENMM_LIB_PATH')
    if not openmm_lib_path:
        reportError("Set OPENMM_LIB_PATH to point to the lib directory for OpenMM")

    extra_compile_args=[]
    extra_link_args=[]
    if platform.system() == "Windows":
        define_macros.append( ('WIN32', None) )
        define_macros.append( ('_WINDOWS', None) )
        define_macros.append( (' _MSC_VER', None) )
        extra_compile_args.append('/EHsc')
    else:
        if platform.system() == 'Darwin':
Robert McGibbon's avatar
Robert McGibbon committed
197
198
            extra_compile_args += ['-stdlib=libc++', '-mmacosx-version-min=10.7']
            extra_link_args += ['-stdlib=libc++', '-mmacosx-version-min=10.7', '-Wl', '-rpath', openmm_lib_path]
199
200
201
202

    library_dirs=[openmm_lib_path]
    include_dirs=openmm_include_path.split(';')

peastman's avatar
peastman committed
203
204
205
206
207
208
209
210
211
212
213
    extensionArgs = {"name": "simtk.openmm._openmm",
                    "sources": ["src/swig_doxygen/OpenMMSwig.cxx"],
                    "include_dirs": include_dirs,
                    "define_macros": define_macros,
                    "library_dirs": library_dirs,
                    "libraries": libraries,
                    "extra_compile_args": extra_compile_args,
                    "extra_link_args": extra_link_args}
    if platform.system() != "Windows":
        extensionArgs["runtime_library_dirs"] = library_dirs
    setupKeywords["ext_modules"] = [Extension(**extensionArgs)]
214
215
216
217

    outputString = ''
    firstTab     = 40
    secondTab    = 60
Peter Eastman's avatar
Peter Eastman committed
218
    for key in sorted(iter(setupKeywords)):
219
220
         value         = setupKeywords[key]
         outputString += key.rjust(firstTab) + str( value ).rjust(secondTab) + "\n"
Robert McGibbon's avatar
Robert McGibbon committed
221

Peter Eastman's avatar
Peter Eastman committed
222
    sys.stdout.write("%s" % outputString)
223
224

    return setupKeywords
Robert McGibbon's avatar
Robert McGibbon committed
225

226
227
228
229
230
231
232
233

def main():
    if sys.version_info < (2, 6):
        reportError("OpenMM requires Python 2.6 or better.")
    if platform.system() == 'Darwin':
        macVersion = [int(x) for x in platform.mac_ver()[0].split('.')]
        if tuple(macVersion) < (10, 5):
            reportError("OpenMM requires Mac OS X Leopard (10.5) or better.")
234
235
236
237
    try:
        uninstall()
    except:
        pass
238
    setupKeywords=buildKeywordDictionary()
239
    writeVersionPy()
240
241
242
243
244
245
    setup(**setupKeywords)

if __name__ == '__main__':
    main()