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

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',
                     81:               'function','flags','exvector']
                     82: 
                     83: #wrap_input += ['indexed','color','clifford','tensor']
                     84: 
                     85: #wrap_input = ['function','inifcns']
                     86: #wrap_input = ['add','mul','power','lst','pseries','relational','matrix','numeric','constant','symbol','varidx']
                     87: #wrap_input = ['symbol','function']
                     88: #wrap_input = ['symbol','tensor']
                     89: #wrap_input = ['symbol','add','mul','lst','numeric','power']
                     90: 
1.3       pearu      91: wrap_input = ['ex','symbol','numeric','lst','add','mul','power',
1.4     ! pearu      92:               'inifcns','function','relational','seq',
        !            93:               'constant','matrix']
1.1       pearu      94: 
                     95: #++++++++++++++++ Parameters ++++++++++++++++
1.3       pearu      96: #nof_lst_params = 10   # max 15 for ginac, max 10 for boost.python, min 1
                     97: #nof_ncmul_params = 6  # max 6
                     98: nof_function_params = 12 # max 12 for ginac (depends also on the code in function_py.cpp)
1.1       pearu      99: #++++++++++++++++++++ boost +++++++++++++++++++++
                    100: 
                    101: boost_dir = '/usr/local/share/boost'
                    102: 
                    103: if not os.path.isdir(boost_dir):
                    104:     print 'boost_dir=%s must be existing directory.'%(`boost_dir`)
                    105:     print 'Get Boost from http://www.boost.org/ and fix its path in setup.py'
                    106:     sys.exit()
                    107: 
                    108: bpl_dir = os.path.join(boost_dir,'libs','python','src')
                    109: bpl_src = map(lambda f:os.path.join(bpl_dir,f),
                    110:               ['classes.cpp','conversions.cpp','extension_class.cpp',
                    111:                'functions.cpp','init_function.cpp','module_builder.cpp',
                    112:                'objects.cpp','types.cpp'])
                    113: 
                    114: #++++++++++++++++++++++++++++++++++++++++++++++++
                    115: from distutils.core import setup, Extension
                    116: 
                    117: #+++HACK: replace linker gcc with g++ +++++++++++
                    118: from distutils import sysconfig
                    119: save_init_posix = sysconfig._init_posix
                    120: def my_init_posix():
                    121:     save_init_posix()
                    122:     g = sysconfig._config_vars
                    123:     if g['LDSHARED'][:3]=='gcc':
                    124:         print 'my_init_posix: changing LDSHARED =',`g['LDSHARED']`,
                    125:         g['LDSHARED'] = 'g++'+g['LDSHARED'][3:]
                    126:         print 'to',`g['LDSHARED']`
                    127:     if disable_opt and g['OPT'][:6]=='-g -O2':
                    128:         print 'my_init_posix: changing OPT =',`g['OPT']`,
                    129:         g['OPT'] = '-g'+g['OPT'][6:]
                    130:         print 'to',`g['OPT']`
                    131: sysconfig._init_posix = my_init_posix
                    132: 
                    133: #+++++++++++++++++ PyGiNaC version ++++++++++++++
                    134: 
1.2       pearu     135: wrapper_dir = 'wrappers3'
                    136: lib_dir = 'lib3'
                    137: 
1.1       pearu     138: major_version = 0
1.2       pearu     139: minor_version = 3
1.1       pearu     140: try: execfile(os.path.join('tools','get_revision.py'))
                    141: except: revision_version = 0
                    142: version='%d.%d.%d'%(major_version,minor_version,revision_version)
                    143: 
                    144: #++++++++++++++++ ginac._ginac +++++++++++++++++++++
                    145: 
                    146: ginac_cpp = os.path.join('src','_ginac.cpp')
1.2       pearu     147: 
1.1       pearu     148: 
                    149: ex_src = [
1.3       pearu     150:     os.path.join(wrapper_dir,'ginac_enhancements.cpp'),
1.1       pearu     151:     os.path.join(wrapper_dir,'ex_py.cpp'),
                    152:     os.path.join(wrapper_dir,'python_repr.cpp'),
                    153:     os.path.join(wrapper_dir,'python_str.cpp'),
1.3       pearu     154:     os.path.join(wrapper_dir,'pyfunc.cpp'),
1.4     ! pearu     155:     os.path.join(wrapper_dir,'slice.c'),
1.1       pearu     156:     ]
                    157: 
                    158: if gentest:
                    159:     import re
                    160:     dt_match = re.compile(r'\s*/[*]DT(?P<text>.*?)[*]/',re.M|re.S)
                    161:     mdt_match = re.compile(r'\s*/[*]M_DT(?P<text>.*?)[*]/',re.M|re.S)
                    162:     fdt_match = re.compile(r'\s*/[*]F_DT(?P<text>.*?)[*]/',re.M|re.S)
