xref: /freebsd/crypto/openssl/util/add-depends.pl (revision e0c4386e7e71d93b0edc0c8fa156263fc4a8b0b6)
1*e0c4386eSCy Schubert#! /usr/bin/env perl
2*e0c4386eSCy Schubert# Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved.
3*e0c4386eSCy Schubert#
4*e0c4386eSCy Schubert# Licensed under the Apache License 2.0 (the "License").  You may not use
5*e0c4386eSCy Schubert# this file except in compliance with the License.  You can obtain a copy
6*e0c4386eSCy Schubert# in the file LICENSE in the source distribution or at
7*e0c4386eSCy Schubert# https://www.openssl.org/source/license.html
8*e0c4386eSCy Schubert
9*e0c4386eSCy Schubertuse strict;
10*e0c4386eSCy Schubertuse warnings;
11*e0c4386eSCy Schubert
12*e0c4386eSCy Schubertuse lib '.';
13*e0c4386eSCy Schubertuse configdata;
14*e0c4386eSCy Schubert
15*e0c4386eSCy Schubertuse File::Spec::Functions qw(:DEFAULT rel2abs);
16*e0c4386eSCy Schubertuse File::Compare qw(compare_text);
17*e0c4386eSCy Schubertuse feature 'state';
18*e0c4386eSCy Schubert
19*e0c4386eSCy Schubert# When using stat() on Windows, we can get it to perform better by avoid some
20*e0c4386eSCy Schubert# data.  This doesn't affect the mtime field, so we're not losing anything...
21*e0c4386eSCy Schubert${^WIN32_SLOPPY_STAT} = 1;
22*e0c4386eSCy Schubert
23*e0c4386eSCy Schubertmy $debug = $ENV{ADD_DEPENDS_DEBUG};
24*e0c4386eSCy Schubertmy $buildfile = $config{build_file};
25*e0c4386eSCy Schubertmy $build_mtime = (stat($buildfile))[9];
26*e0c4386eSCy Schubertmy $configdata_mtime = (stat('configdata.pm'))[9];
27*e0c4386eSCy Schubertmy $rebuild = 0;
28*e0c4386eSCy Schubertmy $depext = $target{dep_extension} || ".d";
29*e0c4386eSCy Schubertmy @depfiles =
30*e0c4386eSCy Schubert    sort
31*e0c4386eSCy Schubert    grep {
32*e0c4386eSCy Schubert        # This grep has side effects.  Not only does if check the existence
33*e0c4386eSCy Schubert        # of the dependency file given in $_, but it also checks if it's
34*e0c4386eSCy Schubert        # newer than the build file or older than configdata.pm, and if it
35*e0c4386eSCy Schubert        # is, sets $rebuild.
36*e0c4386eSCy Schubert        my @st = stat($_);
37*e0c4386eSCy Schubert        $rebuild = 1
38*e0c4386eSCy Schubert            if @st && ($st[9] > $build_mtime || $st[9] < $configdata_mtime);
39*e0c4386eSCy Schubert        scalar @st > 0;         # Determines the grep result
40*e0c4386eSCy Schubert    }
41*e0c4386eSCy Schubert    map { (my $x = $_) =~ s|\.o$|$depext|; $x; }
42*e0c4386eSCy Schubert    ( ( grep { $unified_info{sources}->{$_}->[0] =~ /\.cc?$/ }
43*e0c4386eSCy Schubert            keys %{$unified_info{sources}} ),
44*e0c4386eSCy Schubert      ( grep { $unified_info{shared_sources}->{$_}->[0] =~ /\.cc?$/ }
45*e0c4386eSCy Schubert            keys %{$unified_info{shared_sources}} ) );
46*e0c4386eSCy Schubert
47*e0c4386eSCy Schubertexit 0 unless $rebuild;
48*e0c4386eSCy Schubert
49*e0c4386eSCy Schubert# Ok, primary checks are done, time to do some real work
50*e0c4386eSCy Schubert
51*e0c4386eSCy Schubertmy $producer = shift @ARGV;
52*e0c4386eSCy Schubertdie "Producer not given\n" unless $producer;
53*e0c4386eSCy Schubert
54*e0c4386eSCy Schubertmy $srcdir = $config{sourcedir};
55*e0c4386eSCy Schubertmy $blddir = $config{builddir};
56*e0c4386eSCy Schubertmy $abs_srcdir = rel2abs($srcdir);
57*e0c4386eSCy Schubertmy $abs_blddir = rel2abs($blddir);
58*e0c4386eSCy Schubert
59*e0c4386eSCy Schubert# Convenient cache of absolute to relative map.  We start with filling it
60*e0c4386eSCy Schubert# with mappings for the known generated header files.  They are relative to
61*e0c4386eSCy Schubert# the current working directory, so that's an easy task.
62*e0c4386eSCy Schubert# NOTE: there's more than C header files that are generated.  They will also
63*e0c4386eSCy Schubert# generate entries in this map.  We could of course deal with C header files
64*e0c4386eSCy Schubert# only, but in case we decide to handle more than just C files in the future,
65*e0c4386eSCy Schubert# we already have the mechanism in place here.
66*e0c4386eSCy Schubert# NOTE2: we lower case the index to make it searchable without regard for
67*e0c4386eSCy Schubert# character case.  That could seem dangerous, but as long as we don't have
68*e0c4386eSCy Schubert# files we depend on in the same directory that only differ by character case,
69*e0c4386eSCy Schubert# we're fine.
70*e0c4386eSCy Schubertmy %depconv_cache =
71*e0c4386eSCy Schubert    map { catfile($abs_blddir, $_) => $_ }
72*e0c4386eSCy Schubert    keys %{$unified_info{generate}};
73*e0c4386eSCy Schubert
74*e0c4386eSCy Schubertmy %procedures = (
75*e0c4386eSCy Schubert    'gcc' =>
76*e0c4386eSCy Schubert        sub {
77*e0c4386eSCy Schubert            (my $objfile = shift) =~ s|\.d$|.o|i;
78*e0c4386eSCy Schubert            my $line = shift;
79*e0c4386eSCy Schubert
80*e0c4386eSCy Schubert            # Remove the original object file
81*e0c4386eSCy Schubert            $line =~ s|^.*\.o: | |;
82*e0c4386eSCy Schubert            # All we got now is a dependency, shave off surrounding spaces
83*e0c4386eSCy Schubert            $line =~ s/^\s+//;
84*e0c4386eSCy Schubert            $line =~ s/\s+$//;
85*e0c4386eSCy Schubert            # Also, shave off any continuation
86*e0c4386eSCy Schubert            $line =~ s/\s*\\$//;
87*e0c4386eSCy Schubert
88*e0c4386eSCy Schubert            # Split the line into individual header files, and keep those
89*e0c4386eSCy Schubert            # that exist in some form
90*e0c4386eSCy Schubert            my @headers;
91*e0c4386eSCy Schubert            for (split(/\s+/, $line)) {
92*e0c4386eSCy Schubert                my $x = rel2abs($_);
93*e0c4386eSCy Schubert
94*e0c4386eSCy Schubert                if (!$depconv_cache{$x}) {
95*e0c4386eSCy Schubert                    if (-f $x) {
96*e0c4386eSCy Schubert                        $depconv_cache{$x} = $_;
97*e0c4386eSCy Schubert                    }
98*e0c4386eSCy Schubert                }
99*e0c4386eSCy Schubert
100*e0c4386eSCy Schubert                if ($depconv_cache{$x}) {
101*e0c4386eSCy Schubert                    push @headers, $_;
102*e0c4386eSCy Schubert                } else {
103*e0c4386eSCy Schubert                    print STDERR "DEBUG[$producer]: ignoring $objfile <- $line\n"
104*e0c4386eSCy Schubert                        if $debug;
105*e0c4386eSCy Schubert                }
106*e0c4386eSCy Schubert            }
107*e0c4386eSCy Schubert            return ($objfile, join(' ', @headers)) if @headers;
108*e0c4386eSCy Schubert            return undef;
109*e0c4386eSCy Schubert    },
110*e0c4386eSCy Schubert    'makedepend' =>
111*e0c4386eSCy Schubert        sub {
112*e0c4386eSCy Schubert            # makedepend, in its infinite wisdom, wants to have the object file
113*e0c4386eSCy Schubert            # in the same directory as the source file.  This doesn't work too
114*e0c4386eSCy Schubert            # well with out-of-source-tree builds, so we must resort to tricks
115*e0c4386eSCy Schubert            # to get things right.  Fortunately, the .d files are always placed
116*e0c4386eSCy Schubert            # parallel with the object files, so all we need to do is construct
117*e0c4386eSCy Schubert            # the object file name from the dep file name.
118*e0c4386eSCy Schubert            (my $objfile = shift) =~ s|\.d$|.o|i;
119*e0c4386eSCy Schubert            my $line = shift;
120*e0c4386eSCy Schubert
121*e0c4386eSCy Schubert            # Discard comments
122*e0c4386eSCy Schubert            return undef if $line =~ /^(#.*|\s*)$/;
123*e0c4386eSCy Schubert
124*e0c4386eSCy Schubert            # Remove the original object file
125*e0c4386eSCy Schubert            $line =~ s|^.*\.o: | |;
126*e0c4386eSCy Schubert            # Also, remove any dependency that starts with a /, because those
127*e0c4386eSCy Schubert            # are typically system headers
128*e0c4386eSCy Schubert            $line =~ s/\s+\/(\\.|\S)*//g;
129*e0c4386eSCy Schubert            # Finally, discard all empty lines
130*e0c4386eSCy Schubert            return undef if $line =~ /^\s*$/;
131*e0c4386eSCy Schubert
132*e0c4386eSCy Schubert            # All we got now is a dependency, just shave off surrounding spaces
133*e0c4386eSCy Schubert            $line =~ s/^\s+//;
134*e0c4386eSCy Schubert            $line =~ s/\s+$//;
135*e0c4386eSCy Schubert            return ($objfile, $line);
136*e0c4386eSCy Schubert        },
137*e0c4386eSCy Schubert    'VMS C' =>
138*e0c4386eSCy Schubert        sub {
139*e0c4386eSCy Schubert            state $abs_srcdir_shaved = undef;
140*e0c4386eSCy Schubert            state $srcdir_shaved = undef;
141*e0c4386eSCy Schubert
142*e0c4386eSCy Schubert            unless (defined $abs_srcdir_shaved) {
143*e0c4386eSCy Schubert                ($abs_srcdir_shaved = $abs_srcdir) =~ s|[>\]]$||;
144*e0c4386eSCy Schubert                ($srcdir_shaved = $srcdir) =~ s|[>\]]$||;
145*e0c4386eSCy Schubert            }
146*e0c4386eSCy Schubert
147*e0c4386eSCy Schubert            # current versions of DEC / Compaq / HP / VSI C strips away all
148*e0c4386eSCy Schubert            # directory information from the object file, so we must insert it
149*e0c4386eSCy Schubert            # back.  To make life simpler, we simply replace it with the
150*e0c4386eSCy Schubert            # corresponding .D file that's had its extension changed.  Since
151*e0c4386eSCy Schubert            # .D files are always written parallel to the object files, we
152*e0c4386eSCy Schubert            # thereby get the directory information for free.
153*e0c4386eSCy Schubert            (my $objfile = shift) =~ s|\.D$|.OBJ|i;
154*e0c4386eSCy Schubert            my $line = shift;
155*e0c4386eSCy Schubert
156*e0c4386eSCy Schubert            # Shave off the target.
157*e0c4386eSCy Schubert            #
158*e0c4386eSCy Schubert            # The pattern for target and dependencies will always take this
159*e0c4386eSCy Schubert            # form:
160*e0c4386eSCy Schubert            #
161*e0c4386eSCy Schubert            #   target SPACE : SPACE deps
162*e0c4386eSCy Schubert            #
163*e0c4386eSCy Schubert            # This is so a volume delimiter (a : without any spaces around it)
164*e0c4386eSCy Schubert            # won't get mixed up with the target / deps delimiter.  We use this
165*e0c4386eSCy Schubert            # to easily identify what needs to be removed.
166*e0c4386eSCy Schubert            m|\s:\s|; $line = $';
167*e0c4386eSCy Schubert
168*e0c4386eSCy Schubert            # We know that VMS has system header files in text libraries,
169*e0c4386eSCy Schubert            # extension .TLB.  We also know that our header files aren't stored
170*e0c4386eSCy Schubert            # in text libraries.  Finally, we know that VMS C produces exactly
171*e0c4386eSCy Schubert            # one dependency per line, so we simply discard any line ending with
172*e0c4386eSCy Schubert            # .TLB.
173*e0c4386eSCy Schubert            return undef if /\.TLB\s*$/;
174*e0c4386eSCy Schubert
175*e0c4386eSCy Schubert            # All we got now is a dependency, just shave off surrounding spaces
176*e0c4386eSCy Schubert            $line =~ s/^\s+//;
177*e0c4386eSCy Schubert            $line =~ s/\s+$//;
178*e0c4386eSCy Schubert
179*e0c4386eSCy Schubert            # VMS C gives us absolute paths, always.  Let's see if we can
180*e0c4386eSCy Schubert            # make them relative instead.
181*e0c4386eSCy Schubert            $line = canonpath($line);
182*e0c4386eSCy Schubert
183*e0c4386eSCy Schubert            unless (defined $depconv_cache{$line}) {
184*e0c4386eSCy Schubert                my $dep = $line;
185*e0c4386eSCy Schubert                # Since we have already pre-populated the cache with
186*e0c4386eSCy Schubert                # mappings for generated headers, we only need to deal
187*e0c4386eSCy Schubert                # with the source tree.
188*e0c4386eSCy Schubert                if ($dep =~ s|^\Q$abs_srcdir_shaved\E([\.>\]])?|$srcdir_shaved$1|i) {
189*e0c4386eSCy Schubert                    # Also check that the header actually exists
190*e0c4386eSCy Schubert                    if (-f $line) {
191*e0c4386eSCy Schubert                        $depconv_cache{$line} = $dep;
192*e0c4386eSCy Schubert                    }
193*e0c4386eSCy Schubert                }
194*e0c4386eSCy Schubert            }
195*e0c4386eSCy Schubert            return ($objfile, $depconv_cache{$line})
196*e0c4386eSCy Schubert                if defined $depconv_cache{$line};
197*e0c4386eSCy Schubert            print STDERR "DEBUG[$producer]: ignoring $objfile <- $line\n"
198*e0c4386eSCy Schubert                if $debug;
199*e0c4386eSCy Schubert
200*e0c4386eSCy Schubert            return undef;
201*e0c4386eSCy Schubert        },
202*e0c4386eSCy Schubert    'VC' =>
203*e0c4386eSCy Schubert        sub {
204*e0c4386eSCy Schubert            # With Microsoft Visual C the flags /Zs /showIncludes give us the
205*e0c4386eSCy Schubert            # necessary output to be able to create dependencies that nmake
206*e0c4386eSCy Schubert            # (or any 'make' implementation) should be able to read, with a
207*e0c4386eSCy Schubert            # bit of help.  The output we're interested in looks something
208*e0c4386eSCy Schubert            # like this (it always starts the same)
209*e0c4386eSCy Schubert            #
210*e0c4386eSCy Schubert            #   Note: including file: {whatever header file}
211*e0c4386eSCy Schubert            #
212*e0c4386eSCy Schubert            # This output is localized, so for example, the German pack gives
213*e0c4386eSCy Schubert            # us this:
214*e0c4386eSCy Schubert            #
215*e0c4386eSCy Schubert            #   Hinweis: Einlesen der Datei:   {whatever header file}
216*e0c4386eSCy Schubert            #
217*e0c4386eSCy Schubert            # To accomodate, we need to use a very general regular expression
218*e0c4386eSCy Schubert            # to parse those lines.
219*e0c4386eSCy Schubert            #
220*e0c4386eSCy Schubert            # Since there's no object file name at all in that information,
221*e0c4386eSCy Schubert            # we must construct it ourselves.
222*e0c4386eSCy Schubert
223*e0c4386eSCy Schubert            (my $objfile = shift) =~ s|\.d$|.obj|i;
224*e0c4386eSCy Schubert            my $line = shift;
225*e0c4386eSCy Schubert
226*e0c4386eSCy Schubert            # There are also other lines mixed in, for example compiler
227*e0c4386eSCy Schubert            # warnings, so we simply discard anything that doesn't start with
228*e0c4386eSCy Schubert            # the Note:
229*e0c4386eSCy Schubert
230*e0c4386eSCy Schubert            if (/^[^:]*: [^:]*: */) {
231*e0c4386eSCy Schubert                (my $tail = $') =~ s/\s*\R$//;
232*e0c4386eSCy Schubert
233*e0c4386eSCy Schubert                # VC gives us absolute paths for all include files, so to
234*e0c4386eSCy Schubert                # remove system header dependencies, we need to check that
235*e0c4386eSCy Schubert                # they don't match $abs_srcdir or $abs_blddir.
236*e0c4386eSCy Schubert                $tail = canonpath($tail);
237*e0c4386eSCy Schubert
238*e0c4386eSCy Schubert                unless (defined $depconv_cache{$tail}) {
239*e0c4386eSCy Schubert                    my $dep = $tail;
240*e0c4386eSCy Schubert                    # Since we have already pre-populated the cache with
241*e0c4386eSCy Schubert                    # mappings for generated headers, we only need to deal
242*e0c4386eSCy Schubert                    # with the source tree.
243*e0c4386eSCy Schubert                    if ($dep =~ s|^\Q$abs_srcdir\E\\|\$(SRCDIR)\\|i) {
244*e0c4386eSCy Schubert                        # Also check that the header actually exists
245*e0c4386eSCy Schubert                        if (-f $line) {
246*e0c4386eSCy Schubert                            $depconv_cache{$tail} = $dep;
247*e0c4386eSCy Schubert                        }
248*e0c4386eSCy Schubert                    }
249*e0c4386eSCy Schubert                }
250*e0c4386eSCy Schubert                return ($objfile, '"'.$depconv_cache{$tail}.'"')
251*e0c4386eSCy Schubert                    if defined $depconv_cache{$tail};
252*e0c4386eSCy Schubert                print STDERR "DEBUG[$producer]: ignoring $objfile <- $tail\n"
253*e0c4386eSCy Schubert                    if $debug;
254*e0c4386eSCy Schubert            }
255*e0c4386eSCy Schubert
256*e0c4386eSCy Schubert            return undef;
257*e0c4386eSCy Schubert        },
258*e0c4386eSCy Schubert    'embarcadero' =>
259*e0c4386eSCy Schubert        sub {
260*e0c4386eSCy Schubert            # With Embarcadero C++Builder's preprocessor (cpp32.exe) the -Sx -Hp
261*e0c4386eSCy Schubert            # flags give us the list of #include files read, like the following:
262*e0c4386eSCy Schubert            #
263*e0c4386eSCy Schubert            #   Including ->->{whatever header file}
264*e0c4386eSCy Schubert            #
265*e0c4386eSCy Schubert            # where each "->" indicates the nesting level of the #include.  The
266*e0c4386eSCy Schubert            # logic here is otherwise the same as the 'VC' scheme.
267*e0c4386eSCy Schubert            #
268*e0c4386eSCy Schubert            # Since there's no object file name at all in that information,
269*e0c4386eSCy Schubert            # we must construct it ourselves.
270*e0c4386eSCy Schubert
271*e0c4386eSCy Schubert            (my $objfile = shift) =~ s|\.d$|.obj|i;
272*e0c4386eSCy Schubert            my $line = shift;
273*e0c4386eSCy Schubert
274*e0c4386eSCy Schubert            # There are also other lines mixed in, for example compiler
275*e0c4386eSCy Schubert            # warnings, so we simply discard anything that doesn't start with
276*e0c4386eSCy Schubert            # the Note:
277*e0c4386eSCy Schubert
278*e0c4386eSCy Schubert            if (/^Including (->)*/) {
279*e0c4386eSCy Schubert                (my $tail = $') =~ s/\s*\R$//;
280*e0c4386eSCy Schubert
281*e0c4386eSCy Schubert                # C++Builder gives us relative paths when possible, so to
282*e0c4386eSCy Schubert                # remove system header dependencies, we convert them to
283*e0c4386eSCy Schubert                # absolute paths and check that they don't match $abs_srcdir
284*e0c4386eSCy Schubert                # or $abs_blddir, just as the 'VC' scheme.
285*e0c4386eSCy Schubert                $tail = rel2abs($tail);
286*e0c4386eSCy Schubert
287*e0c4386eSCy Schubert                unless (defined $depconv_cache{$tail}) {
288*e0c4386eSCy Schubert                    my $dep = $tail;
289*e0c4386eSCy Schubert                    # Since we have already pre-populated the cache with
290*e0c4386eSCy Schubert                    # mappings for generated headers, we only need to deal
291*e0c4386eSCy Schubert                    # with the source tree.
292*e0c4386eSCy Schubert                    if ($dep =~ s|^\Q$abs_srcdir\E\\|\$(SRCDIR)\\|i) {
293*e0c4386eSCy Schubert                        # Also check that the header actually exists
294*e0c4386eSCy Schubert                        if (-f $line) {
295*e0c4386eSCy Schubert                            $depconv_cache{$tail} = $dep;
296*e0c4386eSCy Schubert                        }
297*e0c4386eSCy Schubert                    }
298*e0c4386eSCy Schubert                }
299*e0c4386eSCy Schubert                return ($objfile, '"'.$depconv_cache{$tail}.'"')
300*e0c4386eSCy Schubert                    if defined $depconv_cache{$tail};
301*e0c4386eSCy Schubert                print STDERR "DEBUG[$producer]: ignoring $objfile <- $tail\n"
302*e0c4386eSCy Schubert                    if $debug;
303*e0c4386eSCy Schubert            }
304*e0c4386eSCy Schubert
305*e0c4386eSCy Schubert            return undef;
306*e0c4386eSCy Schubert        },
307*e0c4386eSCy Schubert);
308*e0c4386eSCy Schubertmy %continuations = (
309*e0c4386eSCy Schubert    'gcc' => "\\",
310*e0c4386eSCy Schubert    'makedepend' => "\\",
311*e0c4386eSCy Schubert    'VMS C' => "-",
312*e0c4386eSCy Schubert    'VC' => "\\",
313*e0c4386eSCy Schubert    'embarcadero' => "\\",
314*e0c4386eSCy Schubert);
315*e0c4386eSCy Schubert
316*e0c4386eSCy Schubertdie "Producer unrecognised: $producer\n"
317*e0c4386eSCy Schubert    unless exists $procedures{$producer} && exists $continuations{$producer};
318*e0c4386eSCy Schubert
319*e0c4386eSCy Schubertmy $procedure = $procedures{$producer};
320*e0c4386eSCy Schubertmy $continuation = $continuations{$producer};
321*e0c4386eSCy Schubert
322*e0c4386eSCy Schubertmy $buildfile_new = "$buildfile-$$";
323*e0c4386eSCy Schubert
324*e0c4386eSCy Schubertmy %collect = ();
325*e0c4386eSCy Schubertforeach my $depfile (@depfiles) {
326*e0c4386eSCy Schubert    open IDEP,$depfile or die "Trying to read $depfile: $!\n";
327*e0c4386eSCy Schubert    while (<IDEP>) {
328*e0c4386eSCy Schubert        s|\R$||;                # The better chomp
329*e0c4386eSCy Schubert        my ($target, $deps) = $procedure->($depfile, $_);
330*e0c4386eSCy Schubert        $collect{$target}->{$deps} = 1 if defined $target;
331*e0c4386eSCy Schubert    }
332*e0c4386eSCy Schubert    close IDEP;
333*e0c4386eSCy Schubert}
334*e0c4386eSCy Schubert
335*e0c4386eSCy Schubertopen IBF, $buildfile or die "Trying to read $buildfile: $!\n";
336*e0c4386eSCy Schubertopen OBF, '>', $buildfile_new or die "Trying to write $buildfile_new: $!\n";
337*e0c4386eSCy Schubertwhile (<IBF>) {
338*e0c4386eSCy Schubert    last if /^# DO NOT DELETE THIS LINE/;
339*e0c4386eSCy Schubert    print OBF or die "$!\n";
340*e0c4386eSCy Schubert}
341*e0c4386eSCy Schubertclose IBF;
342*e0c4386eSCy Schubert
343*e0c4386eSCy Schubertprint OBF "# DO NOT DELETE THIS LINE -- make depend depends on it.\n";
344*e0c4386eSCy Schubert
345*e0c4386eSCy Schubertforeach my $target (sort keys %collect) {
346*e0c4386eSCy Schubert    my $prefix = $target . ' :';
347*e0c4386eSCy Schubert    my @deps = sort keys %{$collect{$target}};
348*e0c4386eSCy Schubert
349*e0c4386eSCy Schubert    while (@deps) {
350*e0c4386eSCy Schubert        my $buf = $prefix;
351*e0c4386eSCy Schubert        $prefix = '';
352*e0c4386eSCy Schubert
353*e0c4386eSCy Schubert        while (@deps && ($buf eq ''
354*e0c4386eSCy Schubert                         || length($buf) + length($deps[0]) <= 77)) {
355*e0c4386eSCy Schubert            $buf .= ' ' . shift @deps;
356*e0c4386eSCy Schubert        }
357*e0c4386eSCy Schubert        $buf .= ' '.$continuation if @deps;
358*e0c4386eSCy Schubert
359*e0c4386eSCy Schubert        print OBF $buf,"\n" or die "Trying to print: $!\n"
360*e0c4386eSCy Schubert    }
361*e0c4386eSCy Schubert}
362*e0c4386eSCy Schubert
363*e0c4386eSCy Schubertclose OBF;
364*e0c4386eSCy Schubert
365*e0c4386eSCy Schubertif (compare_text($buildfile_new, $buildfile) != 0) {
366*e0c4386eSCy Schubert    rename $buildfile_new, $buildfile
367*e0c4386eSCy Schubert        or die "Trying to rename $buildfile_new -> $buildfile: $!\n";
368*e0c4386eSCy Schubert}
369*e0c4386eSCy Schubert
370*e0c4386eSCy SchubertEND {
371*e0c4386eSCy Schubert    # On VMS, we want to remove all generations of this file, in case there
372*e0c4386eSCy Schubert    # are more than one, so we loop.
373*e0c4386eSCy Schubert    if (defined $buildfile_new) {
374*e0c4386eSCy Schubert        while (unlink $buildfile_new) {}
375*e0c4386eSCy Schubert    }
376*e0c4386eSCy Schubert}
377