#!/usr/local/perl/bin/perl # # file: build/build_list_targets # purpose: 1. prints list of target files to stdout # 2. creates missing directories in the target tree # created: pasha oct 14 2000 # modified: pasha aug 6 2011 # modification: - shebang # - when processing directory, remove target file with the same name, # if exists # synopsis: build_list_targets --src= # --target= # --rules= # notes: supposed to be called from Makefile # use strict; use warnings; use File::Find; use FindBin; use lib $FindBin::Bin; use Getopt::Long; use pasha::dieonwarn; use pasha::common; use homepage::specials; ################################################## # # # get command line opts # # # ################################################## my ($SRC, $TARGET, $RULES); GetOptions ( 'src=s' => \$SRC, 'target=s' => \$TARGET, 'rules=s' => \$RULES ); me_die ('--src argument is absent') if (! defined ($SRC)); me_die ('--target argument is absent') if (! defined ($TARGET)); me_die ('--rules argument is absent') if (! defined ($RULES)); ################################################## # # # get special files/dirs # # # ################################################## my @EXCLUDE_DIRS = (@{$SPECIALS->{EXCLUDE_DIRS}}, @{$SPECIALS->{SPECIAL_DIRS}}); my @EXCLUDE_FILES = @{$SPECIALS->{EXCLUDE_FILES}}; my @AS_IS_FILES = @{$SPECIALS->{AS_IS_FILES}}; ################################################## # # # get list of src and target extensions # # # ################################################## my @EXT = (); # list of (anonymous 2-element lists of) extensions: # [target extension, corresponding source extension] my ($target, $target_ext, $src, $src_ext); open (F, "<$RULES") || me_die ("failed to open $RULES"); for () { chomp ($_); s/#.*$//; # wipe out comments ($target, $src) = split (/:/o, $_); next if ((! defined ($target)) || (! defined ($src))); #next if ($target !~ /%\.(.*)$/); next if ($target !~ /%(\.[\w]+)?$/o); $target_ext = (defined $1 ? $1 : ''); undef ($src_ext); for (split (/\s+/o, $src)) { if (/%(\.[\w]+)?$/o) { if (defined ($src_ext)) { me_die ("wrong rule in $RULES: more than one % sign in dependencies for target $target"); } $src_ext = (defined $1 ? $1 : ''); } } push (@EXT, [$target_ext, $src_ext]); } close (F); ################################################## # # # process src and target dirs # # # ################################################## my %TARGET_FILES = (); # hash of target files: key - full filename, value = 1; me_print ("building list of target files"); find (\&process_src, $SRC); for (keys %TARGET_FILES) { print ($_, "\n"); } exit (0); ################################################## # # # subroutines # # # ################################################## sub process_src { (my $target = $File::Find::name) =~ s/^$SRC/$TARGET/o; my $ex; if (-d $_) { for $ex (@EXCLUDE_DIRS) { if ("$SRC/$ex" eq $File::Find::name) { me_print ("excluding $File::Find::name from processing"); $File::Find::prune = 1; return; } } me_print ("processing dir $File::Find::name"); system_or_die ("rm -f $target") if (-f $target); system_or_die ("mkdir -p $target") if (! -d $target); } # end of dir case elsif (-f $_) { # ignore *.backup, *.old, *~ and #...# files: return if (/(\.(backup|old)|~)$/o || /^\#.*\#$/o ); for $ex (@EXCLUDE_FILES) { if ("$SRC/$ex" eq $File::Find::name) { me_print ("excluding $File::Find::name from processing"); return; } } me_print ("processing file ${File::Find::name}"); for $ex (@AS_IS_FILES) { if ("$SRC/$ex" eq $File::Find::name) { add_to_list ($target); return; } } # generate src name from target name my $ext = '.' . get_ext ($_); my $a; for $a (@EXT) { # $a->[0] is target extension # $a->[1] is corresponding source extension if ($a->[1] eq $ext) { $target =~ s/$a->[1]$/$a->[0]/; last; } } add_to_list ($target); } # end of file case } # end of sub process_src() # add filename to the list of targets # args: 0 - filename # return: 1 always sub add_to_list ($) { if (exists $TARGET_FILES{$_[0]}) { me_print ("WARNING: $_[0] may be generated from more than one source"); } else { $TARGET_FILES{$_[0]} = 1; } return (1); } __END__