summaryrefslogtreecommitdiff
path: root/ACE/MPC/modules/AutomakeWorkspaceCreator.pm
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/MPC/modules/AutomakeWorkspaceCreator.pm')
-rw-r--r--ACE/MPC/modules/AutomakeWorkspaceCreator.pm778
1 files changed, 778 insertions, 0 deletions
diff --git a/ACE/MPC/modules/AutomakeWorkspaceCreator.pm b/ACE/MPC/modules/AutomakeWorkspaceCreator.pm
new file mode 100644
index 00000000000..e3cdf9c6048
--- /dev/null
+++ b/ACE/MPC/modules/AutomakeWorkspaceCreator.pm
@@ -0,0 +1,778 @@
+package AutomakeWorkspaceCreator;
+
+# ************************************************************
+# Description : A Automake Workspace (Makefile) creator
+# Author : J.T. Conklin & Steve Huston
+# Create Date : 5/13/2002
+# ************************************************************
+
+# ************************************************************
+# Pragmas
+# ************************************************************
+
+use strict;
+use File::Copy;
+
+use AutomakeProjectCreator;
+use WorkspaceCreator;
+use WorkspaceHelper;
+
+use vars qw(@ISA);
+@ISA = qw(WorkspaceCreator);
+
+# ************************************************************
+# Data Section
+# ************************************************************
+
+my $acfile = 'configure.ac';
+my $acmfile = 'configure.ac.Makefiles';
+
+# ************************************************************
+# Subroutine Section
+# ************************************************************
+
+sub compare_output {
+ return 1;
+}
+
+
+sub files_are_different {
+ my($self, $old, $new) = @_;
+ my $diff = 1;
+ if (-r $old) {
+ my $lh = new FileHandle();
+ my $rh = new FileHandle();
+ if (open($lh, $old)) {
+ if (open($rh, $new)) {
+ my $done = 0;
+ my $lline;
+ my $rline;
+
+ $diff = 0;
+ do {
+ $lline = <$lh>;
+ $rline = <$rh>;
+ if (defined $lline) {
+ if (defined $rline) {
+ $lline =~ s/#.*//;
+ $rline =~ s/#.*//;
+ $diff = 1 if ($lline ne $rline);
+ }
+ else {
+ $done = 1;
+ }
+ }
+ else {
+ $diff = 1 if (defined $rline);
+ $done = 1;
+ }
+ } while(!$done && !$diff);
+ close($rh);
+ }
+ close($lh);
+ }
+ }
+ return $diff;
+}
+
+
+sub workspace_file_name {
+ return $_[0]->get_modified_workspace_name('Makefile', '.am');
+}
+
+
+sub workspace_per_project {
+ #my $self = shift;
+ return 1;
+}
+
+
+sub pre_workspace {
+ my($self, $fh) = @_;
+ my $crlf = $self->crlf();
+
+ $self->print_workspace_comment($fh,
+ '## Process this file with automake to create Makefile.in', $crlf,
+ '##', $crlf,
+ '## ', '$', 'Id', '$', $crlf,
+ '##', $crlf,
+ '## This file was generated by MPC. Any changes made directly to', $crlf,
+ '## this file will be lost the next time it is generated.', $crlf,
+ '##', $crlf,
+ '## MPC Command:', $crlf,
+ '## ', $self->create_command_line_string($0, @ARGV), $crlf, $crlf);
+}
+
+
+sub write_comps {
+ my($self, $fh, $creator, $toplevel) = @_;
+ my $projects = $self->get_projects();
+ my @list = $self->sort_dependencies($projects);
+ my $crlf = $self->crlf();
+ my %unique;
+ my @dirs;
+ my @locals;
+ my %proj_dir_seen;
+ my $have_subdirs = 0;
+ my $outdir = $self->get_outdir();
+ my $cond = '--';
+
+ ## This step writes a configure.ac.Makefiles list into the starting
+ ## directory. The list contains of all the Makefiles generated down
+ ## the tree. configure.ac can include this to get an up-to-date list
+ ## of all the involved Makefiles.
+ my $mfh;
+ my $makefile;
+ if ($toplevel) {
+ my $need_acmfile = 1;
+ if (! -e "$outdir/$acfile") {
+ my $acfh = new FileHandle();
+ if (open($acfh, ">$outdir/$acfile")) {
+ print $acfh "AC_INIT(", $self->get_workspace_name(), ", 1.0)$crlf",
+ "AM_INIT_AUTOMAKE([1.9])$crlf",
+ $crlf,
+ "AC_PROG_CXX$crlf",
+ "AC_PROG_CXXCPP$crlf",
+ "AC_PROG_LIBTOOL$crlf",
+ $crlf;
+
+ my $fp = $creator->get_feature_parser();
+ my $features = $fp->get_names();
+ my %assoc = %{$self->get_associated_projects()};
+ foreach my $feature (sort @$features) {
+ print $acfh 'AM_CONDITIONAL(BUILD_', uc($feature),
+ ', ', ($fp->get_value($feature) ? 'true' : 'false'),
+ ')', $crlf;
+ delete $assoc{$feature};
+ }
+ foreach my $akey (keys %assoc) {
+ print $acfh 'AM_CONDITIONAL(BUILD_', uc($akey), ', true)', $crlf
+ if ($akey ne $cond);
+ }
+
+ print $acfh $crlf,
+ "m4_include([$acmfile])$crlf",
+ $crlf,
+ "AC_OUTPUT$crlf";
+ close($acfh);
+ }
+ }
+ else {
+ $self->information("$acfile already exists.");
+ $need_acmfile = !$self->edit_config_ac("$outdir/$acfile", \@list);
+ }
+
+ if ($need_acmfile) {
+ unlink("$outdir/$acmfile");
+ $mfh = new FileHandle();
+ open($mfh, ">$outdir/$acmfile");
+ ## The top-level is never listed as a dependency, so it needs to be
+ ## added explicitly.
+ $makefile = $self->mpc_basename($self->get_current_output_name());
+ $makefile =~ s/\.am$//;
+ print $mfh "AC_CONFIG_FILES([ $makefile ])$crlf";
+ $proj_dir_seen{'.'} = 1;
+ }
+ }
+
+ ## If we're writing a configure.ac.Makefiles file, every seen project
+ ## goes into it. Since we only write this at the starting directory
+ ## level, it'll include all projects processed at this level and below.
+ foreach my $dep (@list) {
+ if ($mfh) {
+ ## There should be a Makefile at each level, but it's not a project,
+ ## it's a workspace; therefore, it's not in the list of projects.
+ ## Since we're consolidating all the project files into one workspace
+ ## Makefile.am per directory level, be sure to add that Makefile.am
+ ## entry at each level there's a project dependency.
+ my $dep_dir = $self->mpc_dirname($dep);
+ if (!defined $proj_dir_seen{$dep_dir}) {
+ $proj_dir_seen{$dep_dir} = 1;
+ ## If there are directory levels between project-containing
+ ## directories (for example, at this time in
+ ## ACE_wrappers/apps/JAWS/server, there are no projects at the
+ ## apps or apps/JAWS level) we need to insert the Makefile
+ ## entries for the levels without projects. They won't be listed
+ ## in @list but are needed for make to traverse intervening directory
+ ## levels down to where the project(s) to build are.
+ my @dirs = split /\//, $dep_dir;
+ my $inter_dir = "";
+ foreach my $dep (@dirs) {
+ $inter_dir .= $dep;
+ if (!defined $proj_dir_seen{$inter_dir}) {
+ $proj_dir_seen{$inter_dir} = 1;
+ print $mfh "AC_CONFIG_FILES([ $inter_dir/$makefile ])$crlf";
+ }
+ $inter_dir .= '/';
+ }
+ print $mfh "AC_CONFIG_FILES([ $dep_dir/$makefile ])$crlf";
+ }
+ }
+
+ ## Get a unique list of next-level directories for SUBDIRS.
+ ## To make sure we keep the dependencies correct, insert the '.' for
+ ## any local projects in the proper place. Remember if any subdirs
+ ## are seen to know if we need a SUBDIRS entry generated.
+ my $dir = $self->get_first_level_directory($dep);
+ if (!defined $unique{$dir}) {
+ $unique{$dir} = 1;
+ unshift(@dirs, $dir);
+ }
+ if ($dir eq '.') {
+ ## At each directory level, each project is written into a separate
+ ## Makefile.<project>.am file. To bring these back into the build
+ ## process, they'll be sucked back into the workspace Makefile.am file.
+ ## Remember which ones to pull in at this level.
+ unshift(@locals, $dep);
+ }
+ else {
+ $have_subdirs = 1;
+ }
+ }
+ close($mfh) if ($mfh);
+
+ # The Makefile.<project>.am files append values to build target macros
+ # for each program/library to build. When using conditionals, however,
+ # a plain empty assignment is done outside the conditional to be sure
+ # that each append can be done regardless of the condition test. Because
+ # automake fails if the first isn't a plain assignment, we need to resolve
+ # these situations when combining the files. The code below makes sure
+ # that there's always a plain assignment, whether it's one outside a
+ # conditional or the first append is changed to a simple assignment.
+ #
+ # We should consider extending this to support all macros that match
+ # automake's uniform naming convention. A true perl wizard probably
+ # would be able to do this in a single line of code.
+
+ my %seen;
+ my %conditional_targets;
+ my %unconditional_targets;
+ my %first_instance_unconditional;
+ my $installable_headers;
+ my $installable_pkgconfig;
+ my $includedir;
+ my $project_name;
+
+ ## To avoid unnecessarily emitting blank assignments, rip through the
+ ## Makefile.<project>.am files and check for conditions.
+ if (@locals) {
+ my $pfh = new FileHandle();
+ foreach my $local (reverse @locals) {
+ if ($local =~ /Makefile\.(.*)\.am/) {
+ $project_name = $1;
+ }
+ else {
+ $project_name = 'nobase';
+ }
+
+ if (open($pfh, "$outdir/$local")) {
+ my $in_condition = 0;
+ my $regok = $self->escape_regex_special($project_name);
+ my $inc_pattern = $regok . '_include_HEADERS';
+ my $pkg_pattern = $regok . '_pkginclude_HEADERS';
+ while (<$pfh>) {
+ # Don't look at comments
+ next if (/^#/);
+
+ $in_condition++ if (/^if\s*/);
+ $in_condition-- if (/^endif\s*/);
+
+ if ( /(^[a-zA-Z][a-zA-Z0-9_]*_(PROGRAMS|LIBRARIES|LTLIBRARIES|LISP|PYTHON|JAVA|SCRIPTS|DATA|SOURCES|HEADERS|MANS|TEXINFOS|LIBADD|LDADD|DEPENDENCIES))\s*\+=\s*/
+ || /(^CLEANFILES)\s*\+=\s*/
+ || /(^EXTRA_DIST)\s*\+=\s*/
+ ) {
+
+ if ($in_condition) {
+ $conditional_targets{$1}++;
+ } else {
+ if (! $seen{$1} ) {
+ $first_instance_unconditional{$1} = 1;
+ }
+ $unconditional_targets{$1}++;
+ }
+ $seen{$1} = 1;
+
+ $installable_pkgconfig= 1 if (/^pkgconfig_DATA/);
+ $installable_headers = 1
+ if (/^$inc_pattern\s*\+=\s*/ || /^$pkg_pattern\s*\+=\s*/);
+ }
+ elsif (/includedir\s*=\s*(.*)/) {
+ $includedir = $1;
+ }
+ }
+
+ close($pfh);
+ $in_condition = 0;
+ }
+ else {
+ $self->error("Unable to open $local for reading.");
+ }
+ }
+ }
+
+ #
+ # Clear seen hash
+ #
+ %seen = ();
+
+ ## Print out the Makefile.am.
+ my $wsHelper = WorkspaceHelper::get($self);
+ my $convert_header_name;
+ if ((!defined $includedir && $installable_headers)
+ || $installable_pkgconfig) {
+ if (!defined $includedir && $installable_headers) {
+ my $incdir = $wsHelper->modify_value('includedir',
+ $self->get_includedir());
+ if ($incdir ne '') {
+ print $fh "includedir = \@includedir\@$incdir$crlf";
+ $convert_header_name = 1;
+ }
+ }
+ if ($installable_pkgconfig) {
+ print $fh "pkgconfigdir = \@libdir\@/pkgconfig$crlf";
+ }
+
+ print $fh $crlf;
+ }
+
+ if (@locals) {
+ my($status, $error) = $wsHelper->write_settings($self, $fh, @locals);
+ if (!$status) {
+ $self->error($error);
+ }
+ }
+
+ ## Create the SUBDIRS setting. If there are associated projects, then
+ ## we will also set up conditionals for it as well.
+ if ($have_subdirs == 1) {
+ my $assoc = $self->get_associated_projects();
+ my @aorder;
+ my %afiles;
+ my $entry = " \\$crlf ";
+ print $fh 'SUBDIRS =';
+ foreach my $dir (reverse @dirs) {
+ my $found;
+ foreach my $akey (keys %$assoc) {
+ if (defined $$assoc{$akey}->{$dir}) {
+ if ($akey eq $cond) {
+ if ($toplevel) {
+ print $fh $entry, '@', $dir, '@';
+ $found = 1;
+ }
+ }
+ else {
+ push(@aorder, $akey);
+ push(@{$afiles{$akey}}, $dir);
+ $found = 1;
+ }
+ last;
+ }
+ elsif ($toplevel && defined $$assoc{$akey}->{uc($dir)} &&
+ $akey eq $cond) {
+ print $fh $entry, '@', uc($dir), '@';
+ $found = 1;
+ last;
+ }
+ }
+ print $fh $entry, $dir if (!$found);
+ }
+ print $fh $crlf;
+ my $second = 1;
+ foreach my $aorder (@aorder) {
+ if (defined $afiles{$aorder}) {
+ $second = undef;
+ print $fh $crlf,
+ 'if BUILD_', uc($aorder), "\n",
+ 'SUBDIRS +=';
+ foreach my $afile (@{$afiles{$aorder}}) {
+ print $fh " $afile";
+ }
+ delete $afiles{$aorder};
+ print $fh $crlf, 'endif', $crlf;
+ }
+ }
+ print $fh $crlf if ($second);
+ }
+
+ ## Now, for each target used in a conditional, emit a blank assignment
+ ## and mark that we've seen that target to avoid changing the += to =
+ ## as the individual files are pulled in.
+ if (%conditional_targets) {
+ my $primary;
+ my $count;
+
+ while ( ($primary, $count) = each %conditional_targets) {
+ if (! $first_instance_unconditional{$primary}
+ && ($unconditional_targets{$primary} || ($count > 1)))
+ {
+ print $fh "$primary =$crlf";
+ $seen{$primary} = 1;
+ }
+ }
+
+ print $fh $crlf;
+ }
+
+ ## Take the local Makefile.<project>.am files and insert each one here,
+ ## then delete it.
+ if (@locals) {
+ my $pfh = new FileHandle();
+ my $liblocs = $self->get_lib_locations();
+ my $here = $self->getcwd();
+ my $start = $self->getstartdir();
+ my %explicit;
+ foreach my $local (reverse @locals) {
+ if (open($pfh, "$outdir/$local")) {
+ print $fh "## $local", $crlf;
+
+ my $look_for_libs = 0;
+ my $prev_line;
+ my $in_explicit;
+
+ while (<$pfh>) {
+ # Don't emit comments
+ next if (/^#/);
+
+ # Check for explicit targets
+ if ($in_explicit) {
+ if (/^\t/) {
+ next;
+ }
+ else {
+ $in_explicit = undef;
+ }
+ }
+ elsif (/^([\w\/\.\-\s]+):/) {
+ my $target = $1;
+ $target =~ s/^\s+//;
+ $target =~ s/\s+$//;
+ if (defined $explicit{$target}) {
+ $in_explicit = 1;
+ next;
+ }
+ else {
+ $explicit{$target} = 1;
+ }
+ }
+
+ if ($convert_header_name) {
+ if ($local =~ /Makefile\.(.*)\.am/) {
+ $project_name = $1;
+ }
+ else {
+ $project_name = 'nobase';
+ }
+ my $regok = $self->escape_regex_special($project_name);
+ my $inc_pattern = $regok . '_include_HEADERS';
+ my $pkg_pattern = $regok . '_pkginclude_HEADERS';
+ if (/^$inc_pattern\s*\+=\s*/ || /^$pkg_pattern\s*\+=\s*/) {
+ $_ =~ s/^$regok/nobase/;
+ }
+ }
+
+ if ( /(^[a-zA-Z][a-zA-Z0-9_]*_(PROGRAMS|LIBRARIES|LTLIBRARIES|LISP|PYTHON|JAVA|SCRIPTS|DATA|SOURCES|HEADERS|MANS|TEXINFOS|LIBADD|LDADD|DEPENDENCIES))\s*\+=\s*/
+ || /(^CLEANFILES)\s*\+=\s*/
+ || /(^EXTRA_DIST)\s*\+=\s*/
+ ) {
+ if (!defined ($seen{$1})) {
+ $seen{$1} = 1;
+ s/\+=/=/;
+ }
+ }
+
+ ## This scheme relies on automake.mpd emitting the 'la' libs first.
+ ## Look for all the libXXXX.la, find out where they are located
+ ## relative to the start of the MPC run, and relocate the reference
+ ## to that location under $top_builddir. Unless the referred-to
+ ## library is in the current directory, then leave it undecorated
+ ## so the automake-generated dependency orders the build correctly.
+ if ($look_for_libs) {
+ my @libs = /\s+(lib(\w+).la)/gm;
+ my $libcount = @libs / 2;
+ for(my $i = 0; $i < $libcount; ++$i) {
+ my $libfile = $libs[$i * 2];
+ my $libname = $libs[$i * 2 + 1];
+ my $reldir = $$liblocs{$libname};
+
+ ## If we could not find a relative directory for this
+ ## library, it may be that it is a decorated library name.
+ ## We will search for an approximate match.
+ if (!defined $reldir) {
+ my $tmpname = $libname;
+ while($tmpname ne '') {
+ $tmpname = substr($tmpname, 0, length($tmpname) - 1);
+ if (defined $$liblocs{$tmpname}) {
+ $reldir = $$liblocs{$tmpname};
+ $self->warning("Relative directory for $libname " .
+ "was approximated with $tmpname.");
+ last;
+ }
+ }
+ }
+
+ if (defined $reldir) {
+ my $append = ($reldir eq '' ? '' : "/$reldir");
+ if ("$start$append" ne $here) {
+ my $mod = $wsHelper->modify_libpath($_, $reldir, $libfile);
+ if (defined $mod) {
+ $_ = $mod;
+ }
+ else {
+ s/$libfile/\$(top_builddir)$append\/$libfile/;
+ }
+ }
+ }
+ else {
+ my $mod = $wsHelper->modify_libpath($_, $reldir, $libfile);
+ if (defined $mod) {
+ $_ = $mod;
+ }
+ else {
+ $self->warning("No reldir found for $libname ($libfile).");
+ }
+ }
+ }
+ $look_for_libs = 0 if ($libcount == 0);
+ }
+ $look_for_libs = 1 if (/_LDADD = \\$/ || /_LIBADD = \\$/);
+
+ ## I have introduced a one line delay so that I can simplify
+ ## the automake template. If our current line is empty, then
+ ## we will remove the trailing backslash before printing the
+ ## previous line. Automake is horribly unforgiving so we must
+ ## avoid this situation at all cost.
+ if (defined $prev_line) {
+ $prev_line =~ s/\s*\\$// if ($_ =~ /^\s*$/);
+ print $fh $prev_line;
+ }
+ $prev_line = $_;
+ }
+ ## The one line delay requires that we print out the previous
+ ## line (if there was one) when we reach the end of the file.
+ if (defined $prev_line) {
+ $prev_line =~ s/\s*\\$//;
+ print $fh $prev_line;
+ }
+
+ close($pfh);
+ unlink("$outdir/$local");
+ print $fh $crlf;
+ }
+ else {
+ $self->error("Unable to open $local for reading.");
+ }
+ }
+ }
+
+ ## If this is the top-level Makefile.am, it needs the directives to pass
+ ## autoconf/automake flags down the tree when running autoconf.
+ ## *** This may be too closely tied to how we have things set up in ACE,
+ ## even though it's recommended practice. ***
+ if ($toplevel) {
+ my $m4inc = '-I m4';
+ print $fh $crlf,
+ 'ACLOCAL = @ACLOCAL@', $crlf,
+ 'ACLOCAL_AMFLAGS = ',
+ (defined $wsHelper ?
+ $wsHelper->modify_value('amflags', $m4inc) : $m4inc), $crlf,
+ 'AUTOMAKE_OPTIONS = foreign', $crlf, $crlf,
+ (defined $wsHelper ?
+ $wsHelper->modify_value('extra', '') : '');
+ }
+
+ ## Finish up with the cleanup specs.
+ if (@locals) {
+ ## There is no reason to emit this if there are no local targets.
+ ## An argument could be made that it shouldn't be emitted in any
+ ## case because it could be handled by CLEANFILES or a verbatim
+ ## clause.
+
+ print $fh '## Clean up template repositories, etc.', $crlf,
+ 'clean-local:', $crlf,
+ "\t-rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.*",
+ $crlf,
+ "\t-rm -f gcctemp.c gcctemp so_locations *.ics", $crlf,
+ "\t-rm -rf cxx_repository ptrepository ti_files", $crlf,
+ "\t-rm -rf templateregistry ir.out", $crlf,
+ "\t-rm -rf ptrepository SunWS_cache Templates.DB", $crlf;
+ }
+}
+
+
+sub get_includedir {
+ my $self = shift;
+ my $value = $self->getcwd();
+ my $start = $self->getstartdir();
+
+ ## Take off the starting directory
+ $value =~ s/\Q$start\E//;
+ return $value;
+}
+
+
+sub edit_config_ac {
+ my($self, $file, $files) = @_;
+ my $fh = new FileHandle();
+ my $status = 0;
+
+ if (open($fh, $file)) {
+ my $crlf = $self->crlf();
+ my @in;
+ my @lines;
+ my $assoc = $self->get_associated_projects();
+ my $indent = '';
+ my %proj_dir_seen;
+ my $in_config_files = 0;
+
+ while(<$fh>) {
+ my $line = $_;
+ push(@lines, $line);
+
+ ## Remove comments and trailing space
+ $line =~ s/\bdnl\s+.*//;
+ $line =~ s/\s+$//;
+
+ if ($line eq '') {
+ }
+ elsif ($line =~ /^\s*if\s+test\s+["]?([^"]+)["]?\s*=\s*\w+;\s*then/) {
+ ## Entering an if test, save the name
+ my $name = $1;
+ $name =~ s/\s+$//;
+ $name =~ s/.*_build_//;
+ push(@in, $name);
+ }
+ elsif ($line =~ /^\s*if\s+test\s+-d\s+(.+);\s*then/) {
+ ## Entering an if test -d, save the name
+ my $name = $1;
+ $name =~ s/\s+$//;
+ $name =~ s/\$srcdir\///;
+ push(@in, $name);
+ }
+ elsif ($line =~ /^\s*fi$/) {
+ pop(@in);
+ }
+ elsif ($line =~ /^(\s*AC_CONFIG_FILES\s*\(\s*\[)/) {
+ ## Entering an AC_CONFIG_FILES section, start ignoring the entries
+ pop(@lines);
+ push(@lines, "$1\n");
+ $indent = ' ';
+ if ($lines[$#lines] =~ /^(\s+)/) {
+ $indent .= $1;
+ }
+ $in_config_files = 1;
+ }
+ elsif ($in_config_files) {
+ if ($line =~ /(.*)\]\s*\).*/) {
+ ## We've reached the end of the AC_CONFIG_FILES section
+ my $olast = pop(@lines);
+ if ($olast =~ /^[^\s]+(\s*\]\s*\).*)/) {
+ $olast = $1;
+ }
+ ## Add in the Makefiles for this configuration
+ if ($#in < 0 && !defined $proj_dir_seen{'.'}) {
+ push(@lines, $indent . 'Makefile' . $crlf);
+ $proj_dir_seen{'.'} = 1;
+ }
+
+ foreach my $dep (@$files) {
+ ## First things first, see if we've already seen this
+ ## project's directory. If we have, then there's nothing
+ ## else we need to do with it.
+ my $dep_dir = $self->mpc_dirname($dep);
+ if (!defined $proj_dir_seen{$dep_dir}) {
+ my $ok = 1;
+ my @dirs = split(/\//, $dep_dir);
+ my $base = $dep;
+
+ if ($base =~ s/\/.*//) {
+ my $found = 0;
+ foreach my $akey (keys %$assoc) {
+ if (defined $$assoc{$akey}->{$base} ||
+ defined $$assoc{$akey}->{uc($base)}) {
+ if ($#in >= 0) {
+ if (index($base, $in[0]) >= 0) {
+ if ($#in >= 1) {
+ $found = 1;
+ for(my $i = 0; $i <= $#in; $i++) {
+ if (!defined $dirs[$i] ||
+ index($dirs[$i], $in[$i]) < 0) {
+ $found = 0;
+ last;
+ }
+ }
+ }
+ else {
+ ## We need to see into the future here. :-)
+ ## If the second element of @dirs matches an
+ ## association key, we'll guess that there will
+ ## be a "build" section devoted to it.
+ if (!defined $dirs[1] ||
+ !defined $$assoc{$dirs[1]}) {
+ $found = 1;
+ }
+ }
+ }
+ }
+ else {
+ $found = 1;
+ }
+ last;
+ }
+ }
+ if ($#in >= 0) {
+ $ok = $found;
+ }
+ else {
+ $ok = !$found;
+ }
+ }
+
+ if ($ok) {
+ $proj_dir_seen{$dep_dir} = 1;
+ my $inter_dir = '';
+ foreach my $dep (@dirs) {
+ $inter_dir .= $dep;
+ if (!defined $proj_dir_seen{$inter_dir}) {
+ $proj_dir_seen{$inter_dir} = 1;
+ push(@lines, $indent . $inter_dir . "/Makefile$crlf");
+ }
+ $inter_dir .= '/';
+ }
+ push(@lines, $indent . $dep_dir . "/Makefile$crlf");
+ }
+ }
+ }
+ push(@lines, $olast);
+ $in_config_files = 0;
+ }
+ else {
+ ## Ignore the entry
+ pop(@lines);
+ }
+ }
+ }
+ close($fh);
+
+ ## Make a backup and create the new file
+ my $backup = $file . '.bak';
+ if (copy($file, $backup)) {
+ my @buf = stat($file);
+ if (defined $buf[8] && defined $buf[9]) {
+ utime($buf[8], $buf[9], $backup);
+ }
+ if (open($fh, ">$file")) {
+ foreach my $line (@lines) {
+ print $fh $line;
+ }
+ close($fh);
+ $status = 1;
+ }
+ }
+ else {
+ $self->warning("Unable to create backup file: $backup");
+ }
+ }
+ return $status;
+}
+
+1;