Beispiel #1
0
 def put_files_cache(self):
     if getattr(self, "cached", None):
         return None
     sig = self.signature()
     ssig = Utils.to_hex(self.uid()) + Utils.to_hex(sig)
     dname = os.path.join(self.generator.bld.cache_global, ssig)
     tmpdir = tempfile.mkdtemp(prefix=self.generator.bld.cache_global + os.sep + "waf")
     try:
         shutil.rmtree(dname)
     except:
         pass
     try:
         for node in self.outputs:
             dest = os.path.join(tmpdir, node.name)
             shutil.copy2(node.abspath(), dest)
     except (OSError, IOError):
         try:
             shutil.rmtree(tmpdir)
         except:
             pass
     else:
         try:
             os.rename(tmpdir, dname)
         except OSError:
             try:
                 shutil.rmtree(tmpdir)
             except:
                 pass
         else:
             try:
                 os.chmod(dname, Utils.O755)
             except:
                 pass
Beispiel #2
0
 def can_retrieve_cache(self):
     if not getattr(self, "outputs", None):
         return None
     sig = self.signature()
     ssig = Utils.to_hex(self.uid()) + Utils.to_hex(sig)
     dname = os.path.join(self.generator.bld.cache_global, ssig)
     try:
         t1 = os.stat(dname).st_mtime
     except OSError:
         return None
     for node in self.outputs:
         orig = os.path.join(dname, node.name)
         try:
             shutil.copy2(orig, node.abspath())
             os.utime(orig, None)
         except (OSError, IOError):
             Logs.debug("task: failed retrieving file")
             return None
     try:
         t2 = os.stat(dname).st_mtime
     except OSError:
         return None
     if t1 != t2:
         return None
     for node in self.outputs:
         node.sig = sig
         if self.generator.bld.progress_bar < 1:
             self.generator.bld.to_log("restoring from cache %r\n" % node.abspath())
     self.cached = True
     return True
Beispiel #3
0
 def can_retrieve_cache(self):
     if not getattr(self, 'outputs', None):
         return None
     sig = self.signature()
     ssig = Utils.to_hex(self.uid()) + Utils.to_hex(sig)
     dname = os.path.join(self.generator.bld.cache_global, ssig)
     try:
         t1 = os.stat(dname).st_mtime
     except OSError:
         return None
     for node in self.outputs:
         orig = os.path.join(dname, node.name)
         try:
             shutil.copy2(orig, node.abspath())
             os.utime(orig, None)
         except (OSError, IOError):
             Logs.debug('task: failed retrieving file')
             return None
     try:
         t2 = os.stat(dname).st_mtime
     except OSError:
         return None
     if t1 != t2:
         return None
     for node in self.outputs:
         node.sig = sig
         if self.generator.bld.progress_bar < 1:
             self.generator.bld.to_log('restoring from cache %r\n' %
                                       node.abspath())
     self.cached = True
     return True
Beispiel #4
0
 def put_files_cache(self):
     if getattr(self, 'cached', None):
         return None
     sig = self.signature()
     ssig = Utils.to_hex(self.uid()) + Utils.to_hex(sig)
     dname = os.path.join(self.generator.bld.cache_global, ssig)
     tmpdir = tempfile.mkdtemp(prefix=self.generator.bld.cache_global +
                               os.sep + 'waf')
     try:
         shutil.rmtree(dname)
     except:
         pass
     try:
         for node in self.outputs:
             dest = os.path.join(tmpdir, node.name)
             shutil.copy2(node.abspath(), dest)
     except (OSError, IOError):
         try:
             shutil.rmtree(tmpdir)
         except:
             pass
     else:
         try:
             os.rename(tmpdir, dname)
         except OSError:
             try:
                 shutil.rmtree(tmpdir)
             except:
                 pass
         else:
             try:
                 os.chmod(dname, Utils.O755)
             except:
                 pass
Beispiel #5
0
    def can_retrieve_cache(self):
        """
		Used by :py:meth:`waflib.Task.cache_outputs`

		Retrieve build nodes from the cache
		update the file timestamps to help cleaning the least used entries from the cache
		additionally, set an attribute 'cached' to avoid re-creating the same cache files

		Suppose there are files in `cache/dir1/file1` and `cache/dir2/file2`:

		#. read the timestamp of dir1
		#. try to copy the files
		#. look at the timestamp again, if it has changed, the data may have been corrupt (cache update by another process)
		#. should an exception occur, ignore the data
		"""

        if not getattr(self, 'outputs', None):
            return None

        sig = self.signature()
        ssig = Utils.to_hex(self.uid()) + Utils.to_hex(sig)

        # first try to access the cache folder for the task
        dname = os.path.join(self.generator.bld.cache_global, ssig)
        try:
            t1 = os.stat(dname).st_mtime
        except OSError:
            return None

        for node in self.outputs:
            orig = os.path.join(dname, node.name)
            try:
                shutil.copy2(orig, node.abspath())
                # mark the cache file as used recently (modified)
                os.utime(orig, None)
            except (OSError, IOError):
                Logs.debug('task: failed retrieving file')
                return None

        # is it the same folder?
        try:
            t2 = os.stat(dname).st_mtime
        except OSError:
            return None

        if t1 != t2:
            return None

        for node in self.outputs:
            node.sig = sig
            if self.generator.bld.progress_bar < 1:
                self.generator.bld.to_log('restoring from cache %r\n' %
                                          node.abspath())

        self.cached = True
        return True
	def can_retrieve_cache(self):
		"""
		Used by :py:meth:`waflib.Task.cache_outputs`

		Retrieve build nodes from the cache
		update the file timestamps to help cleaning the least used entries from the cache
		additionally, set an attribute 'cached' to avoid re-creating the same cache files

		Suppose there are files in `cache/dir1/file1` and `cache/dir2/file2`:

		#. read the timestamp of dir1
		#. try to copy the files
		#. look at the timestamp again, if it has changed, the data may have been corrupt (cache update by another process)
		#. should an exception occur, ignore the data
		"""

		if not getattr(self, 'outputs', None):
			return None

		sig = self.signature()
		ssig = Utils.to_hex(self.uid()) + Utils.to_hex(sig)

		# first try to access the cache folder for the task
		dname = os.path.join(self.generator.bld.cache_global, ssig)
		try:
			t1 = os.stat(dname).st_mtime
		except OSError:
			return None

		for node in self.outputs:
			orig = os.path.join(dname, node.name)
			try:
				shutil.copy2(orig, node.abspath())
				# mark the cache file as used recently (modified)
				os.utime(orig, None)
			except (OSError, IOError):
				Logs.debug('task: failed retrieving file')
				return None

		# is it the same folder?
		try:
			t2 = os.stat(dname).st_mtime
		except OSError:
			return None

		if t1 != t2:
			return None

		for node in self.outputs:
			node.sig = sig
			if self.generator.bld.progress_bar < 1:
				self.generator.bld.to_log('restoring from cache %r\n' % node.abspath())

		self.cached = True
		return True
Beispiel #7
0
def put_files_cache(self):
    """
    Used by :py:func:`waflib.Task.cache_outputs` to store the build files in the cache
    """

    # file caching, if possible
    # try to avoid data corruption as much as possible
    if not isinstance(self.generator.bld, Build.BuildContext):
        return

    if hasattr(self, 'cached'):
        return

    sig = self.signature()
    ssig = Utils.to_hex(self.uid()) + Utils.to_hex(sig)
    dname = os.path.join(self.generator.bld.artifacts_cache, ssig)
    dname_tmp = dname + '_tmp'

    if os.path.exists(dname) or os.path.exists(dname_tmp):
        return
    else:
        try:
            os.makedirs(dname_tmp)
        except OSError:
            return

    for node in self.outputs:
        dest = os.path.join(dname_tmp, node.name)
        dest = Utils.extended_path(dest)
        try:
            if Utils.is_win32:
                os.system('copy {} {} /Y>nul'.format(node.abspath(), dest))
            else:
                os.system('cp -f {} {}'.format(node.abspath(), dest))
        except Exception as e:
            Logs.warn(
                '[WARN] task: failed caching file {} due to exception\n {}\n'.
                format(dest, e))
            return

    try:
        os.utime(dname_tmp, None)
        os.chmod(dname_tmp, Utils.O755)
        if Utils.is_win32:
            # For rename in Windows, target path cannot be full path, it will remain in the same folder with source path
            os.system('rename {} {}'.format(dname_tmp, ssig))
        else:
            os.system('mv {} {}'.format(dname_tmp, dname))
    except Exception as e:
        Logs.warn(
            '[WARN] task: failed updating timestamp/permission for cached outputs folder for task signature {} due to exception\n {}\n'
            .format(dname, e))
        pass

    self.cached = True
Beispiel #8
0
def rsync_and_ssh(task):

	# remove a warning
	task.uid_ = id(task)

	bld = task.generator.bld

	task.env.user, _, _ = task.env.login.partition('@')
	task.env.hdir = Utils.to_hex(Utils.h_list((task.generator.path.abspath(), task.env.variant)))
	task.env.remote_dir = '~%s/wafremote/%s' % (task.env.user, task.env.hdir)
	task.env.local_dir = bld.srcnode.abspath() + '/'

	task.env.remote_dir_variant = '%s/%s/%s' % (task.env.remote_dir, Context.g_module.out, task.env.variant)
	task.env.build_dir = bld.bldnode.abspath()

	ret = task.exec_command(bld.make_mkdir_command(task))
	if ret:
		return ret
	ret = task.exec_command(bld.make_send_command(task))
	if ret:
		return ret
	ret = task.exec_command(bld.make_exec_command(task))
	if ret:
		return ret
	ret = task.exec_command(bld.make_save_command(task))
	if ret:
		return ret
def rsync_and_ssh(task):

    # remove a warning
    task.uid_ = id(task)

    bld = task.generator.bld

    task.env.user, _, _ = task.env.login.partition("@")
    task.env.hdir = Utils.to_hex(
        Utils.h_list((task.generator.path.abspath(), task.env.variant)))
    task.env.remote_dir = f"~{task.env.user}/wafremote/{task.env.hdir}"
    task.env.local_dir = bld.srcnode.abspath() + "/"

    task.env.remote_dir_variant = f"{task.env.remote_dir}/{Context.g_module.out}/{task.env.variant}"
    task.env.build_dir = bld.bldnode.abspath()

    ret = task.exec_command(bld.make_mkdir_command(task))
    if ret:
        return ret
    ret = task.exec_command(bld.make_send_command(task))
    if ret:
        return ret
    ret = task.exec_command(bld.make_exec_command(task))
    if ret:
        return ret
    ret = task.exec_command(bld.make_save_command(task))
    if ret:
        return ret
Beispiel #10
0
def hash_env_vars(self, env, vars_lst):
    """
    Override env signature computation, and make it to be engine path and 3rdParty path independent.
    """
    if not env.table:
        env = env.parent
        if not env:
            return Utils.SIG_NIL

    idx = str(id(env)) + str(vars_lst)
    try:
        cache = self.cache_env
    except AttributeError:
        cache = self.cache_env = {}
    else:
        try:
            return self.cache_env[idx]
        except KeyError:
            pass

    lst = [
        env[x] for x in vars_lst
        if x not in ['INCLUDES', 'INCPATHS', 'LIBPATH', 'STLIBPATH']
    ]
    env_str = replace_engine_path_and_tp_root_in_string(self, str(lst))
    m = Utils.md5()
    m.update(env_str.encode())
    ret = m.digest()
    Logs.debug('envhash: %s %r', Utils.to_hex(ret), lst)

    cache[idx] = ret

    return ret
Beispiel #11
0
def put_files_cache(self):
    """
	New method for waf Task classes
	"""
    if WAFCACHE_NO_PUSH or getattr(self, 'cached', None) or not self.outputs:
        return

    bld = self.generator.bld
    sig = self.signature()
    ssig = Utils.to_hex(self.uid() + sig)

    files_from = [node.abspath() for node in self.outputs]
    err = cache_command(ssig, files_from, [])

    if err.startswith(OK):
        if WAFCACHE_VERBOSITY:
            Logs.pprint('CYAN',
                        '  Successfully uploaded %s to cache' % files_from)
        else:
            Logs.debug('wafcache: Successfully uploaded %r to cache',
                       files_from)
    else:
        if WAFCACHE_VERBOSITY:
            Logs.pprint(
                'RED',
                '  Error caching step results %s: %s' % (files_from, err))
        else:
            Logs.debug('wafcache: Error caching results %s: %s', files_from,
                       err)

    bld.task_sigs[self.uid()] = self.cache_sig
Beispiel #12
0
def put_files_cache(self):
    if not Task.push_addr:
        return
    if not self.outputs:
        return
    if getattr(self, 'cached', None):
        return

    #print "called put_files_cache", id(self)
    bld = self.generator.bld
    sig = self.signature()
    ssig = Utils.to_hex(self.uid() + sig)

    conn = None
    cnt = 0
    try:
        for node in self.outputs:
            # We could re-create the signature of the task with the signature of the outputs
            # in practice, this means hashing the output files
            # this is unnecessary
            try:
                if not conn:
                    conn = get_connection(push=True)
                sock_send(conn, ssig, cnt, node.abspath())
            except Exception as e:
                Logs.debug("netcache: could not push the files %r" % e)

                # broken connection? remove this one
                close_connection(conn)
                conn = None
            cnt += 1
    finally:
        release_connection(conn, push=True)

    bld.task_sigs[self.uid()] = self.cache_sig
Beispiel #13
0
def can_retrieve_cache(self):
    """
	New method for waf Task classes
	"""
    if not self.outputs:
        return False

    self.cached = False

    sig = self.signature()
    ssig = Utils.to_hex(self.uid() + sig)

    if WAFCACHE_STATS:
        self.generator.bld.cache_reqs += 1

    files_to = [node.abspath() for node in self.outputs]
    err = cache_command(ssig, [], files_to)
    if err.startswith(OK):
        if WAFCACHE_VERBOSITY:
            Logs.pprint('CYAN', '  Fetched %r from cache' % files_to)
        else:
            Logs.debug('wafcache: fetched %r from cache', files_to)
        if WAFCACHE_STATS:
            self.generator.bld.cache_hits += 1
    else:
        if WAFCACHE_VERBOSITY:
            Logs.pprint('YELLOW', '  No cache entry %s' % files_to)
        else:
            Logs.debug('wafcache: No cache entry %s: %s', files_to, err)
        return False

    self.cached = True
    return True
Beispiel #14
0
	def hash_env_vars(self, env, vars_lst):
		"""
		Hashes configuration set variables::

			def build(bld):
				bld.hash_env_vars(bld.env, ['CXX', 'CC'])

		This method uses an internal cache.

		:param env: Configuration Set
		:type env: :py:class:`waflib.ConfigSet.ConfigSet`
		:param vars_lst: list of variables
		:type vars_list: list of string
		"""

		if not env.table:
			env = env.parent
			if not env:
				return Utils.SIG_NIL

		idx = str(id(env)) + str(vars_lst)
		try:
			cache = self.cache_env
		except AttributeError:
			cache = self.cache_env = {}
		else:
			try:
				return self.cache_env[idx]
			except KeyError:
				pass

		lst = [env[a] for a in vars_lst]
		cache[idx] = ret = Utils.h_list(lst)
		Logs.debug('envhash: %s %r', Utils.to_hex(ret), lst)
		return ret
    def hash_env_vars(self, env, vars_lst):
        """
		Hashes configuration set variables::

			def build(bld):
				bld.hash_env_vars(bld.env, ['CXX', 'CC'])

		This method uses an internal cache.

		:param env: Configuration Set
		:type env: :py:class:`waflib.ConfigSet.ConfigSet`
		:param vars_lst: list of variables
		:type vars_list: list of string
		"""

        if not env.table:
            env = env.parent
            if not env:
                return Utils.SIG_NIL

        idx = str(id(env)) + str(vars_lst)
        try:
            cache = self.cache_env
        except AttributeError:
            cache = self.cache_env = {}
        else:
            try:
                return self.cache_env[idx]
            except KeyError:
                pass

        lst = [env[a] for a in vars_lst]
        cache[idx] = ret = Utils.h_list(lst)
        Logs.debug('envhash: %s %r', Utils.to_hex(ret), lst)
        return ret
