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

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

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