Annotation of python/pyGiNaC/setup3.py, revision 1.5

1.1       pearu       1: #!/usr/bin/env python
                      2: #
                      3: #   Setup file for building/installing PyGiNaC
                      4: #
                      5: # Requirements:
                      6: #   Python 2.0 or higher (http://www.python.org/)
1.3       pearu       7: #   GiNaC 0.8.1 or higher (http://www.ginac.de/)
1.1       pearu       8: #     For GiNaC, you'll need CLN 1.1 (http://clisp.cons.org/~haible/packages-cln.html)
                      9: #       Optional, but recommended, CLN can use GMP 3.1.1 (http://www.swox.com/gmp/)
                     10: #   Boost 1.21.1 or higher (http://www.boost.org/)
                     11: #  
                     12: # Usage:
                     13: #   > python setup.py doc install  # this will generate ginac.doc, builds _ginac
                     14: #                                  # and installs the package.
                     15: #   > python setup.py test -v      # this will generate and run test/test_dt.py
                     16: #
                     17: # In Python `import ginac'. Module `ginac' extension classes exposing
                     18: # almost all GiNaC classes to Python.
                     19: # See GiNaC documentation (http://www.ginac.de/tutorial/) for usage.
                     20: #
                     21: # Notes:
                     22: # 1. Compilation of PyGiNaC requires more than 160MB memory (with gcc -O2
                     23: #   on Intel Linux). However, if you don't need all the GiNaC classes
                     24: #   to be exposed to Python, you can edit the list `wrap_input' below
                     25: #   to indicate your needs, this will decrease also the memory consumption
                     26: #   during the compilation. You don't need to worry about class dependencies
                     27: #   they are solved automatically. After you edit `wrap_input', run
                     28: #  > python setup.py reinstall
                     29: #
                     30: # Pearu Peterson <pearu@cens.ioc.ee>
                     31: # 30 March 2001
1.3       pearu      32: # 23 April 2001
1.1       pearu      33: 
                     34: __credits__ = """\
                     35: GiNaC people (www.ginac.de), for the GiNaC library.
                     36: Boost.Python people (www.boost.org), for BPL that considerably
                     37: simplified the wrapping of GiNaC C++ classes to Python.
                     38: """
                     39: 
                     40: import sys,os,string,time
                     41: 
                     42: #++++++++++++++ Require Python 2.x +++++++++++++
                     43: 
                     44: if eval(sys.version[0])<2:
                     45:     print "You'll need Python 2.0 or higher to build PyGiNaC"
                     46:     sys.exit()
                     47: 
                     48: #++++++++++++++ Rebuild ++++++++++++++++++++++++
                     49: rebuild = 0
                     50: gendoc = 0
                     51: gentest = 0
                     52: disable_opt = 1 # set 0 for final compilation
                     53: 
                     54: if 'test' in sys.argv:
                     55:     i = sys.argv.index('test')
                     56:     gentest = 1
                     57:     if len(sys.argv)>i+1 and sys.argv[i+1]=='-v':
                     58:         gentest = 2
                     59:         del sys.argv[i+1]
                     60:     del sys.argv[i]
                     61: if 'doc' in sys.argv:
                     62:     del sys.argv[sys.argv.index('doc')]
                     63:     gendoc = 1
                     64: 
                     65: if 'rebuild' in sys.argv:
                     66:     sys.argv[sys.argv.index('rebuild')] = 'build'
                     67:     rebuild = 1
                     68: if 'reinstall' in sys.argv:
                     69:     sys.argv[sys.argv.index('reinstall')] = 'install'
                     70:     rebuild = 1
                     71: 
                     72: wrap_input = ['symbol','numeric','constant','relational',
                     73:               'lst','idx','varidx','power','add','mul',
                     74:               'ncmul','pseries','matrix','function','inifcns',
                     75:               'function','flags','exvector',
                     76:               'indexed','color','clifford','tensor']
                     77: 
                     78: wrap_input = ['symbol','numeric','constant','relational',
                     79:               'lst','power','add','mul',
                     80:               'ncmul','pseries','matrix','function','inifcns',
1.5     ! pearu      81:               'function',
        !            82:               'flags','exvector']
