-
Notifications
You must be signed in to change notification settings - Fork 56
/
Builder.pm
98 lines (89 loc) · 2.93 KB
/
Builder.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
class Panda::Builder;
use Panda::Common;
use File::Find;
use Shell::Command;
sub topo-sort(@modules, %dependencies) {
my @order;
my %color_of = @modules X=> 'not yet visited';
sub dfs-visit($module) {
%color_of{$module} = 'visited';
for %dependencies{$module}.list -> $used {
if (%color_of{$used} // '') eq 'not yet visited' {
dfs-visit($used);
}
}
push @order, $module;
}
for @modules -> $module {
if %color_of{$module} eq 'not yet visited' {
dfs-visit($module);
}
}
@order;
}
sub path-to-module-name($path) {
$path.subst(/^'lib/'/, '').subst(/^'lib6/'/, '').subst(/\.pm6?$/, '').subst('/', '::', :g);
}
sub build-order(@module-files) {
my @modules = map { path-to-module-name($_) }, @module-files;
my %module-to-path = @modules Z=> @module-files;
my %usages_of;
for @module-files -> $module-file {
my $module = path-to-module-name($module-file);
%usages_of{$module} = [];
next unless $module-file.Str ~~ /\.pm6?$/; # don't try to "parse" non-perl files
my $fh = open($module-file.Str, :r);
for $fh.lines() {
if /^\s* ['use'||'need'||'require'] \s+ (\w+ ['::' \w+]*)/ && $0 -> $used {
next if $used eq 'v6';
next if $used eq 'MONKEY_TYPING';
%usages_of{$module}.push(~$used);
}
}
}
my @order = topo-sort(@modules, %usages_of);
return map { %module-to-path{$_} }, @order;
}
method build($where) {
indir $where, {
my @files;
if 'lib'.IO.d {
@files = find(dir => 'lib', type => 'file').grep({
$_.name.substr(0, 1) ne '.'
});
}
if "Build.pm".IO.f {
@*INC.push('.');
require 'Build.pm';
if ::('Build').isa(Panda::Builder) {
::('Build').new.build($where);
}
@*INC.pop;
}
my @dirs = @files.map(*.dir).uniq;
mkpath "blib/$_" for @dirs;
my @tobuild = build-order(@files);
withp6lib {
for @tobuild -> $file {
$file.IO.copy: "blib/{$file.dir}/{$file.name}";
next unless $file ~~ /\.pm6?$/;
my $dest = "blib/{$file.dir}/"
~ "{$file.name.subst(/\.pm6?$/, '.pir')}";
#note "$dest modified: ", $dest.IO.modified;
#note "$file modified: ", $file.IO.modified;
#if $dest.IO.modified >= $file.IO.modified {
# say "$file already compiled, skipping";
# next;
#}
say "Compiling $file";
shell "$*EXECUTABLE_NAME --target=pir "
~ "--output=$dest $file"
and fail "Failed building $file";
}
1;
}
1;
};
return True;
}
# vim: ft=perl6