1.2       pearu     163:     todo_match = re.compile(r'\s*/[*]\s*TODO(?P<text>.*?)[*]/',re.M|re.S)
                    164:     fon = os.path.join(lib_dir,'doc','__init__.py')
1.1       pearu     165:     fo = open(fon,'w')
1.2       pearu     166:     ftodo = open('TODO_py.txt','w')
1.1       pearu     167:     fo.write('''#!/usr/bin/env python
                    168: import sys,os
                    169: from distutils import util
                    170: sys.path.insert(0,os.path.abspath(os.path.join("build","lib.%s-%s" % (util.get_platform(),sys.version[0:3]))))
                    171: ''')
                    172:     ex_methods = []
                    173:     for s in wrap_input:
                    174:         f = s + '_py.cpp'
                    175:         fn = os.path.join(wrapper_dir,f)
                    176:         if not os.path.isfile(fn): continue
                    177:         m = dt_match.findall(open(fn,'r').read())
                    178:         if m:
                    179:             fo.write('\nclass test_%s:\n    """\n'%s)
                    180:             fo.write(''.join(m))
                    181:             fo.write('\n"""\n')
                    182:         m = mdt_match.findall(open(fn,'r').read())
                    183:         if m:
                    184:             for l in m:
                    185:                 p,d=l.split('\n',1)
                    186:                 ex_methods.append('''\n    def %s:\n        """%s"""\n'''%(p.strip(),d.strip()))
1.2       pearu     187:         m = todo_match.findall(open(fn,'r').read())
                    188:         if m:
                    189:             ftodo.write('In file %s:\n'%fn)
                    190:             ftodo.write('\n'.join(map(lambda s:s.strip(),m))+'\n')
1.1       pearu     191:         m = fdt_match.findall(open(fn,'r').read())
                    192:         if m:
                    193:             for l in m:
                    194:                 p,d=l.split('\n',1)
                    195:                 fo.write('''def %s:\n    """%s"""\n'''%(p.strip(),d.strip()))
                    196:     fo.write('''\
                    197: class ex:
                    198: %s
                    199: def _test():
                    200:     import doctest
                    201:     import __init__ as tt
                    202:     return doctest.testmod(tt)
                    203: if __name__ == "__main__":
                    204:     _test()\n'''%('\n'.join(ex_methods)))
1.2       pearu     205:     fo.close()
                    206:     ftodo.close()
1.1       pearu     207:     if gentest==2:
                    208:         os.system('%s %s -v'%(sys.executable,fon))
                    209:     else:
                    210:         os.system('%s %s'%(sys.executable,fon))
                    211: 
                    212: if len(sys.argv)==1:
                    213:     print "PyGiNaC Version",version
                    214:     sys.exit()
1.3       pearu     215: 
1.1       pearu     216: if rebuild:
1.2       pearu     217:     print 'Creating file',os.path.join(wrapper_dir,'ex_py_subs.cpp')
1.1       pearu     218:     f=open(os.path.join(wrapper_dir,'ex_py_subs.cpp'),'w')
                    219:     for n in wrap_input:
                    220:         ff = n + '_py.cpp'
                    221:         fn = os.path.join(wrapper_dir,ff)
                    222:         if n=='ex': continue
                    223:         if not os.path.isfile(fn):
                    224:             print 'File does not exist:',fn,'    Skipping.'
                    225:             continue
                    226:         f.write('#include "%s"\n'%ff)
                    227:     f.write('#undef PYGINAC_DEFS\n#undef PYGINAC_EX_PROTOS\n#undef PYGINAC_PROTOS\n')
                    228:     f.close()
                    229:     os.system('touch wrappers3/ex_py.cpp')