1.1       pearu      83: 
                     84: #wrap_input += ['indexed','color','clifford','tensor']
                     85: 
                     86: #wrap_input = ['function','inifcns']
                     87: #wrap_input = ['add','mul','power','lst','pseries','relational','matrix','numeric','constant','symbol','varidx']
                     88: #wrap_input = ['symbol','function']
                     89: #wrap_input = ['symbol','tensor']
                     90: #wrap_input = ['symbol','add','mul','lst','numeric','power']
                     91: 
1.3       pearu      92: wrap_input = ['ex','symbol','numeric','lst','add','mul','power',
1.4       pearu      93:               'inifcns','function','relational','seq',
                     94:               'constant','matrix']
1.1       pearu      95: 
                     96: #++++++++++++++++ Parameters ++++++++++++++++
1.3       pearu      97: #nof_lst_params = 10   # max 15 for ginac, max 10 for boost.python, min 1
                     98: #nof_ncmul_params = 6  # max 6
                     99: nof_function_params = 12 # max 12 for ginac (depends also on the code in function_py.cpp)
1.1       pearu     100: #++++++++++++++++++++ boost +++++++++++++++++++++
                    101: 
                    102: boost_dir = '/usr/local/share/boost'
                    103: 
                    104: if not os.path.isdir(boost_dir):
                    105:     print 'boost_dir=%s must be existing directory.'%(`boost_dir`)
                    106:     print 'Get Boost from http://www.boost.org/ and fix its path in setup.py'
                    107:     sys.exit()
                    108: 
                    109: bpl_dir = os.path.join(boost_dir,'libs','python','src')
                    110: bpl_src = map(lambda f:os.path.join(bpl_dir,f),
                    111:               ['classes.cpp','conversions.cpp','extension_class.cpp',
                    112:                'functions.cpp','init_function.cpp','module_builder.cpp',
                    113:                'objects.cpp','types.cpp'])
                    114: 
                    115: #++++++++++++++++++++++++++++++++++++++++++++++++
                    116: from distutils.core import setup, Extension
                    117: 
                    118: #+++HACK: replace linker gcc with g++ +++++++++++
                    119: from distutils import sysconfig
                    120: save_init_posix = sysconfig._init_posix
                    121: def my_init_posix():
                    122:     save_init_posix()
                    123:     g = sysconfig._config_vars
                    124:     if g['LDSHARED'][:3]=='gcc':
                    125:         print 'my_init_posix: changing LDSHARED =',`g['LDSHARED']`,
                    126:         g['LDSHARED'] = 'g++'+g['LDSHARED'][3:]
                    127:         print 'to',`g['LDSHARED']`
                    128:     if disable_opt and g['OPT'][:6]=='-g -O2':
                    129:         print 'my_init_posix: changing OPT =',`g['OPT']`,
                    130:         g['OPT'] = '-g'+g['OPT'][6:]
                    131:         print 'to',`g['OPT']`
                    132: sysconfig._init_posix = my_init_posix
                    133: 
                    134: #+++++++++++++++++ PyGiNaC version ++++++++++++++
                    135: 
1.2       pearu     136: wrapper_dir = 'wrappers3'
                    137: lib_dir = 'lib3'
                    138: 
1.1       pearu     139: major_version = 0
1.2       pearu     140: minor_version = 3
1.1       pearu     141: try: execfile(os.path.join('tools','get_revision.py'))
                    142: except: revision_version = 0
                    143: version='%d.%d.%d'%(major_version,minor_version,revision_version)
                    144: 
                    145: #++++++++++++++++ ginac._ginac +++++++++++++++++++++
                    146: 
                    147: ginac_cpp = os.path.join('src','_ginac.cpp')
1.2       pearu     148: 
1.1       pearu     149: 
                    150: ex_src = [
1.3       pearu     151:     os.path.join(wrapper_dir,'ginac_enhancements.cpp'),
1.1       pearu     152:     os.path.join(wrapper_dir,'ex_py.cpp'),
                    153:     os.path.join(wrapper_dir,'python_repr.cpp'),
                    154:     os.path.join(wrapper_dir,'python_str.cpp'),
1.3       pearu     155:     os.path.join(wrapper_dir,'pyfunc.cpp'),
1.4       pearu     156:     os.path.join(wrapper_dir,'slice.c'),
1.1       pearu     157:     ]
                    158: 
                    159: if gentest:
                    160:     import re
                    161:     dt_match = re.compile(r'\s*/[*]DT(?P<text>.*?)[*]/',re.M|re.S)
                    162:     mdt_match = re.compile(r'\s*/[*]M_DT(?P<text>.*?)[*]/',re.M|re.S)
                    163:     fdt_match = re.compile(r'\s*/[*]F_DT(?P<text>.*?)[*]/',re.M|re.S)
