mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-30 05:35:31 +00:00
316 lines
9.0 KiB
Perl
Executable File
316 lines
9.0 KiB
Perl
Executable File
#! /usr/bin/env perl
|
|
# ***** BEGIN LICENSE BLOCK *****
|
|
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
#
|
|
# The contents of this file are subject to the Mozilla Public License Version
|
|
# 1.1 (the "License"); you may not use this file except in compliance with
|
|
# the License. You may obtain a copy of the License at
|
|
# http://www.mozilla.org/MPL/
|
|
#
|
|
# Software distributed under the License is distributed on an "AS IS" basis,
|
|
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
# for the specific language governing rights and limitations under the
|
|
# License.
|
|
#
|
|
# The Original Code is mozilla.org code.
|
|
#
|
|
# The Initial Developer of the Original Code is
|
|
# Netscape Communications Corporation.
|
|
# Portions created by the Initial Developer are Copyright (C) 1999
|
|
# the Initial Developer. All Rights Reserved.
|
|
#
|
|
# Contributor(s):
|
|
#
|
|
# Alternatively, the contents of this file may be used under the terms of
|
|
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
|
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
# in which case the provisions of the GPL or the LGPL are applicable instead
|
|
# of those above. If you wish to allow use of your version of this file only
|
|
# under the terms of either the GPL or the LGPL, and not to allow others to
|
|
# use your version of this file under the terms of the MPL, indicate your
|
|
# decision by deleting the provisions above and replace them with the notice
|
|
# and other provisions required by the GPL or the LGPL. If you do not delete
|
|
# the provisions above, a recipient may use your version of this file under
|
|
# the terms of any one of the MPL, the GPL or the LGPL.
|
|
#
|
|
# ***** END LICENSE BLOCK *****
|
|
|
|
# make-makefiles - Quickly create Makefiles for subdirectories.
|
|
# Also, creates any needed subdirectories.
|
|
#
|
|
# usage: make-makefiles [ -t <topsrcdir> -p <print_topsrcdir> -d <depth> ] [ <subdir> | <subdir>/Makefile ] ...
|
|
|
|
# Send comments, improvements, bugs to Steve Lamm (slamm@netscape.com).
|
|
|
|
#$debug = 1;
|
|
|
|
# Determine various tree path variables
|
|
#
|
|
($topsrcdir, $ptopsrcdir, $depth, @makefiles) = parse_arguments(@ARGV);
|
|
|
|
$object_fullpath = `pwd`;
|
|
chdir $depth;
|
|
$object_root = `pwd`;
|
|
chomp $object_fullpath;
|
|
chomp $object_root;
|
|
|
|
# $source_subdir is the path from the object root to where
|
|
# 'make-makefile' was called. For example, if make-makefile was
|
|
# called from "mozilla/gfx/src", then $source_subdir would be
|
|
# "gfx/src/".
|
|
$source_subdir = "$object_fullpath/";
|
|
my $quoted_object_root = quotemeta($object_root);
|
|
$source_subdir =~ s|^$quoted_object_root/||;
|
|
|
|
# Prefix makefiles with $source_subdir so that paths
|
|
# will be relative to the top of the object tree.
|
|
#
|
|
for $makefile (@makefiles) {
|
|
$makefile = "$source_subdir$makefile";
|
|
}
|
|
|
|
create_directories(@makefiles);
|
|
|
|
# Find the path to the source directory based on how 'make-makefile'
|
|
# was invoked. The path is either relative to the object directory
|
|
# or an absolute path.
|
|
$given_srcdir = find_srcdir($topsrcdir, $depth);
|
|
$pgiven_srcdir = find_srcdir($ptopsrcdir, $depth);
|
|
|
|
if ($debug) {
|
|
warn "object_fullpath = $object_fullpath\n";
|
|
warn "object_root = $object_root\n";
|
|
warn "source_subdir = $source_subdir\n";
|
|
warn "makefiles = @makefiles\n";
|
|
warn "given_srcdir = $given_srcdir\n";
|
|
}
|
|
|
|
@unhandled = update_makefiles($given_srcdir, $pgiven_srcdir, @makefiles);
|
|
|
|
run_config_status(@unhandled);
|
|
|
|
# end of Main
|
|
############################################################
|
|
|
|
sub dirname {
|
|
return $_[0] =~ /(.*)\/.*/ ? "$1" : '.';
|
|
}
|
|
|
|
# find_depth: Pull the value of DEPTH out of a Makefile (or Makefile.in)
|
|
sub find_depth {
|
|
my $depth = '';
|
|
open(MAKEFILE, "<$_[0]") || die "Unable to open $_[0]: $!\n";
|
|
while (<MAKEFILE>) {
|
|
next unless /^DEPTH\s*=\s*(\..*)/;
|
|
$depth = $1;
|
|
last;
|
|
}
|
|
close MAKEFILE;
|
|
return $depth;
|
|
}
|
|
|
|
sub parse_arguments {
|
|
my @args = @_;
|
|
my $depth = '';
|
|
my $topsrcdir = '';
|
|
my $ptopsrcdir;
|
|
my @makefiles = ();
|
|
|
|
while (1) {
|
|
if ($args[0] eq '-d') {
|
|
$depth = $args[1];
|
|
shift @args;
|
|
shift @args;
|
|
} elsif ($args[0] eq '-t') {
|
|
$topsrcdir = $args[1];
|
|
shift @args;
|
|
shift @args;
|
|
} elsif ($args[0] eq '-p') {
|
|
$ptopsrcdir = $args[1];
|
|
shift @args;
|
|
shift @args;
|
|
} else {
|
|
last;
|
|
}
|
|
}
|
|
|
|
if ($topsrcdir eq '') {
|
|
$topsrcdir = $0; # Figure out topsrcdir based on program name.
|
|
$topsrcdir =~ s|/?build/autoconf/.*$||;
|
|
}
|
|
if ($ptopsrcdir eq '') {
|
|
$ptopsrcdir = $topsrcdir;
|
|
}
|
|
if ($depth eq '') {
|
|
# Use $(DEPTH) in the Makefile or Makefile.in to determine the depth
|
|
if (-e "Makefile.in") {
|
|
$depth = find_depth("Makefile.in");
|
|
} elsif (-e "Makefile") {
|
|
$depth = find_depth("Makefile");
|
|
} elsif (-e "../Makefile") {
|
|
$depth = "../".find_depth("../Makefile");
|
|
$depth =~ s/\/\.$//;
|
|
} else {
|
|
warn "Unable to determine depth (e.g. ../..) to root of objdir tree.\n";
|
|
die "No Makefile(.in) present. Try running with '-d <depth>'\n";
|
|
}
|
|
}
|
|
|
|
# Build the list of makefiles to generate
|
|
#
|
|
@makefiles = ();
|
|
my $makefile;
|
|
foreach $makefile (@args) {
|
|
$makefile =~ s/\.in$//;
|
|
$makefile =~ s/\/$//;
|
|
$makefile =~ /Makefile$/ or $makefile .= "/Makefile";
|
|
push @makefiles, "$makefile";
|
|
}
|
|
@makefiles = "Makefile" unless @args;
|
|
|
|
return ($topsrcdir, $ptopsrcdir, $depth, @makefiles);
|
|
}
|
|
|
|
|
|
# Create all the directories at once.
|
|
# This can be much faster than calling mkdir() for each one.
|
|
sub create_directories {
|
|
my @makefiles = @_;
|
|
my @dirs = ();
|
|
my $ac_file;
|
|
foreach $ac_file (@makefiles) {
|
|
push @dirs, dirname($ac_file);
|
|
}
|
|
# Call mkdir with the directories sorted by subdir count (how many /'s)
|
|
system "mkdir -p ". join(' ', map("\"$_\"", @dirs)) if @dirs;
|
|
}
|
|
|
|
# Find the top of the source directory
|
|
# (Assuming that the executable is in $top_srcdir/build/autoconf)
|
|
sub find_srcdir {
|
|
my ($ac_given_srcdir, $depth) = @_;
|
|
|
|
if ($debug) {
|
|
print "ac_given_srcdir = $ac_given_srcdir\n";
|
|
print "depth = $depth\n";
|
|
}
|
|
if ($ac_given_srcdir =~ /^\./ and $depth ne '.') {
|
|
my $quoted_depth = quotemeta($depth);
|
|
$ac_given_srcdir =~ s|^$quoted_depth/?||;
|
|
}
|
|
if ($debug) {
|
|
print "ac_given_srcdir = $ac_given_srcdir\n";
|
|
}
|
|
$ac_given_srcdir = '.' if $ac_given_srcdir eq '';
|
|
return $ac_given_srcdir;
|
|
}
|
|
|
|
# Output the makefiles.
|
|
#
|
|
sub update_makefiles {
|
|
my ($ac_given_srcdir, $pac_given_srcdir, @makefiles) = @_;
|
|
my @unhandled=();
|
|
|
|
my $ac_file;
|
|
foreach $ac_file (@makefiles) {
|
|
my $ac_file_in = "$ac_given_srcdir/${ac_file}.in";
|
|
my $ac_dir = dirname($ac_file);
|
|
my $ac_dots = '';
|
|
my $ac_dir_suffix = '';
|
|
my $srcdir = '.';
|
|
my $top_srcdir = '.';
|
|
|
|
# Determine $srcdir and $top_srcdir
|
|
#
|
|
if ($ac_dir ne '.') {
|
|
$ac_dir_suffix = "/$ac_dir";
|
|
$ac_dir_suffix =~ s%^/\./%/%;
|
|
$ac_dots = $ac_dir_suffix;
|
|
# Remove .. components from the provided dir suffix, and
|
|
# also the forward path components they were reversing.
|
|
my $backtracks = $ac_dots =~ s%\.\.(/|$)%%g;
|
|
while ($backtracks--) {
|
|
$ac_dots =~ s%/[^/]*%%;
|
|
}
|
|
$ac_dots =~ s%/[^/]*%../%g;
|
|
}
|
|
if ($ac_given_srcdir eq '.') {
|
|
if ($ac_dots ne '') {
|
|
$top_srcdir = $ac_dots;
|
|
$top_srcdir =~ s%/$%%;
|
|
}
|
|
} elsif ($pac_given_srcdir =~ m%^/% or $pac_given_srcdir =~ m%^.:/%) {
|
|
$srcdir = "$pac_given_srcdir$ac_dir_suffix";
|
|
$top_srcdir = "$pac_given_srcdir";
|
|
} else {
|
|
if ($debug) {
|
|
print "ac_dots = $ac_dots\n";
|
|
print "ac_dir_suffix = $ac_dir_suffix\n";
|
|
}
|
|
$srcdir = "$ac_dots$ac_given_srcdir$ac_dir_suffix";
|
|
$top_srcdir = "$ac_dots$ac_given_srcdir";
|
|
}
|
|
|
|
if ($debug) {
|
|
print "ac_dir = $ac_dir\n";
|
|
print "ac_file = $ac_file\n";
|
|
print "ac_file_in = $ac_file_in\n";
|
|
print "srcdir = $srcdir\n";
|
|
print "top_srcdir = $top_srcdir\n";
|
|
print "cwd = " . `pwd` . "\n";
|
|
}
|
|
|
|
# Copy the file and make substitutions.
|
|
# @srcdir@ -> value of $srcdir
|
|
# @top_srcdir@ -> value of $top_srcdir
|
|
#
|
|
if (-e $ac_file) {
|
|
next if -M _ < -M $ac_file_in; # Next if Makefile is up-to-date.
|
|
warn "updating $ac_file\n";
|
|
} else {
|
|
warn "creating $ac_file\n";
|
|
}
|
|
|
|
open INFILE, "<$ac_file_in" or do {
|
|
warn "$0: Cannot read $ac_file_in: No such file or directory\n";
|
|
next;
|
|
};
|
|
open OUTFILE, ">$ac_file" or do {
|
|
warn "$0: Unable to create $ac_file\n";
|
|
next;
|
|
};
|
|
|
|
while (<INFILE>) {
|
|
#if (/\@[_a-zA-Z]*\@.*\@[_a-zA-Z]*\@/) {
|
|
# #warn "Two defines on a line:$ac_file:$.:$_";
|
|
# push @unhandled, $ac_file;
|
|
# last;
|
|
#}
|
|
|
|
s/\@srcdir\@/$srcdir/g;
|
|
s/\@top_srcdir\@/$top_srcdir/g;
|
|
|
|
if (/\@[_a-zA-Z]*\@/) {
|
|
#warn "Unknown variable:$ac_file:$.:$_";
|
|
push @unhandled, $ac_file;
|
|
last;
|
|
}
|
|
print OUTFILE;
|
|
}
|
|
close INFILE;
|
|
close OUTFILE;
|
|
}
|
|
return @unhandled;
|
|
}
|
|
|
|
sub run_config_status {
|
|
my @unhandled = @_;
|
|
|
|
# Run config.status with any unhandled files.
|
|
#
|
|
if (@unhandled) {
|
|
$ENV{CONFIG_FILES}= join ' ', @unhandled;
|
|
system "./config.status";
|
|
}
|
|
}
|