1.3       pearu     230:     print 'Creating file',os.path.join(wrapper_dir,'function_py_subs.cpp')
                    231:     f=open(os.path.join(wrapper_dir,'function_py_subs.cpp'),'w')
                    232:     protos,impl = [],[]
                    233:     for k in ['eval','evalf']:
                    234:         for i in range(nof_function_params+1):
                    235:             a1 = ['const GiNaC::ex & a'+`j` for j in range(i)]+['const GiNaC::ex & ser']
                    236:             a2 = ['args.set_item(%s,a%s);'%(j,j) for j in range(i)]
                    237:             impl.append('PYGINAC_CB_FUNC(%s,%s,(%s),%s,%s)\n'%(k,i,', '.join(a1),i,' '.join(a2)))
                    238:             protos.append('PYGINAC_CB_FUNC_PROTO(%s,%s,(%s));\n'%(k,i,', '.join(a1)))
                    239:     if 1:
                    240:         k = 'derivative'
                    241:         for i in range(nof_function_params+1):
                    242:             a1 = ['const GiNaC::ex & a'+`j` for j in range(i)]
                    243:             a1 += ['const GiNaC::ex & ser','unsigned n']
                    244:             a2 = ['args.set_item(%s,a%s);'%(j,j) for j in range(i)]
                    245:             a2 += ['args.set_item(%s,n);'%i]
                    246:             impl.append('PYGINAC_CB_FUNC(%s,%s,(%s),%s,%s)\n'%(k,i,', '.join(a1),i+1,' '.join(a2)))
                    247:             protos.append('PYGINAC_CB_FUNC_PROTO(%s,%s,(%s));\n'%(k,i,', '.join(a1)))
                    248:     if 1:
                    249:         k = 'series'
                    250:         for i in range(nof_function_params+1):
                    251:             a1 = ['const GiNaC::ex & a'+`j` for j in range(i)]
                    252:             a1 += ['const GiNaC::ex & ser']
                    253:             a1 += ['const GiNaC::relational & rel']
                    254:             a1 += ['int order']
                    255:             a1 += ['unsigned opt']
                    256:             a2 = ['args.set_item(%s,a%s);'%(j,j) for j in range(i)]
                    257:             a2+= ['args.set_item(%s,rel);'%i]
                    258:             a2+= ['args.set_item(%s,order);'%(i+1)]
                    259:             a2+= ['args.set_item(%s,opt);'%(i+2)]
                    260:             impl.append('PYGINAC_CB_FUNC(%s,%s,(%s),%s,%s)\n'%(k,i,', '.join(a1),i+3,' '.join(a2)))
                    261:             protos.append('PYGINAC_CB_FUNC_PROTO(%s,%s,(%s));\n'%(k,i,', '.join(a1)))
                    262:     f.write('#ifdef PYGINAC_PROTOS\n')
                    263:     f.write('\n'.join(protos))
                    264:     f.write('#else\n')
                    265:     f.write('\n'.join(impl))
                    266:     f.write('#endif\n')
                    267:     f.close() 
                    268:            
1.1       pearu     269: ginac_ext = Extension('ginac._ginac3',
                    270:                       sources=ex_src+bpl_src,
                    271:                       include_dirs=[boost_dir,wrapper_dir],
                    272:                       libraries=['ginac','cln'],
                    273:                       library_dirs=[],
                    274:                       )
                    275: 
                    276: #++++++++++++++++++++ setup +++++++++++++++++++++
                    277: 
                    278: setup (name = "PyGiNaC",
                    279:        version = version,
                    280:        description = "PyGiNaC --- the wrapper of C++ library GiNaC to Python",
                    281:        author = "Pearu Peterson",
                    282:        author_email = "pearu@cens.ioc.ee",
                    283:        maintainer = "Pearu Peterson",
                    284:        maintainer_email = "pearu@cens.ioc.ee",
                    285:        licence = "LGPL",
                    286:        long_description= """
                    287: GiNaC is an open framework for symbolic computation within the C++
                    288: programming language (http://www.ginac.de/).
1.3       pearu     289: PyGiNaC is a Python extension package that implements a complete
                    290: and transparent interface to the GiNaC library.
1.1       pearu     291: """,
                    292:        url = "http://cens.ioc.ee/projects/pyginac/",
                    293:        ext_modules = [ ginac_ext ],
                    294:        packages = ['ginac','ginac.doc'],
1.2       pearu     295:        package_dir = {'ginac': lib_dir,
                    296:                       'ginac.doc':os.path.join(lib_dir,'doc') },
1.1       pearu     297:        )
                    298: 
                    299: print "PyGiNaC Version",version

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