Beispiel #16
0
def put_files_cache(self):
	if not Task.push_addr:
		return
	if not self.outputs:
		return
	if getattr(self, 'cached', None):
		return

	#print "called put_files_cache", id(self)
	bld = self.generator.bld
	sig = self.signature()
	ssig = Utils.to_hex(self.uid() + sig)

	conn = None
	cnt = 0
	try:
		for node in self.outputs:
			# We could re-create the signature of the task with the signature of the outputs
			# in practice, this means hashing the output files
			# this is unnecessary
			try:
				if not conn:
					conn = get_connection(push=True)
				sock_send(conn, ssig, cnt, node.abspath())
			except Exception as e:
				Logs.debug("netcache: could not push the files %r" % e)

				# broken connection? remove this one
				close_connection(conn)
				conn = None
			cnt += 1
	finally:
		release_connection(conn, push=True)

	bld.task_sigs[self.uid()] = self.cache_sig
Beispiel #17
0
def rsync_and_ssh(task):

    # remove a warning
    task.uid_ = id(task)

    bld = task.generator.bld

    task.env.user, _, _ = task.env.login.partition('@')
    task.env.hdir = Utils.to_hex(
        Utils.h_list((task.generator.path.abspath(), task.env.variant)))
    task.env.remote_dir = '~%s/wafremote/%s' % (task.env.user, task.env.hdir)
    task.env.local_dir = bld.srcnode.abspath() + '/'

    task.env.remote_dir_variant = '%s/%s/%s' % (
        task.env.remote_dir, Context.g_module.out, task.env.variant)
    task.env.build_dir = bld.bldnode.abspath()

    ret = task.exec_command(bld.make_mkdir_command(task))
    if ret:
        return ret
    ret = task.exec_command(bld.make_send_command(task))
    if ret:
        return ret
    ret = task.exec_command(bld.make_exec_command(task))
    if ret:
        return ret
    ret = task.exec_command(bld.make_save_command(task))
    if ret:
        return ret
Beispiel #18
0
def run_c_code(self, *k, **kw):
    lst = [str(v) for (p, v) in kw.items() if p != 'env']
    h = Utils.h_list(lst)
    dir = self.bldnode.abspath() + os.sep + (
        sys.platform != 'win32' and '.'
        or '') + 'conf_check_' + Utils.to_hex(h)
    try:
        os.makedirs(dir)
    except:
        pass
    try:
        os.stat(dir)
    except:
        self.fatal('cannot use the configuration test folder %r' % dir)
    cachemode = getattr(Options.options, 'confcache', None)
    if cachemode == CACHE_RESULTS:
        try:
            proj = ConfigSet.ConfigSet(os.path.join(dir, 'cache_run_c_code'))
            ret = proj['cache_run_c_code']
        except:
            pass
        else:
            if isinstance(ret, str) and ret.startswith('Test does not build'):
                self.fatal(ret)
            return ret
    bdir = os.path.join(dir, 'testbuild')
    if not os.path.exists(bdir):
        os.makedirs(bdir)
    self.test_bld = bld = Build.BuildContext(top_dir=dir, out_dir=bdir)
    bld.init_dirs()
    bld.progress_bar = 0
    bld.targets = '*'
    if kw['compile_filename']:
        node = bld.srcnode.make_node(kw['compile_filename'])
        node.write(kw['code'])
    bld.logger = self.logger
    bld.all_envs.update(self.all_envs)
    bld.env = kw['env']
    o = bld(features=kw['features'],
            source=kw['compile_filename'],
            target='testprog')
    for k, v in kw.items():
        setattr(o, k, v)
    self.to_log("==>\n%s\n<==" % kw['code'])
    bld.targets = '*'
    ret = -1
    try:
        try:
            bld.compile()
        except Errors.WafError:
            ret = 'Test does not build: %s' % Utils.ex_stack()
            self.fatal(ret)
        else:
            ret = getattr(bld, 'retval', 0)
    finally:
        proj = ConfigSet.ConfigSet()
        proj['cache_run_c_code'] = ret
        proj.store(os.path.join(dir, 'cache_run_c_code'))
    return ret
Beispiel #19
0
    def run(self):
        tsk = self
        env = self.env
        gen = self.generator
        bld = gen.bld
        zpy = bld.zpy
        py = bld.py

        if getattr(self, 'cwd', None) is None:
            self.cwd = pth.join(bld.bldnode.abspath(), self.dist.key)

        python = bld.zippy_dist_get('python')
        self._key = '%s-%s-%s' % (python.key, python.version,
                                  Utils.to_hex(self.signature()))
        self._cache_conf = pth.join(zpy.cache_tmp, 'conf-%s' % self._key)
        self._cache_prof = pth.join(zpy.cache_tmp, 'prof-%s' % self._key)

        ret = 0
        with open(pth.join(self.cwd, 'zippy.sh'), mode='a') as fp:
            fd = fp.fileno()
            fstat = os.fstat(fd)
            fmode = fstat.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
            os.fchmod(fd, fmode)

            if fp.tell() == 0:
                fp.write('#!/bin/bash\n\n')
            fp.write('cd ' + pipes.quote(self.cwd) + '\n')
            fp.write('unset $(compgen -e)' + '\n\n')
            for k, v in sorted(env.env.iteritems()):
                v = pipes.quote(v)
                fp.write('export {0}={1}\n'.format(k, v))
            fp.write('\n')

            for app in Utils.to_list(self.app):
                if not isinstance(app, basestring):
                    fp.write('# ' + str(app))
                    ret |= app(self)
                    continue

                kwds = dict()
                if bld.zero_log:
                    kwds = {'stdout': None, 'stderr': -2}

                larg = None
                app = app.format(**locals())
                app = app.strip('\0').split('\0')
                for arg in map(pipes.quote, app):
                    if larg is not None:
                        fp.write(' \\\n    ')
                    fp.write(arg)
                    larg = arg
                fp.write('\n\n')

                ret |= self.exec_command(app,
                                         cwd=self.cwd,
                                         env=env.env or None,
                                         **kwds)

        return ret
Beispiel #20
0
def run_build(self, *k, **kw):
    lst = [str(v) for (p, v) in kw.items() if p != 'env']
    h = Utils.h_list(lst)
    dir = self.bldnode.abspath() + os.sep + (
        not Utils.is_win32 and '.' or '') + 'conf_check_' + Utils.to_hex(h)
    try:
        os.makedirs(dir)
    except OSError:
        pass
    try:
        os.stat(dir)
    except OSError:
        self.fatal('cannot use the configuration test folder %r' % dir)
    cachemode = getattr(Options.options, 'confcache', None)
    if cachemode == 1:
        try:
            proj = ConfigSet.ConfigSet(os.path.join(dir, 'cache_run_build'))
        except EnvironmentError:
            pass
        else:
            ret = proj['cache_run_build']
            if isinstance(ret, str) and ret.startswith('Test does not build'):
                self.fatal(ret)
            return ret
    bdir = os.path.join(dir, 'testbuild')
    if not os.path.exists(bdir):
        os.makedirs(bdir)
    cls_name = kw.get('run_build_cls') or getattr(self, 'run_build_cls',
                                                  'build')
    self.test_bld = bld = Context.create_context(cls_name,
                                                 top_dir=dir,
                                                 out_dir=bdir)
    bld.init_dirs()
    bld.progress_bar = 0
    bld.targets = '*'
    bld.logger = self.logger
    bld.all_envs.update(self.all_envs)
    bld.env = kw['env']
    bld.kw = kw
    bld.conf = self
    kw['build_fun'](bld)
    ret = -1
    try:
        try:
            bld.compile()
        except Errors.WafError:
            ret = 'Test does not build: %s' % traceback.format_exc()
            self.fatal(ret)
        else:
            ret = getattr(bld, 'retval', 0)
    finally:
        if cachemode == 1:
            proj = ConfigSet.ConfigSet()
            proj['cache_run_build'] = ret
            proj.store(os.path.join(dir, 'cache_run_build'))
        else:
            shutil.rmtree(dir)
    return ret
Beispiel #21
0
    def put_files_cache(self):
        """
		Used by :py:func:`waflib.Task.cache_outputs` to store the build files in the cache
		"""

        # file caching, if possible
        # try to avoid data corruption as much as possible
        if getattr(self, 'cached', None):
            return None
        if not getattr(self, 'outputs', None):
            return None

        sig = self.signature()
        ssig = Utils.to_hex(self.uid()) + Utils.to_hex(sig)
        dname = os.path.join(self.generator.bld.cache_global, ssig)
        tmpdir = tempfile.mkdtemp(prefix=self.generator.bld.cache_global +
                                  os.sep + 'waf')

        try:
            shutil.rmtree(dname)
        except Exception:
            pass

        try:
            for node in self.outputs:
                dest = os.path.join(tmpdir, node.name)
                shutil.copy2(node.abspath(), dest)
        except (OSError, IOError):
            try:
                shutil.rmtree(tmpdir)
            except Exception:
                pass
        else:
            try:
                os.rename(tmpdir, dname)
            except OSError:
                try:
                    shutil.rmtree(tmpdir)
                except Exception:
                    pass
            else:
                try:
                    os.chmod(dname, Utils.O755)
                except Exception:
                    pass
	def put_files_cache(self):
		"""
		Used by :py:func:`waflib.Task.cache_outputs` to store the build files in the cache
		"""

		# file caching, if possible
		# try to avoid data corruption as much as possible
		if getattr(self, 'cached', None):
			return None
		if not getattr(self, 'outputs', None):
			return None

		sig = self.signature()
		ssig = Utils.to_hex(self.uid()) + Utils.to_hex(sig)
		dname = os.path.join(self.generator.bld.cache_global, ssig)
		tmpdir = tempfile.mkdtemp(prefix=self.generator.bld.cache_global + os.sep + 'waf')

		try:
			shutil.rmtree(dname)
		except Exception:
			pass

		try:
			for node in self.outputs:
				dest = os.path.join(tmpdir, node.name)
				shutil.copy2(node.abspath(), dest)
		except (OSError, IOError):
			try:
				shutil.rmtree(tmpdir)
			except Exception:
				pass
		else:
			try:
				os.rename(tmpdir, dname)
			except OSError:
				try:
					shutil.rmtree(tmpdir)
				except Exception:
					pass
			else:
				try:
					os.chmod(dname, Utils.O755)
				except Exception:
					pass
Beispiel #23
0
def run_c_code(self,*k,**kw):
	lst=[str(v)for(p,v)in kw.items()if p!='env']
	h=Utils.h_list(lst)
	dir=self.bldnode.abspath()+os.sep+(not Utils.is_win32 and'.'or'')+'conf_check_'+Utils.to_hex(h)
	try:
		os.makedirs(dir)
	except OSError:
		pass
	try:
		os.stat(dir)
	except OSError:
		self.fatal('cannot use the configuration test folder %r'%dir)
	cachemode=getattr(Options.options,'confcache',None)
	if cachemode==CACHE_RESULTS:
		try:
			proj=ConfigSet.ConfigSet(os.path.join(dir,'cache_run_c_code'))
		except OSError:
			pass
		else:
			ret=proj['cache_run_c_code']
			if isinstance(ret,str)and ret.startswith('Test does not build'):
				self.fatal(ret)
			return ret
	bdir=os.path.join(dir,'testbuild')
	if not os.path.exists(bdir):
		os.makedirs(bdir)
	self.test_bld=bld=Build.BuildContext(top_dir=dir,out_dir=bdir)
	bld.init_dirs()
	bld.progress_bar=0
	bld.targets='*'
	if kw['compile_filename']:
		node=bld.srcnode.make_node(kw['compile_filename'])
		node.write(kw['code'])
	bld.logger=self.logger
	bld.all_envs.update(self.all_envs)
	bld.env=kw['env']
	o=bld(features=kw['features'],source=kw['compile_filename'],target='testprog')
	for k,v in kw.items():
		setattr(o,k,v)
	if not kw.get('quiet',None):
		self.to_log("==>\n%s\n<=="%kw['code'])
	bld.targets='*'
	ret=-1
	try:
		try:
			bld.compile()
		except Errors.WafError:
			ret='Test does not build: %s'%Utils.ex_stack()
			self.fatal(ret)
		else:
			ret=getattr(bld,'retval',0)
	finally:
		proj=ConfigSet.ConfigSet()
		proj['cache_run_c_code']=ret
		proj.store(os.path.join(dir,'cache_run_c_code'))
	return ret
def run_build(self,*k,**kw):
	lst=[str(v)for(p,v)in kw.items()if p!='env']
	h=Utils.h_list(lst)
	dir=self.bldnode.abspath()+os.sep+(not Utils.is_win32 and'.'or'')+'conf_check_'+Utils.to_hex(h)
	try:
		os.makedirs(dir)
	except OSError:
		pass
	try:
		os.stat(dir)
	except OSError:
		self.fatal('cannot use the configuration test folder %r'%dir)
	cachemode=getattr(Options.options,'confcache',None)
	if cachemode==1:
		try:
			proj=ConfigSet.ConfigSet(os.path.join(dir,'cache_run_build'))
		except OSError:
			pass
		except IOError:
			pass
		else:
			ret=proj['cache_run_build']
			if isinstance(ret,str)and ret.startswith('Test does not build'):
				self.fatal(ret)
			return ret
	bdir=os.path.join(dir,'testbuild')
	if not os.path.exists(bdir):
		os.makedirs(bdir)
	self.test_bld=bld=Build.BuildContext(top_dir=dir,out_dir=bdir)
	bld.init_dirs()
	bld.progress_bar=0
	bld.targets='*'
	bld.logger=self.logger
	bld.all_envs.update(self.all_envs)
	bld.env=kw['env']
	bld.kw=kw
	bld.conf=self
	kw['build_fun'](bld)
	ret=-1
	try:
		try:
			bld.compile()
		except Errors.WafError:
			ret='Test does not build: %s'%Utils.ex_stack()
			self.fatal(ret)
		else:
			ret=getattr(bld,'retval',0)
	finally:
		if cachemode==1:
			proj=ConfigSet.ConfigSet()
			proj['cache_run_build']=ret
			proj.store(os.path.join(dir,'cache_run_build'))
		else:
			shutil.rmtree(dir)
	return ret
Beispiel #25
0
	def run(self):
		for x in self.inputs:
			cmd = Utils.to_list(self.env.AR) + ["x", x.abspath() ]

			ar_dir_basename = x.name.replace(".a", "_a")
			ar_dir = self.generator.path.get_bld().make_node(ar_dir_basename)
			print(ar_dir.abspath())
			try:
				ar_dir.delete()
			except:
				pass
			ar_dir.mkdir()
			d = ar_dir.abspath()

			self.exec_command(cmd, cwd=d)

			bdir = self.generator.path.get_bld()

			nodes = []
			for _cwd, _dirs, _files in Node.os.walk(d):
				for f in _files:
					dirname = Node.os.path.basename(_cwd)
					filename = Node.os.path.join(_cwd, f)
					h = Utils.h_file(filename)
					new_filename = Node.os.path.join(
					 _cwd,
					 "%s-%s-%s" % (dirname, Utils.to_hex(h), f))

					rd = Node.os.path.relpath(new_filename, bdir.abspath())
					Node.os.rename(filename, new_filename)
					n = bdir.find_node(rd)
					n.sig = h

					# cache outputs for future runs
					try:
						self.generator.bld.pouet[self.uid()].append(n.bldpath())
					except:
						self.generator.bld.pouet[self.uid()] = [n.bldpath()]

					self.generator.add_those_o_files(n)
					nodes.append(n)

			try:
				link = self.generator.link_task
				link.inputs += nodes
				link.inputs.sort(key=lambda x: x.abspath())
			except:
				pass
Beispiel #26
0
def run_c_code(self, *k, **kw):
	lst = [str(v) for (p, v) in kw.items() if p != 'env']
	h = Utils.h_list(lst)
	dir = self.bldnode.abspath() + os.sep + '.conf_check_' + Utils.to_hex(h)

	try:
		os.makedirs(dir)
	except:
		pass

	try:
		os.stat(dir)
	except:
		self.fatal('cannot use the configuration test folder %r' % dir)

	bdir = os.path.join(dir, 'testbuild')

	if not os.path.exists(bdir):
		os.makedirs(bdir)

	self.test_bld = bld = Build.BuildContext(top_dir=dir, out_dir=bdir) # keep the temporary build context on an attribute for debugging
	bld.load() # configuration test cache
	bld.targets = '*'

	if kw['compile_filename']:
		node = bld.srcnode.make_node(kw['compile_filename'])
		node.write(kw['code'])

	bld.logger = self.logger
	bld.all_envs.update(self.all_envs)
	bld.all_envs['default'] = kw['env']

	o = bld(features=kw['features'], source=kw['compile_filename'], target='testprog')

	for k, v in kw.items():
		setattr(o, k, v)

	self.to_log("==>\n%s\n<==" % kw['code'])

	# compile the program
	bld.targets = '*'
	try:
		bld.compile()
	except Errors.WafError:
		self.fatal('Test does not build: %s' % Utils.ex_stack())

	return getattr(bld, 'retval', 0)
