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