blob: fe5c30c8acb1f51b12da4ca61932c0046d9a8800 [file] [log] [blame]
akmhoquefa8ee9b2014-03-14 09:06:24 -05001#! /usr/bin/env python
2# encoding: utf-8
3# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
4
5import os,shlex,shutil,traceback,errno,sys,stat
6from waflib import Utils,Configure,Logs,Options,ConfigSet,Context,Errors,Build,Node
7build_dir_override=None
8no_climb_commands=['configure']
9default_cmd="build"
10def waf_entry_point(current_directory,version,wafdir):
11 Logs.init_log()
12 if Context.WAFVERSION!=version:
13 Logs.error('Waf script %r and library %r do not match (directory %r)'%(version,Context.WAFVERSION,wafdir))
14 sys.exit(1)
15 if'--version'in sys.argv:
16 Context.run_dir=current_directory
17 ctx=Context.create_context('options')
18 ctx.curdir=current_directory
19 ctx.parse_args()
20 sys.exit(0)
21 Context.waf_dir=wafdir
22 Context.launch_dir=current_directory
23 no_climb=os.environ.get('NOCLIMB',None)
24 if not no_climb:
25 for k in no_climb_commands:
26 if k in sys.argv:
27 no_climb=True
28 break
29 cur=current_directory
30 while cur:
31 lst=os.listdir(cur)
32 if Options.lockfile in lst:
33 env=ConfigSet.ConfigSet()
34 try:
35 env.load(os.path.join(cur,Options.lockfile))
36 ino=os.stat(cur)[stat.ST_INO]
37 except Exception:
38 pass
39 else:
40 for x in[env.run_dir,env.top_dir,env.out_dir]:
41 if Utils.is_win32:
42 if cur==x:
43 load=True
44 break
45 else:
46 try:
47 ino2=os.stat(x)[stat.ST_INO]
48 except OSError:
49 pass
50 else:
51 if ino==ino2:
52 load=True
53 break
54 else:
55 Logs.warn('invalid lock file in %s'%cur)
56 load=False
57 if load:
58 Context.run_dir=env.run_dir
59 Context.top_dir=env.top_dir
60 Context.out_dir=env.out_dir
61 break
62 if not Context.run_dir:
63 if Context.WSCRIPT_FILE in lst:
64 Context.run_dir=cur
65 next=os.path.dirname(cur)
66 if next==cur:
67 break
68 cur=next
69 if no_climb:
70 break
71 if not Context.run_dir:
72 if'-h'in sys.argv or'--help'in sys.argv:
73 Logs.warn('No wscript file found: the help message may be incomplete')
74 Context.run_dir=current_directory
75 ctx=Context.create_context('options')
76 ctx.curdir=current_directory
77 ctx.parse_args()
78 sys.exit(0)
79 Logs.error('Waf: Run from a directory containing a file named %r'%Context.WSCRIPT_FILE)
80 sys.exit(1)
81 try:
82 os.chdir(Context.run_dir)
83 except OSError:
84 Logs.error('Waf: The folder %r is unreadable'%Context.run_dir)
85 sys.exit(1)
86 try:
87 set_main_module(Context.run_dir+os.sep+Context.WSCRIPT_FILE)
88 except Errors.WafError ,e:
89 Logs.pprint('RED',e.verbose_msg)
90 Logs.error(str(e))
91 sys.exit(1)
92 except Exception ,e:
93 Logs.error('Waf: The wscript in %r is unreadable'%Context.run_dir,e)
94 traceback.print_exc(file=sys.stdout)
95 sys.exit(2)
96 try:
97 run_commands()
98 except Errors.WafError ,e:
99 if Logs.verbose>1:
100 Logs.pprint('RED',e.verbose_msg)
101 Logs.error(e.msg)
102 sys.exit(1)
103 except SystemExit:
104 raise
105 except Exception ,e:
106 traceback.print_exc(file=sys.stdout)
107 sys.exit(2)
108 except KeyboardInterrupt:
109 Logs.pprint('RED','Interrupted')
110 sys.exit(68)
111def set_main_module(file_path):
112 Context.g_module=Context.load_module(file_path)
113 Context.g_module.root_path=file_path
114 def set_def(obj):
115 name=obj.__name__
116 if not name in Context.g_module.__dict__:
117 setattr(Context.g_module,name,obj)
118 for k in[update,dist,distclean,distcheck,update]:
119 set_def(k)
120 if not'init'in Context.g_module.__dict__:
121 Context.g_module.init=Utils.nada
122 if not'shutdown'in Context.g_module.__dict__:
123 Context.g_module.shutdown=Utils.nada
124 if not'options'in Context.g_module.__dict__:
125 Context.g_module.options=Utils.nada
126def parse_options():
127 Context.create_context('options').execute()
128 if not Options.commands:
129 Options.commands=[default_cmd]
130 Options.commands=[x for x in Options.commands if x!='options']
131 Logs.verbose=Options.options.verbose
132 Logs.init_log()
133 if Options.options.zones:
134 Logs.zones=Options.options.zones.split(',')
135 if not Logs.verbose:
136 Logs.verbose=1
137 elif Logs.verbose>0:
138 Logs.zones=['runner']
139 if Logs.verbose>2:
140 Logs.zones=['*']
141def run_command(cmd_name):
142 ctx=Context.create_context(cmd_name)
143 ctx.log_timer=Utils.Timer()
144 ctx.options=Options.options
145 ctx.cmd=cmd_name
146 ctx.execute()
147 return ctx
148def run_commands():
149 parse_options()
150 run_command('init')
151 while Options.commands:
152 cmd_name=Options.commands.pop(0)
153 ctx=run_command(cmd_name)
154 Logs.info('%r finished successfully (%s)'%(cmd_name,str(ctx.log_timer)))
155 run_command('shutdown')
156def _can_distclean(name):
157 for k in'.o .moc .exe'.split():
158 if name.endswith(k):
159 return True
160 return False
161def distclean_dir(dirname):
162 for(root,dirs,files)in os.walk(dirname):
163 for f in files:
164 if _can_distclean(f):
165 fname=root+os.sep+f
166 try:
167 os.remove(fname)
168 except OSError:
169 Logs.warn('Could not remove %r'%fname)
170 for x in[Context.DBFILE,'config.log']:
171 try:
172 os.remove(x)
173 except OSError:
174 pass
175 try:
176 shutil.rmtree('c4che')
177 except OSError:
178 pass
179def distclean(ctx):
180 '''removes the build directory'''
181 lst=os.listdir('.')
182 for f in lst:
183 if f==Options.lockfile:
184 try:
185 proj=ConfigSet.ConfigSet(f)
186 except IOError:
187 Logs.warn('Could not read %r'%f)
188 continue
189 if proj['out_dir']!=proj['top_dir']:
190 try:
191 shutil.rmtree(proj['out_dir'])
192 except IOError:
193 pass
194 except OSError ,e:
195 if e.errno!=errno.ENOENT:
196 Logs.warn('project %r cannot be removed'%proj[Context.OUT])
197 else:
198 distclean_dir(proj['out_dir'])
199 for k in(proj['out_dir'],proj['top_dir'],proj['run_dir']):
200 try:
201 os.remove(os.path.join(k,Options.lockfile))
202 except OSError ,e:
203 if e.errno!=errno.ENOENT:
204 Logs.warn('file %r cannot be removed'%f)
205 if f.startswith('.waf')and not Options.commands:
206 shutil.rmtree(f,ignore_errors=True)
207class Dist(Context.Context):
208 '''creates an archive containing the project source code'''
209 cmd='dist'
210 fun='dist'
211 algo='tar.bz2'
212 ext_algo={}
213 def execute(self):
214 self.recurse([os.path.dirname(Context.g_module.root_path)])
215 self.archive()
216 def archive(self):
217 import tarfile
218 arch_name=self.get_arch_name()
219 try:
220 self.base_path
221 except AttributeError:
222 self.base_path=self.path
223 node=self.base_path.make_node(arch_name)
224 try:
225 node.delete()
226 except Exception:
227 pass
228 files=self.get_files()
229 if self.algo.startswith('tar.'):
230 tar=tarfile.open(arch_name,'w:'+self.algo.replace('tar.',''))
231 for x in files:
232 self.add_tar_file(x,tar)
233 tar.close()
234 elif self.algo=='zip':
235 import zipfile
236 zip=zipfile.ZipFile(arch_name,'w',compression=zipfile.ZIP_DEFLATED)
237 for x in files:
238 archive_name=self.get_base_name()+'/'+x.path_from(self.base_path)
239 zip.write(x.abspath(),archive_name,zipfile.ZIP_DEFLATED)
240 zip.close()
241 else:
242 self.fatal('Valid algo types are tar.bz2, tar.gz or zip')
243 try:
244 from hashlib import sha1 as sha
245 except ImportError:
246 from sha import sha
247 try:
248 digest=" (sha=%r)"%sha(node.read()).hexdigest()
249 except Exception:
250 digest=''
251 Logs.info('New archive created: %s%s'%(self.arch_name,digest))
252 def get_tar_path(self,node):
253 return node.abspath()
254 def add_tar_file(self,x,tar):
255 p=self.get_tar_path(x)
256 tinfo=tar.gettarinfo(name=p,arcname=self.get_tar_prefix()+'/'+x.path_from(self.base_path))
257 tinfo.uid=0
258 tinfo.gid=0
259 tinfo.uname='root'
260 tinfo.gname='root'
261 fu=None
262 try:
263 fu=open(p,'rb')
264 tar.addfile(tinfo,fileobj=fu)
265 finally:
266 if fu:
267 fu.close()
268 def get_tar_prefix(self):
269 try:
270 return self.tar_prefix
271 except AttributeError:
272 return self.get_base_name()
273 def get_arch_name(self):
274 try:
275 self.arch_name
276 except AttributeError:
277 self.arch_name=self.get_base_name()+'.'+self.ext_algo.get(self.algo,self.algo)
278 return self.arch_name
279 def get_base_name(self):
280 try:
281 self.base_name
282 except AttributeError:
283 appname=getattr(Context.g_module,Context.APPNAME,'noname')
284 version=getattr(Context.g_module,Context.VERSION,'1.0')
285 self.base_name=appname+'-'+version
286 return self.base_name
287 def get_excl(self):
288 try:
289 return self.excl
290 except AttributeError:
291 self.excl=Node.exclude_regs+' **/waf-1.7.* **/.waf-1.7* **/waf3-1.7.* **/.waf3-1.7* **/*~ **/*.rej **/*.orig **/*.pyc **/*.pyo **/*.bak **/*.swp **/.lock-w*'
292 nd=self.root.find_node(Context.out_dir)
293 if nd:
294 self.excl+=' '+nd.path_from(self.base_path)
295 return self.excl
296 def get_files(self):
297 try:
298 files=self.files
299 except AttributeError:
300 files=self.base_path.ant_glob('**/*',excl=self.get_excl())
301 return files
302def dist(ctx):
303 '''makes a tarball for redistributing the sources'''
304 pass
305class DistCheck(Dist):
306 fun='distcheck'
307 cmd='distcheck'
308 def execute(self):
309 self.recurse([os.path.dirname(Context.g_module.root_path)])
310 self.archive()
311 self.check()
312 def check(self):
313 import tempfile,tarfile
314 t=None
315 try:
316 t=tarfile.open(self.get_arch_name())
317 for x in t:
318 t.extract(x)
319 finally:
320 if t:
321 t.close()
322 cfg=[]
323 if Options.options.distcheck_args:
324 cfg=shlex.split(Options.options.distcheck_args)
325 else:
326 cfg=[x for x in sys.argv if x.startswith('-')]
327 instdir=tempfile.mkdtemp('.inst',self.get_base_name())
328 ret=Utils.subprocess.Popen([sys.executable,sys.argv[0],'configure','install','uninstall','--destdir='+instdir]+cfg,cwd=self.get_base_name()).wait()
329 if ret:
330 raise Errors.WafError('distcheck failed with code %i'%ret)
331 if os.path.exists(instdir):
332 raise Errors.WafError('distcheck succeeded, but files were left in %s'%instdir)
333 shutil.rmtree(self.get_base_name())
334def distcheck(ctx):
335 '''checks if the project compiles (tarball from 'dist')'''
336 pass
337def update(ctx):
338 '''updates the plugins from the *waflib/extras* directory'''
339 lst=Options.options.files.split(',')
340 if not lst:
341 lst=[x for x in Utils.listdir(Context.waf_dir+'/waflib/extras')if x.endswith('.py')]
342 for x in lst:
343 tool=x.replace('.py','')
344 try:
345 Configure.download_tool(tool,force=True,ctx=ctx)
346 except Errors.WafError:
347 Logs.error('Could not find the tool %s in the remote repository'%x)
348def autoconfigure(execute_method):
349 def execute(self):
350 if not Configure.autoconfig:
351 return execute_method(self)
352 env=ConfigSet.ConfigSet()
353 do_config=False
354 try:
355 env.load(os.path.join(Context.top_dir,Options.lockfile))
356 except Exception:
357 Logs.warn('Configuring the project')
358 do_config=True
359 else:
360 if env.run_dir!=Context.run_dir:
361 do_config=True
362 else:
363 h=0
364 for f in env['files']:
365 h=hash((h,Utils.readf(f,'rb')))
366 do_config=h!=env.hash
367 if do_config:
368 Options.commands.insert(0,self.cmd)
369 Options.commands.insert(0,'configure')
370 return
371 return execute_method(self)
372 return execute
373Build.BuildContext.execute=autoconfigure(Build.BuildContext.execute)