Beispiel #27
0
def can_retrieve_cache(self):
    if not Task.pull_addr:
        return False
    if not self.outputs:
        return False
    self.cached = False

    cnt = 0
    sig = self.signature()
    ssig = Utils.to_hex(self.uid() + sig)

    conn = None
    err = False
    try:
        try:
            conn = get_connection()
            for node in self.outputs:
                p = node.abspath()
                recv_file(conn, ssig, cnt, p)
                cnt += 1
        except MissingFile as e:
            Logs.debug('netcache: file is not in the cache %r' % e)
            err = True

        except Exception as e:
            Logs.debug('netcache: could not get the files %r' % e)
            err = True

            # broken connection? remove this one
            close_connection(conn)
            conn = None
    finally:
        release_connection(conn)
    if err:
        return False

    for node in self.outputs:
        node.sig = sig
        #if self.generator.bld.progress_bar < 1:
        #	self.generator.bld.to_log('restoring from cache %r\n' % node.abspath())

    self.cached = True
    return True
Beispiel #28
0
def can_retrieve_cache(self):
	if not Task.pull_addr:
		return False
	if not self.outputs:
		return False
	self.cached = False

	cnt = 0
	sig = self.signature()
	ssig = Utils.to_hex(self.uid() + sig)

	conn = None
	err = False
	try:
		try:
			conn = get_connection()
			for node in self.outputs:
				p = node.abspath()
				recv_file(conn, ssig, cnt, p)
				cnt += 1
		except MissingFile as e:
			Logs.debug('netcache: file is not in the cache %r' % e)
			err = True

		except Exception as e:
			Logs.debug('netcache: could not get the files %r' % e)
			err = True

			# broken connection? remove this one
			close_connection(conn)
			conn = None
	finally:
		release_connection(conn)
	if err:
		return False

	for node in self.outputs:
		node.sig = sig
		#if self.generator.bld.progress_bar < 1:
		#	self.generator.bld.to_log('restoring from cache %r\n' % node.abspath())

	self.cached = True
	return True
 def hash_env_vars(self, env, vars_lst):
     if not env.table:
         env = env.parent
         if not env:
             return Utils.SIG_NIL
     idx = str(id(env)) + str(vars_lst)
     try:
         cache = self.cache_env
     except AttributeError:
         cache = self.cache_env = {}
     else:
         try:
             return self.cache_env[idx]
         except KeyError:
             pass
     lst = [env[a] for a in vars_lst]
     cache[idx] = ret = Utils.h_list(lst)
     Logs.debug('envhash: %s %r', Utils.to_hex(ret), lst)
     return ret
Beispiel #30
0
    def scan(self):
        env = self.env
        gen = self.generator
        bld = gen.bld
        zpy = bld.zpy
        out = self.outputs[0].parent
        sig = Utils.to_hex(
            (self.inputs and getattr(self.inputs[0], 'sig', None))
            or getattr(out, 'sig', None)
            or Utils.md5(self.dist.name_and_version).digest())

        deps = ([], [])

        #self.signode = out.make_node(sig)
        self.signode = bld.bldnode.make_node(str('.%s.%s' % (out.name, sig)), )
        self.signode.mkdir()
        #deps[0].append(self.signode)

        return deps
Beispiel #31
0
	def hash_env_vars(self,env,vars_lst):
		if not env.table:
			env=env.parent
			if not env:
				return Utils.SIG_NIL
		idx=str(id(env))+str(vars_lst)
		try:
			cache=self.cache_env
		except AttributeError:
			cache=self.cache_env={}
		else:
			try:
				return self.cache_env[idx]
			except KeyError:
				pass
		lst=[env[a]for a in vars_lst]
		cache[idx]=ret=Utils.h_list(lst)
		Logs.debug('envhash: %s %r',Utils.to_hex(ret),lst)
		return ret
Beispiel #32
0
def can_retrieve_cache(self):
    if not Task.pull_addr:
        return False
    if not self.outputs:
        return False
    self.cached = False

    cnt = 0
    sig = self.signature()
    ssig = Utils.to_hex(self.uid() + sig)

    conn = None
    err = False
    try:
        try:
            conn = get_connection()
            for node in self.outputs:
                p = node.abspath()
                recv_file(conn, ssig, cnt, p)
                cnt += 1
        except MissingFile as e:
            Logs.debug('netcache: file is not in the cache %r', e)
            err = True
        except Exception as e:
            Logs.debug('netcache: could not get the files %r', self.outputs)
            if Logs.verbose > 1:
                Logs.debug('netcache: exception %r', e)
            err = True

            # broken connection? remove this one
            close_connection(conn)
            conn = None
        else:
            Logs.debug('netcache: obtained %r from cache', self.outputs)

    finally:
        release_connection(conn)
    if err:
        return False

    self.cached = True
    return True
Beispiel #33
0
def can_retrieve_cache(self):
    if not Task.pull_addr:
        return False
    if not self.outputs:
        return False
    self.cached = False

    cnt = 0
    sig = self.signature()
    ssig = Utils.to_hex(self.uid() + sig)

    conn = None
    err = False
    try:
        try:
            conn = get_connection()
            for node in self.outputs:
                p = node.abspath()
                recv_file(conn, ssig, cnt, p)
                cnt += 1
            else:
                Logs.debug("netcache: obtained %r from cache", self.outputs)
        except MissingFile as e:
            Logs.debug("netcache: file is not in the cache %r", e)
            err = True

        except Exception as e:
            Logs.debug("netcache: could not get the files %r", self.outputs)
            if Logs.verbose > 1:
                Logs.debug("netcache: exception %r", e)
            err = True

            # broken connection? remove this one
            close_connection(conn)
            conn = None
    finally:
        release_connection(conn)
    if err:
        return False

    self.cached = True
    return True
Beispiel #34
0
def can_retrieve_cache(self):
    """
	New method for waf Task classes
	"""
    if not self.outputs:
        return False

    self.cached = False

    sig = self.signature()
    ssig = Utils.to_hex(self.uid() + sig)

    files_to = [node.abspath() for node in self.outputs]
    err = cache_command(ssig, [], files_to)
    if not err.startswith(OK):
        if Logs.verbose:
            Logs.debug('wafcache: error getting from cache %s', err)
        return False

    self.cached = True
    return True
Beispiel #35
0
    def scan(self):
        env = self.env
        gen = self.generator
        bld = gen.bld
        zpy = bld.zpy
        out = self.outputs[0].parent
        sig = Utils.to_hex(
            (self.inputs and getattr(self.inputs[0], 'sig', None))
            or getattr(out, 'sig', None)
            or Utils.md5(self.dist.name_and_version).digest()
            )

        deps = ([], [])

        #self.signode = out.make_node(sig)
        self.signode = bld.bldnode.make_node(
            str('.%s.%s' % (out.name, sig)),
            )
        self.signode.mkdir()
        #deps[0].append(self.signode)

        return deps
Beispiel #36
0
def put_files_cache(self):
    """
	New method for waf Task classes
	"""
    if not self.outputs:
        return

    if getattr(self, 'cached', None):
        return

    bld = self.generator.bld
    sig = self.signature()
    ssig = Utils.to_hex(self.uid() + sig)

    files_from = [node.abspath() for node in self.outputs]
    err = cache_command(ssig, files_from, [])

    if not err.startswith(OK):
        if Logs.verbose:
            Logs.debug('wafcache: error caching %s', err)

    bld.task_sigs[self.uid()] = self.cache_sig
Beispiel #37
0
    def run(self):
        tsk = self
        env = self.env
        gen = self.generator
        bld = gen.bld
        zpy = bld.zpy
        py = bld.py

        if getattr(self, 'cwd', None) is None:
            self.cwd = pth.join(bld.bldnode.abspath(), self.dist.key)

        python = bld.zippy_dist_get('python')
        self._key = '%s-%s-%s' % (
                python.key,
                python.version,
                Utils.to_hex(self.signature())
                )
        self._cache_conf = pth.join(zpy.cache_tmp, 'conf-%s' % self._key)
        self._cache_prof = pth.join(zpy.cache_tmp, 'prof-%s' % self._key)

        ret = 0
        with open(pth.join(self.cwd, 'zippy.sh'), mode='a') as fp:
            fd = fp.fileno()
            fstat = os.fstat(fd)
            fmode = fstat.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
            os.fchmod(fd, fmode)

            if fp.tell() == 0:
                fp.write('#!/bin/bash\n\n')
            fp.write('cd ' + pipes.quote(self.cwd) + '\n')
            fp.write('unset $(compgen -e)' + '\n\n')
            for k,v in sorted(env.env.iteritems()):
                v = pipes.quote(v)
                fp.write('export {0}={1}\n'.format(k, v))
            fp.write('\n')

            for app in Utils.to_list(self.app):
                if not isinstance(app, basestring):
                    fp.write('# ' + str(app))
                    ret |= app(self)
                    continue

                kwds = dict()
                if bld.zero_log:
                    kwds = {'stdout': None, 'stderr': -2}

                larg = None
                app = app.format(**locals())
                app = app.strip('\0').split('\0')
                for arg in map(pipes.quote, app):
                    if larg is not None:
                        fp.write(' \\\n    ')
                    fp.write(arg)
                    larg = arg
                fp.write('\n\n')

                ret |= self.exec_command(
                    app,
                    cwd=self.cwd,
                    env=env.env or None,
                    **kwds
                    )

        return ret
Beispiel #38
0
def run_c_code(self, *k, **kw):
    lst = [str(v) for (p, v) in kw.items() if p != "env"]
    h = Utils.h_list(lst)
    dir = self.bldnode.abspath() + os.sep + (sys.platform != "win32" and "." or "") + "conf_check_" + Utils.to_hex(h)
    try:
        os.makedirs(dir)
    except:
        pass
    try:
        os.stat(dir)
    except:
        self.fatal("cannot use the configuration test folder %r" % dir)
    cachemode = getattr(Options.options, "confcache", None)
    if cachemode == CACHE_RESULTS:
        try:
            proj = ConfigSet.ConfigSet(os.path.join(dir, "cache_run_c_code"))
            ret = proj["cache_run_c_code"]
        except:
            pass
        else:
            if isinstance(ret, str) and ret.startswith("Test does not build"):
                self.fatal(ret)
            return ret
    bdir = os.path.join(dir, "testbuild")
    if not os.path.exists(bdir):
        os.makedirs(bdir)
    self.test_bld = bld = Build.BuildContext(top_dir=dir, out_dir=bdir)
    bld.init_dirs()
    bld.progress_bar = 0
    bld.targets = "*"
    if kw["compile_filename"]:
        node = bld.srcnode.make_node(kw["compile_filename"])
        node.write(kw["code"])
    bld.logger = self.logger
    bld.all_envs.update(self.all_envs)
    bld.env = kw["env"]
    o = bld(features=kw["features"], source=kw["compile_filename"], target="testprog")
    for k, v in kw.items():
        setattr(o, k, v)
    self.to_log("==>\n%s\n<==" % kw["code"])
    bld.targets = "*"
    ret = -1
    try:
        try:
            bld.compile()
        except Errors.WafError:
            ret = "Test does not build: %s" % Utils.ex_stack()
            self.fatal(ret)
        else:
            ret = getattr(bld, "retval", 0)
    finally:
        proj = ConfigSet.ConfigSet()
        proj["cache_run_c_code"] = ret
        proj.store(os.path.join(dir, "cache_run_c_code"))
    return ret
Beispiel #39
0
def can_retrieve_cache(self):
    """
    Used by :py:meth:`waflib.Task.cache_outputs`

    Retrieve build nodes from the cache
    update the file timestamps to help cleaning the least used entries from the cache
    additionally, set an attribute 'cached' to avoid re-creating the same cache files

    Suppose there are files in `cache/dir1/file1` and `cache/dir2/file2`:

    #. read the timestamp of dir1
    #. try to copy the files
    #. look at the timestamp again, if it has changed, the data may have been corrupt (cache update by another process)
    #. should an exception occur, ignore the data
    """
    bld = self.generator.bld
    if not isinstance(bld, Build.BuildContext):
        return False

    if not getattr(self, 'outputs', None):
        return False

    if not hasattr(self, 'can_retrieve_cache_checked'):
        self.can_retrieve_cache_checked = True
    else:
        return False

    bld.artifacts_cache_metrics.tasks_processed.add(self)

    sig = self.signature()
    ssig = Utils.to_hex(self.uid()) + Utils.to_hex(sig)

    # first try to access the cache folder for the task
    dname = os.path.join(bld.artifacts_cache, ssig)
    if not os.path.exists(dname):
        bld.artifacts_cache_metrics.tasks_missed.add(self)
        return False

    for node in self.outputs:
        orig = os.path.join(dname, node.name)
        # Maximum Path Length Limitation on Windows is 260 characters, starting from Windows 10, we can enable long path to remove this limitation.
        # In case long path is not enabled, extended-length path to bypass this limitation.
        orig = Utils.extended_path(orig)
        try:
            t1 = os.stat(orig).st_mtime
        except OSError:
            bld.artifacts_cache_metrics.tasks_missed.add(self)
            return False
        dir_name = os.path.dirname(node.abspath())
        try:
            os.makedirs(dir_name)
        except Exception:
            pass

        try:
            # Do not use shutil.copy2(orig, node.abspath()), otherwise, it will cause threading issue with compiler and linker.
            # shutil.copy2() first calls shutil.copyfile() to copy the file contents, and then calls os.copystat() to copy the file stats, after the file contents are copied, waf is able to get the node's signature and might think the runnable status of a task is ready to run, but the copied file is then opened by os.copystat(), and compiler or linker who use the copied file as input file will fail.
            if Utils.is_win32:
                os.system('copy {} {} /Y>nul'.format(orig, node.abspath()))
            else:
                os.system('cp {} {}'.format(orig, node.abspath()))
            # is it the same file?
            try:
                t2 = os.stat(orig).st_mtime
                if t1 != t2:
                    bld.artifacts_cache_metrics.tasks_failed_to_retrieve.add(
                        self)
                    return False
            except OSError:
                bld.artifacts_cache_metrics.tasks_failed_to_retrieve.add(self)
                return False
        except Exception as e:
            Logs.warn(
                '[WARN] task: failed retrieving file {} due to exception\n{}\n'
                .format(node.abspath(), e))
            bld.artifacts_cache_metrics.tasks_failed_to_retrieve.add(self)
            return False

    for node in self.outputs:
        node.sig = sig
        if bld.progress_bar < 1:
            bld.to_log('restoring from cache %r\n' % node.abspath())

    # mark the cache file folder as used recently (modified)
    os.utime(dname, None)

    self.cached = True
    return True
