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 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
######################################################################
# setup script for the Python wrapper of ODE
######################################################################
from setuptools import setup, Extension
import shutil, os, os.path, sys, glob, subprocess
from stat import *
def system(cmd):
f = os.popen(cmd)
return f.read()
# Include directories
INC_DIRS = []
# Library directories
LIB_DIRS = []
# Libraries to link with
LIBS = []
# Additional compiler arguments
CC_ARGS = []
CC_ARGS.extend(system("ode-config --cflags").split())
# Additional linker arguments
LINK_ARGS = []
LINK_ARGS.extend(system("ode-config --libs").split())
# If your version of ODE was compiled with OPCODE (trimesh support) enabled,
# this should be set to True.
TRIMESH_ENABLE = False
######################################################################
# Windows specific settings
######################################################################
if sys.platform=="win32":
ODE_BASE = r"insert_your_path_here"
INC_DIRS += [os.path.join(ODE_BASE, "include")]
LIB_DIRS += [os.path.join(ODE_BASE, "lib", "releaselib")]
LIBS += ["ode", "user32"] # user32 because of the MessageBox() call
CC_ARGS += ["/ML"]
LINK_ARGS += ["/NODEFAULTLIB:LIBCMT"]
######################################################################
# Linux (and other) specific settings
######################################################################
else:
for base in ["/usr", "/usr/local", "/opt/local", os.path.expanduser("~/ode")]:
INC_DIRS += [os.path.join(base, "include")]
LIB_DIRS += [os.path.join(base, "lib")]
LIBS += ["ode", "stdc++"]
######################################################################
######################################################################
######################################################################
def info(msg):
"""Output an info message.
"""
print("INFO:",msg)
def warning(msg):
"""Output a warning message.
"""
print("WARNING:",msg)
def error(msg, errorcode=1):
"""Output an error message and abort.
"""
print("ERROR:",msg)
sys.exit(errorcode)
# Generate the C source file (if necessary)
def generate(name, trimesh_support):
"""Run Cython to generate the extension module source code.
"""
# Generate the trimesh_switch file
f = open("_trimesh_switch.pyx", "wt")
print('# This file was generated by the setup script and is included in ode.pyx.\n', file=f)
if (trimesh_support):
print('include "trimeshdata.pyx"', file=f)
print('include "trimesh.pyx"', file=f)
else:
print('include "trimesh_dummy.pyx"', file=f)
f.close()
cmd = "cython3 -3 -o %s -I. -Isrc src/ode.pyx" % name
cython_out = name
# Check if the cython output is still up to date or if it has to be generated
# (ode.c will be updated if any of the *.pyx files in the directory "src"
# is newer than ode.c)
if os.access(cython_out, os.F_OK):
ctime = os.stat(cython_out)[ST_MTIME]
for pyx in glob.glob("src/*.pyx"):
pytime = os.stat(pyx)[ST_MTIME]
if pytime>ctime:
info("Updating %s"%cython_out)
print(cmd)
err = os.system(cmd)
break
else:
info("%s is up to date"%cython_out)
err = 0
else:
info("Creating %s"%cython_out)
print(cmd)
err = os.system(cmd)
# Check if calling cython produced an error
if err!=0:
error("An error occured while generating the C source file.", err)
def install_ode(install_dir='${HOME}/ode'):
"""Download and install ODE.
"""
if install_dir:
os.makedirs(install_dir, exist_ok=True)
######################################################################
# Check if ode.h can be found
# (if it is not found it might not be an error because it may be located
# in any of the include paths that are built into the compiler)
num = 0
for path in INC_DIRS:
ode_h = os.path.join(path, "ode", "ode.h")
if os.path.exists(ode_h):
info("<ode/ode.h> found in %s"%path)
num += 1
if num==0:
warning("<ode/ode.h> not found. Downloading and installing it now to your home directory."
"\nIf it's already installed you may have to adjust INC_DIRS in setup.py.")
install_ode()
elif num>1:
warning("ode.h was found more than once. Make sure the header and lib matches.")
# Generate all possible source code versions so that they can be
# packaged with the source archive and a user doesn't require Cython
generate('ode_trimesh.c', True)
generate('ode_notrimesh.c', False)
if (TRIMESH_ENABLE):
info("Installing with trimesh support.")
install = 'ode_trimesh.c'
else:
info("INFO: Installing without trimesh support.")
install = 'ode_notrimesh.c'
# Compile the module
setup(name = "Py3ODE",
version = "1.2.0.dev15",
description = "Port of PyODE for Python 3",
author = "see file AUTHORS",
author_email = "filipeabperes@gmail.com",
license = "BSD or LGPL",
url = "https://github.com/filipeabperes/Py3ODE",
packages = ["xode"],
python_requires='>=3',
install_requires=['cython3'],
ext_modules = [Extension("ode", [install]
,libraries=LIBS
,include_dirs=INC_DIRS
,library_dirs=LIB_DIRS
,extra_compile_args=CC_ARGS
,extra_link_args=LINK_ARGS)
])
|