3 # ************************************************************
4 # Description : Generate dependencies for Make and NMake.
5 # Author : Chad Elliott
6 # Create Date : 3/21/2007
7 # ************************************************************
9 # ************************************************************
11 # ************************************************************
18 # ************************************************************
20 # ************************************************************
23 my $os = ($^O
eq 'MSWin32' ?
'Windows' : 'UNIX');
25 my %defaults = ('UNIX' => 'make',
29 # ************************************************************
31 # ************************************************************
34 my $fh = new FileHandle
();
35 my(%writers, %generators);
37 ## Find all the dependency writers and object generators
38 foreach my $dir (@INC) {
39 if (opendir($fh, $dir)) {
40 foreach my $module (readdir($fh)) {
41 if ($module =~ /(.+)DependencyWriter\.pm$/) {
46 $writers{$type} = $class;
49 elsif ($module =~ /(.+)ObjectGenerator\.pm$/) {
54 $generators{$type} = $class;
61 ## Register them with the right factory
62 DependencyWriterFactory
::register
(\
%writers);
63 ObjectGeneratorFactory
::register
(\
%generators);
69 my $self = bless {'automatic' => [],
72 foreach my $add (@_) {
73 if ($add =~ /(UNIX|Windows)=(.*)/) {
76 elsif ($add =~ /automatic=(.*)/) {
77 my @auto = split(/,/, $1);
78 $self->{'automatic'} = \
@auto;
81 print "WARNING: Unknown parameter: $add\n";
91 my $base = basename
($0);
97 print "$base v$version\n" .
98 "Usage: $base [-D<MACRO>[=VALUE]] [-I<include dir>] ",
99 (defined $self->{'automatic'}->[0] ?
"[-A] " : ''),
101 " " . (" " x
length($base)) .
102 " [-e <file>] [-f <output file>] [-g] [-i] [-t <type>] [-n]\n" .
103 " " . (" " x
length($base)) . " <files...>\n" .
105 if (defined $self->{'automatic'}->[0]) {
106 print "-A Replace paths equal to the following variables with ",
107 "the corresponding \$()\n value: ",
108 join(', ', @
{$self->{'automatic'}}), ".\n";
110 print "-D This option sets a macro to an optional value.\n" .
111 "-I The -I option adds an include directory.\n" .
112 "-R Replace \$VARNAME paths with \$(VARNAME).\n" .
113 "-a Append to existing dependencies." .
114 (exists $types{'gnuidl'} ?
' Useful with -t gnuidl.' : '') . "\n" .
115 "-e Exclude dependencies generated by <file>, but not <file> " .
117 "-f Specifies the output file. This file will be edited if it " .
118 "already\n exists.\n" .
119 "-g Do not create Cygwin paths when on Windows.\n" .
120 "-i Do not print an error if no source files are provided.\n" .
121 "-n Do not include inline files (ending in .i or .inl) in the " .
123 "-t Use specified type (";
124 my @keys = sort keys %types;
125 for(my $i = 0; $i <= $#keys; ++$i) {
127 ($i != $#keys ?
$i == $#keys - 1 ?
' or ' : ', ' : '');;
129 print ") instead of the default.\n" .
131 @keys = sort keys %defaults;
132 for(my $i = 0; $i <= $#keys; ++$i) {
134 print $defaults{$def} . " on $def" .
135 ($i != $#keys ?
$i == $#keys - 1 ?
' and ' : ', ' : '');
143 my($self, $replace, $name, $value) = @_;
146 ## The key will be used in a regular expression.
147 ## So, we need to escape some special characters.
148 $name = File
::Spec
->canonpath($name);
149 $name =~ s/([\+\-\\\$\[\]\(\)\.])/\\$1/g;
151 $$replace{$name} = $value;
157 my($self, $args) = @_;
158 my $argc = scalar(@
$args);
159 my $type = $defaults{$os};
162 my($noinline, @files, %macros, @ipaths, %replace, %exclude, $append);
164 for(my $i = 0; $i < $argc; ++$i) {
165 my $arg = $$args[$i];
166 if ($arg =~ /^\-D(\w+)(=(.*))?/) {
169 elsif ($arg =~ /^\-(I|isystem)(.*)/) {
170 # support '-Idir' and '-I dir'
173 push(@ipaths, File
::Spec
->canonpath($2));
180 $self->usageAndExit('Invalid use of -' . $opt);
183 push(@ipaths, File
::Spec
->canonpath($arg));
186 $self->usageAndExit('Invalid use of -' . $opt);
190 elsif ($arg eq '-A') {
191 foreach my $auto (@
{$self->{'automatic'}}) {
192 $self->setReplace(\
%replace, $ENV{$auto}, '$(' . $auto . ')');
195 elsif ($arg eq '-R') {
199 my $val = $ENV{$arg};
201 $self->setReplace(\
%replace, $val, "\$($arg)");
205 $self->usageAndExit('Invalid use of -R');
208 elsif ($arg eq '-e') {
215 $self->usageAndExit('Invalid use of -e');
218 elsif ($arg eq '-f') {
225 $self->usageAndExit('Invalid use of -f');
228 elsif ($arg eq '-g') {
229 ## By default, on Windows, we assume Cygwin and create paths with
230 ## /cygdrive. Some users have a non-Cygwin make and need paths with
234 elsif ($arg eq '-a') {
237 elsif ($arg eq '-i') {
240 elsif ($arg eq '-n') {
243 elsif ($arg eq '-h') {
244 $self->usageAndExit();
246 elsif ($arg eq '-t') {
249 if (defined $arg && defined $types{$arg}) {
253 $self->usageAndExit('Invalid use of -t');
256 elsif ($arg =~ /^[\-+]/) {
257 ## We will ignore unknown options
258 ## Some options for aCC start with +
265 if (!defined $files[0]) {
267 $self->usageAndExit('No files specified');
271 my $editor = new DependencyEditor
();
272 return $editor->process($output, $type, $noinline, \
%macros, \
@ipaths,
273 \
%replace, \
%exclude, \
@files, $append);