Beispiel #40
0
def run_build(self, *k, **kw):
    """
	Create a temporary build context to execute a build. A reference to that build
	context is kept on self.test_bld for debugging purposes, and you should not rely
	on it too much (read the note on the cache below).
	The parameters given in the arguments to this function are passed as arguments for
	a single task generator created in the build. Only three parameters are obligatory:

	:param features: features to pass to a task generator created in the build
	:type features: list of string
	:param compile_filename: file to create for the compilation (default: *test.c*)
	:type compile_filename: string
	:param code: code to write in the filename to compile
	:type code: string

	Though this function returns *0* by default, the build may set an attribute named *retval* on the
	build context object to return a particular value. See :py:func:`waflib.Tools.c_config.test_exec_fun` for example.

	This function also provides a limited cache. To use it, provide the following option::

		def options(opt):
			opt.add_option('--confcache', dest='confcache', default=0,
				action='count', help='Use a configuration cache')

	And execute the configuration with the following command-line::

		$ waf configure --confcache

	"""

    lst = [str(v) for (p, v) in kw.items() if p != "env"]
    h = Utils.h_list(lst)
    dir = self.bldnode.abspath() + os.sep + (not Utils.is_win32 and "." or "") + "conf_check_" + Utils.to_hex(h)

    try:
        os.makedirs(dir)
    except OSError:
        pass

    try:
        os.stat(dir)
    except OSError:
        self.fatal("cannot use the configuration test folder %r" % dir)

    cachemode = getattr(Options.options, "confcache", None)
    if cachemode == 1:
        try:
            proj = ConfigSet.ConfigSet(os.path.join(dir, "cache_run_build"))
        except OSError:
            pass
        except IOError:
            pass
        else:
            ret = proj["cache_run_build"]
            if isinstance(ret, str) and ret.startswith("Test does not build"):
                self.fatal(ret)
            return ret

    bdir = os.path.join(dir, "testbuild")

    if not os.path.exists(bdir):
        os.makedirs(bdir)

    self.test_bld = bld = Build.BuildContext(top_dir=dir, out_dir=bdir)
    bld.init_dirs()
    bld.progress_bar = 0
    bld.targets = "*"

    bld.logger = self.logger
    bld.all_envs.update(self.all_envs)  # not really necessary
    bld.env = kw["env"]

    # OMG huge hack
    bld.kw = kw
    bld.conf = self
    kw["build_fun"](bld)

    ret = -1
    try:
        try:
            bld.compile()
        except Errors.WafError:
            ret = "Test does not build: %s" % Utils.ex_stack()
            self.fatal(ret)
        else:
            ret = getattr(bld, "retval", 0)
    finally:
        if cachemode == 1:
            # cache the results each time
            proj = ConfigSet.ConfigSet()
            proj["cache_run_build"] = ret
            proj.store(os.path.join(dir, "cache_run_build"))
        else:
            shutil.rmtree(dir)

    return ret
Beispiel #41
0
def run_c_code(self, *k, **kw):
    """
	Create a temporary build context to execute a build. A reference to that build
	context is kept on self.test_bld for debugging purposes.
	The parameters given in the arguments to this function are passed as arguments for
	a single task generator created in the build. Only three parameters are obligatory:

	:param features: features to pass to a task generator created in the build
	:type features: list of string
	:param compile_filename: file to create for the compilation (default: *test.c*)
	:type compile_filename: string
	:param code: code to write in the filename to compile
	:type code: string

	Though this function returns *0* by default, the build may set an attribute named *retval* on the
	build context object to return a particular value. See :py:func:`waflib.Tools.c_config.test_exec_fun` for example.

	This function also provides a limited cache. To use it, provide the following option::

		def options(opt):
			opt.add_option('--confcache', dest='confcache', default=0,
				action='count', help='Use a configuration cache')

	And execute the configuration with the following command-line::

		$ waf configure --confcache

	"""

    lst = [str(v) for (p, v) in kw.items() if p != 'env']
    h = Utils.h_list(lst)
    dir = self.bldnode.abspath() + os.sep + (
        not Utils.is_win32 and '.' or '') + 'conf_check_' + Utils.to_hex(h)

    try:
        os.makedirs(dir)
    except:
        pass

    try:
        os.stat(dir)
    except:
        self.fatal('cannot use the configuration test folder %r' % dir)

    cachemode = getattr(Options.options, 'confcache', None)
    if cachemode == CACHE_RESULTS:
        try:
            proj = ConfigSet.ConfigSet(os.path.join(dir, 'cache_run_c_code'))
            ret = proj['cache_run_c_code']
        except:
            pass
        else:
            if isinstance(ret, str) and ret.startswith('Test does not build'):
                self.fatal(ret)
            return ret

    bdir = os.path.join(dir, 'testbuild')

    if not os.path.exists(bdir):
        os.makedirs(bdir)

    self.test_bld = bld = Build.BuildContext(top_dir=dir, out_dir=bdir)
    bld.init_dirs()
    bld.progress_bar = 0
    bld.targets = '*'

    if kw['compile_filename']:
        node = bld.srcnode.make_node(kw['compile_filename'])
        node.write(kw['code'])

    bld.logger = self.logger
    bld.all_envs.update(self.all_envs)  # not really necessary
    bld.env = kw['env']

    o = bld(features=kw['features'],
            source=kw['compile_filename'],
            target='testprog')

    for k, v in kw.items():
        setattr(o, k, v)

    self.to_log("==>\n%s\n<==" % kw['code'])

    # compile the program
    bld.targets = '*'

    ret = -1
    try:
        try:
            bld.compile()
        except Errors.WafError:
            ret = 'Test does not build: %s' % Utils.ex_stack()
            self.fatal(ret)
        else:
            ret = getattr(bld, 'retval', 0)
    finally:
        # cache the results each time
        proj = ConfigSet.ConfigSet()
        proj['cache_run_c_code'] = ret
        proj.store(os.path.join(dir, 'cache_run_c_code'))

    return ret
Beispiel #42
0
def run_c_code(self, *k, **kw):
	"""
	To use the cache in your scripts, provide the following option
	and execute  "waf configure --confcache"

	def options(opt):
		opt.add_option('--confcache', dest='confcache', default=0,
			action='count', help='Use a configuration cache')

	The temporary build context created is kept on self.test_bld for debugging purposes
	"""

	lst = [str(v) for (p, v) in kw.items() if p != 'env']
	h = Utils.h_list(lst)
	dir = self.bldnode.abspath() + os.sep + (sys.platform != 'win32' and '.' or '') + 'conf_check_' + Utils.to_hex(h)

	try:
		os.makedirs(dir)
	except:
		pass

	try:
		os.stat(dir)
	except:
		self.fatal('cannot use the configuration test folder %r' % dir)

	cachemode = getattr(Options.options, 'confcache', None)
	if cachemode == CACHE_RESULTS:
		try:
			proj = ConfigSet.ConfigSet(os.path.join(dir, 'cache_run_c_code'))
			ret = proj['cache_run_c_code']
		except:
			pass
		else:
			if isinstance(ret, str) and ret.startswith('Test does not build'):
				self.fatal(ret)
			return ret

	bdir = os.path.join(dir, 'testbuild')

	if not os.path.exists(bdir):
		os.makedirs(bdir)

	self.test_bld = bld = Build.BuildContext(top_dir=dir, out_dir=bdir)
	bld.init_dirs()
	bld.progress_bar = 0
	bld.targets = '*'

	if kw['compile_filename']:
		node = bld.srcnode.make_node(kw['compile_filename'])
		node.write(kw['code'])

	bld.logger = self.logger
	bld.all_envs.update(self.all_envs) # not really necessary
	bld.env = kw['env']

	o = bld(features=kw['features'], source=kw['compile_filename'], target='testprog')

	for k, v in kw.items():
		setattr(o, k, v)

	self.to_log("==>\n%s\n<==" % kw['code'])

	# compile the program
	bld.targets = '*'

	ret = -1
	try:
		try:
			bld.compile()
		except Errors.WafError:
			ret = 'Test does not build: %s' % Utils.ex_stack()
			self.fatal(ret)
		else:
			ret = getattr(bld, 'retval', 0)
	finally:
		# cache the results each time
		proj = ConfigSet.ConfigSet()
		proj['cache_run_c_code'] = ret
		proj.store(os.path.join(dir, 'cache_run_c_code'))

	return ret
