def do_install(self,src,tgt,chmod=0644): if Options.commands['install']: if not Options.options.force: try: t1=os.stat(tgt).st_mtime t2=os.stat(src).st_mtime except OSError: pass else: if t1>=t2: return False srclbl=src.replace(self.srcnode.abspath(None)+os.sep,'') info("* installing %s as %s"%(srclbl,tgt)) try:os.remove(tgt) except OSError:pass try: shutil.copy2(src,tgt) os.chmod(tgt,chmod) except IOError: try: os.stat(src) except IOError: error('File %r does not exist'%src) raise Utils.WafError('Could not install the file %r'%tgt) return True elif Options.commands['uninstall']: info("* uninstalling %s"%tgt) self.uninstall.append(tgt) try:os.remove(tgt) except OSError:pass return True
def addlines(self, node): self.currentnode_stack.append(node.parent) filepath = node.abspath(self.env) self.count_files += 1 if self.count_files > recursion_limit: raise PreprocError("recursion limit exceeded") pc = self.parse_cache debug('preproc: reading file %r', filepath) try: lns = pc[filepath] except KeyError: pass else: self.lines.extend(lns) return try: lines = filter_comments(filepath) lines.append((POPFILE, '')) lines.reverse() pc[filepath] = lines # cache the lines filtered self.lines.extend(lines) except IOError: raise PreprocError("could not read the file %s" % filepath) except Exception: if Logs.verbose > 0: error("parsing %s failed" % filepath) traceback.print_exc()
def load_envs(self): try: lst=Utils.listdir(self.cachedir) except OSError as e: if e.errno==errno.ENOENT: raise Utils.WafError('The project was not configured: run "waf configure" first!') else: raise if not lst: raise Utils.WafError('The cache directory is empty: reconfigure the project') for file in lst: if file.endswith(CACHE_SUFFIX): env=Environment.Environment(os.path.join(self.cachedir,file)) name=file[:-len(CACHE_SUFFIX)] self.all_envs[name]=env self.init_variants() for env in self.all_envs.values(): for f in env[CFG_FILES]: newnode=self.path.find_or_declare(f) try: hash=Utils.h_file(newnode.abspath(env)) except(IOError,AttributeError): error("cannot find "+f) hash=SIG_NIL self.node_sigs[env.variant()][newnode.id]=hash self.bldnode=self.root.find_dir(self.bldnode.abspath()) self.path=self.srcnode=self.root.find_dir(self.srcnode.abspath()) self.cwd=self.bldnode.abspath()
def apply_barchive_after(self): if self.source_root is None: return error('source_root is not specified!') if self.resource_name is None: return error('resource_name is not specified!') builder = self.create_task('resource_archive') builder.inputs = [] for task in self.tasks: if task != builder: builder.set_run_after(task) builder.inputs.extend(task.outputs) builder.outputs = [] for extension in ['dmanifest', 'arci', 'arcd', 'public', 'manifest_hash']: current_filepath = '%s.%s' % (self.resource_name, extension) current_output = self.path.find_or_declare(current_filepath) builder.outputs.append(current_output) classpath = [ self.env['DYNAMO_HOME'] + '/share/java/bob-light.jar', 'default/src/java' ] builder.env['CLASSPATH'] = os.pathsep.join(classpath) arg_root = self.source_root arg_output = os.path.abspath( os.path.join('build', self.path.bldpath(self.env), self.resource_name)) builder.env.append_value('ARCHIVEBUILDER_ROOT', [arg_root]) builder.env.append_value('ARCHIVEBUILDER_OUTPUT', [arg_output]) builder.env.append_value('ARCHIVEBUILDER_FLAGS', ['-m']) if self.use_compression: builder.env.append_value('ARCHIVEBUILDER_FLAGS', ['-c'])
def do_install(self,src,tgt,chmod=O644): if self.is_install>0: if not Options.options.force: try: st1=os.stat(tgt) st2=os.stat(src) except OSError: pass else: if st1.st_mtime>=st2.st_mtime and st1.st_size==st2.st_size: return False srclbl=src.replace(self.srcnode.abspath(None)+os.sep,'') info("* installing %s as %s"%(srclbl,tgt)) try:os.remove(tgt) except OSError:pass try: shutil.copy2(src,tgt) os.chmod(tgt,chmod) except IOError: try: os.stat(src) except(OSError,IOError): error('File %r does not exist'%src) raise Utils.WafError('Could not install the file %r'%tgt) return True elif self.is_install<0: info("* uninstalling %s"%tgt) self.uninstall.append(tgt) try:os.remove(tgt) except OSError:pass return True
def addlines(self,node): self.currentnode_stack.append(node.parent) filepath=node.abspath(self.env) self.count_files+=1 if self.count_files>30000:raise PreprocError,"recursion limit exceeded, bailing out" pc=self.parse_cache debug('preproc: reading file %r'%filepath) try: lns=pc[filepath] except KeyError: pass else: self.lines=lns+self.lines return try: lines=filter_comments(filepath) lines.append((POPFILE,'')) pc[filepath]=lines self.lines=lines+self.lines except IOError: raise PreprocError,"could not read the file %s"%filepath except Exception: if Logs.verbose>0: error("parsing %s failed"%filepath) traceback.print_exc()
def load_envs(self): try: lst = Utils.listdir(self.cachedir) except OSError as e: if e.errno == errno.ENOENT: raise Utils.WafError( 'The project was not configured: run "waf configure" first!' ) else: raise if not lst: raise Utils.WafError( 'The cache directory is empty: reconfigure the project') for file in lst: if file.endswith(CACHE_SUFFIX): env = Environment.Environment(os.path.join( self.cachedir, file)) name = file[:-len(CACHE_SUFFIX)] self.all_envs[name] = env self.init_variants() for env in self.all_envs.values(): for f in env[CFG_FILES]: newnode = self.path.find_or_declare(f) try: hash = Utils.h_file(newnode.abspath(env)) except (IOError, AttributeError): error("cannot find " + f) hash = SIG_NIL self.node_sigs[env.variant()][newnode.id] = hash self.bldnode = self.root.find_dir(self.bldnode.abspath()) self.path = self.srcnode = self.root.find_dir(self.srcnode.abspath()) self.cwd = self.bldnode.abspath()
def run(self): if self.env['VALADOC']: if not self.env['VALADOCFLAGS']: self.env['VALADOCFLAGS'] = '' cmd = [Utils.subst_vars(VALADOC_STR, self.env)] cmd.append ('-o %s' % self.output_dir) if getattr(self, 'doclet', None): cmd.append ('--doclet %s' % self.doclet) cmd.append ('--package-name %s' % self.package_name) if getattr(self, 'version', None): cmd.append ('--package-version %s' % self.package_version) if getattr(self, 'packages', None): for package in self.packages: cmd.append ('--pkg %s' % package) if getattr(self, 'vapi_dirs', None): for vapi_dir in self.vapi_dirs: cmd.append ('--vapidir %s' % vapi_dir) if not getattr(self, 'protected', None): cmd.append ('--no-protected') if getattr(self, 'private', None): cmd.append ('--private') if getattr(self, 'inherit', None): cmd.append ('--inherit') if getattr(self, 'deps', None): cmd.append ('--deps') if getattr(self, 'enable_non_null_experimental', None): cmd.append ('--enable-non-null-experimental') if getattr(self, 'force', None): cmd.append ('--force') cmd.append (' '.join ([x.relpath_gen (self.generator.bld.bldnode) for x in self.files])) return self.generator.bld.exec_command(' '.join(cmd)) else: error ('You must install valadoc <http://live.gnome.org/Valadoc> for generate the API documentation') return -1
def run(self): if self.env['VALADOC']: if not self.env['VALADOCFLAGS']: self.env['VALADOCFLAGS'] = '' cmd = [Utils.subst_vars(VALADOC_STR, self.env)] cmd.append ('-o %s' % self.output_dir) if getattr(self, 'doclet', None): cmd.append ('--doclet %s' % self.doclet) cmd.append ('--package-name %s' % self.package_name) if getattr(self, 'version', None): cmd.append ('--package-version %s' % self.package_version) if getattr(self, 'packages', None): for package in self.packages: cmd.append ('--pkg %s' % package) if getattr(self, 'vapi_dirs', None): for vapi_dir in self.vapi_dirs: cmd.append ('--vapidir %s' % vapi_dir) if getattr(self, 'protected', None): cmd.append ('--protected') if getattr(self, 'private', None): cmd.append ('--private') if getattr(self, 'inherit', None): cmd.append ('--inherit') if getattr(self, 'deps', None): cmd.append ('--deps') if getattr(self, 'enable_non_null_experimental', None): cmd.append ('--enable-non-null-experimental') if getattr(self, 'force', None): cmd.append ('--force') cmd.append (' '.join ([x.relpath_gen (self.generator.bld.bldnode) for x in self.files])) return self.generator.bld.exec_command(' '.join(cmd)) else: error ('You must install valadoc <http://live.gnome.org/Valadoc> for generate the API documentation') return -1
def addlines(self, node): self.currentnode_stack.append(node.parent) filepath = node.abspath(self.env) self.count_files += 1 if self.count_files > recursion_limit: raise PreprocError("recursion limit exceeded") pc = self.parse_cache debug('preproc: reading file %r', filepath) try: lns = pc[filepath] except KeyError: pass else: self.lines = lns + self.lines return try: lines = filter_comments(filepath) lines.append((POPFILE, '')) pc[filepath] = lines self.lines = lines + self.lines except IOError: raise PreprocError("could not read the file %s" % filepath) except Exception: if Logs.verbose > 0: error("parsing %s failed" % filepath) traceback.print_exc()
def _iter(self, node): path = node.abspath(self.tg.env) try: code = Utils.cmd_output(' '.join([self.tg.env['GOFMT'], '-comments=false', path])) except ValueError, e: error(str(e)) exit(1)
def iapply_intltool_in_f(self): try: self.meths.remove('apply_core') except ValueError: pass for i in self.to_list(self.source): node = self.path.find_resource(i) podir = getattr(self, 'podir', 'po') podirnode = self.path.find_dir(podir) if not podirnode: error("could not find the podir %r" % podir) continue cache = getattr(self, 'intlcache', '.intlcache') self.env['INTLCACHE'] = os.path.join(self.path.bldpath(self.env), podir, cache) self.env['INTLPODIR'] = podirnode.srcpath(self.env) self.env['INTLFLAGS'] = getattr(self, 'flags', ['-q', '-u', '-c']) task = self.create_task('intltool') task.set_inputs(node) task.set_outputs(node.change_ext('')) task.install_path = self.install_path
def do_install(self, src, tgt, chmod=O644): if self.is_install > 0: if not Options.options.force: try: st1 = os.stat(tgt) st2 = os.stat(src) except OSError: pass else: if st1.st_mtime >= st2.st_mtime and st1.st_size == st2.st_size: return False srclbl = src.replace(self.srcnode.abspath(None) + os.sep, '') info("* installing %s as %s" % (srclbl, tgt)) try: os.remove(tgt) except OSError: pass try: shutil.copy2(src, tgt) os.chmod(tgt, chmod) except IOError: try: os.stat(src) except (OSError, IOError): error('File %r does not exist' % src) raise Utils.WafError('Could not install the file %r' % tgt) return True elif self.is_install < 0: info("* uninstalling %s" % tgt) self.uninstall.append(tgt) try: os.remove(tgt) except OSError: pass return True
def add_moc_tasks(self): node=self.inputs[0] tree=node.__class__.bld try: self.signature() except KeyError: pass else: delattr(self,'cache_sig') moctasks=[] mocfiles=[] variant=node.variant(self.env) try: tmp_lst=tree.raw_deps[self.unique_id()] tree.raw_deps[self.unique_id()]=[] except KeyError: tmp_lst=[] for d in tmp_lst: if not d.endswith('.moc'):continue if d in mocfiles: error("paranoia owns") continue mocfiles.append(d) base2=d[:-4] for path in[node.parent]+self.generator.env['INC_PATHS']: tree.rescan(path) vals=getattr(Options.options,'qt_header_ext','')or MOC_H for ex in vals: h_node=path.find_resource(base2+ex) if h_node: break else: continue break else: raise Utils.WafError("no header found for %s which is a moc file"%str(d)) m_node=h_node.change_ext('.moc') tree.node_deps[(self.inputs[0].parent.id,self.env.variant(),m_node.name)]=h_node task=Task.TaskBase.classes['moc'](self.env,normal=0) task.set_inputs(h_node) task.set_outputs(m_node) generator=tree.generator generator.outstanding.insert(0,task) generator.total+=1 moctasks.append(task) tmp_lst=tree.raw_deps[self.unique_id()]=mocfiles lst=tree.node_deps.get(self.unique_id(),()) for d in lst: name=d.name if name.endswith('.moc'): task=Task.TaskBase.classes['moc'](self.env,normal=0) task.set_inputs(tree.node_deps[(self.inputs[0].parent.id,self.env.variant(),name)]) task.set_outputs(d) generator=tree.generator generator.outstanding.insert(0,task) generator.total+=1 moctasks.append(task) self.run_after=moctasks self.moc_done=1
def apply_go_link(self): main = self.packages['main'] if not main: error('Could not find a `main\' package') exit(1) main output = self.path.find_or_declare(main.target) main.link_task = self.create_task('golink', main.build_task.outputs, output)
def add_group(self, name=None, set=True): g = TaskGroup() if name and name in self.groups_names: error("add_group: name %s already present" % name) self.groups_names[name] = g self.groups.append(g) if set: self.current_group = len(self.groups) - 1
def add_group(self, name=None, set=True): g = TaskGroup() if name and name in self.groups_names: error('add_group: name %s already present' % name) self.groups_names[name] = g self.groups.append(g) if set: self.current_group = len(self.groups) - 1
def env_of_name(self, name): if not name: error('env_of_name called with no name!') return None try: return self.all_envs[name] except KeyError: error('no such environment: '+name) return None
def prepare(t,cwd,ver,wafdir): if WAFVERSION!=ver: msg='Version mismatch: waf %s <> wafadmin %s (wafdir %s)'%(ver,WAFVERSION,wafdir) print('\033[91mError: %s\033[0m'%msg) sys.exit(1) try: prepare_impl(t,cwd,ver,wafdir) except Utils.WafError,e: error(str(e)) sys.exit(1)
def add_group(self, name=None, set=True): #if self.groups and not self.groups[0].tasks: # error('add_group: an empty group is already present') g = TaskGroup() if name and name in self.groups_names: error('add_group: name %s already present' % name) self.groups_names[name] = g self.groups.append(g) if set: self.current_group = len(self.groups) - 1
def apply_incpaths_ml(self): inc_lst = self.includes.split() lst = self.incpaths_lst for dir in inc_lst: node = self.path.find_dir(dir) if not node: error("node not found: " + str(dir)) continue self.bld.rescan(node) if not node in lst: lst.append(node) self.bld_incpaths_lst.append(node)
def apply_incpaths_ml(self): inc_lst=self.includes.split() lst=self.incpaths_lst for dir in inc_lst: node=self.path.find_dir(dir) if not node: error("node not found: "+str(dir)) continue self.bld.rescan(node) if not node in lst:lst.append(node) self.bld_incpaths_lst.append(node)
def do_install(self, src, tgt, chmod=O644): """returns true if the file was effectively installed or uninstalled, false otherwise""" if self.is_install > 0: if not Options.options.force: # check if the file is already there to avoid a copy try: st1 = os.stat(tgt) st2 = os.stat(src) except OSError: pass else: # same size and identical timestamps -> make no copy if st1.st_mtime >= st2.st_mtime and st1.st_size == st2.st_size: return False srclbl = src.replace(self.srcnode.abspath(None) + os.sep, '') info("* installing %s as %s" % (srclbl, tgt)) # following is for shared libs and stale inodes (-_-) try: os.remove(tgt) except OSError: pass try: shutil.copy2(src, tgt) if chmod >= 0: os.chmod(tgt, chmod) except IOError: try: os.stat(src) except (OSError, IOError): error('File %r does not exist' % src) raise Utils.WafError('Could not install the file %r' % tgt) return True elif self.is_install < 0: info("* uninstalling %s" % tgt) self.uninstall.append(tgt) try: os.remove(tgt) except OSError, e: if e.errno != errno.ENOENT: if not getattr(self, 'uninstall_error', None): self.uninstall_error = True Logs.warn( 'build: some files could not be uninstalled (retry with -vv to list them)' ) if Logs.verbose > 1: Logs.warn('could not remove %s (error code %r)' % (e.filename, e.errno)) return True
def prepare(t, cwd, ver, wafdir): if WAFVERSION != ver: msg = 'Version mismatch: waf {0!s} <> wafadmin {1!s} (wafdir {2!s})'.format(ver, WAFVERSION, wafdir) print('\033[91mError: {0!s}\033[0m'.format(msg)) sys.exit(1) #""" try: prepare_impl(t, cwd, ver, wafdir) except Utils.WafError, e: error(str(e)) sys.exit(1)
def prepare(t,cwd,ver,wafdir): if WAFVERSION!=ver: msg='Version mismatch: waf %s <> wafadmin %s (wafdir %s)'%(ver,WAFVERSION,wafdir) print('\033[91mError: %s\033[0m'%msg) sys.exit(1) try: prepare_impl(t,cwd,ver,wafdir) except Utils.WafError as e: error(str(e)) sys.exit(1) except KeyboardInterrupt: Utils.pprint('RED','Interrupted') sys.exit(68)
def go_vars(conf): v = conf.env fail = False ok = check_and_set_var('GOROOT', v) if not ok: error('GOROOT is set not set. Set in environment or in wscript.') fail = True ok = check_and_set_var('GOOS', v, ['darwin', 'linux', 'nacl']) if not ok: error('GOOS is set to `%s\', must be either darwin, linux or nacl.') fail = True ok = check_and_set_var('GOARCH', v, ['amd64', '386', 'arm']) if not ok: error('GOARCH is set to `%s\', must be either amd64, 386 or arm.') fail = True if fail: error('Set in environment or in wscript') exit(1) arch_dict = { 'arm': '5', 'amd64': '6', '386': '8', } v['GOARCH_O'] = arch_dict[v['GOARCH']]
def prepare(t, cwd, ver, wafdir): if WAFVERSION != ver: msg = 'Version mismatch: waf %s <> wafadmin %s (wafdir %s)' % ( ver, WAFVERSION, wafdir) print('\033[91mError: %s\033[0m' % msg) sys.exit(1) try: prepare_impl(t, cwd, ver, wafdir) except Utils.WafError as e: error(str(e)) sys.exit(1) except KeyboardInterrupt: Utils.pprint('RED', 'Interrupted') sys.exit(68)
def start_local(self, filename): self.addlines(filename) #print self.lines while self.lines: (kind, line) = self.lines.pop(0) if kind == POPFILE: self.currentnode_stack.pop() continue try: self.process_line(kind, line) except Exception, e: if Logs.verbose: error("line parsing failed (%s): %s" % (str(e), line)) traceback.print_exc() raise e
def do_install(self, src, tgt, chmod=O644): """returns true if the file was effectively installed or uninstalled, false otherwise""" if self.is_install > 0: if not Options.options.force: # check if the file is already there to avoid a copy try: st1 = os.stat(tgt) st2 = os.stat(src) except OSError: pass else: # same size and identical timestamps -> make no copy if st1.st_mtime >= st2.st_mtime and st1.st_size == st2.st_size: return False srclbl = src.replace(self.srcnode.abspath(None)+os.sep, '') info("* installing %s as %s" % (srclbl, tgt)) # following is for shared libs and stale inodes (-_-) try: os.remove(tgt) except OSError: pass try: shutil.copy2(src, tgt) os.chmod(tgt, chmod) except IOError: try: os.stat(src) except (OSError, IOError): error('File %r does not exist' % src) raise Utils.WafError('Could not install the file %r' % tgt) return True elif self.is_install < 0: info("* uninstalling %s" % tgt) self.uninstall.append(tgt) try: os.remove(tgt) except OSError, e: if e.errno != errno.ENOENT: if not getattr(self, 'uninstall_error', None): self.uninstall_error = True Logs.warn('build: some files could not be uninstalled (retry with -vv to list them)') if Logs.verbose > 1: Logs.warn('could not remove %s (error code %r)' % (e.filename, e.errno)) return True
def iapply_intltool_in_f(self): try:self.meths.remove('apply_core') except ValueError:pass for i in self.to_list(self.source): node=self.path.find_resource(i) podir=getattr(self,'podir','po') podirnode=self.path.find_dir(podir) if not podirnode: error("could not find the podir %r"%podir) continue cache=getattr(self,'intlcache','.intlcache') self.env['INTLCACHE']=os.path.join(self.path.bldpath(self.env),podir,cache) self.env['INTLPODIR']=podirnode.srcpath(self.env) self.env['INTLFLAGS']=getattr(self,'flags',['-q','-u','-c']) task=self.create_task('intltool',node,node.change_ext('')) task.install_path=self.install_path
def start(self,node,env): debug('preproc: scanning %s (in %s)'%(node.name,node.parent.name)) self.env=env variant=node.variant(env) self.addlines(node) if env['DEFLINES']: self.lines=[('define',x)for x in env['DEFLINES']]+self.lines while self.lines: (type,line)=self.lines.pop(0) if type==POPFILE: self.currentnode_stack.pop() continue try: self.process_line(type,line) except Exception,ex: if Logs.verbose: error("line parsing failed (%s): %s"%(str(ex),line)) traceback.print_exc()
def apply_go_usepkg(self): """Add flags and build order constraints on packages listed in usepkg and usepkg_local properties. """ names = self.to_list(self.usepkg_local) seen = set([]) tmp = Utils.deque(names) # consume a copy of the list of names while tmp: pkg_name = tmp.popleft() # visit dependencies only once if pkg_name in seen: continue tg = self.name_to_obj(pkg_name) if not tg: raise Utils.WafError('object %r was not found in usepkg_local (required by %r)' % (pkg_name, self.name)) seen.add(pkg_name) # Post the task_gen so it can create its tasks, which we'll need tg.post() if pkg_name not in tg.packages: error('task_gen %r does not build the package %s' % (tg, pkg_name)) exit(1) dep_pkg = tg.packages[pkg_name] # Add build flags path = dep_pkg.build_task.outputs[0].bld_dir(tg.env) self.env.append_unique('GOFLAGS', self.env['GOPATH_ST'] % path) # Set run order for pkg in self.packages.itervalues(): pkg.build_task.set_run_after(dep_pkg.build_task) # Add dependencies dep_nodes = getattr(pkg.build_task, 'dep_nodes', []) pkg.build_task.dep_nodes = dep_nodes + dep_pkg.build_task.outputs # Add usepkg flags pkgs = self.to_list(self.usepkg) for pkg in pkgs: if 'PKGPATH_'+pkg in self.env: path = self.env['PKGPATH_'+pkg] self.env.append_unique('GOFLAGS', self.env.GOPATH_ST % path) self.env.append_unique('GOLDFLAGS', self.env.GOPKGPATH_ST % path)
def do_install(self, src, tgt, chmod=O644): if self.is_install > 0: if not Options.options.force: try: st1 = os.stat(tgt) st2 = os.stat(src) except OSError: pass else: if st1.st_mtime >= st2.st_mtime and st1.st_size == st2.st_size: return False srclbl = src.replace(self.srcnode.abspath(None) + os.sep, '') info("* installing %s as %s" % (srclbl, tgt)) try: os.remove(tgt) except OSError: pass try: shutil.copy2(src, tgt) os.chmod(tgt, chmod) except IOError: try: os.stat(src) except (OSError, IOError): error('File %r does not exist' % src) raise Utils.WafError('Could not install the file %r' % tgt) return True elif self.is_install < 0: info("* uninstalling %s" % tgt) self.uninstall.append(tgt) try: os.remove(tgt) except OSError, e: if e.errno != errno.ENOENT: if not getattr(self, 'uninstall_error', None): self.uninstall_error = True Logs.warn( 'build: some files could not be uninstalled (retry with -vv to list them)' ) if Logs.verbose > 1: Logs.warn('could not remove %s (error code %r)' % (e.filename, e.errno)) return True
def do_install(self, src, tgt, chmod=O644): """returns true if the file was effectively installed or uninstalled, false otherwise""" if Options.commands['install']: if not Options.options.force: # check if the file is already there to avoid a copy try: t1 = os.stat(tgt).st_mtime t2 = os.stat(src).st_mtime except OSError: pass else: if t1 >= t2: return False srclbl = src.replace(self.srcnode.abspath(None)+os.sep, '') info("* installing %s as %s" % (srclbl, tgt)) # following is for shared libs and stale inodes (-_-) try: os.remove(tgt) except OSError: pass try: shutil.copy2(src, tgt) os.chmod(tgt, chmod) except IOError: try: os.stat(src) except (OSError, IOError): error('File %r does not exist' % src) raise Utils.WafError('Could not install the file %r' % tgt) return True elif Options.commands['uninstall']: info("* uninstalling %s" % tgt) self.uninstall.append(tgt) try: os.remove(tgt) except OSError: pass return True
def do_install(self, src, tgt, chmod=O644): if self.is_install > 0: if not Options.options.force: try: st1 = os.stat(tgt) st2 = os.stat(src) except OSError: pass else: if st1.st_mtime >= st2.st_mtime and st1.st_size == st2.st_size: return False srclbl = src.replace(self.srcnode.abspath(None) + os.sep, "") info("* installing %s as %s" % (srclbl, tgt)) try: os.remove(tgt) except OSError: pass try: shutil.copy2(src, tgt) os.chmod(tgt, chmod) except IOError: try: os.stat(src) except (OSError, IOError): error("File %r does not exist" % src) raise Utils.WafError("Could not install the file %r" % tgt) return True elif self.is_install < 0: info("* uninstalling %s" % tgt) self.uninstall.append(tgt) try: os.remove(tgt) except OSError, e: if e.errno != errno.ENOENT: if not getattr(self, "uninstall_error", None): self.uninstall_error = True Logs.warn("build: some files could not be uninstalled (retry with -vv to list them)") if Logs.verbose > 1: Logs.warn("could not remove %s (error code %r)" % (e.filename, e.errno)) return True
def iapply_intltool_in_f(self): try: self.meths.remove("apply_core") except ValueError: pass for i in self.to_list(self.source): node = self.path.find_resource(i) podir = getattr(self, "podir", "po") podirnode = self.path.find_dir(podir) if not podirnode: error("could not find the podir %r" % podir) continue cache = getattr(self, "intlcache", ".intlcache") self.env["INTLCACHE"] = os.path.join(self.path.bldpath(self.env), podir, cache) self.env["INTLPODIR"] = podirnode.srcpath(self.env) self.env["INTLFLAGS"] = getattr(self, "flags", ["-q", "-u", "-c"]) task = self.create_task("intltool", node, node.change_ext("")) task.install_path = self.install_path
def runnable_status(self): if self.inputs and(not self.outputs): if not getattr(self.__class__,'quiet',None): error("task is invalid : no inputs or outputs (override in a Task subclass?) %r"%self) for t in self.run_after: if not t.hasrun: return ASK_LATER env=self.env bld=self.generator.bld time=None for node in self.outputs: variant=node.variant(env) try: time=bld.node_sigs[variant][node.id] except KeyError: debug("task: task %r must run as the first node does not exist"%self) time=None break if time is None: try: new_sig=self.signature() except KeyError: debug("task: something is wrong, computing the task signature failed") return RUN_ME return RUN_ME key=self.unique_id() try: prev_sig=bld.task_sigs[key][0] except KeyError: debug("task: task %r must run as it was never run before or the task code changed"%self) return RUN_ME new_sig=self.signature() if Logs.verbose:self.debug_why(bld.task_sigs[key]) if new_sig!=prev_sig: return RUN_ME return SKIP_ME
def env_of_name(self, name): try: return self.all_envs[name] except KeyError: error("no such environment: " + name) return None
def add_moc_tasks(self): node = self.inputs[0] tree = node.__class__.bld try: self.signature() except KeyError: pass else: delattr(self, 'cache_sig') moctasks = [] mocfiles = [] variant = node.variant(self.env) try: tmp_lst = tree.raw_deps[self.unique_id()] tree.raw_deps[self.unique_id()] = [] except KeyError: tmp_lst = [] for d in tmp_lst: if not d.endswith('.moc'): continue if d in mocfiles: error("paranoia owns") continue mocfiles.append(d) ext = '' try: ext = Options.options.qt_header_ext except AttributeError: pass if not ext: base2 = d[:-4] paths = [ node.parent.srcpath(self.env), node.parent.bldpath(self.env) ] poss = [(x, y) for x in MOC_H for y in paths] for (i, path) in poss: try: os.stat(os.path.join(path, base2 + i)) except OSError: pass else: ext = i break if not ext: raise Utils.WafError( "no header found for %s which is a moc file" % str(d)) h_node = node.parent.find_resource(base2 + i) m_node = h_node.change_ext('.moc') tree.node_deps[(self.inputs[0].parent.id, self.env.variant(), m_node.name)] = h_node task = Task.TaskBase.classes['moc'](self.env, normal=0) task.set_inputs(h_node) task.set_outputs(m_node) generator = tree.generator generator.outstanding.insert(0, task) generator.total += 1 moctasks.append(task) tmp_lst = tree.raw_deps[self.unique_id()] = mocfiles lst = tree.node_deps.get(self.unique_id(), ()) for d in lst: name = d.name if name.endswith('.moc'): task = Task.TaskBase.classes['moc'](self.env, normal=0) task.set_inputs(tree.node_deps[(self.inputs[0].parent.id, self.env.variant(), name)]) task.set_outputs(d) generator = tree.generator generator.outstanding.insert(0, task) generator.total += 1 moctasks.append(task) self.run_after = moctasks self.moc_done = 1
def filter_comments(filename): txt = Utils.readf(filename) buf = [] i = 0 max = len(txt) while i < max: c = txt[i] # skip a string if c == '"': i += 1 c = '' while i < max: p = c c = txt[i] i += 1 if i == max: return buf if c == '"': cnt = 0 while i < cnt and i < max: #print "cntcnt = ", str(cnt), self.txt[self.i-2-cnt] if txt[i - 2 - cnt] == '\\': cnt += 1 else: break #print "cnt is ", str(cnt) if (cnt % 2) == 0: break # i -= 1 # <- useless in practice # skip a char elif c == "'": i += 1 if i == max: return buf c = txt[i] if c == '\\': i += 1 if i == max: return buf c = txt[i] if c == 'x': i += 2 # skip two chars elif c == 'u': i += 4 # skip unicode chars i += 1 if i == max: return buf c = txt[i] if c != '\'': error("uh-oh, invalid character") # skip a comment elif c == '/': if i == max: break c = txt[i + 1] # eat /+ +/ comments if c == '+': i += 1 nesting = 1 prev = 0 while i < max: c = txt[i] if c == '+': prev = 1 elif c == '/': if prev: nesting -= 1 if nesting == 0: break else: if i < max: i += 1 c = txt[i] if c == '+': nesting += 1 else: return buf else: prev = 0 i += 1 # eat /* */ comments elif c == '*': i += 1 while i < max: c = txt[i] if c == '*': prev = 1 elif c == '/': if prev: break else: prev = 0 i += 1 # eat // comments elif c == '/': i += 1 c = txt[i] while i < max and c != '\n': i += 1 c = txt[i] # a valid char, add it to the buffer else: buf.append(c) i += 1 return buf
def filter_comments(filename): txt = Utils.readf(filename) buf = [] i = 0 max = len(txt) while i < max: c = txt[i] # skip a string if c == '"': i += 1 c = '' while i < max: p = c c = txt[i] i += 1 if i == max: return buf if c == '"': cnt = 0 while i < cnt and i < max: #print "cntcnt = ", str(cnt), self.txt[self.i-2-cnt] if txt[i-2-cnt] == '\\': cnt+=1 else: break #print "cnt is ", str(cnt) if (cnt%2)==0: break # i -= 1 # <- useless in practice # skip a char elif c == "'": i += 1 if i == max: return buf c = txt[i] if c == '\\': i += 1 if i == max: return buf c = txt[i] if c == 'x': i += 2 # skip two chars elif c == 'u': i += 4 # skip unicode chars i += 1 if i == max: return buf c = txt[i] if c != '\'': error("uh-oh, invalid character") # skip a comment elif c == '/': if i == max: break c = txt[i+1] # eat /+ +/ comments if c == '+': i += 1 nesting = 1 prev = 0 while i < max: c = txt[i] if c == '+': prev = 1 elif c == '/': if prev: nesting -= 1 if nesting == 0: break else: if i < max: i += 1 c = txt[i] if c == '+': nesting += 1 else: return buf else: prev = 0 i += 1 # eat /* */ comments elif c == '*': i += 1 while i < max: c = txt[i] if c == '*': prev = 1 elif c == '/': if prev: break else: prev = 0 i += 1 # eat // comments elif c == '/': i += 1 c = txt[i] while i < max and c != '\n': i += 1 c = txt[i] # a valid char, add it to the buffer else: buf.append(c) i += 1 return buf
def add_moc_tasks(self): node=self.inputs[0] tree=node.__class__.bld try: self.signature() except KeyError: pass else: delattr(self,'cache_sig') moctasks=[] mocfiles=[] variant=node.variant(self.env) try: tmp_lst=tree.raw_deps[self.unique_id()] tree.raw_deps[self.unique_id()]=[] except KeyError: tmp_lst=[] for d in tmp_lst: if not d.endswith('.moc'):continue if d in mocfiles: error("paranoia owns") continue mocfiles.append(d) ext='' try:ext=Options.options.qt_header_ext except AttributeError:pass if not ext: base2=d[:-4] paths=[node.parent.srcpath(self.env),node.parent.bldpath(self.env)] poss=[(x,y)for x in MOC_H for y in paths] for(i,path)in poss: try: os.stat(os.path.join(path,base2+i)) except OSError: pass else: ext=i break if not ext:raise Utils.WafError("no header found for %s which is a moc file"%str(d)) h_node=node.parent.find_resource(base2+i) m_node=h_node.change_ext('.moc') tree.node_deps[(self.inputs[0].parent.id,self.env.variant(),m_node.name)]=h_node task=Task.TaskBase.classes['moc'](self.env,normal=0) task.set_inputs(h_node) task.set_outputs(m_node) generator=tree.generator generator.outstanding.insert(0,task) generator.total+=1 moctasks.append(task) tmp_lst=tree.raw_deps[self.unique_id()]=mocfiles lst=tree.node_deps.get(self.unique_id(),()) for d in lst: name=d.name if name.endswith('.moc'): task=Task.TaskBase.classes['moc'](self.env,normal=0) task.set_inputs(tree.node_deps[(self.inputs[0].parent.id,self.env.variant(),name)]) task.set_outputs(d) generator=tree.generator generator.outstanding.insert(0,task) generator.total+=1 moctasks.append(task) self.run_after=moctasks self.moc_done=1
def env_of_name(self, name): try: return self.all_envs[name] except KeyError: error('no such environment: ' + name) return None
def tex_build(task, command='LATEX'): env = task.env bld = task.generator.bld com = '%s %s' % (env[command], env.get_flat(command + 'FLAGS')) if not env['PROMPT_LATEX']: com = "%s %s" % (com, '-interaction=batchmode') node = task.inputs[0] reldir = node.bld_dir(env) srcfile = node.srcpath(env) lst = [] for c in Utils.split_path(reldir): if c: lst.append('..') sr = os.path.join(*(lst + [srcfile])) sr2 = os.path.join(*(lst + [node.parent.srcpath(env)])) aux_node = node.change_ext('.aux') idx_node = node.change_ext('.idx') hash = '' old_hash = '' nm = aux_node.name docuname = nm[:len(nm) - 4] latex_compile_cmd = 'cd %s && TEXINPUTS=%s:$TEXINPUTS %s %s' % ( reldir, sr2, com, sr) warn('first pass on %s' % command) ret = bld.exec_command(latex_compile_cmd) if ret: return ret try: ct = Utils.readf(aux_node.abspath(env)) except (OSError, IOError): error('error bibtex scan') else: fo = g_bibtex_re.findall(ct) if fo: bibtex_compile_cmd = 'cd %s && BIBINPUTS=%s:$BIBINPUTS %s %s' % ( reldir, sr2, env['BIBTEX'], docuname) warn('calling bibtex') ret = bld.exec_command(bibtex_compile_cmd) if ret: error('error when calling bibtex %s' % bibtex_compile_cmd) return ret try: idx_path = idx_node.abspath(env) os.stat(idx_path) except OSError: error('error file.idx scan') else: makeindex_compile_cmd = 'cd %s && %s %s' % (reldir, env['MAKEINDEX'], idx_path) warn('calling makeindex') ret = bld.exec_command(makeindex_compile_cmd) if ret: error('error when calling makeindex %s' % makeindex_compile_cmd) return ret i = 0 while i < 10: i += 1 old_hash = hash try: hash = Utils.h_file(aux_node.abspath(env)) except KeyError: error('could not read aux.h -> %s' % aux_node.abspath(env)) pass if hash and hash == old_hash: break warn('calling %s' % command) ret = bld.exec_command(latex_compile_cmd) if ret: error('error when calling %s %s' % (command, latex_compile_cmd)) return ret return 0
def add_moc_tasks(self): node = self.inputs[0] tree = node.__class__.bld try: self.signature() except KeyError: pass else: delattr(self, 'cache_sig') moctasks = [] mocfiles = [] variant = node.variant(self.env) try: tmp_lst = tree.raw_deps[self.unique_id()] tree.raw_deps[self.unique_id()] = [] except KeyError: tmp_lst = [] for d in tmp_lst: if not d.endswith('.moc'): continue if d in mocfiles: error("paranoia owns") continue mocfiles.append(d) base2 = d[:-4] for path in [node.parent] + self.generator.env['INC_PATHS']: tree.rescan(path) vals = getattr(Options.options, 'qt_header_ext', '') or MOC_H for ex in vals: h_node = path.find_resource(base2 + ex) if h_node: break else: continue break else: raise Utils.WafError( "no header found for %s which is a moc file" % str(d)) m_node = h_node.change_ext('.moc') tree.node_deps[(self.inputs[0].parent.id, self.env.variant(), m_node.name)] = h_node task = Task.TaskBase.classes['moc'](self.env, normal=0) task.set_inputs(h_node) task.set_outputs(m_node) generator = tree.generator generator.outstanding.insert(0, task) generator.total += 1 moctasks.append(task) tmp_lst = tree.raw_deps[self.unique_id()] = mocfiles lst = tree.node_deps.get(self.unique_id(), ()) for d in lst: name = d.name if name.endswith('.moc'): task = Task.TaskBase.classes['moc'](self.env, normal=0) task.set_inputs(tree.node_deps[(self.inputs[0].parent.id, self.env.variant(), name)]) task.set_outputs(d) generator = tree.generator generator.outstanding.insert(0, task) generator.total += 1 moctasks.append(task) self.run_after = moctasks self.moc_done = 1
class BuildContext(Utils.Context): "holds the dependency tree" def __init__(self): # not a singleton, but provided for compatibility global bld bld = self self.task_manager = Task.TaskManager() # instead of hashing the nodes, we assign them a unique id when they are created self.id_nodes = 0 self.idx = {} # map names to environments, the 'Release' must be defined self.all_envs = {} # ======================================= # # code for reading the scripts # project build directory - do not reset() from load_dirs() self.bdir = '' # the current directory from which the code is run # the folder changes everytime a wscript is read self.path = None # Manual dependencies. self.deps_man = Utils.DefaultDict(list) # ======================================= # # cache variables # local cache for absolute paths - cache_node_abspath[variant][node] self.cache_node_abspath = {} # list of folders that are already scanned # so that we do not need to stat them one more time self.cache_scanned_folders = {} # list of targets to uninstall for removing the empty folders after uninstalling self.uninstall = [] # ======================================= # # tasks and objects # build dir variants (release, debug, ..) for v in 'cache_node_abspath task_sigs node_deps raw_deps node_sigs'.split( ): var = {} setattr(self, v, var) self.cache_dir_contents = {} self.all_task_gen = [] self.task_gen_cache_names = {} self.cache_sig_vars = {} self.log = None self.root = None self.srcnode = None self.bldnode = None # bind the build context to the nodes in use # this means better encapsulation and no build context singleton class node_class(Node.Node): pass self.node_class = node_class self.node_class.__module__ = "Node" self.node_class.__name__ = "Nodu" self.node_class.bld = self self.is_install = None def __copy__(self): "nodes are not supposed to be copied" raise Utils.WafError('build contexts are not supposed to be cloned') def load(self): "load the cache from the disk" try: env = Environment.Environment( os.path.join(self.cachedir, 'build.config.py')) except (IOError, OSError): pass else: if env['version'] < HEXVERSION: raise Utils.WafError( 'Version mismatch! reconfigure the project') for t in env['tools']: self.setup(**t) try: gc.disable() f = data = None Node.Nodu = self.node_class try: f = open(os.path.join(self.bdir, DBFILE), 'rb') except (IOError, EOFError): # handle missing file/empty file pass try: if f: data = cPickle.load(f) except AttributeError: # handle file of an old Waf version # that has an attribute which no longer exist # (e.g. AttributeError: 'module' object has no attribute 'BuildDTO') if Logs.verbose > 1: raise if data: for x in SAVED_ATTRS: setattr(self, x, data[x]) else: debug('build: Build cache loading failed') finally: if f: f.close() gc.enable() def save(self): "store the cache on disk, see self.load" gc.disable() self.root.__class__.bld = None # some people are very nervous with ctrl+c so we have to make a temporary file Node.Nodu = self.node_class db = os.path.join(self.bdir, DBFILE) file = open(db + '.tmp', 'wb') data = {} for x in SAVED_ATTRS: data[x] = getattr(self, x) cPickle.dump(data, file, -1) file.close() # do not use shutil.move try: os.unlink(db) except OSError: pass os.rename(db + '.tmp', db) self.root.__class__.bld = self gc.enable() # ======================================= # def clean(self): debug('build: clean called') # does not clean files created during the configuration precious = set([]) for env in self.all_envs.values(): for x in env[CFG_FILES]: node = self.srcnode.find_resource(x) if node: precious.add(node.id) def clean_rec(node): for x in list(node.childs.keys()): nd = node.childs[x] tp = nd.id & 3 if tp == Node.DIR: clean_rec(nd) elif tp == Node.BUILD: if nd.id in precious: continue for env in self.all_envs.values(): try: os.remove(nd.abspath(env)) except OSError: pass node.childs.__delitem__(x) clean_rec(self.srcnode) for v in 'node_sigs node_deps task_sigs raw_deps cache_node_abspath'.split( ): setattr(self, v, {}) def compile(self): """The cache file is not written if nothing was build at all (build is up to date)""" debug('build: compile called') """ import cProfile, pstats cProfile.run("import Build\nBuild.bld.flush()", 'profi.txt') p = pstats.Stats('profi.txt') p.sort_stats('cumulative').print_stats(80) """ self.flush() #""" self.generator = Runner.Parallel(self, Options.options.jobs) def dw(on=True): if Options.options.progress_bar: if on: sys.stderr.write(Logs.colors.cursor_on) else: sys.stderr.write(Logs.colors.cursor_off) debug('build: executor starting') back = os.getcwd() os.chdir(self.bldnode.abspath()) try: try: dw(on=False) self.generator.start() except KeyboardInterrupt: dw() if Runner.TaskConsumer.consumers: self.save() raise except Exception: dw() # do not store anything, for something bad happened raise else: dw() if Runner.TaskConsumer.consumers: self.save() if self.generator.error: raise BuildError(self, self.task_manager.tasks_done) finally: os.chdir(back) def install(self): "this function is called for both install and uninstall" debug('build: install called') self.flush() # remove empty folders after uninstalling if self.is_install < 0: lst = [] for x in self.uninstall: dir = os.path.dirname(x) if not dir in lst: lst.append(dir) lst.sort() lst.reverse() nlst = [] for y in lst: x = y while len(x) > 4: if not x in nlst: nlst.append(x) x = os.path.dirname(x) nlst.sort() nlst.reverse() for x in nlst: try: os.rmdir(x) except OSError: pass def new_task_gen(self, *k, **kw): if self.task_gen_cache_names: self.task_gen_cache_names = {} kw['bld'] = self if len(k) == 0: ret = TaskGen.task_gen(*k, **kw) else: cls_name = k[0] try: cls = TaskGen.task_gen.classes[cls_name] except KeyError: raise Utils.WscriptError( '%s is not a valid task generator -> %s' % (cls_name, [x for x in TaskGen.task_gen.classes])) ret = cls(*k, **kw) return ret def __call__(self, *k, **kw): if self.task_gen_cache_names: self.task_gen_cache_names = {} kw['bld'] = self return TaskGen.task_gen(*k, **kw) def load_envs(self): try: lst = Utils.listdir(self.cachedir) except OSError, e: if e.errno == errno.ENOENT: raise Utils.WafError( 'The project was not configured: run "waf configure" first!' ) else: raise if not lst: raise Utils.WafError( 'The cache directory is empty: reconfigure the project') for file in lst: if file.endswith(CACHE_SUFFIX): env = Environment.Environment(os.path.join( self.cachedir, file)) name = file[:-len(CACHE_SUFFIX)] self.all_envs[name] = env self.init_variants() for env in self.all_envs.values(): for f in env[CFG_FILES]: newnode = self.path.find_or_declare(f) try: hash = Utils.h_file(newnode.abspath(env)) except (IOError, AttributeError): error("cannot find " + f) hash = SIG_NIL self.node_sigs[env.variant()][newnode.id] = hash # TODO: hmmm, these nodes are removed from the tree when calling rescan() self.bldnode = self.root.find_dir(self.bldnode.abspath()) self.path = self.srcnode = self.root.find_dir(self.srcnode.abspath()) self.cwd = self.bldnode.abspath()
def tex_build(task, command='LATEX'): env = task.env bld = task.generator.bld if not env['PROMPT_LATEX']: env.append_value('LATEXFLAGS', '-interaction=batchmode') env.append_value('PDFLATEXFLAGS', '-interaction=batchmode') fun = latex_fun if command == 'PDFLATEX': fun = pdflatex_fun node = task.inputs[0] reldir = node.bld_dir(env) #lst = [] #for c in Utils.split_path(reldir): # if c: lst.append('..') #srcfile = os.path.join(*(lst + [node.srcpath(env)])) #sr2 = os.path.join(*(lst + [node.parent.srcpath(env)])) srcfile = node.abspath(env) sr2 = node.parent.abspath() + os.pathsep + node.parent.abspath(env) + os.pathsep aux_node = node.change_ext('.aux') idx_node = node.change_ext('.idx') nm = aux_node.name docuname = nm[ : len(nm) - 4 ] # 4 is the size of ".aux" # important, set the cwd for everybody task.cwd = task.inputs[0].parent.abspath(task.env) warn('first pass on %s' % command) task.env.env = {'TEXINPUTS': sr2} task.env.SRCFILE = srcfile ret = fun(task) if ret: return ret # look in the .aux file if there is a bibfile to process try: ct = Utils.readf(aux_node.abspath(env)) except (OSError, IOError): error('error bibtex scan') else: fo = g_bibtex_re.findall(ct) # there is a .aux file to process if fo: warn('calling bibtex') task.env.env = {'BIBINPUTS': sr2, 'BSTINPUTS': sr2} task.env.SRCFILE = docuname ret = bibtex_fun(task) if ret: error('error when calling bibtex %s' % docuname) return ret # look on the filesystem if there is a .idx file to process try: idx_path = idx_node.abspath(env) os.stat(idx_path) except OSError: error('error file.idx scan') else: warn('calling makeindex') task.env.SRCFILE = idx_node.name task.env.env = {} ret = makeindex_fun(task) if ret: error('error when calling makeindex %s' % idx_path) return ret hash = '' i = 0 while i < 10: # prevent against infinite loops - one never knows i += 1 # watch the contents of file.aux prev_hash = hash try: hash = Utils.h_file(aux_node.abspath(env)) except KeyError: error('could not read aux.h -> %s' % aux_node.abspath(env)) pass # debug #print "hash is, ", hash, " ", old_hash # stop if file.aux does not change anymore if hash and hash == prev_hash: break # run the command warn('calling %s' % command) task.env.env = {'TEXINPUTS': sr2 + os.pathsep} task.env.SRCFILE = srcfile ret = fun(task) if ret: error('error when calling %s %s' % (command, latex_fun)) return ret return None # ok
def add_moc_tasks(self): node = self.inputs[0] tree = node.__class__.bld try: # compute the signature once to know if there is a moc file to create self.signature() except KeyError: # the moc file may be referenced somewhere else pass else: # remove the signature, it must be recomputed with the moc task delattr(self, 'cache_sig') moctasks=[] mocfiles=[] variant = node.variant(self.env) try: tmp_lst = tree.raw_deps[self.unique_id()] tree.raw_deps[self.unique_id()] = [] except KeyError: tmp_lst = [] for d in tmp_lst: if not d.endswith('.moc'): continue # paranoid check if d in mocfiles: error("paranoia owns") continue # process that base.moc only once mocfiles.append(d) # find the extension (performed only when the .cpp has changes) base2 = d[:-4] for path in [node.parent] + self.generator.env['INC_PATHS']: tree.rescan(path) vals = getattr(Options.options, 'qt_header_ext', '') or MOC_H for ex in vals: h_node = path.find_resource(base2 + ex) if h_node: break else: continue break else: raise Utils.WafError("no header found for %s which is a moc file" % str(d)) m_node = h_node.change_ext('.moc') tree.node_deps[(self.inputs[0].parent.id, self.env.variant(), m_node.name)] = h_node # create the task task = Task.TaskBase.classes['moc'](self.env, normal=0) task.set_inputs(h_node) task.set_outputs(m_node) generator = tree.generator generator.outstanding.insert(0, task) generator.total += 1 moctasks.append(task) # remove raw deps except the moc files to save space (optimization) tmp_lst = tree.raw_deps[self.unique_id()] = mocfiles # look at the file inputs, it is set right above lst = tree.node_deps.get(self.unique_id(), ()) for d in lst: name = d.name if name.endswith('.moc'): task = Task.TaskBase.classes['moc'](self.env, normal=0) task.set_inputs(tree.node_deps[(self.inputs[0].parent.id, self.env.variant(), name)]) # 1st element in a tuple task.set_outputs(d) generator = tree.generator generator.outstanding.insert(0, task) generator.total += 1 moctasks.append(task) # simple scheduler dependency: run the moc task before others self.run_after = moctasks self.moc_done = 1
def add_moc_tasks(self): node = self.inputs[0] tree = node.__class__.bld try: # compute the signature once to know if there is a moc file to create self.signature() except KeyError: # the moc file may be referenced somewhere else pass else: # remove the signature, it must be recomputed with the moc task delattr(self, 'cache_sig') moctasks = [] mocfiles = [] variant = node.variant(self.env) try: tmp_lst = tree.raw_deps[self.unique_id()] tree.raw_deps[self.unique_id()] = [] except KeyError: tmp_lst = [] for d in tmp_lst: if not d.endswith('.moc'): continue # paranoid check if d in mocfiles: error("paranoia owns") continue # process that base.moc only once mocfiles.append(d) # find the extension - this search is done only once ext = '' try: ext = Options.options.qt_header_ext except AttributeError: pass if not ext: base2 = d[:-4] paths = [ node.parent.srcpath(self.env), node.parent.bldpath(self.env) ] poss = [(x, y) for x in MOC_H for y in paths] for (i, path) in poss: try: # TODO we could use find_resource os.stat(os.path.join(path, base2 + i)) except OSError: pass else: ext = i break if not ext: raise Utils.WafError( "no header found for %s which is a moc file" % str(d)) # next time we will not search for the extension (look at the 'for' loop below) h_node = node.parent.find_resource(base2 + i) m_node = h_node.change_ext('.moc') tree.node_deps[(self.inputs[0].parent.id, self.env.variant(), m_node.name)] = h_node # create the task task = Task.TaskBase.classes['moc'](self.env, normal=0) task.set_inputs(h_node) task.set_outputs(m_node) generator = tree.generator generator.outstanding.insert(0, task) generator.total += 1 moctasks.append(task) # remove raw deps except the moc files to save space (optimization) tmp_lst = tree.raw_deps[self.unique_id()] = mocfiles # look at the file inputs, it is set right above lst = tree.node_deps.get(self.unique_id(), ()) for d in lst: name = d.name if name.endswith('.moc'): task = Task.TaskBase.classes['moc'](self.env, normal=0) task.set_inputs( tree.node_deps[(self.inputs[0].parent.id, self.env.variant(), name)]) # 1st element in a tuple task.set_outputs(d) generator = tree.generator generator.outstanding.insert(0, task) generator.total += 1 moctasks.append(task) # simple scheduler dependency: run the moc task before others self.run_after = moctasks self.moc_done = 1
def tex_build(task, command='LATEX'): env = task.env bld = task.generator.bld com = '%s %s' % (env[command], env.get_flat(command + 'FLAGS')) if not env['PROMPT_LATEX']: com = "%s %s" % (com, '-interaction=batchmode') node = task.inputs[0] reldir = node.bld_dir(env) srcfile = node.srcpath(env) lst = [] for c in Utils.split_path(reldir): if c: lst.append('..') sr = os.path.join(*(lst + [srcfile])) sr2 = os.path.join(*(lst + [node.parent.srcpath(env)])) aux_node = node.change_ext('.aux') idx_node = node.change_ext('.idx') hash = '' old_hash = '' nm = aux_node.name docuname = nm[:len(nm) - 4] # 4 is the size of ".aux" latex_compile_cmd = 'cd %s && TEXINPUTS=%s:$TEXINPUTS %s %s' % ( reldir, sr2, com, sr) warn('first pass on %s' % command) ret = bld.exec_command(latex_compile_cmd) if ret: return ret # look in the .aux file if there is a bibfile to process try: ct = Utils.readf(aux_node.abspath(env)) except (OSError, IOError): error('error bibtex scan') else: fo = g_bibtex_re.findall(ct) # yes, there is a .aux file to process if fo: bibtex_compile_cmd = 'cd %s && BIBINPUTS=%s:$BIBINPUTS %s %s' % ( reldir, sr2, env['BIBTEX'], docuname) warn('calling bibtex') ret = bld.exec_command(bibtex_compile_cmd) if ret: error('error when calling bibtex %s' % bibtex_compile_cmd) return ret # look on the filesystem if there is a .idx file to process try: idx_path = idx_node.abspath(env) os.stat(idx_path) except OSError: error('error file.idx scan') else: makeindex_compile_cmd = 'cd %s && %s %s' % (reldir, env['MAKEINDEX'], idx_path) warn('calling makeindex') ret = bld.exec_command(makeindex_compile_cmd) if ret: error('error when calling makeindex %s' % makeindex_compile_cmd) return ret i = 0 while i < 10: # prevent against infinite loops - one never knows i += 1 # watch the contents of file.aux old_hash = hash try: hash = Utils.h_file(aux_node.abspath(env)) except KeyError: error('could not read aux.h -> %s' % aux_node.abspath(env)) pass # debug #print "hash is, ", hash, " ", old_hash # stop if file.aux does not change anymore if hash and hash == old_hash: break # run the command warn('calling %s' % command) ret = bld.exec_command(latex_compile_cmd) if ret: error('error when calling %s %s' % (command, latex_compile_cmd)) return ret # 0 means no error return 0
def filter_comments(filename): txt = Utils.readf(filename) buf = [] i = 0 max = len(txt) while i < max: c = txt[i] if c == '"': i += 1 c = '' while i < max: p = c c = txt[i] i += 1 if i == max: return buf if c == '"': cnt = 0 while i < cnt and i < max: if txt[i - 2 - cnt] == '\\': cnt += 1 else: break if (cnt % 2) == 0: break i += 1 elif c == "'": i += 1 if i == max: return buf c = txt[i] if c == '\\': i += 1 if i == max: return buf c = txt[i] if c == 'x': i += 2 elif c == 'u': i += 4 i += 1 if i == max: return buf c = txt[i] if c != '\'': error("uh-oh, invalid character") elif c == '/': if i == max: break c = txt[i + 1] if c == '+': i += 1 nesting = 1 prev = 0 while i < max: c = txt[i] if c == '+': prev = 1 elif c == '/': if prev: nesting -= 1 if nesting == 0: break else: if i < max: i += 1 c = txt[i] if c == '+': nesting += 1 else: return buf else: prev = 0 i += 1 elif c == '*': i += 1 while i < max: c = txt[i] if c == '*': prev = 1 elif c == '/': if prev: break else: prev = 0 i += 1 elif c == '/': i += 1 c = txt[i] while i < max and c != '\n': i += 1 c = txt[i] else: buf.append(c) i += 1 return buf
class BuildContext(Utils.Context): def __init__(self): global bld bld = self self.task_manager = Task.TaskManager() self.id_nodes = 0 self.idx = {} self.all_envs = {} self.bdir = '' self.path = None self.deps_man = Utils.DefaultDict(list) self.cache_node_abspath = {} self.cache_scanned_folders = {} self.uninstall = [] for v in 'cache_node_abspath task_sigs node_deps raw_deps node_sigs'.split( ): var = {} setattr(self, v, var) self.cache_dir_contents = {} self.all_task_gen = [] self.task_gen_cache_names = {} self.cache_sig_vars = {} self.log = None self.root = None self.srcnode = None self.bldnode = None class node_class(Node.Node): pass self.node_class = node_class self.node_class.__module__ = "Node" self.node_class.__name__ = "Nodu" self.node_class.bld = self self.is_install = None def __copy__(self): raise Utils.WafError('build contexts are not supposed to be cloned') def load(self): try: env = Environment.Environment( os.path.join(self.cachedir, 'build.config.py')) except (IOError, OSError): pass else: if env['version'] < HEXVERSION: raise Utils.WafError( 'Version mismatch! reconfigure the project') for t in env['tools']: self.setup(**t) try: gc.disable() f = data = None Node.Nodu = self.node_class try: f = open(os.path.join(self.bdir, DBFILE), 'rb') except (IOError, EOFError): pass try: if f: data = cPickle.load(f) except AttributeError: if Logs.verbose > 1: raise if data: for x in SAVED_ATTRS: setattr(self, x, data[x]) else: debug('build: Build cache loading failed') finally: if f: f.close() gc.enable() def save(self): gc.disable() self.root.__class__.bld = None Node.Nodu = self.node_class db = os.path.join(self.bdir, DBFILE) file = open(db + '.tmp', 'wb') data = {} for x in SAVED_ATTRS: data[x] = getattr(self, x) cPickle.dump(data, file, -1) file.close() try: os.unlink(db) except OSError: pass os.rename(db + '.tmp', db) self.root.__class__.bld = self gc.enable() def clean(self): debug('build: clean called') precious = set([]) for env in self.all_envs.values(): for x in env[CFG_FILES]: node = self.srcnode.find_resource(x) if node: precious.add(node.id) def clean_rec(node): for x in list(node.childs.keys()): nd = node.childs[x] tp = nd.id & 3 if tp == Node.DIR: clean_rec(nd) elif tp == Node.BUILD: if nd.id in precious: continue for env in self.all_envs.values(): try: os.remove(nd.abspath(env)) except OSError: pass node.childs.__delitem__(x) clean_rec(self.srcnode) for v in 'node_sigs node_deps task_sigs raw_deps cache_node_abspath'.split( ): setattr(self, v, {}) def compile(self): debug('build: compile called') self.flush() self.generator = Runner.Parallel(self, Options.options.jobs) def dw(on=True): if Options.options.progress_bar: if on: sys.stderr.write(Logs.colors.cursor_on) else: sys.stderr.write(Logs.colors.cursor_off) debug('build: executor starting') back = os.getcwd() os.chdir(self.bldnode.abspath()) try: try: dw(on=False) self.generator.start() except KeyboardInterrupt: dw() self.save() raise except Exception: dw() raise else: dw() self.save() if self.generator.error: raise BuildError(self, self.task_manager.tasks_done) finally: os.chdir(back) def install(self): debug('build: install called') self.flush() if self.is_install < 0: lst = [] for x in self.uninstall: dir = os.path.dirname(x) if not dir in lst: lst.append(dir) lst.sort() lst.reverse() nlst = [] for y in lst: x = y while len(x) > 4: if not x in nlst: nlst.append(x) x = os.path.dirname(x) nlst.sort() nlst.reverse() for x in nlst: try: os.rmdir(x) except OSError: pass def new_task_gen(self, *k, **kw): if self.task_gen_cache_names: self.task_gen_cache_names = {} kw['bld'] = self if len(k) == 0: ret = TaskGen.task_gen(*k, **kw) else: cls_name = k[0] try: cls = TaskGen.task_gen.classes[cls_name] except KeyError: raise Utils.WscriptError( '%s is not a valid task generator -> %s' % (cls_name, [x for x in TaskGen.task_gen.classes])) ret = cls(*k, **kw) return ret def __call__(self, *k, **kw): if self.task_gen_cache_names: self.task_gen_cache_names = {} kw['bld'] = self return TaskGen.task_gen(*k, **kw) def load_envs(self): try: lst = Utils.listdir(self.cachedir) except OSError, e: if e.errno == errno.ENOENT: raise Utils.WafError( 'The project was not configured: run "waf configure" first!' ) else: raise if not lst: raise Utils.WafError( 'The cache directory is empty: reconfigure the project') for file in lst: if file.endswith(CACHE_SUFFIX): env = Environment.Environment(os.path.join( self.cachedir, file)) name = file[:-len(CACHE_SUFFIX)] self.all_envs[name] = env self.init_variants() for env in self.all_envs.values(): for f in env[CFG_FILES]: newnode = self.path.find_or_declare(f) try: hash = Utils.h_file(newnode.abspath(env)) except (IOError, AttributeError): error("cannot find " + f) hash = SIG_NIL self.node_sigs[env.variant()][newnode.id] = hash self.bldnode = self.root.find_dir(self.bldnode.abspath()) self.path = self.srcnode = self.root.find_dir(self.srcnode.abspath()) self.cwd = self.bldnode.abspath()
def tex_build(task, command='LATEX'): env = task.env bld = task.generator.bld if not env['PROMPT_LATEX']: env.append_value('LATEXFLAGS', '-interaction=batchmode') env.append_value('PDFLATEXFLAGS', '-interaction=batchmode') fun = latex_fun if command == 'PDFLATEX': fun = pdflatex_fun node = task.inputs[0] reldir = node.bld_dir(env) lst = [] for c in Utils.split_path(reldir): if c: lst.append('..') srcfile = os.path.join(*(lst + [node.srcpath(env)])) sr2 = os.path.join(*(lst + [node.parent.srcpath(env)])) aux_node = node.change_ext('.aux') idx_node = node.change_ext('.idx') nm = aux_node.name docuname = nm[:len(nm) - 4] task.cwd = task.inputs[0].parent.abspath(task.env) warn('first pass on %s' % command) task.env.env = {'TEXINPUTS': sr2 + os.pathsep} task.env.SRCFILE = srcfile ret = fun(task) if ret: return ret try: ct = Utils.readf(aux_node.abspath(env)) except (OSError, IOError): error('error bibtex scan') else: fo = g_bibtex_re.findall(ct) if fo: warn('calling bibtex') task.env.env = { 'BIBINPUTS': sr2 + os.pathsep, 'BSTINPUTS': sr2 + os.pathsep } task.env.SRCFILE = docuname ret = bibtex_fun(task) if ret: error('error when calling bibtex %s' % docuname) return ret try: idx_path = idx_node.abspath(env) os.stat(idx_path) except OSError: error('error file.idx scan') else: warn('calling makeindex') task.env.SRCFILE = idx_node.name task.env.env = {} ret = makeindex_fun(task) if ret: error('error when calling makeindex %s' % idx_path) return ret hash = '' i = 0 while i < 10: i += 1 prev_hash = hash try: hash = Utils.h_file(aux_node.abspath(env)) except KeyError: error('could not read aux.h -> %s' % aux_node.abspath(env)) pass if hash and hash == prev_hash: break warn('calling %s' % command) task.env.env = {'TEXINPUTS': sr2 + os.pathsep} task.env.SRCFILE = srcfile ret = fun(task) if ret: error('error when calling %s %s' % (command, latex_compile_cmd)) return ret return None
def prepare_impl(t,cwd,ver,wafdir): Options.tooldir=[t] Options.launch_dir=cwd if'--version'in sys.argv: opt_obj=Options.Handler() opt_obj.curdir=cwd opt_obj.parse_args() sys.exit(0) msg1='Waf: Please run waf from a directory containing a file named "%s" or run distclean'%WSCRIPT_FILE build_dir_override=None candidate=None lst=os.listdir(cwd) search_for_candidate=True if WSCRIPT_FILE in lst: candidate=cwd elif'configure'in sys.argv and not WSCRIPT_BUILD_FILE in lst: calldir=os.path.abspath(os.path.dirname(sys.argv[0])) if WSCRIPT_FILE in os.listdir(calldir): candidate=calldir search_for_candidate=False else: error('arg[0] directory does not contain a wscript file') sys.exit(1) build_dir_override=cwd while search_for_candidate: if len(cwd)<=3: break dirlst=os.listdir(cwd) if WSCRIPT_FILE in dirlst: candidate=cwd if'configure'in sys.argv and candidate: break if Options.lockfile in dirlst: env=Environment.Environment() try: env.load(os.path.join(cwd,Options.lockfile)) except: error('could not load %r'%Options.lockfile) try: os.stat(env['cwd']) except: candidate=cwd else: candidate=env['cwd'] break cwd=os.path.dirname(cwd) if not candidate: if'-h'in sys.argv or'--help'in sys.argv: warn('No wscript file found: the help message may be incomplete') opt_obj=Options.Handler() opt_obj.curdir=cwd opt_obj.parse_args() else: error(msg1) sys.exit(0) try: os.chdir(candidate) except OSError: raise Utils.WafError("the folder %r is unreadable"%candidate) Utils.set_main_module(os.path.join(candidate,WSCRIPT_FILE)) if build_dir_override: d=getattr(Utils.g_module,BLDDIR,None) if d: msg=' Overriding build directory %s with %s'%(d,build_dir_override) warn(msg) Utils.g_module.blddir=build_dir_override def set_def(obj,name=''): n=name or obj.__name__ if not n in Utils.g_module.__dict__: setattr(Utils.g_module,n,obj) for k in[dist,distclean,distcheck,clean,install,uninstall]: set_def(k) set_def(Configure.ConfigurationContext,'configure_context') for k in['build','clean','install','uninstall']: set_def(Build.BuildContext,k+'_context') opt_obj=Options.Handler(Utils.g_module) opt_obj.curdir=candidate try: f=Utils.g_module.set_options except AttributeError: pass else: opt_obj.sub_options(['']) opt_obj.parse_args() if not'init'in Utils.g_module.__dict__: Utils.g_module.init=Utils.nada if not'shutdown'in Utils.g_module.__dict__: Utils.g_module.shutdown=Utils.nada main()
def prepare_impl(t, cwd, ver, wafdir): Options.tooldir = [t] Options.launch_dir = cwd # some command-line options can be processed immediately if '--version' in sys.argv: opt_obj = Options.Handler() opt_obj.curdir = cwd opt_obj.parse_args() sys.exit(0) # now find the wscript file msg1 = 'Waf: Please run waf from a directory containing a file named "%s" or run distclean' % WSCRIPT_FILE # in theory projects can be configured in an autotool-like manner: # mkdir build && cd build && ../waf configure && ../waf build_dir_override = None candidate = None lst = os.listdir(cwd) search_for_candidate = True if WSCRIPT_FILE in lst: candidate = cwd elif 'configure' in sys.argv and not WSCRIPT_BUILD_FILE in lst: # autotool-like configuration calldir = os.path.abspath(os.path.dirname(sys.argv[0])) if WSCRIPT_FILE in os.listdir(calldir): candidate = calldir search_for_candidate = False else: error('arg[0] directory does not contain a wscript file') sys.exit(1) build_dir_override = cwd # climb up to find a script if it is not found while search_for_candidate: if len(cwd) <= 3: break # stop at / or c: dirlst = os.listdir(cwd) if WSCRIPT_FILE in dirlst: candidate = cwd if 'configure' in sys.argv and candidate: break if Options.lockfile in dirlst: env = Environment.Environment() try: env.load(os.path.join(cwd, Options.lockfile)) except: error('could not load %r' % Options.lockfile) try: os.stat(env['cwd']) except: candidate = cwd else: candidate = env['cwd'] break cwd = os.path.dirname(cwd) # climb up if not candidate: # check if the user only wanted to display the help if '-h' in sys.argv or '--help' in sys.argv: warn('No wscript file found: the help message may be incomplete') opt_obj = Options.Handler() opt_obj.curdir = cwd opt_obj.parse_args() else: error(msg1) sys.exit(0) # We have found wscript, but there is no guarantee that it is valid try: os.chdir(candidate) except OSError: raise Utils.WafError("the folder %r is unreadable" % candidate) # define the main module containing the functions init, shutdown, .. Utils.set_main_module(os.path.join(candidate, WSCRIPT_FILE)) if build_dir_override: d = getattr(Utils.g_module, BLDDIR, None) if d: # test if user has set the blddir in wscript. msg = ' Overriding build directory %s with %s' % ( d, build_dir_override) warn(msg) Utils.g_module.blddir = build_dir_override # bind a few methods and classes by default def set_def(obj, name=''): n = name or obj.__name__ if not n in Utils.g_module.__dict__: setattr(Utils.g_module, n, obj) for k in [dist, distclean, distcheck, clean, install, uninstall]: set_def(k) set_def(Configure.ConfigurationContext, 'configure_context') for k in ['build', 'clean', 'install', 'uninstall']: set_def(Build.BuildContext, k + '_context') # now parse the options from the user wscript file opt_obj = Options.Handler(Utils.g_module) opt_obj.curdir = candidate try: f = Utils.g_module.set_options except AttributeError: pass else: opt_obj.sub_options(['']) opt_obj.parse_args() if not 'init' in Utils.g_module.__dict__: Utils.g_module.init = Utils.nada if not 'shutdown' in Utils.g_module.__dict__: Utils.g_module.shutdown = Utils.nada main()