#!/usr/bin/perl # # File: idldeps.pl # Version: 2011/11/22 # # Purpose: Print dependencies from all IDL files in the given directory. # # Usage: # # idldeps.pl [ -I ] [-e ] [-a ] # # idl_dir is the directory in which to search for IDL files to analyze # (default: current working directory.) # The option -I specifies an in which to search for # further IDL files on which the files from idl_dir depend. # Multiple -I options may be supplied. # The can also be given in the following syntax: # '${ENV_VAR}/rest/of/path' # in which case the given environment variable is used in the # generated dependencies. (Notice that the expression must be # enclosed in apostrophes.) # The option -e specifies a to use as the target file # extension. For example, # -e cpp # would produce a dependency line such as: # x.cpp : x.idl y.idl z.idl # This option may be given multiple times. # The option -a specifies an to generate as the # action following a generated dependency. # Notice that the should be enclosed in apostrophes # as the action usually contains spaces. # # # Copyright (C) 2005-2011, O. Kellogg # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # $idl_dir = "."; @include_paths = (); %file_not_found = (); @file_extension = (); $action_line = ""; sub fqn { my $name = shift; if ($name =~ /^[\/\$]/) { # already absolute path return $name; } if (-e "$idl_dir/$name") { if ($idl_dir eq '.') { return $name; } return "$idl_dir/$name"; } foreach my $expr (@include_paths) { if ($expr =~ /^\$[\(\{](\w+)[\)\}](.*)/) { my $env_path = $ENV{$1}; my $rest_of_path = $2; if (-e "$env_path$rest_of_path/$name") { return "$expr/$name"; } } if (-e "$expr/$name") { return "$expr/$name"; } } return undef; } sub expand_stem_to_targets { my $stem = shift; my @ext = @file_extension; my $targets = $stem . shift(@ext); foreach (@ext) { $targets .= " $stem$_"; } return $targets; } # Main program print("# Invocation was:\n"); print("# idldeps.pl " . join(' ', @ARGV) . "\n"); print("#\n\n"); while (@ARGV) { my $arg = shift @ARGV; if ($arg =~ /^-I(.*)/) { my $expr = $1; unless ($expr) { $expr = shift @ARGV; } # if ($expr =~ /^\$/) { # print " '$expr'"; # } else { # print " $expr"; # } if ($expr =~ /^\$[\(\{](\w+)[\)\}](.*)/) { my $env_var_name = $1; my $rest_of_path = $2; unless (exists $ENV{$env_var_name}) { warn "Environment variable $env_var_name does not exist, skipping.\n"; next; } my $env_path = $ENV{$env_var_name}; unless (-d "$env_path$rest_of_path") { warn "$expr is not a valid path (skipping)\n"; next; } } else { unless (-d $expr) { warn "$expr is not a valid path (skipping)\n"; next; } } push @include_paths, $expr; } elsif ($arg =~ /^-e(.*)/) { my $ext = $1; unless ($ext) { $ext = shift @ARGV; } push @file_extension, $ext; } elsif ($arg =~ /^-a(.*)/) { $action_line = $1; unless ($action_line) { $action_line = shift @ARGV; } } else { $idl_dir = $arg; } } unless (@file_extension) { if (exists $ENV{EXT}) { push @file_extension, $ENV{EXT}; } else { push @file_extension, '${EXT}'; print "# These rules depend on a symbol EXT containing the target file extension\n"; } } my $include_switches; foreach (@include_paths) { $include_switches .= " -I$_"; } foreach $idlfile (glob "$idl_dir/*.idl") { # print "cpp ${include_switches} $idlfile\n"; my $includes = `cpp ${include_switches} $idlfile | sed -n 's/^# [0-9][0-9]* "\\([^"]*\\)" 1\$/\\1/p'`; # print "includes: $includes\n"; my $stem = $idlfile; $stem =~ s@^.*/@@; $stem =~ s/\.idl$//; my $target = expand_stem_to_targets($stem); print "${target} : $idlfile"; if ($includes) { my @lines = split(/\s+/, $includes); foreach my $include (@lines) { my $filename_with_path = fqn($include); if (! $filename_with_path) { unless (exists $file_not_found{$include}) { warn "$idlfile: cannot find file $include (this warning is printed only once)\n"; $file_not_found{$include} = 1; } } else { print(" " . $filename_with_path); } } } print "\n"; if ($action_line) { print("\t$action_line\n"); } print "\n"; }