Beispiel #43
0
def run_build(self, *k, **kw):
	"""
	Create a temporary build context to execute a build. A reference to that build
	context is kept on self.test_bld for debugging purposes, and you should not rely
	on it too much (read the note on the cache below).
	The parameters given in the arguments to this function are passed as arguments for
	a single task generator created in the build. Only three parameters are obligatory:

	:param features: features to pass to a task generator created in the build
	:type features: list of string
	:param compile_filename: file to create for the compilation (default: *test.c*)
	:type compile_filename: string
	:param code: code to write in the filename to compile
	:type code: string

	Though this function returns *0* by default, the build may set an attribute named *retval* on the
	build context object to return a particular value. See :py:func:`waflib.Tools.c_config.test_exec_fun` for example.

	This function also provides a limited cache. To use it, provide the following option::

		def options(opt):
			opt.add_option('--confcache', dest='confcache', default=0,
				action='count', help='Use a configuration cache')

	And execute the configuration with the following command-line::

		$ waf configure --confcache

	"""
	lst = [str(v) for (p, v) in kw.items() if p != 'env']
	h = Utils.h_list(lst)
	dir = self.bldnode.abspath() + os.sep + (not Utils.is_win32 and '.' or '') + 'conf_check_' + Utils.to_hex(h)

	try:
		os.makedirs(dir)
	except OSError:
		pass

	try:
		os.stat(dir)
	except OSError:
		self.fatal('cannot use the configuration test folder %r' % dir)

	cachemode = getattr(Options.options, 'confcache', None)
	if cachemode == 1:
		try:
			proj = ConfigSet.ConfigSet(os.path.join(dir, 'cache_run_build'))
		except EnvironmentError:
			pass
		else:
			ret = proj['cache_run_build']
			if isinstance(ret, str) and ret.startswith('Test does not build'):
				self.fatal(ret)
			return ret

	bdir = os.path.join(dir, 'testbuild')

	if not os.path.exists(bdir):
		os.makedirs(bdir)

	cls_name = kw.get('run_build_cls') or getattr(self, 'run_build_cls', 'build')
	self.test_bld = bld = Context.create_context(cls_name, top_dir=dir, out_dir=bdir)
	bld.init_dirs()
	bld.progress_bar = 0
	bld.targets = '*'

	bld.logger = self.logger
	bld.all_envs.update(self.all_envs) # not really necessary
	bld.env = kw['env']

	bld.kw = kw
	bld.conf = self
	kw['build_fun'](bld)
	ret = -1
	try:
		try:
			bld.compile()
		except Errors.WafError:
			ret = 'Test does not build: %s' % traceback.format_exc()
			self.fatal(ret)
		else:
			ret = getattr(bld, 'retval', 0)
	finally:
		if cachemode == 1:
			# cache the results each time
			proj = ConfigSet.ConfigSet()
			proj['cache_run_build'] = ret
			proj.store(os.path.join(dir, 'cache_run_build'))
		else:
			shutil.rmtree(dir)
	return ret
Beispiel #44
0
			def v(x):
				return Utils.to_hex(x)
Beispiel #45
0
def run_c_code(self, *k, **kw):
	"""
	Create a temporary build context to execute a build. A reference to that build
	context is kept on self.test_bld for debugging purposes, and you should not rely
	on it too much (read the note on the cache below).
	The parameters given in the arguments to this function are passed as arguments for
	a single task generator created in the build. Only three parameters are obligatory:

	:param features: features to pass to a task generator created in the build
	:type features: list of string
	:param compile_filename: file to create for the compilation (default: *test.c*)
	:type compile_filename: string
	:param code: code to write in the filename to compile
	:type code: string

	Though this function returns *0* by default, the build may set an attribute named *retval* on the
	build context object to return a particular value. See :py:func:`waflib.Tools.c_config.test_exec_fun` for example.

	This function also provides a limited cache. To use it, provide the following option::

		def options(opt):
			opt.add_option('--confcache', dest='confcache', default=0,
				action='count', help='Use a configuration cache')

	And execute the configuration with the following command-line::

		$ waf configure --confcache

	"""

	lst = [str(v) for (p, v) in kw.items() if p != 'env']
	h = Utils.h_list(lst)
	dir = self.bldnode.abspath() + os.sep + (not Utils.is_win32 and '.' or '') + 'conf_check_' + Utils.to_hex(h)

	try:
		os.makedirs(dir)
	except:
		pass

	try:
		os.stat(dir)
	except:
		self.fatal('cannot use the configuration test folder %r' % dir)

	cachemode = getattr(Options.options, 'confcache', None)
	if cachemode == CACHE_RESULTS:
		try:
			proj = ConfigSet.ConfigSet(os.path.join(dir, 'cache_run_c_code'))
			ret = proj['cache_run_c_code']
		except:
			pass
		else:
			if isinstance(ret, str) and ret.startswith('Test does not build'):
				self.fatal(ret)
			return ret

	bdir = os.path.join(dir, 'testbuild')

	if not os.path.exists(bdir):
		os.makedirs(bdir)

	self.test_bld = bld = Build.BuildContext(top_dir=dir, out_dir=bdir)
	bld.init_dirs()
	bld.progress_bar = 0
	bld.targets = '*'

	if kw['compile_filename']:
		node = bld.srcnode.make_node(kw['compile_filename'])
		node.write(kw['code'])

	bld.logger = self.logger
	bld.all_envs.update(self.all_envs) # not really necessary
	bld.env = kw['env']

	o = bld(features=kw['features'], source=kw['compile_filename'], target='testprog')

	for k, v in kw.items():
		setattr(o, k, v)

	self.to_log("==>\n%s\n<==" % kw['code'])

	# compile the program
	bld.targets = '*'

	ret = -1
	try:
		try:
			bld.compile()
		except Errors.WafError:
			ret = 'Test does not build: %s' % Utils.ex_stack()
			self.fatal(ret)
		else:
			ret = getattr(bld, 'retval', 0)
	finally:
		# cache the results each time
		proj = ConfigSet.ConfigSet()
		proj['cache_run_c_code'] = ret
		proj.store(os.path.join(dir, 'cache_run_c_code'))

	return ret
Beispiel #46
0
			def v(x):
				return Utils.to_hex(x)
Beispiel #47
0
def run_build(self, *k, **kw):
    """
	Create a temporary build context to execute a build. A temporary reference to that build
	context is kept on self.test_bld for debugging purposes.
	The arguments to this function are passed to a single task generator for that build.
	Only three parameters are mandatory:

	:param features: features to pass to a task generator created in the build
	:type features: list of string
	:param compile_filename: file to create for the compilation (default: *test.c*)
	:type compile_filename: string
	:param code: input file contents
	:type code: string

	Though this function returns *0* by default, the build may bind attribute named *retval* on the
	build context object to return a particular value. See :py:func:`waflib.Tools.c_config.test_exec_fun` for example.

	The temporary builds creates a temporary folder; the name of that folder is calculated
	by hashing input arguments to this function, with the exception of :py:class:`waflib.ConfigSet.ConfigSet`
	objects which are used for both reading and writing values.

	This function also features a cache which is disabled by default; that cache relies
	on the hash value calculated as indicated above::

		def options(opt):
			opt.add_option('--confcache', dest='confcache', default=0,
				action='count', help='Use a configuration cache')

	And execute the configuration with the following command-line::

		$ waf configure --confcache

	"""
    buf = []
    for key in sorted(kw.keys()):
        v = kw[key]
        if isinstance(v, ConfigSet.ConfigSet):
            # values are being written to, so they are excluded from contributing to the hash
            continue
        elif hasattr(v, '__call__'):
            buf.append(Utils.h_fun(v))
        else:
            buf.append(str(v))
    h = Utils.h_list(buf)
    dir = self.bldnode.abspath() + os.sep + (
        not Utils.is_win32 and '.' or '') + 'conf_check_' + Utils.to_hex(h)

    cachemode = kw.get('confcache', getattr(Options.options, 'confcache',
                                            None))

    if not cachemode and os.path.exists(dir):
        shutil.rmtree(dir)

    try:
        os.makedirs(dir)
    except OSError:
        pass

    try:
        os.stat(dir)
    except OSError:
        self.fatal('cannot use the configuration test folder %r' % dir)

    if cachemode == 1:
        try:
            proj = ConfigSet.ConfigSet(os.path.join(dir, 'cache_run_build'))
        except EnvironmentError:
            pass
        else:
            ret = proj['cache_run_build']
            if isinstance(ret, str) and ret.startswith('Test does not build'):
                self.fatal(ret)
            return ret

    bdir = os.path.join(dir, 'testbuild')

    if not os.path.exists(bdir):
        os.makedirs(bdir)

    cls_name = kw.get('run_build_cls') or getattr(self, 'run_build_cls',
                                                  'build')
    self.test_bld = bld = Context.create_context(cls_name,
                                                 top_dir=dir,
                                                 out_dir=bdir)
    bld.init_dirs()
    bld.progress_bar = 0
    bld.targets = '*'

    bld.logger = self.logger
    bld.all_envs.update(self.all_envs)  # not really necessary
    bld.env = kw['env']

    bld.kw = kw
    bld.conf = self
    kw['build_fun'](bld)
    ret = -1
    try:
        try:
            bld.compile()
        except Errors.WafError:
            ret = 'Test does not build: %s' % traceback.format_exc()
            self.fatal(ret)
        else:
            ret = getattr(bld, 'retval', 0)
    finally:
        if cachemode:
            # cache the results each time
            proj = ConfigSet.ConfigSet()
            proj['cache_run_build'] = ret
            proj.store(os.path.join(dir, 'cache_run_build'))
        else:
            shutil.rmtree(dir)
    return ret