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

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

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