Configuration: rework how dependency making is handled
authorRichard Levitte <levitte@openssl.org>
Mon, 26 Apr 2021 07:17:05 +0000 (09:17 +0200)
committerRichard Levitte <levitte@openssl.org>
Wed, 28 Apr 2021 19:35:26 +0000 (21:35 +0200)
Previously, we had dependency making pretty much hard coded in the
build file templates, with a bit of an exception for Unix family
platforms, where we had different cases depending on what dependency
making program was found.

With the Embarcadero C++ builder, a separate scheme appeared, with a
different logic.

This change merges the two, and introduces two config target
attributes:

    makedepcmd          The program to use, where this is relevant.
                        This replaces the earlier configuration
                        attribute 'makedepprog'.
    makedep_scheme      This is a keyword that can be used by build
                        files templates to produce different sorts of
                        commands, but most importantly, to pass as
                        argument to util/add-depend.pl, which uses
                        this keyword as a "producer" for the
                        dependency lines.

If the config target doesn't define the 'makedep_scheme' attribute,
Configure tries to figure it out by looking for GCC compatible
compilers or for the 'makedepend' command.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
(Merged from https://github.com/openssl/openssl/pull/15006)

Configurations/10-main.conf
Configurations/50-cppbuilder.conf
Configurations/descrip.mms.tmpl
Configurations/platform/Unix.pm
Configurations/platform/mingw.pm
Configurations/unix-Makefile.tmpl
Configurations/windows-makefile.tmpl
Configure
util/add-depends.pl

index 882af5e..1e53f20 100644 (file)
@@ -1276,7 +1276,6 @@ my %targets = (
         template         => 1,
         CC               => "cl",
         CPP              => '"$(CC)" /EP /C',
-        make_depend      => '"$(CC)" /Zs /showIncludes',
         CFLAGS           => "/W3 /wd4090 /nologo",
         coutflag         => "/Fo",
         LD               => "link",
@@ -1285,6 +1284,8 @@ my %targets = (
         ldpostoutflag    => "",
         ld_resp_delim    => "\n",
         bin_lflags       => "setargv.obj",
+        makedepcmd       => '"$(CC)" /Zs /showIncludes',
+        makedep_scheme   => 'VC',
         AR               => "lib",
         ARFLAGS          => "/nologo",
         aroutflag        => "/out:",
@@ -1838,6 +1839,7 @@ my %targets = (
         dso_scheme       => "vms",
         thread_scheme    => "pthreads",
 
+        makedep_scheme   => 'VMS C',
         AS               => sub { vms_info()->{AS} },
         ASFLAGS          => sub { vms_info()->{ASFLAGS} },
         asoutflag        => sub { vms_info()->{asoutflag} },
index fad9052..f19928c 100644 (file)
@@ -6,10 +6,6 @@ my %targets = (
         thread_scheme    => "winthreads",
         cc               => "bcc32c",
         CPP              => "cpp32 -oCON -Sc -Sr",
-        # -Sx isn't documented, but 'cpp32 -H -S' explains it:
-        #
-        # -Sx     Omit preprocessed text in output
-        make_depend      => "cpp32 -oCON -Sx -Hp",
         defines          => add("WIN32_LEAN_AND_MEAN", "OPENSSL_SYS_WIN32",
                                 "L_ENDIAN", "DSO_WIN32", "_stricmp=stricmp",
                                 "_strnicmp=strnicmp", "_malloca=malloc",
@@ -22,6 +18,13 @@ my %targets = (
         bin_cflags       => "-tWC",
         lib_cflags       => shared("-tWD -D_WINDLL -D_DLL"),
         coutflag         => "-o",
+
+        # -Sx isn't documented, but 'cpp32 -H -S' explains it:
+        #
+        # -Sx     Omit preprocessed text in output
+        makedepcmd       => "cpp32 -oCON -Sx -Hp",
+        makedep_scheme   => "embarcadero",
+
         LD               => "ilink32",
         LDFLAGS          => picker(default => "-x -Gn -q -w-dup",
                                    debug   => '-j"$(BDS)\lib\win32c\debug" ' .
index efc0224..065854d 100644 (file)
@@ -523,7 +523,7 @@ distclean : clean
 depend : descrip.mms
 descrip.mms : FORCE
        @ ! {- output_off() if $disabled{makedepend}; "" -}
-       @ $(PERL) {- sourcefile("util", "add-depends.pl") -} "VMS C"
+       @ $(PERL) {- sourcefile("util", "add-depends.pl") -} "{- $config{makedep_scheme} -}"
        @ ! {- output_on() if $disabled{makedepend}; "" -}
 
 # Install helper targets #############################################
index f05ff67..0c03c07 100644 (file)
@@ -32,7 +32,7 @@ sub shlibextsimple      { (my $x = $target{shared_extension} || '.so')
                               =~ s|\.\$\(SHLIB_VERSION_NUMBER\)||;
                           $x; }
 sub shlibvariant        { $target{shlib_variant} || "" }
-sub makedepprog         { $disabled{makedepend} ? undef : $config{makedepprog} }
+sub makedepcmd          { $disabled{makedepend} ? undef : $config{makedepcmd} }
 
 # No conversion of assembler extension on Unix
 sub asm {
index d525ae8..c4dbce8 100644 (file)
@@ -23,7 +23,7 @@ sub resext              { '.res.obj' }
 sub shlibext            { '.dll' }
 sub shlibextimport      { $target{shared_import_extension} || '.dll.a' }
 sub shlibextsimple      { undef }
-sub makedepprog         { $disabled{makedepend} ? undef : $config{makedepprog} }
+sub makedepcmd          { $disabled{makedepend} ? undef : $config{makedepcmd} }
 
 (my $sover_filename = $config{shlib_version}) =~ s|\.|_|g;
 sub shlib_version_as_filename {
index be6036c..e2df304 100644 (file)
@@ -3,7 +3,8 @@
 ##
 ## {- join("\n## ", @autowarntext) -}
 {-
-     our $makedepprog = platform->makedepprog();
+     our $makedep_scheme = $config{makedep_scheme};
+     our $makedepcmd = platform->makedepcmd();
 
      sub windowsdll { $config{target} =~ /^(?:Cygwin|mingw)/ }
 
@@ -315,7 +316,7 @@ CXXFLAGS={- join(' ', @{$config{CXXFLAGS}}) -}
 LDFLAGS= {- join(' ', @{$config{LDFLAGS}}) -}
 EX_LIBS= {- join(' ', @{$config{LDLIBS}}) -}
 
-MAKEDEPEND={- $config{makedepprog} -}
+MAKEDEPEND={- $config{makedepcmd} -}
 
 PERL={- $config{PERL} -}
 
@@ -570,9 +571,7 @@ distclean: clean
 # concatenate only if that is true.
 depend:
        @: {- output_off() if $disabled{makedepend}; "" -}
-       @$(PERL) $(SRCDIR)/util/add-depends.pl {-
-                defined $makedepprog  && $makedepprog =~ /\/makedepend/
-                 ? 'makedepend' : 'gcc' -}
+       @$(PERL) $(SRCDIR)/util/add-depends.pl "{- $makedep_scheme -}"
        @: {- output_on() if $disabled{makedepend}; "" -}
 
 # Install helper targets #############################################
@@ -1516,8 +1515,7 @@ EOF
 $obj: $deps
        $cmd $incs $defs $cmdflags -c -o \$\@ $srcs
 EOF
-      } elsif (defined $makedepprog && $makedepprog !~ /\/makedepend/
-               && !grep /\.rc$/, @srcs) {
+      } elsif ($makedep_scheme eq 'gcc' && !grep /\.rc$/, @srcs) {
           $recipe .= <<"EOF";
 $obj: $deps
        $cmd $incs $defs $cmdflags -MMD -MF $dep.tmp -MT \$\@ -c -o \$\@ $srcs
@@ -1533,7 +1531,7 @@ EOF
 $obj: $deps
        $cmd $incs $defs $cmdflags $cmdcompile -o \$\@ $srcs
 EOF
-          if (defined $makedepprog  && $makedepprog =~ /\/makedepend/) {
+          if ($makedep_scheme eq 'makedepend') {
               $recipe .= <<"EOF";
        \$(MAKEDEPEND) -f- -Y -- $incs $cmdflags -- $srcs 2>/dev/null \\
            > $dep
index a5afe38..2cd003c 100644 (file)
@@ -457,7 +457,7 @@ distclean: clean
 
 depend:
        @ {- output_off() if $disabled{makedepend}; "" -}
-       @ "$(PERL)" "$(SRCDIR)\util\add-depends.pl" "VC"
+       @ "$(PERL)" "$(SRCDIR)\util\add-depends.pl" "{- $target{makedep_scheme} -}"
        @ {- output_on() if $disabled{makedepend}; "" -}
 
 # Install helper targets #############################################
@@ -809,7 +809,7 @@ EOF
                     lib => ' $(LIB_ASFLAGS)',
                     dso => ' $(DSO_ASFLAGS)',
                     bin => ' $(BIN_ASFLAGS)' } -> {$args{intent}};
-     my $makedepprog = $config{makedepprog};
+     my $makedepcmd = $config{makedepcmd} unless $disabled{makedepend};
      if ($srcs[0] =~ /\.rc$/) {
          my $res = platform->res($args{obj});
          return <<"EOF";
@@ -836,7 +836,7 @@ $obj: $deps
        \$(CC) $cflags $defs -c \$(COUTFLAG)\$\@ $srcs
 EOF
      $recipe .= <<"EOF"        unless $disabled{makedepend};
-       cmd /C "$target{make_depend} $cflags $defs $srcs > $dep 2>&1"
+       cmd /C "$makedepcmd $cflags $defs $srcs > $dep 2>&1"
 EOF
      return $recipe;
  }
index 6d0ffbf..b068b60 100755 (executable)
--- a/Configure
+++ b/Configure
@@ -1533,22 +1533,32 @@ unless ($disabled{asm}) {
 
 # Check for makedepend capabilities.
 if (!$disabled{makedepend}) {
-    if ($config{target} =~ /^(VC|BC|vms)-/) {
-        # For VC-, BC- and vms- targets, there's nothing more to do here.  The
-        # functionality is hard coded in the corresponding build files for
-        # cl/cpp32 (Windows) and CC/DECC (VMS).
+    # If the attribute makedep_scheme is defined, then we assume that the
+    # config target and its associated build file are programmed to deal
+    # with it.
+    # If makedep_scheme is undefined, we go looking for GCC compatible
+    # dependency making, and if that's not available, we try to fall back
+    # on 'makedepend'.
+    if ($target{makedep_scheme}) {
+        $config{makedep_scheme} = $target{makedep_scheme};
+        # If the makedepcmd attribute is defined, copy it.  If not, the
+        # build files will have to fend for themselves.
+        $config{makedepcmd} = $target{makedepcmd} if $target{makedepcmd};
     } elsif (($predefined_C{__GNUC__} // -1) >= 3
              && !($predefined_C{__APPLE_CC__} && !$predefined_C{__clang__})) {
         # We know that GNU C version 3 and up as well as all clang
         # versions support dependency generation, but Xcode did not
         # handle $cc -M before clang support (but claims __GNUC__ = 3)
-        $config{makedepprog} = "\$(CROSS_COMPILE)$config{CC}";
+        $config{makedep_scheme} = 'gcc';
     } else {
-        # In all other cases, we look for 'makedepend', and disable the
-        # capability if not found.
-        $config{makedepprog} = which('makedepend');
-        disable('unavailable', 'makedepend') unless $config{makedepprog};
+        # In all other cases, we look for 'makedepend', and set the
+        # makedep_scheme value if we found it.
+        $config{makedepcmd} = which('makedepend');
+        $config{makedep_scheme} = 'makedepend' if $config{makedepcmd};
     }
+
+    # If no depend scheme is set, we disable makedepend
+    disable('unavailable', 'makedepend') unless $config{makedep_scheme};
 }
 
 if (!$disabled{asm} && !$predefined_C{__MACH__} && $^O ne 'VMS') {
index 4a0f1d5..f145432 100644 (file)
@@ -154,21 +154,58 @@ my %procedures = (
             }
             return ($objfile, $depconv_cache{$line})
                 if defined $depconv_cache{$line};
-            print STDERR "DEBUG[VMS C]: ignoring $objfile <- $line\n"
+            print STDERR "DEBUG[$producer]: ignoring $objfile <- $line\n"
                 if $debug;
 
             return undef;
         },
     'VC' =>
         sub {
-            # On Windows, with Microsoft Visual C the flags /Zs /showIncludes
-            # give us the necessary output to be able to create dependencies
-            # that nmake (or any 'make' implementation) should be able to read,
-            # with a bit of help.  The output we're interested in looks like
-            # this (it always starts the same)
+            # With Microsoft Visual C the flags /Zs /showIncludes give us the
+            # necessary output to be able to create dependencies that nmake
+            # (or any 'make' implementation) should be able to read, with a
+            # bit of help.  The output we're interested in looks something
+            # like this (it always starts the same)
             #
             #   Note: including file: {whatever header file}
             #
+            # Since there's no object file name at all in that information,
+            # we must construct it ourselves.
+
+            (my $objfile = shift) =~ s|\.d$|.obj|i;
+            my $line = shift;
+
+            # There are also other lines mixed in, for example compiler
+            # warnings, so we simply discard anything that doesn't start with
+            # the Note:
+
+            if (/^Note: including file: */) {
+                (my $tail = $') =~ s/\s*\R$//;
+
+                # VC gives us absolute paths for all include files, so to
+                # remove system header dependencies, we need to check that
+                # they don't match $abs_srcdir or $abs_blddir.
+                $tail = canonpath($tail);
+
+                unless (defined $depconv_cache{$tail}) {
+                    my $dep = $tail;
+                    # Since we have already pre-populated the cache with
+                    # mappings for generated headers, we only need to deal
+                    # with the source tree.
+                    if ($dep =~ s|^\Q$abs_srcdir\E\\|\$(SRCDIR)\\|i) {
+                        $depconv_cache{$tail} = $dep;
+                    }
+                }
+                return ($objfile, '"'.$depconv_cache{$tail}.'"')
+                    if defined $depconv_cache{$tail};
+                print STDERR "DEBUG[$producer]: ignoring $objfile <- $tail\n"
+                    if $debug;
+            }
+
+            return undef;
+        },
+    'embarcadero' =>
+        sub {
             # With Embarcadero C++Builder's preprocessor (cpp32.exe) the -Hp
             # flag gives us the preprocessed output annotated with the following
             # note whenever a #include file is read:
@@ -176,7 +213,7 @@ my %procedures = (
             #    Including ->->{whatever header file}
             #
             # where each "->" indicates the nesting level of the #include.  The
-            # logic here is otherwise the same as the 'VC' case.
+            # logic here is otherwise the same as the 'VC' scheme.
             #
             # Since there's no object file name at all in that information,
             # we must construct it ourselves.
@@ -188,13 +225,13 @@ my %procedures = (
             # warnings, so we simply discard anything that doesn't start with
             # the Note:
 
-            if (/^Note: including file: */ or /^Including (->)*/) {
+            if (/^Including (->)*/) {
                 (my $tail = $') =~ s/\s*\R$//;
 
-                # VC gives us absolute paths for all include files, so to
-                # remove system header dependencies, we need to check that
-                # they don't match $abs_srcdir or $abs_blddir.  C++Builder gives
-                # us relative paths when possible, so convert to absolute paths.
+                # C++Builder gives us relative paths when possible, so to
+                # remove system header dependencies, we convert them to
+                # absolute paths and check that they don't match $abs_srcdir
+                # or $abs_blddir, just as the 'VC' scheme.
                 $tail = rel2abs($tail);
 
                 unless (defined $depconv_cache{$tail}) {
@@ -208,7 +245,7 @@ my %procedures = (
                 }
                 return ($objfile, '"'.$depconv_cache{$tail}.'"')
                     if defined $depconv_cache{$tail};
-                print STDERR "DEBUG[VC]: ignoring $objfile <- $tail\n"
+                print STDERR "DEBUG[$producer]: ignoring $objfile <- $tail\n"
                     if $debug;
             }
 
@@ -220,6 +257,7 @@ my %continuations = (
     'makedepend' => "\\",
     'VMS C' => "-",
     'VC' => "\\",
+    'embarcadero' => "\\",
 );
 
 die "Producer unrecognised: $producer\n"