[Scons-users] Scanners
Carnë Draug
carandraug+dev at gmail.com
Wed Jan 20 10:05:32 EST 2016
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ë
More information about the Scons-users
mailing list