sbsv1_os/e32toolp/bldmake/metabld.pl
changeset 0 83f4b4db085c
child 10 d4b442d23379
equal deleted inserted replaced
-1:000000000000 0:83f4b4db085c
       
     1 # Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 # All rights reserved.
       
     3 # This component and the accompanying materials are made available
       
     4 # under the terms of "Eclipse Public License v1.0"
       
     5 # which accompanies this distribution, and is available
       
     6 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 #
       
     8 # Initial Contributors:
       
     9 # Nokia Corporation - initial contribution.
       
    10 #
       
    11 # Contributors:
       
    12 #
       
    13 # Description:
       
    14 # all variables called *Path* are set up to end with a backslash
       
    15 # all variables called *Path or *File are stored as absolute (file)paths within makmake
       
    16 # all variables called UpPath* are stored as relative paths within makmake
       
    17 # 
       
    18 #
       
    19 
       
    20 use strict;
       
    21 
       
    22 use FindBin;		# for FindBin::Bin
       
    23 use File::Find;
       
    24 use Cwd;
       
    25 
       
    26 my $PerlLibPath;    # fully qualified pathname of the directory containing our Perl modules
       
    27 
       
    28 BEGIN {
       
    29 # check user has a version of perl that will cope
       
    30 	require 5.005_03;
       
    31 # establish the path to the Perl libraries: currently the same directory as this script
       
    32 	$PerlLibPath = $FindBin::Bin;	# X:/epoc32/tools
       
    33 	$PerlLibPath =~ s/\//\\/g;	# X:\epoc32\tools
       
    34 	$PerlLibPath .= "\\";
       
    35 }
       
    36 
       
    37 use lib $PerlLibPath;
       
    38 use E32env;
       
    39 use Prepfile;
       
    40 use Pathutl;
       
    41 
       
    42 # autoflush prevents our ouptut from getting jumbled up
       
    43 use FileHandle;
       
    44 autoflush STDOUT 1;
       
    45 autoflush STDERR 1;
       
    46 
       
    47 my (@Commands, @BldInfDirs);
       
    48 # should end in .mbc where .mbc means for "MetaBld Configuration file"
       
    49 # must end in .mbc if passed on command-line
       
    50 my $ConfigFile;
       
    51 
       
    52 my $StartDir=&cwd();
       
    53 my $relative;
       
    54 	{
       
    55 	# Process command-line
       
    56 	
       
    57   	unless (@ARGV)
       
    58 		{
       
    59 		&Usage();
       
    60 		}
       
    61 	else
       
    62 		{
       
    63 		# check to see if we are using a relative path 
       
    64 	  	if ($ARGV[0] eq "-r")
       
    65 			{
       
    66 			$relative = 1;
       
    67 			shift @ARGV;
       
    68 			}
       
    69 
       
    70 		# check for a root from a config file in EPOCROOT dir as first argument
       
    71 	  	if (-e "$ENV{EPOCROOT}$ARGV[0].mbc")
       
    72 			{
       
    73 		  	$ConfigFile="$ENV{EPOCROOT}$ARGV[0].mbc";
       
    74 		  	shift @ARGV;
       
    75 			}
       
    76 		# check for a config file as the first argument
       
    77 	  	elsif ($ARGV[0]=~/.mbc$/io)
       
    78 			{
       
    79 			$ConfigFile=shift @ARGV;
       
    80 			if ($ConfigFile=~/^.:/o)
       
    81 				{
       
    82 				&Error("Config file can't be specified with a drive letter, as \"$ConfigFile\" is");
       
    83 				}
       
    84 			unless (-e $ConfigFile)
       
    85 				{
       
    86 				&Error("Can't find file $ConfigFile");
       
    87 				}
       
    88 			}
       
    89 		if (@ARGV)
       
    90 			{
       
    91 			# pass any other arguments as commands
       
    92 			@Commands=("@ARGV");
       
    93 			}
       
    94 		}
       
    95 	}
       
    96 
       
    97 	{
       
    98 	# scan config file if necessary
       
    99 	
       
   100 	if ($ConfigFile)
       
   101 		{
       
   102 		# make config file path absolute
       
   103 		$ConfigFile=&Path_AbsToWork($ConfigFile);
       
   104 		
       
   105 		my @Config2D;
       
   106 		eval { &Prepfile_ProcessL(\@Config2D, $ConfigFile); };
       
   107 		&Error($@) if $@;
       
   108 		
       
   109 		my %CheckDir;
       
   110 		
       
   111 		my @ConfigCommands;
       
   112 		my $Section='';
       
   113 		my @Death;
       
   114 		my $Line;
       
   115 		my $CurFile=$ConfigFile;
       
   116 	  LINE: foreach $Line (@Config2D)
       
   117 			{
       
   118 			my $LineNum=shift @$Line;
       
   119 			$_=shift @$Line;
       
   120 			if ($LineNum eq '#')
       
   121 				{
       
   122 				$CurFile=$_;
       
   123 				next;
       
   124 				}
       
   125 			if (/^SECTION_(\w*)$/io)
       
   126 				{
       
   127 				$Section=uc $1;
       
   128 				if ($Section=~/^(COMMANDS|DIRS|OPTIONALDIRS)$/o)
       
   129 					{
       
   130 					if (@$Line)
       
   131 						{
       
   132 						push @Death, "$CurFile($LineNum) : Can't specify anything on the same line as a section header\n";
       
   133 						}
       
   134 					next LINE;
       
   135 					}
       
   136 				push @Death, "$CurFile($LineNum) : Unknown section header - $_\n";
       
   137 				$Section=0;
       
   138 				next LINE;
       
   139 				}
       
   140 			unshift @$Line, $_;
       
   141 			if ($Section eq 'COMMANDS')
       
   142 				{
       
   143 				if ($$Line[0]=~/^ONEOFF$/io)
       
   144 					{
       
   145 					# check syntax for oneoff commands
       
   146 					unless (@$Line>=3)
       
   147 						{
       
   148 						push @Death, "$CurFile($LineNum) : Too few arguments for oneoff command\n";
       
   149 						}
       
   150 					# resolve oneoff dir relative to .mb file location
       
   151 					$$Line[1]=~s-^.*[^\\]$-$&\\-o; # add trailing backslash if necessary
       
   152 					$$Line[1]=&Path_MakeAbs($CurFile, $$Line[1]);
       
   153 					unless (-d $$Line[1])
       
   154 						{
       
   155 						warn "$CurFile($LineNum) : Can't find dir $$Line[1]\n";
       
   156 						}
       
   157 					}
       
   158 				push @ConfigCommands, "@$Line";
       
   159 				next LINE;
       
   160 				}
       
   161 			if ($Section eq 'DIRS' || $Section eq 'OPTIONALDIRS')
       
   162 				{
       
   163 				my $Dir;
       
   164 				foreach $Dir (@$Line)
       
   165 					{
       
   166 					if ($Dir=~/^.:/o)
       
   167 						{
       
   168 						push @Death, "$CurFile($LineNum) : directory $Dir is specified with a drive letter\n";
       
   169 						next;
       
   170 						}
       
   171 					$Dir=~s-^.*[^\\]$-$&\\-o;
       
   172 					$Dir=&Path_MakeAbs($CurFile, $Dir); # dirs must be the same for check
       
   173 					if ($CheckDir{uc $Dir})
       
   174 						{
       
   175 						# Silently ignore duplicate directories - #including of several .mbc files
       
   176 						# will often cause directory duplication.
       
   177 						# We can't do the same for duplicate commands because the order in which
       
   178 						# the commands are executed might be significant.
       
   179 						# push @Death, "$CurFile($LineNum) : Directory $Dir already specified\n";
       
   180 						next;
       
   181 						}
       
   182 					print "$Dir\n";
       
   183 					
       
   184 					unless (-d $Dir)
       
   185 						{
       
   186 						if ($Section ne 'OPTIONALDIRS')
       
   187 							{
       
   188 							push @Death, "$CurFile($LineNum) : Can't find directory $Dir\n";
       
   189 							}
       
   190 						next;
       
   191 						}
       
   192 					push @BldInfDirs, $Dir;
       
   193 					$CheckDir{uc $Dir}=$LineNum;
       
   194 					}
       
   195 				next LINE;
       
   196 				}
       
   197 			else
       
   198 				{
       
   199 				push @Death, "$CurFile($LineNum) : No section specified\n";
       
   200 				}
       
   201 			}
       
   202 		
       
   203 		if (@Death)
       
   204 			{
       
   205 			chomp $Death[$#Death];
       
   206 			&Error(@Death);
       
   207 			}
       
   208 		
       
   209 		# apply the commands unless already collected
       
   210 		unless (@Commands)
       
   211 			{
       
   212 			&Error("$ConfigFile : No Commands specified") unless @ConfigCommands;
       
   213 			@Commands=@ConfigCommands;
       
   214 			}
       
   215 		}
       
   216 	
       
   217 	# Should have commands now
       
   218 	&Usage() unless @Commands;
       
   219 	}
       
   220 
       
   221 	{
       
   222 	# Search for the BLD.INF files if necessary
       
   223 
       
   224 	my $mystartdir;
       
   225 	if ($relative)
       
   226 	{
       
   227 		$mystartdir = substr($StartDir, 2);
       
   228 	}
       
   229 
       
   230 	$mystartdir=~s:\/:\\:g;
       
   231 
       
   232 	if ($mystartdir ne "\\")
       
   233 		{
       
   234 		$mystartdir=$mystartdir."\\";
       
   235 		}
       
   236 
       
   237 	unless (@BldInfDirs)
       
   238 		{
       
   239 		# find the files in the source directories - skip the EPOCROOT directory
       
   240 		
       
   241 		my $EPOCROOTDir=$E32env::Data{EPOCPath};
       
   242 		$EPOCROOTDir=~s/^\\([^\\]*).*$/$1/o;
       
   243 		
       
   244 		opendir DIR, $mystartdir or &Error("Can't open dir: $!");
       
   245 		# remove ., .. and EPOCROOT dir
       
   246 		my @SrcDirs=grep !/^(\.\.?|$EPOCROOTDir|RECYCLER|System Volume Information)$/i, readdir DIR; 
       
   247 		foreach (@SrcDirs)
       
   248 			{
       
   249 			# prepend with current path
       
   250 			$_=$mystartdir.$_;
       
   251 			}
       
   252 		@SrcDirs=grep -d, @SrcDirs;
       
   253 		find(\&BldInfDirs, @SrcDirs);
       
   254 		@BldInfDirs=sort @BldInfDirs;
       
   255 
       
   256 		# if we are doing it relative to current location, need to include current dir
       
   257 		# if it contains a bld.inf
       
   258 		if (-f "BLD.INF" && $relative)
       
   259 			{
       
   260 			push @BldInfDirs, $mystartdir;
       
   261 			}
       
   262 
       
   263 		}
       
   264 	}
       
   265 
       
   266 	{
       
   267 	# Execute the commands
       
   268 	
       
   269 	my $Time=localtime;
       
   270 	print "=== metabld started $Time.\n";
       
   271 	my $Command;
       
   272 	foreach $Command (@Commands)
       
   273 		{
       
   274 		
       
   275 		$Time=localtime;
       
   276 		# Check if we should execute this command just the once
       
   277 		if ($Command=~s/^\s*ONEOFF\s+(\S+)\s+(.*)$/$2/io)
       
   278 			{
       
   279 			my $OneOffDir=$1;
       
   280 			# execute the command once rather than for each BLD.INF directory
       
   281 			chdir $OneOffDir or &Error("Can't change dir to $OneOffDir: $!");
       
   282 			print
       
   283 			(
       
   284 			 "===-------------------------------------------------\n",
       
   285 			 "=== $Command\n",
       
   286 			 "===-------------------------------------------------\n",
       
   287 			 "=== $Command started $Time.\n",
       
   288 			 "=== $Command == $OneOffDir\n"
       
   289 			);
       
   290 			system( "$Command");
       
   291 			}
       
   292 		else
       
   293 			{
       
   294 			# execute the command for each BLD.INF directory
       
   295 			print
       
   296 			(
       
   297 			 "===-------------------------------------------------\n",
       
   298 			 "=== $Command\n",
       
   299 			 "===-------------------------------------------------\n",
       
   300 			 "=== $Command started $Time.\n",
       
   301 			);
       
   302 			my $Dir;
       
   303 			foreach $Dir (@BldInfDirs)
       
   304 				{
       
   305 				chdir $Dir or &Error("Can't change dir to $Dir: $!");
       
   306 				print "=== $Command == $Dir\n";
       
   307 				system( "$Command");
       
   308 				}
       
   309 			}
       
   310 		chdir $StartDir or &Error("Can't change dir to $StartDir: $!");
       
   311 		$Time=localtime;
       
   312 		print "=== $Command finished $Time.\n";
       
   313 		}
       
   314 	}
       
   315 
       
   316 
       
   317 #################################################
       
   318 #	SUBROUTINES
       
   319 #################################################
       
   320 
       
   321 sub Usage
       
   322 	{
       
   323 	print <<ENDHERESTRING;
       
   324 usage: metabld [EPOCROOT .mbc file basename|.mbc config file] [command]
       
   325 MetaBld is a tool for carrying out build commands across several components.
       
   326 A .mbc config file contains directories and commands, eg:
       
   327 
       
   328 SECTION_COMMANDS
       
   329 bldmake bldfiles
       
   330 abld target wins udeb
       
   331 // "oneoff" means carry out command just once, not for each directory.
       
   332 // First arg after "oneoff" must be a start dir, and can be "."
       
   333 oneoff \\e32\\rombuild rom xxx
       
   334 oneoff . \\e32test\\group\\abld test build wins urel
       
   335 SECTION_DIRS
       
   336 \\e32
       
   337 \\f32\\group
       
   338 
       
   339 It's possible to #include lists of dirs from other files if necessary,
       
   340 and may be useful for carrying out different sets of commands on the same set
       
   341 of directories via different .mbc files.
       
   342 If a command is specified on the command-line, it will be executed instead
       
   343 of any commands specified in a .mbc file.
       
   344 If no directories are specified in a .mbc file, then all the directories
       
   345 containing a bld.inf file on the current drive will be searched for instead.
       
   346 ENDHERESTRING
       
   347 exit 1;
       
   348 }
       
   349 
       
   350 sub Error (@)
       
   351 	{
       
   352 	
       
   353 	die
       
   354 	@_, "\n",
       
   355 	"Error executing metabld.bat\n"
       
   356 	;
       
   357 	}
       
   358 
       
   359 sub BldInfDirs
       
   360 	{
       
   361 	s-\/-\\-go;
       
   362 	if (/^BLD.INF$/io)
       
   363 		{
       
   364 		$File::Find::dir=~s-\/-\\-go;
       
   365 		push @BldInfDirs, $File::Find::dir;
       
   366 		}
       
   367 	}
       
   368