1.2       pearu     164:     todo_match = re.compile(r'\s*/[*]\s*TODO(?P<text>.*?)[*]/',re.M|re.S)
                    165:     fon = os.path.join(lib_dir,'doc','__init__.py')
1.1       pearu     166:     fo = open(fon,'w')
1.2       pearu     167:     ftodo = open('TODO_py.txt','w')
1.1       pearu     168:     fo.write('''#!/usr/bin/env python
                    169: import sys,os
                    170: from distutils import util
                    171: sys.path.insert(0,os.path.abspath(os.path.join("build","lib.%s-%s" % (util.get_platform(),sys.version[0:3]))))
                    172: ''')
                    173:     ex_methods = []
1.5     ! pearu     174:     i = 0
1.1       pearu     175:     for s in wrap_input:
1.5     ! pearu     176:         i += 1
1.1       pearu     177:         f = s + '_py.cpp'
                    178:         fn = os.path.join(wrapper_dir,f)
                    179:         if not os.path.isfile(fn): continue
                    180:         m = dt_match.findall(open(fn,'r').read())
                    181:         if m:
1.5     ! pearu     182:             fo.write('\nclass test_%.2i_%s:\n    """\n'%(i,s))
1.1       pearu     183:             fo.write(''.join(m))
                    184:             fo.write('\n"""\n')
                    185:         m = mdt_match.findall(open(fn,'r').read())
                    186:         if m:
                    187:             for l in m:
                    188:                 p,d=l.split('\n',1)
                    189:                 ex_methods.append('''\n    def %s:\n        """%s"""\n'''%(p.strip(),d.strip()))
1.2       pearu     190:         m = todo_match.findall(open(fn,'r').read())
                    191:         if m:
1.5     ! pearu     192:             ftodo.write('In %s:\n'%fn)
        !           193:             ftodo.write('\n'.join(map(lambda s:'\t'+s.strip(),m))+'\n')
1.1       pearu     194:         m = fdt_match.findall(open(fn,'r').read())
                    195:         if m:
                    196:             for l in m:
                    197:                 p,d=l.split('\n',1)
                    198:                 fo.write('''def %s:\n    """%s"""\n'''%(p.strip(),d.strip()))
                    199:     fo.write('''\
                    200: class ex:
                    201: %s
                    202: def _test():
                    203:     import doctest
                    204:     import __init__ as tt
                    205:     return doctest.testmod(tt)
                    206: if __name__ == "__main__":
                    207:     _test()\n'''%('\n'.join(ex_methods)))
1.2       pearu     208:     fo.close()
                    209:     ftodo.close()
1.1       pearu     210:     if gentest==2:
                    211:         os.system('%s %s -v'%(sys.executable,fon))
                    212:     else:
                    213:         os.system('%s %s'%(sys.executable,fon))
                    214: 
                    215: if len(sys.argv)==1:
                    216:     print "PyGiNaC Version",version
                    217:     sys.exit()
1.3       pearu     218: 
1.1       pearu     219: if rebuild:
1.2       pearu     220:     print 'Creating file',os.path.join(wrapper_dir,'ex_py_subs.cpp')
1.1       pearu     221:     f=open(os.path.join(wrapper_dir,'ex_py_subs.cpp'),'w')
                    222:     for n in wrap_input:
                    223:         ff = n + '_py.cpp'
                    224:         fn = os.path.join(wrapper_dir,ff)
                    225:         if n=='ex': continue
                    226:         if not os.path.isfile(fn):
                    227:             print 'File does not exist:',fn,'    Skipping.'
                    228:             continue
                    229:         f.write('#include "%s"\n'%ff)
                    230:     f.write('#undef PYGINAC_DEFS\n#undef PYGINAC_EX_PROTOS\n#undef PYGINAC_PROTOS\n')
                    231:     f.close()
                    232:     os.system('touch wrappers3/ex_py.cpp')
