[Scons-users] Scanners

Tom Tanner (BLOOMBERG/ LONDON) ttanner2 at bloomberg.net
Mon Jan 25 07:39:25 EST 2016


I ended up writing a class that inherited from SCons.Scanner.Current and overwrote the __call__  method to sort the list.

The documentation on writing your own scanner is a little unhelpful as it seems to assume that all scanners can use a single regex.

carandraug+dev at gmail.com At: Jan 20 2016 15:05:54" data-digest="From: carandraug+dev at gmail.com At: Jan 20 2016 15:05:54" style="">
From: carandraug+dev at gmail.com At: Jan 20 2016 15:05:54
To: Tom Tanner (BLOOMBERG/ LONDON)
Cc: scons-users at scons.org
Subject: Re: [Scons-users] Scanners


On 20 January 2016 at 11:22, Tom Tanner (BLOOMBERG/ LONDON)
<ttanner2 at bloomberg.net> wrote:
> Is there any way to tell the Scanner class to sort the list of scanned
> dependencies? I have a hand written scanner and it has to sort the
> dependencies it returns so as not to get unexpected rebuilds depending on
> the vagaries of todays choice of filing system and how python has decided to
> order dictionaries today.
>
> But even that isn't always enough as the scanner is recursive so it can
> possibly build multiple lists which are individually sorted but the total
> result isn't.
>
> But at least specifically in my case, and possibly in others, the order of
> the dependencies isn't important.

I had the same issue before.  But I could just sort the list myself to
solve the problem.  It was also recursive, but I used a set and merged
sets together to avoid duplicates.

Is this helpful?

    def perl5_scanner(node, env, path):
      perl_args = ["perl", "-MModule::ScanDeps"] + ["-I" + inc for inc
in env['PERL5LIB']]

      ## We handle the recursion ourselves instead of using the recursion
      ## option from Module::ScanDeps because that will descend deep into
      ## the whole system libraries and our dependencies (from the project)
      ## are likely to be much smaller.
      our_deps = set()
      cwd = os.path.realpath(os.getcwd())
      def scan_deps(fpaths):
        my_deps = set()
        for fpath in fpaths:
          ## Order of keys in perl is random for security, so we need to
          ## sort them, otherwise the order of dependencies will change
          ## causing a rebuild everytime.
          code = """
            $deps = scan_deps (files => ['%s'], recurse => 0);
            foreach (sort keys %%{$deps})
              { print $deps->{$_}->{file} . "\\n"; }
          """ % str(fpath)
          deps = subprocess.check_output(perl_args + ["-e", code],
env=env['ENV'])
          for dep in deps.splitlines():
            dep = os.path.realpath(dep)
            if dep.startswith(cwd) and dep not in our_deps:
              my_deps.add(dep)

        old_len = len(our_deps)
        my_deps.difference_update(our_deps)
        our_deps.update(my_deps)
        if len(our_deps) != old_len:
          scan_deps(my_deps)

      scan_deps([node])
      return env.File(list(our_deps))


    scanner = SCons.Script.Scanner(perl5_scanner, skeys=['.pl', '.pm'])
    env.Append(SCANNERS=scanner)

Carnë


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://pairlist4.pair.net/pipermail/scons-users/attachments/20160125/8588c9b9/attachment-0001.html>


More information about the Scons-users mailing list