Posted by MHordecki on Wed 16 Jan 13:38
report abuse | download | new post
- #!/usr/bin/python
- # $Id: build.py 21 2008-01-16 13:08:31Z mhordecki $
- # $Author: mhordecki $
- # $LastChangedDate: 2008-01-16 13:08:31 +0000 (Wed, 16 Jan 2008) $
- # $LastChangedRevision: 21 $
- # $LastChangedBy: mhordecki $
- #
- #######################################
- #
- # Build.py v. 0.3beta
- #
- # Copyright (c) 2008 Michal Hordecki
- # Licensed under GNU GPLv3
- #
- #######################################
- from optparse import OptionParser
- import sys
- import os
- import shutil
- import pickle
- import hashlib
- def _pkgconfig_check():
- global PKGCONFIG_LIBS
- if len(PKGCONFIG_LIBS)==0: return true
- def _pkgconfig_cflags():
- if len(PKGCONFIG_LIBS)==0: return ''
- pkgc='`pkg-config --cflags '
- for i in PKGCONFIG_LIBS:
- pkgc+=i+' '
- pkgc+='` '
- return pkgc
- def _pkgconfig_libs():
- if len(PKGCONFIG_LIBS)==0: return ''
- pkgc='`pkg-config --libs '
- for i in PKGCONFIG_LIBS:
- pkgc+=i+' '
- pkgc+='` '
- return pkgc
- #### BUILDFILE MACROS
- X=0
- ACT_TARGET=''
- EXT={}
- FILES={}
- DATA=[]
- LINKER=''
- PKGCONFIG_LIBS=[]
- PREFIX='/usr'
- _SHAREDIR=''
- STEP=''
- FLAGS={}
- INCLUDE={}
- LIBS=[]
- #private
- LOG=[]
- LOCLOG={}
- def _save_progress():
- global LOCLOG
- f=open('.buildpy.tmp','w+')
- pickle.dump(LOCLOG,f)
- f.close()
- def _load_progress():
- global LOCLOG
- if not os.path.exists('.buildpy.tmp'):
- LOCLOG={}
- return
- f=open('.buildpy.tmp')
- LOCLOG=pickle.load(f)
- f.close()
- def _file_calc_hash(p):
- f=open(p)
- return hashlib.md5(f.read()).hexdigest()
- def _fmt_libs():
- global LIBS
- ret=''
- for l in LIBS:
- ret+='-l'+l+' '
- return ret
- def _fmt_include(c):
- global INCLUDE
- ret=''
- if not c in INCLUDE: return ''
- for l in INCLUDE[c]:
- ret+='-I'+l+' '
- return ret
- def target(t):
- TARGET='target_'+t
- eval(TARGET)()
- def clean(t):
- CLEAN='clean_'+t
- target(t)
- eval(CLEAN)()
- def build(t):
- BUILD='build_'+t
- target(t)
- eval(BUILD)()
- def install(t):
- INSTALL='install_'+t
- target(t)
- eval(INSTALL)()
- def remove(t):
- REMOVE='remove_'+t
- target(t)
- eval(REMOVE)()
- def assign_c(c):
- EXT['c']=c
- FILES[c]=[]
- def assign_cxx(c):
- EXT['cpp']=c
- EXT['cxx']=c
- FILES[c]=[]
- def add_dir_recursively(c,d):
- if not os.path.exists(d):
- warning('Given path '+d+' does not exist.')
- if c=='source':
- for root, dirs, files in os.walk(d):
- for file in files:
- if root.find('/.')!=-1: continue #checking against hidden folders
- ext=os.path.splitext(file)[1][1:]
- if not EXT.has_key(ext):
- print 'Found ',root+os.sep+file,'- ommitting'
- else:
- print 'Found ',root+os.sep+file
- FILES[EXT[ext]].append(root+os.sep+file)
- elif c=='data':
- for root, dirs, files in os.walk(d):
- for file in files:
- if root.find('/.')!=-1: continue #checking against hidden folders
- print 'Found data file',root+os.sep+file
- DATA.append(root+os.sep+file)
- else:
- warning('Unrecongized add_dir_recursively category.')
- def process_build():
- global OBJ,LOCLOG,FLAGS,LIBS
- OBJ=[]
- libstr=_fmt_libs()
- print "Building.."
- _load_progress()
- if not os.path.exists('obj'):
- os.mkdir('obj')
- if not os.path.exists('bin'):
- os.mkdir('bin')
- for c in FILES:
- print 'Using',c
- incstr=_fmt_include(c)
- for f in FILES[c]:
- objpath=os.path.splitext(f)[0]+'.o '
- if f in LOCLOG:
- if LOCLOG[f]==_file_calc_hash(f):
- OBJ.append(objpath)
- continue
- cmd=c+' '+incstr
- if c in FLAGS:
- cmd+=FLAGS[c]+' '
- cmd+=' -c '
- cmd+=f+' '
- cmd+='-o'
- cmd+=objpath
- cmd+=_pkgconfig_cflags()
- print cmd
- if os.system(cmd)!=0:
- _save_progress()
- error('Build error, stopping.')
- OBJ.append(objpath)
- LOCLOG[f]=_file_calc_hash(f)
- # linking
- print 'Linking'
- cmd=LINKER+' '+libstr
- cmd+='-obin/'+ACT_TARGET+' '
- for c in OBJ:
- cmd+=c+' '
- cmd+=_pkgconfig_libs()
- print cmd
- if os.system(cmd)!=0:
- error('Linking error, stopping.')
- _save_progress()
- print "Finished building",ACT_TARGET
- def start_install():
- global SHAREDIR,_SHAREDIR,LOG
- _SHAREDIR=SHAREDIR
- print 'Installing',ACT_TARGET
- SHAREDIR=os.path.join(SHAREDIR,ACT_TARGET)
- LOG=[]
- def end_install():
- global SHAREDIR,_SHAREDIR,LOG
- LOG.append(SHAREDIR)
- print 'Creating log file'
- f=open(os.path.join(SHAREDIR,'.buildpy.log'),'w+')
- pickle.dump(LOG,f)
- f.close()
- SHAREDIR=_SHAREDIR
- print 'Finshed',ACT_TARGET
- def copy(s,dest):
- global DATA,SHAREDIR,LOG
- if s=='data':
- for d in DATA:
- destdir=os.path.join(dest,os.path.split(d)[0])
- if not os.path.exists(destdir):
- os.makedirs(destdir)
- cmd='install '+d+' '+destdir+os.sep
- print cmd
- LOG.append(os.path.join(destdir,os.path.basename(d)))
- os.system(cmd)
- else:
- warning('Bad copy() target.')
- def copy_bin(dest,symlink=''):
- global LOG,ACT_TARGET
- cmd='install bin'+os.sep+ACT_TARGET+' '+dest+os.sep
- LOG.append(os.path.join(dest,ACT_TARGET))
- print cmd
- os.system(cmd)
- if symlink!='':
- cmd='ln -s '+dest+os.sep+ACT_TARGET+' '+symlink+os.sep+ACT_TARGET
- LOG.append(os.path.join(symlink,ACT_TARGET))
- print cmd
- os.system(cmd)
- def _recursive_del(d):
- if not os.path.exists(d): return
- for root, dirs, files in os.walk(d, topdown=False):
- for name in files:
- os.remove(os.path.join(root, name))
- for name in dirs:
- os.rmdir(os.path.join(root, name))
- os.rmdir(d)
- def process_clean():
- _recursive_del('bin')
- if os.path.exists('.buildpy.tmp'):
- os.remove('.buildpy.tmp')
- for c in FILES:
- for f in FILES[c]:
- objpath=os.path.splitext(f)[0]+'.o'
- if os.path.exists(objpath):
- print objpath
- os.remove(objpath)
- print 'Finished cleaning'
- def process_remove(dir):
- global ACT_TARGET
- dir=os.path.join(dir,ACT_TARGET,'.buildpy.log')
- print 'Removing',ACT_TARGET
- f=open(dir)
- log=pickle.load(f)
- f.close()
- for f in log:
- if os.path.isdir(f):
- _recursive_del(f)
- else:
- os.remove(f)
- print 'Finished removing',ACT_TARGET
- #### BUILD.PY CODE
- def die(text):
- print text
- exit()
- def error(text):
- print 'ERROR :',text
- exit()
- def warning(text):
- print 'WARNING :',text
- opts=OptionParser(version='%prog 0.1', usage="%prog [TARGET] [OPTIONS]", description='Simple build tool written in Python. Useful in small projects where overbloated features of make, jam & co are unnecessary. build.py uses external configuration files called buildfiles, similar to Makefiles and Jamfiles. See docs for more info.')
- opts.set_defaults(file='Buildfile')
- opts.add_option('-f','--file',dest='file',help='set buildfile path. Default : \'buildfile\'')
- """opts.add_option('-G','--Get',action='store_const',const='G',dest='mode',help='Get mangas from server')
- opts.add_option('-Q','--Query',action='store_const',const='Q',dest='mode',help='Query info about mangas from server')
- opts.add_option('-m','--manga',dest='manga',help='Select manga which has NAME as a keyword (See also -Q option)',metavar='NAME')
- opts.add_option('-c','--chapter',dest='chapter',help='Query/get manga from chapter specified by NUM',metavar="NUM")
- opts.add_option('-r','--range',dest='range',help='Query/get range of chapters specified by RANGE (format: START-END)',metavar="RANGE")
- opts.add_option('-a','--all',action="store_true",dest='all',help='Query/get all chapters of manga')
- """
- TARGETS=[]
- opt=opts.parse_args(sys.argv[1:])
- opt=opt[0]
- for a in sys.argv[1:]:
- if a[0]=='-': break
- TARGETS.append(a)
- if len(TARGETS)==0:
- TARGETS=['build']
- if not os.path.exists(opt.file):
- error('Buildfile '+opt.file+' does not exist.')
- execfile(opt.file)
- for t in TARGETS:
- target(t)
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.