From 2e535eb50aa9c6b73c796f668e1aef8bc17f14c4 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Mon, 26 Apr 2021 09:17:05 +0200 Subject: [PATCH] Configuration: rework how dependency making is handled 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 Reviewed-by: Matthias St. Pierre (Merged from https://github.com/openssl/openssl/pull/15006) --- Configurations/10-main.conf | 4 +- Configurations/50-cppbuilder.conf | 11 +++-- Configurations/descrip.mms.tmpl | 2 +- Configurations/platform/Unix.pm | 2 +- Configurations/platform/mingw.pm | 2 +- Configurations/unix-Makefile.tmpl | 14 +++--- Configurations/windows-makefile.tmpl | 6 +-- Configure | 28 ++++++++---- util/add-depends.pl | 64 ++++++++++++++++++++++------ 9 files changed, 92 insertions(+), 41 deletions(-) diff --git a/Configurations/10-main.conf b/Configurations/10-main.conf index 882af5e65b..1e53f20861 100644 --- a/Configurations/10-main.conf +++ b/Configurations/10-main.conf @@ -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} }, diff --git a/Configurations/50-cppbuilder.conf b/Configurations/50-cppbuilder.conf index fad905267b..f19928cb03 100644 --- a/Configurations/50-cppbuilder.conf +++ b/Configurations/50-cppbuilder.conf @@ -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" ' . diff --git a/Configurations/descrip.mms.tmpl b/Configurations/descrip.mms.tmpl index efc0224ecc..065854d2ea 100644 --- a/Configurations/descrip.mms.tmpl +++ b/Configurations/descrip.mms.tmpl @@ -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 ############################################# diff --git a/Configurations/platform/Unix.pm b/Configurations/platform/Unix.pm index f05ff67ad2..0c03c07930 100644 --- a/Configurations/platform/Unix.pm +++ b/Configurations/platform/Unix.pm @@ -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 { diff --git a/Configurations/platform/mingw.pm b/Configurations/platform/mingw.pm index d525ae8e57..c4dbce8041 100644 --- a/Configurations/platform/mingw.pm +++ b/Configurations/platform/mingw.pm @@ -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 { diff --git a/Configurations/unix-Makefile.tmpl b/Configurations/unix-Makefile.tmpl index be6036c227..e2df304061 100644 --- a/Configurations/unix-Makefile.tmpl +++ b/Configurations/unix-Makefile.tmpl @@ -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 diff --git a/Configurations/windows-makefile.tmpl b/Configurations/windows-makefile.tmpl index a5afe3848a..2cd003cf89 100644 --- a/Configurations/windows-makefile.tmpl +++ b/Configurations/windows-makefile.tmpl @@ -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; } diff --git a/Configure b/Configure index 6d0ffbf480..b068b60e66 100755 --- 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') { diff --git a/util/add-depends.pl b/util/add-depends.pl index 4a0f1d5a76..f1454323c5 100644 --- a/util/add-depends.pl +++ b/util/add-depends.pl @@ -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" -- 2.34.1