From 3f399e3787788b1cc3832e254c53cda42873d847 Mon Sep 17 00:00:00 2001
From: Richard Levitte <levitte@openssl.org>
Date: Thu, 25 Feb 2021 16:55:39 +0100
Subject: [PATCH] build.info: Add the possibility to add dependencies on raw
 targets

We need to add something for the 'tests' target to depend on, so a
special syntax for those is introduced:

    DEPEND[|tests|]=fipsmodule.cnf

Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14320)
---
 Configurations/common.tmpl           | 18 ++++++++++++++++--
 Configurations/descrip.mms.tmpl      |  8 ++++++++
 Configurations/unix-Makefile.tmpl    |  8 ++++++++
 Configurations/windows-makefile.tmpl |  8 ++++++++
 Configure                            | 22 ++++++++++++++++------
 doc/internal/man7/build.info.pod     |  6 ++++++
 6 files changed, 62 insertions(+), 8 deletions(-)

diff --git a/Configurations/common.tmpl b/Configurations/common.tmpl
index 5db3471fe2..e25a61fbed 100644
--- a/Configurations/common.tmpl
+++ b/Configurations/common.tmpl
@@ -137,6 +137,8 @@
  # 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;
@@ -171,6 +173,17 @@
      $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 {
@@ -463,11 +476,12 @@
  # 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($_);    }
diff --git a/Configurations/descrip.mms.tmpl b/Configurations/descrip.mms.tmpl
index 3f015a0eb5..abc344594d 100644
--- a/Configurations/descrip.mms.tmpl
+++ b/Configurations/descrip.mms.tmpl
@@ -795,6 +795,14 @@ reconfigure reconf :
       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}});
diff --git a/Configurations/unix-Makefile.tmpl b/Configurations/unix-Makefile.tmpl
index aa4b3ec0ec..610a6f6557 100644
--- a/Configurations/unix-Makefile.tmpl
+++ b/Configurations/unix-Makefile.tmpl
@@ -1305,6 +1305,14 @@ reconfigure reconf:
                  } @_;
   }
 
+  sub generatetarget {
+      my %args = @_;
+      my $deps = join(" ", @{$args{deps}});
+      return <<"EOF";
+$args{target}: $deps
+EOF
+  }
+
   sub generatesrc {
       my %args = @_;
       my $generator = join(" ", @{$args{generator}});
diff --git a/Configurations/windows-makefile.tmpl b/Configurations/windows-makefile.tmpl
index ce042d6ee8..f19efba7d1 100644
--- a/Configurations/windows-makefile.tmpl
+++ b/Configurations/windows-makefile.tmpl
@@ -627,6 +627,14 @@ reconfigure reconf:
      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}};
diff --git a/Configure b/Configure
index 12911d988a..e24564311e 100755
--- a/Configure
+++ b/Configure
@@ -2330,12 +2330,22 @@ EOF
 
         foreach (keys %depends) {
             my $dest = $_;
-            my $ddest = $dest eq "" ? "" : cleanfile($sourced, $_, $blddir);
+            my $ddest = $dest;
 
-            # 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 ($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 eq $src_configdata || ! -f $ddest) {
+                    $ddest = cleanfile($buildd, $_, $blddir);
+                }
             }
             foreach (@{$depends{$dest}}) {
                 my $d = cleanfile($sourced, $_, $blddir);
@@ -2628,7 +2638,7 @@ EOF
 
     ### 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
diff --git a/doc/internal/man7/build.info.pod b/doc/internal/man7/build.info.pod
index 5a2fdd13ed..9acfd02a8d 100644
--- a/doc/internal/man7/build.info.pod
+++ b/doc/internal/man7/build.info.pod
@@ -444,6 +444,12 @@ rather than the specific I<items>.
 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: