2 # ***** BEGIN LICENSE BLOCK *****
3 # Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 # The contents of this file are subject to the Mozilla Public License Version
6 # 1.1 (the "License"); you may not use this file except in compliance with
7 # the License. You may obtain a copy of the License at
8 # http://www.mozilla.org/MPL/
10 # Software distributed under the License is distributed on an "AS IS" basis,
11 # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 # for the specific language governing rights and limitations under the
15 # The Original Code is mozilla.org code.
17 # The Initial Developer of the Original Code is
18 # Netscape Communications Corporation.
19 # Portions created by the Initial Developer are Copyright (C) 1999
20 # the Initial Developer. All Rights Reserved.
24 # Alternatively, the contents of this file may be used under the terms of
25 # either of the GNU General Public License Version 2 or later (the "GPL"),
26 # or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 # in which case the provisions of the GPL or the LGPL are applicable instead
28 # of those above. If you wish to allow use of your version of this file only
29 # under the terms of either the GPL or the LGPL, and not to allow others to
30 # use your version of this file under the terms of the MPL, indicate your
31 # decision by deleting the provisions above and replace them with the notice
32 # and other provisions required by the GPL or the LGPL. If you do not delete
33 # the provisions above, a recipient may use your version of this file under
34 # the terms of any one of the MPL, the GPL or the LGPL.
36 # ***** END LICENSE BLOCK *****
38 # make-makefiles - Quickly create Makefiles for subdirectories.
39 # Also, creates any needed subdirectories.
41 # usage: make-makefiles [ -t <topsrcdir> -p <print_topsrcdir> -d <depth> ] [ <subdir> | <subdir>/Makefile ] ...
43 # Send comments, improvements, bugs to Steve Lamm (slamm@netscape.com).
47 # Determine various tree path variables
49 ($topsrcdir, $ptopsrcdir, $depth, @makefiles) = parse_arguments
(@ARGV);
51 $object_fullpath = `pwd`;
54 chomp $object_fullpath;
57 # $source_subdir is the path from the object root to where
58 # 'make-makefile' was called. For example, if make-makefile was
59 # called from "mozilla/gfx/src", then $source_subdir would be
61 $source_subdir = "$object_fullpath/";
62 my $quoted_object_root = quotemeta($object_root);
63 $source_subdir =~ s
|^$quoted_object_root/||;
65 # Prefix makefiles with $source_subdir so that paths
66 # will be relative to the top of the object tree.
68 for $makefile (@makefiles) {
69 $makefile = "$source_subdir$makefile";
72 create_directories
(@makefiles);
74 # Find the path to the source directory based on how 'make-makefile'
75 # was invoked. The path is either relative to the object directory
76 # or an absolute path.
77 $given_srcdir = find_srcdir
($topsrcdir, $depth);
78 $pgiven_srcdir = find_srcdir
($ptopsrcdir, $depth);
81 warn "object_fullpath = $object_fullpath\n";
82 warn "object_root = $object_root\n";
83 warn "source_subdir = $source_subdir\n";
84 warn "makefiles = @makefiles\n";
85 warn "given_srcdir = $given_srcdir\n";
88 @unhandled = update_makefiles
($given_srcdir, $pgiven_srcdir, @makefiles);
90 run_config_status
(@unhandled);
93 ############################################################
96 return $_[0] =~ /(.*)\/.*/ ?
"$1" : '.';
99 # find_depth: Pull the value of DEPTH out of a Makefile (or Makefile.in)
102 open(MAKEFILE
, "<$_[0]") || die "Unable to open $_[0]: $!\n";
104 next unless /^DEPTH\s*=\s*(\..*)/;
112 sub parse_arguments
{
120 if ($args[0] eq '-d') {
124 } elsif ($args[0] eq '-t') {
125 $topsrcdir = $args[1];
128 } elsif ($args[0] eq '-p') {
129 $ptopsrcdir = $args[1];
137 if ($topsrcdir eq '') {
138 $topsrcdir = $0; # Figure out topsrcdir based on program name.
139 $topsrcdir =~ s
|/?build/autoconf
/.*$||;
141 if ($ptopsrcdir eq '') {
142 $ptopsrcdir = $topsrcdir;
145 # Use $(DEPTH) in the Makefile or Makefile.in to determine the depth
146 if (-e
"Makefile.in") {
147 $depth = find_depth
("Makefile.in");
148 } elsif (-e
"Makefile") {
149 $depth = find_depth
("Makefile");
150 } elsif (-e
"../Makefile") {
151 $depth = "../".find_depth
("../Makefile");
154 warn "Unable to determine depth (e.g. ../..) to root of objdir tree.\n";
155 die "No Makefile(.in) present. Try running with '-d <depth>'\n";
159 # Build the list of makefiles to generate
163 foreach $makefile (@args) {
164 $makefile =~ s/\.in$//;
165 $makefile =~ s/\/$//;
166 $makefile =~ /Makefile$/ or $makefile .= "/Makefile";
167 push @makefiles, "$makefile";
169 @makefiles = "Makefile" unless @args;
171 return ($topsrcdir, $ptopsrcdir, $depth, @makefiles);
175 # Create all the directories at once.
176 # This can be much faster than calling mkdir() for each one.
177 sub create_directories
{
181 foreach $ac_file (@makefiles) {
182 push @dirs, dirname
($ac_file);
184 # Call mkdir with the directories sorted by subdir count (how many /'s)
185 system "mkdir -p ". join(' ', map("\"$_\"", @dirs)) if @dirs;
188 # Find the top of the source directory
189 # (Assuming that the executable is in $top_srcdir/build/autoconf)
191 my ($ac_given_srcdir, $depth) = @_;
194 print "ac_given_srcdir = $ac_given_srcdir\n";
195 print "depth = $depth\n";
197 if ($ac_given_srcdir =~ /^\./ and $depth ne '.') {
198 my $quoted_depth = quotemeta($depth);
199 $ac_given_srcdir =~ s
|^$quoted_depth/?
||;
202 print "ac_given_srcdir = $ac_given_srcdir\n";
204 $ac_given_srcdir = '.' if $ac_given_srcdir eq '';
205 return $ac_given_srcdir;
208 # Output the makefiles.
210 sub update_makefiles
{
211 my ($ac_given_srcdir, $pac_given_srcdir, @makefiles) = @_;
215 foreach $ac_file (@makefiles) {
216 my $ac_file_in = "$ac_given_srcdir/${ac_file}.in";
217 my $ac_dir = dirname
($ac_file);
219 my $ac_dir_suffix = '';
221 my $top_srcdir = '.';
223 # Determine $srcdir and $top_srcdir
225 if ($ac_dir ne '.') {
226 $ac_dir_suffix = "/$ac_dir";
227 $ac_dir_suffix =~ s
%^/\./%/%;
228 $ac_dots = $ac_dir_suffix;
229 # Remove .. components from the provided dir suffix, and
230 # also the forward path components they were reversing.
231 my $backtracks = $ac_dots =~ s
%\
.\
.(/|$)%%g;
232 while ($backtracks--) {
233 $ac_dots =~ s
%/[^/]*%%;
235 $ac_dots =~ s
%/[^/]*%../%g;
237 if ($ac_given_srcdir eq '.') {
238 if ($ac_dots ne '') {
239 $top_srcdir = $ac_dots;
240 $top_srcdir =~ s
%/$%%;
242 } elsif ($pac_given_srcdir =~ m
%^/% or $pac_given_srcdir =~ m%^.:/%) {
243 $srcdir = "$pac_given_srcdir$ac_dir_suffix";
244 $top_srcdir = "$pac_given_srcdir";
247 print "ac_dots = $ac_dots\n";
248 print "ac_dir_suffix = $ac_dir_suffix\n";
250 $srcdir = "$ac_dots$ac_given_srcdir$ac_dir_suffix";
251 $top_srcdir = "$ac_dots$ac_given_srcdir";
255 print "ac_dir = $ac_dir\n";
256 print "ac_file = $ac_file\n";
257 print "ac_file_in = $ac_file_in\n";
258 print "srcdir = $srcdir\n";
259 print "top_srcdir = $top_srcdir\n";
260 print "cwd = " . `pwd` . "\n";
263 # Copy the file and make substitutions.
264 # @srcdir@ -> value of $srcdir
265 # @top_srcdir@ -> value of $top_srcdir
268 next if -M _
< -M
$ac_file_in; # Next if Makefile is up-to-date.
269 warn "updating $ac_file\n";
271 warn "creating $ac_file\n";
274 open INFILE
, "<$ac_file_in" or do {
275 warn "$0: Cannot read $ac_file_in: No such file or directory\n";
278 open OUTFILE
, ">$ac_file" or do {
279 warn "$0: Unable to create $ac_file\n";
284 #if (/\@[_a-zA-Z]*\@.*\@[_a-zA-Z]*\@/) {
285 # #warn "Two defines on a line:$ac_file:$.:$_";
286 # push @unhandled, $ac_file;
290 s/\@srcdir\@/$srcdir/g;
291 s/\@top_srcdir\@/$top_srcdir/g;
293 if (/\@[_a-zA-Z]*\@/) {
294 #warn "Unknown variable:$ac_file:$.:$_";
295 push @unhandled, $ac_file;
306 sub run_config_status
{
309 # Run config.status with any unhandled files.
312 $ENV{CONFIG_FILES
}= join ' ', @unhandled;
313 system "./config.status";