1.3       pearu     233:     print 'Creating file',os.path.join(wrapper_dir,'function_py_subs.cpp')
                    234:     f=open(os.path.join(wrapper_dir,'function_py_subs.cpp'),'w')
                    235:     protos,impl = [],[]
                    236:     for k in ['eval','evalf']:
                    237:         for i in range(nof_function_params+1):
                    238:             a1 = ['const GiNaC::ex & a'+`j` for j in range(i)]+['const GiNaC::ex & ser']
                    239:             a2 = ['args.set_item(%s,a%s);'%(j,j) for j in range(i)]
                    240:             impl.append('PYGINAC_CB_FUNC(%s,%s,(%s),%s,%s)\n'%(k,i,', '.join(a1),i,' '.join(a2)))
                    241:             protos.append('PYGINAC_CB_FUNC_PROTO(%s,%s,(%s));\n'%(k,i,', '.join(a1)))
                    242:     if 1:
                    243:         k = 'derivative'
                    244:         for i in range(nof_function_params+1):
                    245:             a1 = ['const GiNaC::ex & a'+`j` for j in range(i)]
                    246:             a1 += ['const GiNaC::ex & ser','unsigned n']
                    247:             a2 = ['args.set_item(%s,a%s);'%(j,j) for j in range(i)]
                    248:             a2 += ['args.set_item(%s,n);'%i]
                    249:             impl.append('PYGINAC_CB_FUNC(%s,%s,(%s),%s,%s)\n'%(k,i,', '.join(a1),i+1,' '.join(a2)))
                    250:             protos.append('PYGINAC_CB_FUNC_PROTO(%s,%s,(%s));\n'%(k,i,', '.join(a1)))
                    251:     if 1:
                    252:         k = 'series'
                    253:         for i in range(nof_function_params+1):
                    254:             a1 = ['const GiNaC::ex & a'+`j` for j in range(i)]
                    255:             a1 += ['const GiNaC::ex & ser']
                    256:             a1 += ['const GiNaC::relational & rel']
                    257:             a1 += ['int order']
                    258:             a1 += ['unsigned opt']
                    259:             a2 = ['args.set_item(%s,a%s);'%(j,j) for j in range(i)]
                    260:             a2+= ['args.set_item(%s,rel);'%i]
                    261:             a2+= ['args.set_item(%s,order);'%(i+1)]
                    262:             a2+= ['args.set_item(%s,opt);'%(i+2)]
                    263:             impl.append('PYGINAC_CB_FUNC(%s,%s,(%s),%s,%s)\n'%(k,i,', '.join(a1),i+3,' '.join(a2)))
                    264:             protos.append('PYGINAC_CB_FUNC_PROTO(%s,%s,(%s));\n'%(k,i,', '.join(a1)))
                    265:     f.write('#ifdef PYGINAC_PROTOS\n')
                    266:     f.write('\n'.join(protos))
                    267:     f.write('#else\n')
                    268:     f.write('\n'.join(impl))
                    269:     f.write('#endif\n')
                    270:     f.close() 
                    271:            
1.1       pearu     272: ginac_ext = Extension('ginac._ginac3',
                    273:                       sources=ex_src+bpl_src,
                    274:                       include_dirs=[boost_dir,wrapper_dir],
                    275:                       libraries=['ginac','cln'],
                    276:                       library_dirs=[],
                    277:                       )
                    278: 
                    279: #++++++++++++++++++++ setup +++++++++++++++++++++
                    280: 
                    281: setup (name = "PyGiNaC",
                    282:        version = version,
                    283:        description = "PyGiNaC --- the wrapper of C++ library GiNaC to Python",
                    284:        author = "Pearu Peterson",
                    285:        author_email = "pearu@cens.ioc.ee",
                    286:        maintainer = "Pearu Peterson",
                    287:        maintainer_email = "pearu@cens.ioc.ee",
                    288:        licence = "LGPL",
                    289:        long_description= """
                    290: GiNaC is an open framework for symbolic computation within the C++
                    291: programming language (http://www.ginac.de/).
1.3       pearu     292: PyGiNaC is a Python extension package that implements a complete
                    293: and transparent interface to the GiNaC library.
1.1       pearu     294: """,
                    295:        url = "http://cens.ioc.ee/projects/pyginac/",
                    296:        ext_modules = [ ginac_ext ],
                    297:        packages = ['ginac','ginac.doc'],
1.2       pearu     298:        package_dir = {'ginac': lib_dir,
                    299:                       'ginac.doc':os.path.join(lib_dir,'doc') },
1.1       pearu     300:        )
                    301: 
                    302: print "PyGiNaC Version",version

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>