3
# WARNING! All changes made to this file will be lost!
5
import os,shutil,traceback,datetime,inspect,errno,sys,stat
6
from waflib import Utils,Configure,Logs,Options,ConfigSet,Context,Errors,Build,Node
7
build_dir_override=None
8
no_climb_commands=['configure']
9
def waf_entry_point(current_directory,version,wafdir):
11
if Context.WAFVERSION!=version:
12
Logs.error('Waf script %r and library %r do not match (directory %r)'%(version,WAFVERSION,wafdir))
14
Context.waf_dir=wafdir
15
Context.launch_dir=current_directory
19
if Options.lockfile in lst:
20
env=ConfigSet.ConfigSet()
22
env.load(os.path.join(cur,Options.lockfile))
23
ino=os.stat(cur)[stat.ST_INO]
27
for x in[env.run_dir,env.top_dir,env.out_dir]:
28
if sys.platform=='win32':
34
ino2=os.stat(x)[stat.ST_INO]
42
Logs.warn('invalid lock file in %s'%cur)
45
Context.run_dir=env.run_dir
46
Context.top_dir=env.top_dir
47
Context.out_dir=env.out_dir
49
if not Context.run_dir:
50
if Context.WSCRIPT_FILE in lst:
52
next=os.path.dirname(cur)
56
for k in no_climb_commands:
62
if not Context.run_dir:
63
if'-h'in sys.argv or'--help'in sys.argv:
64
Logs.warn('No wscript file found: the help message may be incomplete')
65
opt_obj=Options.OptionsContext()
66
opt_obj.curdir=current_directory
69
elif'--version'in sys.argv:
70
opt_obj=Options.OptionsContext()
71
opt_obj.curdir=current_directory
74
Logs.error('Waf: Run from a directory containing a file named %r'%Context.WSCRIPT_FILE)
77
os.chdir(Context.run_dir)
79
Logs.error('Waf: The folder %r is unreadable'%Context.run_dir)
82
set_main_module(Context.run_dir+os.sep+Context.WSCRIPT_FILE)
83
except Errors.WafError ,e:
84
Logs.pprint('RED',e.verbose_msg)
88
Logs.error('Waf: The wscript in %r is unreadable'%Context.run_dir,e)
89
traceback.print_exc(file=sys.stdout)
94
except Errors.WafError ,e:
96
Logs.pprint('RED',e.verbose_msg)
100
traceback.print_exc(file=sys.stdout)
102
except KeyboardInterrupt:
103
Logs.pprint('RED','Interrupted')
105
def set_main_module(file_path):
106
Context.g_module=Context.load_module(file_path)
107
Context.g_module.root_path=file_path
110
if not name in Context.g_module.__dict__:
111
setattr(Context.g_module,name,obj)
112
for k in[update,dist,distclean,distcheck,update]:
114
if not'init'in Context.g_module.__dict__:
115
Context.g_module.init=Utils.nada
116
if not'shutdown'in Context.g_module.__dict__:
117
Context.g_module.shutdown=Utils.nada
118
if not'options'in Context.g_module.__dict__:
119
Context.g_module.options=Utils.nada
121
opt=Options.OptionsContext().execute()
122
if not Options.commands:
123
Options.commands=['build']
124
Logs.verbose=Options.options.verbose
126
if Options.options.zones:
127
Logs.zones=Options.options.zones.split(',')
131
Logs.zones=['runner']
134
def run_command(cmd_name):
135
ctx=Context.create_context(cmd_name)
136
ctx.options=Options.options
142
while Options.commands:
143
cmd_name=Options.commands.pop(0)
145
run_command(cmd_name)
146
if not Options.options.progress_bar:
147
elapsed=' (%s)'%str(timer)
148
Logs.info('%r finished successfully%s'%(cmd_name,elapsed))
149
run_command('shutdown')
150
def _can_distclean(name):
151
for k in'.o .moc .exe'.split():
155
def distclean_dir(dirname):
156
for(root,dirs,files)in os.walk(dirname):
158
if _can_distclean(f):
163
Logs.warn('could not remove %r'%fname)
164
for x in[DBFILE,'config.log']:
170
shutil.rmtree('c4che')
174
'''removes the build directory'''
177
if f==Options.lockfile:
179
proj=ConfigSet.ConfigSet(f)
181
Logs.warn('could not read %r'%f)
183
if proj['out_dir']!=proj['top_dir']:
185
shutil.rmtree(proj['out_dir'])
189
if e.errno!=errno.ENOENT:
190
Logs.warn('project %r cannot be removed'%proj[Context.OUT])
192
distclean_dir(proj['out_dir'])
193
for k in(proj['out_dir'],proj['top_dir'],proj['run_dir']):
195
os.remove(os.path.join(k,Options.lockfile))
197
if e.errno!=errno.ENOENT:
198
Logs.warn('file %r cannot be removed'%f)
199
if f.startswith('.waf-')and not Options.commands:
200
shutil.rmtree(f,ignore_errors=True)
201
class Dist(Context.Context):
207
self.recurse([os.path.dirname(Context.g_module.root_path)])
211
arch_name=self.get_arch_name()
215
self.base_path=self.path
216
node=self.base_path.make_node(arch_name)
221
files=self.get_files()
222
if self.algo.startswith('tar.'):
223
tar=tarfile.open(arch_name,'w:'+self.algo.replace('tar.',''))
225
tinfo=tar.gettarinfo(name=x.abspath(),arcname=self.get_tar_prefix()+'/'+x.path_from(self.base_path))
232
fu=open(x.abspath(),'rb')
233
tar.addfile(tinfo,fileobj=fu)
237
elif self.algo=='zip':
239
zip=zipfile.ZipFile(arch_name,'w',compression=zipfile.ZIP_DEFLATED)
241
archive_name=self.get_base_name()+'/'+x.path_from(self.base_path)
242
zip.write(x.abspath(),archive_name,zipfile.ZIP_DEFLATED)
245
self.fatal('Valid algo types are tar.bz2, tar.gz or zip')
247
from hashlib import sha1 as sha
251
digest=" (sha=%r)"%sha(node.read()).hexdigest()
254
Logs.info('New archive created: %s%s'%(self.arch_name,digest))
255
def get_tar_prefix(self):
257
return self.tar_prefix
259
return self.get_base_name()
260
def get_arch_name(self):
264
self.arch_name=self.get_base_name()+'.'+self.ext_algo.get(self.algo,self.algo)
265
return self.arch_name
266
def get_base_name(self):
270
appname=getattr(Context.g_module,Context.APPNAME,'noname')
271
version=getattr(Context.g_module,Context.VERSION,'1.0')
272
self.base_name=appname+'-'+version
273
return self.base_name
278
self.excl=Node.exclude_regs+' **/waf-1.6.* **/.waf-1.6* **/*~ **/*.rej **/*.orig **/*.pyc **/*.pyo **/*.bak **/*.swp **/.lock-w*'
279
nd=self.root.find_node(Context.out_dir)
281
self.excl+=' '+nd.path_from(self.base_path)
287
files=self.base_path.ant_glob('**/*',excl=self.get_excl())
290
'''makes a tarball for redistributing the sources'''
292
class DistCheck(Dist):
296
self.recurse([os.path.dirname(Context.g_module.root_path)])
300
import tempfile,tarfile
303
t=tarfile.open(self.get_arch_name())
309
instdir=tempfile.mkdtemp('.inst',self.get_base_name())
310
ret=Utils.subprocess.Popen([sys.argv[0],'configure','install','uninstall','--destdir='+instdir],cwd=self.get_base_name()).wait()
312
raise Errors.WafError('distcheck failed with code %i'%ret)
313
if os.path.exists(instdir):
314
raise Errors.WafError('distcheck succeeded, but files were left in %s'%instdir)
315
shutil.rmtree(self.get_base_name())
317
'''checks if the project compiles (tarball from 'dist')'''
320
'''updates the plugins from the *waflib/extras* directory'''
321
lst=Options.options.files.split(',')
323
lst=[x for x in Utils.listdir(Context.waf_dir+'/waflib/extras')if x.endswith('.py')]
325
tool=x.replace('.py','')
327
Configure.download_tool(tool,force=True,ctx=ctx)
328
except Errors.WafError:
329
Logs.warn('Could not find the tool %s in the remote repository'%x)
330
def autoconfigure(execute_method):
332
if not Configure.autoconfig:
333
return execute_method(self)
334
env=ConfigSet.ConfigSet()
337
env.load(os.path.join(Context.top_dir,Options.lockfile))
339
Logs.warn('Configuring the project')
342
if env.run_dir!=Context.run_dir:
346
for f in env['files']:
347
h=hash((h,Utils.readf(f,'rb')))
348
do_config=h!=env.hash
350
Options.commands.insert(0,self.cmd)
351
Options.commands.insert(0,'configure')
353
return execute_method(self)
355
Build.BuildContext.execute=autoconfigure(Build.BuildContext.execute)