# generated source file.
sub dogenerate {
my $src = shift;
+ # Safety measure
+ return "" unless defined $unified_info{generate}->{$_};
return "" if $cache{$src};
my $obj = shift;
my $bin = shift;
$cache{$src} = 1;
}
+ sub dotarget {
+ my $target = shift;
+ return "" if $cache{$target};
+ $OUT .= generatetarget(target => $target,
+ deps => $unified_info{depends}->{$target});
+ foreach (@{$unified_info{depends}->{$target}}) {
+ dogenerate($_);
+ }
+ $cache{$target} = 1;
+ }
+
# doobj is responsible for producing all the recipes that build
# object files as well as dependency files.
sub doobj {
# Start with populating the cache with all the overrides
%cache = map { $_ => 1 } @{$unified_info{overrides}};
- # Build mandatory generated headers
+ # Build mandatory header file generators
foreach (@{$unified_info{depends}->{""}}) { dogenerate($_); }
- # Build all known libraries, modules, programs and scripts.
+ # Build all known targets, libraries, modules, programs and scripts.
# Everything else will be handled as a consequence.
+ foreach (@{$unified_info{targets}}) { dotarget($_); }
foreach (@{$unified_info{libraries}}) { dolib($_); }
foreach (@{$unified_info{modules}}) { domodule($_); }
foreach (@{$unified_info{programs}}) { dobin($_); }
return ([ @before ], [ @after ]);
}
+ sub generatetarget {
+ my %args = @_;
+ my $deps = join(" ", @{$args{deps}});
+ return <<"EOF";
+$args{target} : $deps
+EOF
+ }
+
sub generatesrc {
my %args = @_;
my $generator = join(" ", @{$args{generator}});
} @_;
}
+ sub generatetarget {
+ my %args = @_;
+ my $deps = join(" ", @{$args{deps}});
+ return <<"EOF";
+$args{target}: $deps
+EOF
+ }
+
sub generatesrc {
my %args = @_;
my $generator = join(" ", @{$args{generator}});
return map { platform->sharedlib_import($_) // platform->staticlib($_) } @_;
}
+ sub generatetarget {
+ my %args = @_;
+ my $deps = join(" ", @{$args{deps}});
+ return <<"EOF";
+$args{target}: $deps
+EOF
+ }
+
sub generatesrc {
my %args = @_;
my ($gen0, @gens) = @{$args{generator}};
foreach (keys %depends) {
my $dest = $_;
- my $ddest = $dest eq "" ? "" : cleanfile($sourced, $_, $blddir);
+ my $ddest = $dest;
+
+ if ($dest =~ /^\|(.*)\|$/) {
+ # Collect the raw target
+ $unified_info{targets}->{$1} = 1;
+ $ddest = $1;
+ } elsif ($dest eq '') {
+ $ddest = '';
+ } else {
+ $ddest = cleanfile($sourced, $_, $blddir);
- # If the destination doesn't exist in source, it can only be
- # a generated file in the build tree.
- if ($ddest ne "" && ($ddest eq $src_configdata || ! -f $ddest)) {
- $ddest = cleanfile($buildd, $_, $blddir);
+ # If the destination doesn't exist in source, it can only be
+ # a generated file in the build tree.
+ if ($ddest eq $src_configdata || ! -f $ddest) {
+ $ddest = cleanfile($buildd, $_, $blddir);
+ }
}
foreach (@{$depends{$dest}}) {
my $d = cleanfile($sourced, $_, $blddir);
### Make unified_info a bit more efficient
# One level structures
- foreach (("programs", "libraries", "modules", "scripts")) {
+ foreach (("programs", "libraries", "modules", "scripts", "targets")) {
$unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
}
# Two level structures
The I<items> may be any program, library, module, script, or any
filename used as a value anywhere.
+The I<items> may also be literal build file targets. Those are
+recognised by being surrounded be vertical bars (also known as the
+"pipe" character), C<|>. For example:
+
+ DEPEND[|tests|]=fipsmodule.cnf
+
B<DEPEND> statements may have attributes, which apply to each
individual dependency in such a statement. For example: