Moving feature configuration out of the buildrom scope.
authorRoss Qin <ross.qin@nokia.com>
Thu, 18 Nov 2010 16:02:32 +0800
changeset 697 818fe0ed324b
parent 696 30aa553e9465
child 698 e3ee96a3961c
child 712 df89378e9223
Moving feature configuration out of the buildrom scope.
imgtools/buildrom/group/BLD.INF
imgtools/buildrom/group/release.txt
imgtools/buildrom/tools/buildrom.pm
imgtools/buildrom/tools/featureconfigurator.pl
--- a/imgtools/buildrom/group/BLD.INF	Wed Nov 17 16:47:55 2010 +0800
+++ b/imgtools/buildrom/group/BLD.INF	Thu Nov 18 16:02:32 2010 +0800
@@ -59,6 +59,7 @@
 ../tools/featuresdat.pm		/epoc32/tools/featuresdat.pm
 ../tools/features.pl		/epoc32/tools/features.pl
 ../tools/features.pm		/epoc32/tools/features.pm
+../tools/featureconfigurator.pl		/epoc32/tools/featureconfigurator.pl
 
 #ifndef TOOLS2_LINUX 
 ../tools/features.cmd		/epoc32/tools/features.cmd
--- a/imgtools/buildrom/group/release.txt	Wed Nov 17 16:47:55 2010 +0800
+++ b/imgtools/buildrom/group/release.txt	Thu Nov 18 16:02:32 2010 +0800
@@ -1,3 +1,8 @@
+Version 3.32.0 (BUILDROM)
+===============
+Released by Ross Qin, 18/11/2010
+	1) Moving feature configuration out of the buildrom scope.
+	
 Version 3.31.0 (BUILDROM)
 ===============
 Released by Lorence Wang, 20/10/2010
--- a/imgtools/buildrom/tools/buildrom.pm	Wed Nov 17 16:47:55 2010 +0800
+++ b/imgtools/buildrom/tools/buildrom.pm	Thu Nov 18 16:02:32 2010 +0800
@@ -67,7 +67,7 @@
 my $enforceFeatureManager = 0; # Flag to make Feature Manager mandatory if SYMBIAN_FEATURE_MANAGER macro is defined. 
 
 my $BuildromMajorVersion = 3 ;
-my $BuildromMinorVersion = 31;
+my $BuildromMinorVersion = 32;
 my $BuildromPatchVersion = 0;
 
 
@@ -75,13 +75,18 @@
 {
 
 	# Option "-fm" will be supported instead of option "-f|fr" if SYMBIAN_FEATURE_MANAGER macro is defined.
-	my $featuresOptionUsage = "-ffeatureuids or -fr=featureuids -- feature registry database XML file name";
+	my $featuresOptionUsage = "-ffeatureuids or -fr=featureuids -- [obsolete] Feature registry database XML file name\n". 
+							   "                                       Please use featureconfigurator.pl to configurate features.\n\n".
+							   "   -nofm                            -- Don't perform feature configuration \n\n"; 
 	if ($enforceFeatureManager) 
 	{
-		$featuresOptionUsage = "-fm=featuredatabasefile          -- feature manager/feature registry database XML file name.\n".
-							   "\t\t\t\t    Multiple XML files can be passed seperated by commas.\n".
-							   "   -nofm=featuresdatafile           -- don't generate features data file.".
-							   " Instead use pre-built features data file.";
+		$featuresOptionUsage = "-fm=featuredatabasefile          -- [obsolete] Feature manager/feature registry database XML file name.\n".
+							   "                                       Multiple XML files can be passed seperated by commas.\n". 
+							   "                                       Please use featureconfigurator.pl to configurate features.\n\n".				
+							   "   -nofm=featuresdatafile           -- [obsolete] Don't generate features data file.\n".
+							   "                                       Use pre-built features data file instead.\n". 
+							   "                                       Please use featureconfigurator.pl to configurate features.\n\n".
+							   "   -nofm                            -- Don't perform feature configuration\n\n";							  
 	}
 
 #........1.........2.........3.........4.........5.........6.........7.....
@@ -117,7 +122,8 @@
    -p                               -- preserves the intermediate files pertaining to data drive, Z drive and BMCONV
    -spi                             -- enable producing SPI files
    -spiplacement                    -- enable positioning of spi file
-   -w                               -- warn if file has been selected from a different directory 
+   -w                               -- warn if file has been selected from a different directory
+   
    $featuresOptionUsage
    -etool                           -- external tool specification (xx is tool's perl module)
    -compress                        -- compression type of ROM image:
@@ -159,7 +165,9 @@
    -prependepocroot                 -- if there is no EPOCROOT## before /epoc32/, prepend EPOCROOT## to epoc32.
    -stdcpp                          -- ignore symbian customized cpp and try to find another cpp in the PATH.(for Windows only)
    -cpp=xxx                         -- specify a CPP preprocessor used by Buildrom.
-   -xiponly                      -- just create the XIP ROM image without creating the ROFS image.
+   -xiponly                         -- just create the XIP ROM image without creating the ROFS image.
+   -nopreprocess                    -- Input oby files have been or don't need to be preprocessed,
+                                       don't preprocess the input oby files.
    -inputoby=<finalOBYfile>         -- Ignore BUILDROM config phase, invoke Rombuild/Rofsbuild using <finalOBYfile>.
                                     <finalOBYfile> must contain one and ONLY one of romsize/rofssize/dataimagename/imagename keywords,
                                     The keywords will be used to identify the OBY type.
@@ -278,6 +286,7 @@
 my $featuremanager = 0; #Flag to enable support for feature manager database XML file and to generate  
 			# features data file.
 my $noFeatureManager = 0; # Flag to stop the generation of features.dat file and use pre-built features.dat if provided.
+my $noFeatureConf  = 0 ;
 my $preBuiltFeaturesDataFile  = ''; # To store the name of pre-built features.dat file provided with "-nofm" option.
 
 #Image Content XML file that supports specific feature to be added
@@ -359,6 +368,7 @@
 my $preprocessor = "cpp";
 my $opt_xiponly = 0;
 my $ignoreconfig = 0;
+my $nopreprocess = 0;
 my $romcount = 0;
 
 sub match_obyfile
@@ -755,8 +765,7 @@
 
 	my ($paramFileFlag, @argList); 
 
-	if (defined @_)
-	{
+	if (defined @_ && scalar(@_) > 0) {
 		($paramFileFlag, @argList) = @_;
 	}
 	else
@@ -783,13 +792,15 @@
 		}
 	}
 	# first searching argList for keepgoing option
+	my @newArgList = ();
 	foreach my $arg (@argList) {
-		if ( $arg =~ /^-k$/i || $arg =~ /^-keepgoing$/i )
-	  {
-			$opt_k = 1;		
-  		next;	
-		}
-		if ($arg =~ /^-workdir=(.*)/)
+		if ( $arg =~ /^-k$/i || $arg =~ /^-keepgoing$/i ) {
+			$opt_k = 1;	 
+		}
+		elsif($arg =~ /^-nopreprocess$/i ) {
+			$nopreprocess = 1 ; 
+		}
+		elsif ($arg =~ /^-workdir=(.*)/)
 		{
 			my $workdir = $1;
 			if (!-d $workdir)
@@ -806,11 +817,13 @@
 				$thisdir =~ s-\/-\\-g;
 			}
 			$opt_workdir = 1;
-			chdir "$currentdir";
-			next;	
+			chdir "$currentdir"; 
+		}
+		else {
+			push @newArgList, $arg ;
 		}
 	}
-	foreach my $arg (@argList)
+	foreach my $arg (@newArgList)
 	{
 	    if ($arg =~ /^-argfile=(.*)/) 
 		{
@@ -927,6 +940,7 @@
 				$errors++;
 				next;
 			}
+			$noFeatureConf = 0;
 			$featureXml = $1;
 			$xmlrequired = 1;
 			$featuremanager = 1;
@@ -978,14 +992,18 @@
 	    	}
 	    	next;
 	    }
-		if ($arg =~ /^-nofm(=(.*))?$/)
-		{
-			if (!$enforceFeatureManager) 
-			{
-				print "Unknown arg: $arg\n";
+		if ($arg =~ /^-nofm(=(.*))?$/) {
+			if(!$1) {
+                $noFeatureConf = 1 ;
+				next ;
+            }
+			 
+			if (!$enforceFeatureManager)  {
+				print "Unsupported option: $arg\n";
 				$errors++;
 				next;
-			}
+			} 
+			$noFeatureConf = 0;
    			$noFeatureManager = 1;
             #DEF125375 If caller is simply giving -nofm without any parameter, a warning message will be given.
             if(!$2)
@@ -1050,42 +1068,49 @@
 			$checkcase_test=1;
 			next;	
 		}
-		if ($arg =~ /^-workdir=(.*)/)
-		{
-			next;
-		}
+		 
 		if ($arg =~ /^-stdcpp$/)
-		{
-			if (&is_linux)
-			{
-				print "Warning: option -stdcpp only apply for Windows\n";
-				next;
+		{	
+			if($nopreprocess) {
+				print STDERR "Warning: -stdcpp option is invalid because the -nopreprocess option set.\n";
 			}
-			if ($cppoption)
-			{
-				die "Error: -stdcpp option and -cpp=xxx option cannot be used at the same time.\n";
+			else {
+				if (&is_linux)
+				{
+					print "Warning: option -stdcpp only apply for Windows\n";
+					next;
+				}
+				if ($cppoption)
+				{
+					die "Error: -stdcpp option and -cpp=xxx option cannot be used at the same time.\n";
+				}
+				$stdcpp = 1;
 			}
-			$stdcpp = 1;
 			next;
 		}
 		if ($arg =~ /^-cpp=(.*)/)
 		{
-			if ($stdcpp)
-			{
-				die "Error: -stdcpp option and -cpp=xxx option cannot be used at the same time.\n";
-			}
-			if ($cppoption)
-			{
-				print "Warning: -cpp option has been set before. The previous configuration will be overwritten!\n";
+			if($nopreprocess) {
+				print STDERR "Warning: -cpp option is invalid because the -nopreprocess option set.\n";
 			}
-			$cppoption = 1;
-			$preprocessor = $1;
-			$preprocessor =~ s-\\-\/-g;
-			$preprocessor =~ s-EPOCROOT##\/?-$epocroot-g;
-			if (-d $preprocessor)
-			{
-				$preprocessor .= "\/" unless $preprocessor =~ /\/$/;
-				$preprocessor .= "cpp";
+			else {
+				if ($stdcpp)
+				{
+					die "Error: -stdcpp option and -cpp=xxx option cannot be used at the same time.\n";
+				}
+				if ($cppoption)
+				{
+					print "Warning: -cpp option has been set before. The previous configuration will be overwritten!\n";
+				}
+				$cppoption = 1;
+				$preprocessor = $1;
+				$preprocessor =~ s-\\-\/-g;
+				$preprocessor =~ s-EPOCROOT##\/?-$epocroot-g;
+				if (-d $preprocessor)
+				{
+					$preprocessor .= "\/" unless $preprocessor =~ /\/$/;
+					$preprocessor .= "cpp";
+				}
 			}
 			next;
 		}
@@ -1265,11 +1290,6 @@
 			}
 			next;
 		}
-		if ( $arg =~ /^-k$/i || $arg =~ /^-keepgoing$/i )
-	    {
-			$opt_k = 1;
-			next;
-	    }
 		if ( $arg =~ /^-r$/i || $arg =~ /^-retainfolder$/i )
 	    {
 			$opt_r = 1;
@@ -1391,98 +1411,122 @@
 
 sub preprocessing_phase
 {
-	my $temp1OBYFile = $thisdir."tmp1.oby";
-	unlink "$temp1OBYFile";
-
-#	Macro "ROM_FEATURE_MANAGEMENT" is defined when "-f|fr" or "-fm" is used
-	if (defined ($featureXml))
-	{
-		$cppargs .= " -DROM_FEATURE_MANAGEMENT ";
-	}
-
-	# add pre-include file and include directories for feature variants
-	if ($featureVariant{'VALID'})
-	{
-		$cppargs .= " -I.";
-		my $incRef = $featureVariant{'ROM_INCLUDES'};
-		if ($incRef)
+	if($nopreprocess == 0) {
+		my $temp1OBYFile = $thisdir."tmp1.oby";
+		unlink "$temp1OBYFile";
+
+	#	Macro "ROM_FEATURE_MANAGEMENT" is defined when "-f|fr" or "-fm" is used
+		if (defined ($featureXml))
 		{
-			foreach (@$incRef)
+			$cppargs .= " -DROM_FEATURE_MANAGEMENT ";
+		}
+
+		# add pre-include file and include directories for feature variants
+		if ($featureVariant{'VALID'})
+		{
+			$cppargs .= " -I.";
+			my $incRef = $featureVariant{'ROM_INCLUDES'};
+			if ($incRef)
+			{
+				foreach (@$incRef)
+				{
+					$cppargs .= " -I \"$_\"";
+				}
+			}
+			my $HRH = $featureVariant{'VARIANT_HRH'};
+			if ($HRH)
 			{
-		    	$cppargs .= " -I \"$_\"";
+				$cppargs .= " -include \"$HRH\"";
 			}
 		}
-		my $HRH = $featureVariant{'VARIANT_HRH'};
-		if ($HRH)
+		else
+		{
+			# no feature variant so use the standard includes
+			$cppargs .= " -I. -I \"$rominclude\"";
+		}
+
+		if ($stdcpp)
+		{
+			$preprocessor = find_stdcpp();
+		}
+		print "* $preprocessor -Wno-endif-labels -o $temp1OBYFile $cppargs\n" if ($opt_v);
+		
+		is_existinpath("$preprocessor", romutl::DIE_NOT_FOUND);
+		$errors = 0;
+		open CPP, "| $preprocessor -Wno-endif-labels -o $temp1OBYFile $cppargs" or die "* Can't execute cpp";
+		foreach my $arg (@obyfiles)
 		{
-		    $cppargs .= " -include \"$HRH\"";
-		}
-	}
-	else
-	{
-		# no feature variant so use the standard includes
-		$cppargs .= " -I. -I \"$rominclude\"";
-	}
-
-	if ($stdcpp)
-	{
-		$preprocessor = find_stdcpp();
+			print CPP "\n#line 1 \"$arg\"\n";
+		
+			if(open(OBY, $arg)) {
+				print "* reading $arg\n" if ($opt_v);
+				while ($line=<OBY>) {
+					print CPP $line;
+				}
+				close OBY;
+			}
+			else {
+				print STDERR "* Can't open $arg\n";
+				if(!$opt_k){			
+					close CPP;
+					exit(1);
+				}
+			}
+		}
+		close CPP;
+		my $cpp_status = $?;
+		die "* cpp failed\n" if ($cpp_status != 0 || !-f "$temp1OBYFile");
+
+		if( defined ($image_content))
+		{
+			#Read the OBY file that was generated by the pre-processor
+			&ReadPreprocessedFile($temp1OBYFile);
+
+	#		Check if the static dependencies of the OBY binaries are resolved.
+			&ImageContentHandler::UpdateObyBinaryStaticDep();
+			
+			#Now append the files collected from cdfs.
+			&ImageContentHandler::GenObyFile($temp1OBYFile);
+		}
+
+		if($obycharset =~ /utf-?8/i)
+		{
+			my $utf8file = $thisdir."tmp1utf8.oby";
+			open INFILE, "<$temp1OBYFile" or die "* Can't open file $temp1OBYFile";
+			open CHARSETTRAN, "| charsettran -to=hostcharset > $utf8file" or die "* Can't execute charsetran";
+			while(<INFILE>)
+			{
+				print CHARSETTRAN $_;
+			}
+			close CHARSETTRAN;
+			close INFILE;	
+			unlink $temp1OBYFile  or die "* Can't remove file $temp1OBYFile";
+			rename 	$utf8file, $temp1OBYFile or die "* Can't rename file $utf8file to file $temp1OBYFile";
+		}
+		@obydata = ();
+		# load tmp1.oby here
+		open TMP1, "$temp1OBYFile" or die("* Can't open $temp1OBYFile\n");
+		while(<TMP1>) { 
+			push @obydata,$_;
+		}
+		close TMP1 ;
 	}
-	print "* $preprocessor -Wno-endif-labels -o $temp1OBYFile $cppargs\n" if ($opt_v);
-	
-	is_existinpath("$preprocessor", romutl::DIE_NOT_FOUND);
-	$errors = 0;
-	open CPP, "| $preprocessor -Wno-endif-labels -o $temp1OBYFile $cppargs" or die "* Can't execute cpp";
-	foreach my $arg (@obyfiles)
-	{
-		print CPP "\n#line 1 \"$arg\"\n";
-	
-		if(open(OBY, $arg)) {
-			print "* reading $arg\n" if ($opt_v);
-			while ($line=<OBY>) {
-				print CPP $line;
-			}
-			close OBY;
-		}
-		else {
-			print STDERR "* Can't open $arg\n";
-			if(!$opt_k){			
-				close CPP;
-				exit(1);
+	else {
+		foreach my $arg (@obyfiles) {		
+			if(open(OBY, $arg)) {
+				print "* reading $arg\n" if ($opt_v);
+				while (<OBY>) {
+					push @obydata,$_;
+				}
+				close OBY;
 			}
-		}
-	}
-	close CPP;
-	my $cpp_status = $?;
-	die "* cpp failed\n" if ($cpp_status != 0 || !-f "$temp1OBYFile");
-
-	if( defined ($image_content))
-	{
-		#Read the OBY file that was generated by the pre-processor
-		&ReadPreprocessedFile($temp1OBYFile);
-
-#		Check if the static dependencies of the OBY binaries are resolved.
-		&ImageContentHandler::UpdateObyBinaryStaticDep();
-		
-		#Now append the files collected from cdfs.
-		&ImageContentHandler::GenObyFile($temp1OBYFile);
-	}
-
-	# Setup default rom configuration
-	$romimage[0] = {xip=>1, compress=>0, extension=>0, composite=>"none",uncompress=>0 };
-	if($obycharset =~ /utf-?8/i)
-	{
-		my $utf8file = $thisdir."tmp1utf8.oby";
-		open INFILE, "<$temp1OBYFile" or die "* Can't open file $temp1OBYFile";
-		open CHARSETTRAN, "| charsettran -to=hostcharset > $utf8file" or die "* Can't execute charsetran";
-		while(<INFILE>)
-		{
-			print CHARSETTRAN $_;
-		}
-		close CHARSETTRAN;
-		close INFILE;	
-		unlink $temp1OBYFile  or die "* Can't remove file $temp1OBYFile";
-		rename 	$utf8file, $temp1OBYFile or die "* Can't rename file $utf8file to file $temp1OBYFile";
+			else {
+				print STDERR "* Can't open $arg\n";
+				if(!$opt_k){	 
+					exit(1);
+				}
+			}
+		}
 	}
 }
 
@@ -1553,50 +1597,46 @@
 		$substitutionData{"RIGHT_NOW"} = sprintf("%02d/%02d/%04d %02d:%02d:%02d", $mday, $mon+1, $year+1900, $hour, $min, $sec);
 		$substitutionData{"EPOCROOT"} = $epocroot;
 		@substitutionOrder = ("TODAY", "RIGHT_NOW", "EPOCROOT");
-	}
-
-	my $temp1OBYFile = $thisdir."tmp1.oby";
-	
-	open TMP1, "$temp1OBYFile" or die("* Can't open $temp1OBYFile\n");
-	while ($line=<TMP1>)
-	{
-		if(($line =~ /^\s*romsize\s*=/i) || ( $line=~ /^\s*rom_image/i) || ($line =~ /^\s*data_image/i))
-		{
+	}	 
+	 
+	foreach $line(@obydata) {
+		if(($line =~ /^\s*romsize\s*=/i) || ( $line=~ /^\s*rom_image/i) || ($line =~ /^\s*data_image/i)) {
 			$onlysmrimage = 0;
 			last;
 		}
 	}
-	close TMP1;	
-	if ($enforceFeatureManager && (!$featuremanager) && (!$noFeatureManager) )
-	{
-		my $defaultFeatureDbFlag = 0;
-		open TMP1, "$temp1OBYFile" or die("* Can't open $temp1OBYFile\n");
-		while ($line=<TMP1>)
-		{
-			if ($line=~/^\s*defaultfeaturedb\s*=?\s*(\S+)/i)
-			{	
-				# Get the default value for featuredatabasefile
-                
-				$featureXml = "$epocroot$1";
-				$featureXml =~ s-\\-\/-g;
-				$featuremanager = 1;				
-				$defaultFeatureDbFlag = 1;
-				load_featuresutil();				
-				last;
+	if($noFeatureConf == 0) { 
+		if ($enforceFeatureManager && (!$featuremanager) && (!$noFeatureManager) ) {
+			my $defaultFeatureDbFlag = 0;
+			foreach $line(@obydata) { 
+				if ($line=~/^\s*defaultfeaturedb\s*=?\s*(\S+)/i)
+				{	
+					# Get the default value for featuredatabasefile
+					
+					$featureXml = "$epocroot$1";
+					$featureXml =~ s-\\-\/-g;
+					$featuremanager = 1;				
+					$defaultFeatureDbFlag = 1;
+					load_featuresutil();				
+					last;
+				}
 			}
-		}
-		close TMP1;
-
-		if(!$defaultFeatureDbFlag && !$onlysmrimage)
-		{
-			print "Error: Neither option \"-fm|-nofm\" nor default value for featuredatabase file is provided.\n";
-			exit(1);			
+		 
+
+			if(!$defaultFeatureDbFlag && !$onlysmrimage)
+			{
+				print "Error: Neither option \"-fm|-nofm\" nor default value for featuredatabase file is provided.\n";
+				exit(1);			
+			}
 		}
 	}
-
-	open TMP1, "$temp1OBYFile" or die("* Can't open $temp1OBYFile\n");
-	while ($line=<TMP1>)
-	{
+	
+	# Setup default rom configuration
+	$romimage[0] = {xip=>1, compress=>0, extension=>0, composite=>"none",uncompress=>0 }; 
+		
+	my @savedObyData = @obydata;
+	@obydata = ();
+	foreach  $line(@savedObyData) {
 		track_source($line);
 		$line =~ s-\\-\/-g;
 
@@ -1653,19 +1693,19 @@
  				}
  			}
 		}
-
-		if($line =~ /^\s*FEATURE\s*(.*)/i || $line =~ /^\s*EXCLUDE_FEATURE\s*(.*)/i)
-		{
-			# Process the feature keywords only when "-f|fr" or "-fm" is passed to buildrom
-			if(defined ($featureXml))
-			{
-				push @obydata, "$line";
+		if($noFeatureConf == 0) { 
+			if($line =~ /^\s*FEATURE\s*(.*)/i || $line =~ /^\s*EXCLUDE_FEATURE\s*(.*)/i) {
+				# Process the feature keywords only when "-f|fr" or "-fm" is passed to buildrom
+				if(defined ($featureXml))
+				{
+					push @obydata, "$line";
+				}
+				else
+				{
+					push @obydata, "REM handled $line";
+				}
+				next;
 			}
-			else
-			{
-				push @obydata, "REM handled $line";
-			}
-			next;
 		}
 
 		if ($line=~/^\s*DEFINE\s+(\w+)\s+(\S+)/i)
@@ -2659,14 +2699,14 @@
 my $spicount=0; #counts number of spi files in each rom image
 my $filescount=0; #counts number of data files
 my $hidefilescount=0; #counts number of data files to be hidden
-my $romimage=0; #number of rom image currently working with
+my $romimagecount=0; #number of rom image currently working with
 
 sub locateexisting 
 { # if an SPI file of this type exists in a base image then returns name of SPI file from the array
-	my ($romimage, $spifile, $base) =@_;
+	my ($index, $spifile, $base) =@_;
 	my $i=0;
 	while(defined $spiarray[$base][$i]) {
-		if($spiarray[$base][$i]{spi} eq $spiarray[$romimage][$spifile]{spi}) {
+		if($spiarray[$base][$i]{spi} eq $spiarray[$index][$spifile]{spi}) {
 			my $spiname;
 			my $spiextension;
 			if($spiarray[$base][$i]{spifile} =~ /(.*)\.(.*)$/) {
@@ -2684,27 +2724,27 @@
 
 sub create 
 { #called to create SPI file and store in specified directory
-	my ($romimage, $spifile, $base) =@_; #$romimage = current rom image number, $spifile = current spifile number, $base=number of rom image basing on
+	my ($index, $spifile, $base) =@_; #$index = current rom image number, $spifile = current spifile number, $base=number of rom image basing on
 	my $existingspi = "";
 	if(defined($base)) { # checks core image for an existing SPI file of this type, if an existing file exists then $existingspi is set to -i<name of existing spi file> which will later be passed to spitool.pm
-		$existingspi = locateexisting($romimage, $spifile, $base);
+		$existingspi = locateexisting($index, $spifile, $base);
 		if($existingspi ne "") {
 			$existingspi = "-i$existingspi";
 			
 		}
 	}
-	if($spiarray[$romimage][$spifile]{spifile} =~ /(.+)\.(.*)$/) {
-		my $targetspi="$1-$romimage-$spifile\.$2"; #add romimage number and identifier for spi file to spi file name to distinguish from other spi files
+	if($spiarray[$index][$spifile]{spifile} =~ /(.+)\.(.*)$/) {
+		my $targetspi="$1-$index-$spifile\.$2"; #add romimage number and identifier for spi file to spi file name to distinguish from other spi files
 		my @dataforspi; # array to store names of data files to include in spi file
 		my @hidedatainspi; # array to store names of data files that are to be hidden in spi file
 		for(my $k=0;$k<scalar @datafiles;$k++) {
-			if($datafiles[$k]{rom}==$romimage && $datafiles[$k]{spifile} == $spifile) {
+			if($datafiles[$k]{rom}==$index && $datafiles[$k]{spifile} == $spifile) {
 				push @dataforspi, $datafiles[$k]{data}; #push name of data file onto array if correct romimage and spi type
 			}
 		}
 
 		for(my $j=0;$j<scalar @hidedatafiles;$j++) {
-			if($hidedatafiles[$j]{rom}==$romimage && $hidedatafiles[$j]{spifile} == $spifile)
+			if($hidedatafiles[$j]{rom}==$index && $hidedatafiles[$j]{spifile} == $spifile)
 			{
 				push @hidedatainspi, $hidedatafiles[$j]{data}; #push name of data file to be hidden onto array if correct romimage and spi type
 			}
@@ -2740,7 +2780,7 @@
 		{
 			if ($line=~/^\s*REM \s*ROM_IMAGE\[(\d)\]/) # specify which romimage following lines are part of
 			{
-				$romimage=$1;
+				$romimagecount=$1;
 				$spicount=0;
 			}	elsif ($line =~ /^\s*REM/i)
 			{
@@ -2751,36 +2791,36 @@
 				my $flag=1;
 				my $i;
 				for($i=0;$i<$spicount && $flag;$i++) { #loop to see if name of spi file already added to this romimage in array
-					if($spiarray[$romimage][$i]{spi} eq $targetspi) {
+					if($spiarray[$romimagecount][$i]{spi} eq $targetspi) {
 						$flag=0;
 					}
 				}
 			
 				if($flag) { # adds spi file if not yet listed for this romimage in array
-					$spiarray[$romimage][$spicount++]={spifile=>$3, spidir=>$4, spi=>$4.$3};
+					$spiarray[$romimagecount][$spicount++]={spifile=>$3, spidir=>$4, spi=>$4.$3};
 					$i=$spicount;
 				}
-					$datafiles[$filescount++]= {data=>$1, rom=>$romimage, spifile=>$i-1}; 
+					$datafiles[$filescount++]= {data=>$1, rom=>$romimagecount, spifile=>$i-1}; 
                         } elsif ($spiplacement && $line =~/^\s*SPI_POSITION/i){
         			# mark the image index at which the SPI_POSITION keyword has occured in order to avoid writing duplicate
         			# entries of the spi file.
-        			$spipositionflag{$romimage} = 1;
+        			$spipositionflag{$romimagecount} = 1;
         		} elsif ($line=~/^\s*spidatahide\s*=\s*(\S+)\s+(\S+)\s(\S+)\s*$/)	{
 				#spidatahide=\epoc32\data\Z\Resource\Plugins\Obexclasscontroller.RSC ecom.spi \private\10003a3f\
 				my $targetspi=$3.$2;
 				my $flag=1;
 				my $i;
 				for($i=0;$i<$spicount && $flag;$i++) { #loop to see if name of spi file already added to this romimage in array
-					if($spiarray[$romimage][$i]{spi} eq $targetspi) {
+					if($spiarray[$romimagecount][$i]{spi} eq $targetspi) {
 						$flag=0;
 					}
 				}
 			
 				if($flag) { # adds spi file if not yet listed for this romimage in array
-					$spiarray[$romimage][$spicount++]={spifile=>$2, spidir=>$3, spi=>$3.$2};
+					$spiarray[$romimagecount][$spicount++]={spifile=>$2, spidir=>$3, spi=>$3.$2};
 					$i=$spicount;
 				}
-					$hidedatafiles[$hidefilescount++]= {data=>$1, rom=>$romimage, spifile=>$i-1}; 
+					$hidedatafiles[$hidefilescount++]= {data=>$1, rom=>$romimagecount, spifile=>$i-1}; 
 			}
 
 		}
@@ -2970,10 +3010,13 @@
 #
 sub featurefile_creation_phase
 {
-	if($onlysmrimage)
-	{
+	if($onlysmrimage){
 		return;
 	}
+	if($noFeatureConf) {
+		checkcase() if ($checkcase);
+		return ;
+	}
 	# Set the name and Rom Image location of feature file.
 	if ($enforceFeatureManager) 
 	{
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/buildrom/tools/featureconfigurator.pl	Thu Nov 18 16:02:32 2010 +0800
@@ -0,0 +1,998 @@
+#
+# Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of the License "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+# This package is to build rom image
+#
+
+use FindBin;		# for FindBin::Bin
+my $PerlLibPath;    # fully qualified pathname of the directory containing our Perl modules
+my $PerlEPOCPath;
+
+BEGIN {
+# check user has a version of perl that will cope
+	require 5.005_03;
+# establish the path to the Perl libraries
+    $PerlLibPath = $FindBin::Bin;	
+#    $PerlLibPath =~ s/\//\\/g;
+    $PerlLibPath .= "\\";
+    $PerlLibPath =~ s/\\/\//g;
+    
+    $PerlEPOCPath = $ENV{EPOCROOT};
+    $PerlEPOCPath =~ s/\\/\//g;
+    $PerlEPOCPath .= "\/" unless $PerlEPOCPath =~ /\/$/;
+    $PerlEPOCPath .= "epoc32\/tools\/";
+}
+use lib $PerlEPOCPath."build/lib/";
+use lib $PerlEPOCPath;
+use lib $PerlLibPath;
+use strict;
+use romutl;
+use romosvariant;
+# Work out the relative path to the epoc32 directory 
+use Cwd; 
+use File::Basename;
+# global variables specific to data drive image generation. 
+use File::Path ;					# Module to provide functions to remove or create directories in a convenient way.
+use File::Find; 
+use features;
+use flexmodload;	     # To load modules dynamically
+
+my $enforceFeatureManager = 0; # Flag to make Feature Manager mandatory if SYMBIAN_FEATURE_MANAGER macro is defined. 
+
+my $BuildromMajorVersion = 0 ;
+my $BuildromMinorVersion = 2;
+my $BuildromPatchVersion = 0;
+
+my $outputoby = "output.oby" ;
+
+
+sub print_usage {
+
+	# Option "-fm" will be supported instead of option "-f|fr" if SYMBIAN_FEATURE_MANAGER macro is defined.
+	my $featuresOptionUsage = "-f<featureuids> or\n".
+	"   -fr=<featureuids>            -- feature registry database XML file name\n";
+	if ($enforceFeatureManager) {
+		$featuresOptionUsage = "-fm=<featuredbfile>          -- feature manager/feature registry database XML file name.\n".
+							   "                                   Multiple XML files can be passed seperated by commas.\n".
+							   "   -nofm=<featuresdatafile>     -- don't generate features data file.\n".
+							   "                                   Instead use pre-built features data file.\n";
+	}
+
+#........1.........2.........3.........4.........5.........6.........7.....
+	print <<USAGE_EOF;
+
+FEATURECONFIGURATOR - feature configuration tool V$BuildromMajorVersion.$BuildromMinorVersion.$BuildromPatchVersion
+
+Usage:
+
+  featureconfigurator [options] obyfile [obyfile2 ...]   
+
+Configurate features from *.iby/*.oby files and output a 
+consolidated obyfile for buildrom's use. 
+
+This is a front end of buildrom, which partly implements 
+functionalities of buildrom.
+
+
+
+The available options are
+
+   -h                           -- Print this message
+
+   $featuresOptionUsage
+   -oby-charset=<charset>       -- Used character set in which OBY was written
+
+   -k or -keepgoing             -- Enable keepgoing,continue to config features
+                                   and create oby file.
+
+   -argfile=xxx                 -- Specify argument-file name containing list of 
+                                   command-line arguments to featureconfigurator
+   -workdir=xxx                 -- Specify a directory for generated files. 
+                                   The working directory will not be changed even this option is used.
+   
+   -I<directory>                -- Use <directory> for the referenced IBY/OBY files
+   -D<xxx>                      -- Define xxx for C++ preprocessor
+
+   -stdcpp                      -- Ignore symbian customized cpp and try to find 
+                                   another cpp in the PATH.(for Windows only)
+   -cpp=<xxx>                   -- Use xxx as path of CPP preprocessor.
+ 
+   -o<xxx.oby>                  -- Output oby file name is set to xxx.oby
+                                   If this argument is not given, then output oby file is
+                                   "output.oby". output files are placed under workdir.
+								   
+	-s                          -- strict option, any missing files will stop buildrom
+	-v                          -- verbose
+	-noiby[=<n>]                -- if n = 0, then create iby files, otherwise don't create iby files, "-noiby=0" is default
+	-w                          -- suppress cpp warnings.
+
+USAGE_EOF
+
+}
+
+
+my $PerlEPOCPath = &get_epocroot()."epoc32\/tools\/";   # fully qualified pathname of the directory containing EPOC Perl modules
+
+ 
+
+my $xmlrequired = 0; # assume xml required is false. Used to determine if xml
+                     # modules should be loaded.
+
+
+my @tempfiles;  	
+my $preserve = 0; 	#flag to indicate if temporary files should be preserved
+my $uppath="x";	    	# will be initialised when first needed
+
+my $epocroot = &get_epocroot;
+
+my @obyfiles;
+my $cppargs = "-nostdinc -undef";
+my $opt_k = 0;
+my $opt_v = 0; 
+my $opt_w = 0 ;
+my $strict = 0;
+my $line;
+my $errors = 0;
+my $thisdir=cwd;
+$thisdir=~s-\\-\/-go;		    # separator from Perl 5.005_02+ is forward slash
+$thisdir.= "\/" unless $thisdir =~ /\/$/;
+$thisdir =~ s-\/-\\-g if (&is_windows); 
+my $workdir = $thisdir ;
+my $rominclude = $epocroot."epoc32\/rom\/include\/";
+$rominclude = &get_epocdrive().$rominclude unless $rominclude =~ /^.:/;
+$rominclude =~s-\\-\/-g;
+
+my @xmlDBFile = ();
+my $noiby = 0;
+my @obydata;
+
+my @featurefilearray; #2d array storing names and locations of feature files in each rom image
+my @featureslist; #array of hashes, stores all the features which are to go into the feature files
+my $featurefilecount=0; #counts number of feature files in each rom image
+my $featurescount=0; #counts number of features
+my $dir; # Stores the ROM image location of features.dat/featreg.cfg files
+my $featurefilename; # Stores the name of feature file to be generated(i.e. "features.dat" or "featreg.cfg")
+
+my $featuremanager = 0; #Flag to enable support for feature manager database XML file and to generate  
+			# features data file.
+my $noFeatureManager = 0; # Flag to stop the generation of features.dat file and use pre-built features.dat if provided.
+my $preBuiltFeaturesDataFile  = ''; # To store the name of pre-built features.dat file provided with "-nofm" option.
+
+#Image Content XML file that supports specific feature to be added
+my $image_content = undef;
+#Feature list XML file that acts as database containing all features details
+my $featureXml = undef; 
+my $customizedPlat = undef; 
+
+#Summary of files(both executables and data files) currently includes 
+#	host and ROM file names, 
+#	size of the file in ROM
+#	whether the file is hidden
+# This option is added so that the above additional information is emitted by rombuild/rofsbuild tools
+# only when supplied with this option so that the existing tools don't get affected.
+my $logLevel="";
+ 
+
+# Feature Variation modules and data
+my %featureVariant;
+
+
+my $opt_workdir = 0; 
+my $stdcpp = 0;
+my $obycharset;
+my $cppoption = 0;
+my $preprocessor = "cpp"; 
+
+sub is_fullpath {
+
+my $path = shift ;
+	if (&is_windows) {
+		if( $path =~ /^[a-z]:/i) {
+			return 1 ;
+		}
+		elsif($path =~ /^\\/) {
+			return 1 ;
+		}
+		else {
+			return 0 ;
+		}			
+	}
+	else {
+		return 1 if($path =~ /^\//) ;
+		return 0;
+	}
+
+}
+
+sub match_obyfile
+{
+	my ($obyfile) = @_;
+	if (-f $obyfile)
+	{
+		push @obyfiles, $obyfile;
+		return 1;
+	}
+
+	# search for the oby file in the list of include directories
+	my @otherDirs = ($rominclude);
+
+	if ($featureVariant{'VALID'})
+	{
+		my $dirRef = $featureVariant{'ROM_INCLUDES'};
+
+		@otherDirs = @$dirRef if ($dirRef);
+	}
+	foreach my $dir (@otherDirs)
+	{
+		print "$dir/$obyfile\n" if ($opt_v);
+		if (-f "$dir/$obyfile")
+		{
+		    push @obyfiles, "$dir/$obyfile";
+		    return 1;
+		}
+	}
+	return 0;
+}
+ 
+# Subroutine to process parameter-file
+sub parameterFileProcessor
+{
+	my $paramFile = shift(@_);	
+	my @paramFileParamaters = ();	
+
+	my $fileOpenFlag = 1;
+	open FILE,"<", $paramFile or $fileOpenFlag = 0;
+	
+	if(!$fileOpenFlag)
+	{
+		print "Error: Could not open parameter-file \"$paramFile\" for reading.\n";
+		return;
+	}
+	
+	# Parse parameter-file and collect all the parameters in an array
+	while(my $line = <FILE>)
+	{
+		# Read the line till character ';'(used for providing comments in the file) or EOL
+		$line = $1 if ($line =~ /(.*);/); 
+		
+		# Split the parameters specified in a line based on white-spaces		
+		my @paramaters = split(/(\s)/,$line);	
+		
+		my $flag = 0;
+		my $argWithQuotes='';
+
+		foreach my $value (@paramaters) 
+		{	
+			# If the parameter doesn't conatian double quotes then push it 
+			# to the list of parameters.
+			if(($value !~ /\"/) && (!$argWithQuotes)) 
+			{
+				if ($value !~ /^\s*$/) 
+				{
+					push @paramFileParamaters,$value;
+				}		
+			}
+			# If the parameter is in the form  -fm="faturedb.xml" then remove
+			# double quotes and push it to the list of parameters.
+			elsif(($value =~ /\".*\"/))
+			{
+				$value =~ s/\"//g;
+				push @paramFileParamaters,$value;
+			}
+			# If the parameter is in the form  -fm="fature  db.xml" then read
+			# the parameter starting from opening quote till the closing quote.
+			elsif( ($value =~ /\"/) && $argWithQuotes) 
+			{
+				$argWithQuotes .= $value;
+				$argWithQuotes =~ s/\"//g;
+				push @paramFileParamaters,$argWithQuotes;
+				$argWithQuotes='';		
+			}
+			else
+			{
+				$argWithQuotes .= $value;
+			}
+		}		
+	}
+
+	close FILE;	
+	if (!@paramFileParamaters)
+	{
+		print "Warning: No parameters specified in paramer-file \"$paramFile\".\n";		
+		return;
+	}
+	
+	my $paramFileFlag = 1;
+
+	# Invoke subroutine "process_cmdline_arguments" to process the parameters read from
+	# the parameter file.
+	&process_cmdline_arguments($paramFileFlag, @paramFileParamaters);
+
+}
+
+# Processes the command line arguments passed to buildrom tool
+
+sub process_cmdline_arguments
+{
+ 
+	my ($paramFileFlag, @argList); 
+
+	if (defined @_) {
+		($paramFileFlag, @argList) = @_;
+	}
+	else {
+		if(scalar(@ARGV) == 0){
+			my @hrhMacros = &get_variantmacrolist;	
+			$enforceFeatureManager = 1 if (grep /^SYMBIAN_FEATURE_MANAGER\s*$/, @hrhMacros);
+			print_usage();
+			exit 1;				
+		}
+		
+		@argList = @ARGV;
+	}
+
+	if (!defined $paramFileFlag)  {
+	
+		# Enforce Feature Manager if macro SYMBIAN_FEATURE_MANAGER is defined in the HRH file.
+		my @hrhMacros = &get_variantmacrolist;	
+		$enforceFeatureManager = 1 if (grep /^SYMBIAN_FEATURE_MANAGER\s*$/, @hrhMacros);
+		# Process the parameters of parameter-file if passed.
+		foreach my $arg (@argList) {
+			if ($arg =~ /^-h/i) {
+				print_usage();
+				exit 1;				
+			}
+		}
+		# Process the parameters of parameter-file if passed.
+		foreach my $arg (@argList) {
+			&parameterFileProcessor($1) if ($arg =~ /^-argfile=(.*)/) ;
+		}
+	}
+	# first searching argList for keepgoing option
+	my @newArgList = () ;
+	foreach my $arg (@argList) {
+		if ( $arg =~ /^-k$/i || $arg =~ /^-keepgoing$/i ) {
+			$opt_k = 1;	 
+		}
+		elsif ($arg =~ /^-s$/) {
+			$strict = 1; 
+	    }
+		elsif ($arg =~ /^-v$/) {
+			$opt_v =1; 
+	    }
+		elsif( $arg =~ /^-w$/) {
+			$opt_w = 1 ;
+		}
+		elsif ($arg =~ /^-workdir=(.*)/) {			
+			$workdir = $1;
+			$workdir = $thisdir.$workdir unless(&is_fullpath($workdir)) ;
+			$workdir.= "\/" unless $workdir =~ /\/$/;
+			mkdir($workdir) unless (-d $workdir); 
+		}else {
+			push @newArgList, $arg ;
+		}
+	}
+	foreach my $arg (@newArgList)
+	{
+	    if ($arg =~ /^-argfile=(.*)/)  {
+			&parameterFileProcessor($1) if (defined $paramFileFlag); 
+		}
+		elsif ($arg =~ /^-DFEATUREVARIANT=(.*)/) {
+			my $varname = $1;			
+			if ($varname =~ /^\.(.*)$/) {
+				# for testing, locate the VAR file in the current directory
+				%featureVariant = get_variant($1, ".");
+			}
+			else {
+				%featureVariant = get_variant($varname);
+			}
+			if (!$featureVariant{'VALID'}) {
+			    print "FEATUREVARIANT $varname is not VALID\n";
+				$errors++;
+			}
+			if ($featureVariant{'VIRTUAL'}) {
+			    print "FEATUREVARIANT $varname is VIRTUAL\n";
+				$errors++;
+			}
+			addDrivesToFeatureVariantPaths(); 
+		}
+		elsif ($arg =~ /^-[DI]/) {
+			$cppargs .= " $arg";  
+	    } 
+	    elsif ($arg =~/^-oby-charset=(.*)$/i) {
+		$obycharset = $1; 
+	    }
+		elsif($arg =~ /^-o(.*)/i)   {
+			$outputoby = $1;  
+		} 
+		elsif ($arg =~ /^-noiby(=(\d))$/i ) {
+			if(!$1) {
+				$noiby = 1;
+			}
+			else {
+				if(!$2) {
+					print "Warning: No value for \"-noiby=\" option, use default.\n";
+				}
+				else {
+					$noiby = $2 ;
+				}
+			}
+		}
+		#Process feature manager database xml file 
+	    elsif($arg =~ /^-fm=(.*)/) {
+			if (!$enforceFeatureManager) {
+				print "Unknown arg: $arg\n";
+				$errors++;
+				next;
+			}
+			$featureXml = $1;			
+			$xmlrequired = 1;
+			$featuremanager = 1;
+			if ($featureXml =~ /^$/)  {
+				print "Error: No filename specified with \"-fm=\" option.\n";
+			} 
+			else {			
+				@xmlDBFile = split /,/,$featureXml if($noiby == 0);
+			} 
+	    }
+		elsif ($arg =~ /^-nofm(=(.*))?$/) {
+			if (!$enforceFeatureManager)  {
+				print "Unknown arg: $arg\n";
+				$errors++;
+				next;
+			}
+   			$noFeatureManager = 1; 
+            if(!$2) {
+                print "Warning: No filename specified with \"-nofm=\" option, feature data file might not be included.\n";
+            }
+            else {
+                $preBuiltFeaturesDataFile = $2;						
+            } 	
+		}
+		#Process feature registry database xml file 
+	    elsif($arg =~ /^-fr=(.*)/ || $arg =~ /^-f(.*)/) {
+			if ($enforceFeatureManager)
+			{
+				print "Error: Option \"-f|-fr\" is no longer supported.\n";
+				$errors++;
+				next;
+			}			
+			$featureXml = $1;
+			$xmlrequired = 1;			
+			print "Error: No filename specified with \"-f|-fr\" option.\n" if ($featureXml =~ /^$/) ;
+	    } 
+		elsif ($arg =~ /^-stdcpp$/i) {
+			if (&is_linux) {
+				print "Warning: option -stdcpp only apply for Windows\n"; 
+			}
+			if ($cppoption) {
+				print "Error: -stdcpp option and -cpp=xxx option cannot be used at the same time.\n";
+				exit (1);
+			}
+			$stdcpp = 1; 
+		}
+		elsif ($arg =~ /^-cpp=(.*)/) {
+			if ($stdcpp) {
+				print "Error: -stdcpp option and -cpp=xxx option cannot be used at the same time.\n";
+				exit (1);
+			}
+			print "Warning: -cpp option has been set before. The previous configuration will be overwritten!\n" if ($cppoption);
+			$cppoption = 1;
+			$preprocessor = $1;
+			$preprocessor =~ s-\\-\/-g;
+			$preprocessor =~ s-EPOCROOT##\/?-$epocroot-g;
+			if (-d $preprocessor) {
+				$preprocessor .= "\/" unless $preprocessor =~ /\/$/;
+				$preprocessor .= "cpp";
+			} 
+		} 
+	    elsif ($arg =~ /^-/)  {
+			print "Unknown arg: $arg\n";
+			$errors++;
+			next;
+	    }
+		else {
+			# It's an OBY file
+			next if (match_obyfile($arg));
+			next if (match_obyfile("$arg.oby"));
+			print "Cannot find oby file: $arg\n";
+			$errors++ if(!$opt_k);
+		}	    
+	}
+
+	return if (defined $paramFileFlag) ;
+	if (@obyfiles<1 ) {
+	    print "Missing obyfile argument\n";
+	    $errors++ if(!$opt_k);
+	}
+	if(defined($obycharset)) {
+		print "Warning: Ignoring not supportted charset $obycharset, local charset will be used as default!\n" unless($obycharset =~ /utf-?8/i);
+	}
+
+	if ($errors) {
+	    print_usage();
+	    exit 1;
+	}
+	
+	if ($noFeatureManager && $featuremanager)  {
+		print "Warning: Ignoring \"-nofm\" option, as both \"-nofm\" and \"-fm\" options are provided.\n";			
+		$noFeatureManager = 0;
+	}
+
+	# Adding variant specific macros by including a HRH file
+	# (only required if no Feature Variant is used)
+	if (!$featureVariant{'VALID'}) {
+	    my $variantMacroHRHFile = get_variantmacroHRHfile();
+	    if($variantMacroHRHFile){
+	        my $variantFilePath = split_path('Path',$variantMacroHRHFile);
+	        $cppargs .= " -I " . &append_driveandquote($variantFilePath) . " -include " . &append_driveandquote($variantMacroHRHFile); 
+	        print "in cmd process $cppargs\n" if ($opt_v);
+	    }
+	}
+	# load the required modules if xml is required
+	if ($xmlrequired == 1) {
+	    load_featuresutil() if (defined ($featureXml));	    
+	}
+}
+
+#----------------------------------------------------------------------------------
+# Preprocessing phase	
+#
+# Concatentate the specified .oby files and pass them through cpp
+# to get the raw ROM specification in tmp1.oby
+
+sub preprocessing_phase
+{
+	 
+	
+	my $temp1OBYFile = $workdir."tmp1.oby";
+	unlink "$temp1OBYFile";
+
+#	Macro "ROM_FEATURE_MANAGEMENT" is defined when "-f|fr" or "-fm" is used
+	$cppargs .= " -w" if($opt_w) ;
+	$cppargs .= " -DROM_FEATURE_MANAGEMENT " if (defined ($featureXml));
+
+	# add pre-include file and include directories for feature variants
+	if ($featureVariant{'VALID'})
+	{
+		$cppargs .= " -I.";
+		my $incRef = $featureVariant{'ROM_INCLUDES'};
+		if ($incRef) {
+			foreach (@$incRef) {
+				$cppargs .= " -I \"$_\"";
+			}
+		}
+		my $HRH = $featureVariant{'VARIANT_HRH'};
+		$cppargs .= " -include \"$HRH\"" if ($HRH);
+	}
+	else {
+		# no feature variant so use the standard includes
+		$cppargs .= " -I. -I \"$rominclude\"";
+	}
+
+	$preprocessor = find_stdcpp() if ($stdcpp);
+	print "* $preprocessor -Wno-endif-labels -o $temp1OBYFile $cppargs\n" if ($opt_v);
+	
+	is_existinpath("$preprocessor", romutl::DIE_NOT_FOUND);
+	$errors = 0; 
+	open CPP, "| $preprocessor -Wno-endif-labels -o $temp1OBYFile $cppargs" or die "* Can't execute cpp";
+	foreach my $arg (@obyfiles) {
+		print CPP "\n#line 1 \"$arg\"\n";
+	
+		if(open(OBY, $arg)) {
+			print "* reading $arg\n" if ($opt_v);
+			while ($line=<OBY>) {
+				print CPP $line;
+			}
+			close OBY;
+		}
+		else {
+			print STDERR "* Can't open $arg\n";
+			if(!$opt_k){			
+				close CPP;
+				exit(1);
+			}
+		}
+	}
+	close CPP;
+	my $cpp_status = $?;
+	die "* cpp failed\n" if ($cpp_status != 0 || !-f "$temp1OBYFile");
+	
+
+	if( defined ($image_content)) {
+		#Read the OBY file that was generated by the pre-processor
+		&ReadPreprocessedFile($temp1OBYFile);
+
+#		Check if the static dependencies of the OBY binaries are resolved.
+		&ImageContentHandler::UpdateObyBinaryStaticDep();
+		
+		#Now append the files collected from cdfs.
+		&ImageContentHandler::GenObyFile($temp1OBYFile);
+	}
+
+ 
+	if($obycharset =~ /utf-?8/i) {
+		my $utf8file = $workdir."tmp1utf8.oby";
+		open INFILE, "<$temp1OBYFile" or die "* Can't open file $temp1OBYFile";
+		open CHARSETTRAN, "| charsettran -to=hostcharset > $utf8file" or die "* Can't execute charsetran";
+		while(<INFILE>) {
+			print CHARSETTRAN $_;
+		}
+		close CHARSETTRAN;
+		close INFILE;	
+		unlink $temp1OBYFile  or die "* Can't remove file $temp1OBYFile";
+		rename 	$utf8file, $temp1OBYFile or die "* Can't rename file $utf8file to file $temp1OBYFile";
+	}
+	
+	open TMPOBY, "<$temp1OBYFile" or die "*cpp output can not be read.\n"; 
+	@obydata = <TMPOBY> ;
+	close TMPOBY;
+ 
+
+	
+}
+ 
+sub load_featuresutil
+{
+	&FlexLoad_ModuleL("featuresutil");
+			
+	# Parse the feature database XML file
+	if(!&featuresutil::parseXMLDatabase($featureXml, $featuremanager, $strict))
+	{
+		$featureXml = undef;
+		exit(1) if($strict);
+	}
+}
+
+#----------------------------------------------------------------------------------
+# Feature registry configuration file/Features data file generation phase
+#
+# If feature registry configuration files/features data files are required then creates these files for
+# each ROM/ROFS image
+#
+sub featurefile_creation_phase
+{
+		# Set the name and Rom Image location of feature file.
+	if ($enforceFeatureManager)  {
+		# features data file location
+		$dir = "private\/10205054\/";
+		$featurefilename = "features.dat";
+	}
+	else {
+		# feature registry configuration file location
+		$dir = "private\/102744CA\/"; 
+		$featurefilename = "featreg.cfg";
+	}
+	my $onlysmrimage  = 1 ;
+	
+	foreach $line(@obydata) {		
+		if(($line =~ /^\s*romsize\s*=/i) || ( $line=~ /^\s*rom_image/i) || ($line =~ /^\s*data_image/i)) {
+			$onlysmrimage = 0;
+			last;
+		}
+	}	
+	if ($enforceFeatureManager && (!$featuremanager) && (!$noFeatureManager) ) {
+		my $defaultFeatureDbFlag = 0;
+		foreach $line(@obydata) { 
+			if ($line=~/^\s*defaultfeaturedb\s*=?\s*(\S+)/i) {	
+				# Get the default value for featuredatabasefile
+				
+				$featureXml = "$epocroot$1";
+				$featureXml =~ s-\\-\/-g;
+				$featuremanager = 1;				
+				$defaultFeatureDbFlag = 1;
+				load_featuresutil();				
+				last;
+			}
+		}
+		if(!$defaultFeatureDbFlag && !$onlysmrimage)
+		{
+			print "Error: Neither option \"-fm|-nofm\" nor default value for featuredatabase file is provided.\n";
+			exit(1);			
+		}
+	}
+	my @newobydata = ();
+	if (defined ($featureXml))  {
+		my $featurefilecount=0;
+		my $romimage=0;
+
+		foreach $line (@obydata) {
+			# specify which romimage following lines are part of
+			if ($line=~/^\s*ROM_IMAGE\[(\d)\]/) {
+				$romimage=$1;
+				$featurefilecount=0;
+			}
+			elsif ($line =~ /^\s*REM/i || $line =~ /^\s*\r?\n$/ ){
+				next ;
+				# ignore empty
+			}
+			elsif($line =~ /^\s*(FEATURE)\s*(\S*)\s*(.*)/i || $line =~ /^\s*(EXCLUDE_FEATURE)\s*(\S*)\s*(.*)/i) {
+				
+				# FEATURE  <feature_name>  [ SF  <status falgs> ] [ UD  <user data> ]
+				my $feature = $1;
+				my $featurevalue = $2;
+				my $featureargs = $3;
+				my $reservedbit = 0;
+				my %featureflags=();			 
+				# Options 'SF' and 'UD' will be supported only for "-fm" option
+				if ($featuremanager)  {
+					# [ SF  <status falgs> ] [ UD  <user data> ]
+					$featureargs =~	/(\S*)\s*(\S*)\s*(\S*)\s*(\S*)\s*/ ;
+
+					# Store the values of 'SF' and 'UD', or any invalid option, if provided					
+					$featureflags{uc($1)} = $2 if ($1);  
+					$featureflags{uc($3)} = $4 if ($3); 
+
+					# Generate a warning if the option provided with Feature/Exclude_Feature keyword is  
+					# not 'SF' or 'UD'.
+					foreach my $Key (keys %featureflags) {						
+						if ($Key !~ /^(SF|UD)$/) {
+							print "Warning: Invalid argument \"$Key\" specified for feature $featurevalue\n";
+							delete $featureflags{$Key};
+							next;
+						}						
+					}							
+				}				
+				# In verbose mode, generate warning if "SF|UD" arguments or invalid arguments are specified
+				# for "-f|fr" option.
+				elsif ($featureargs && $opt_v) {
+					print "Invalid argument(s) \"$featureargs\" provided for feature \"$featurevalue\"\n";
+					foreach my $Key (keys %featureflags) {
+						delete $featureflags{$Key};
+					}
+				}				
+				
+				# The feature file name is of the format featreg.cfg[x-y] or features.dat[x-y] 
+				# where x is the romimage id, y is always 0, reserved for future use.
+				my $targetfeaturefile;
+				if (($romimage == 0) && ($reservedbit == 0)) {
+
+					# Core image will not have the mangled name
+				 	$targetfeaturefile = $featurefilename;
+				}
+				else {
+				 	$targetfeaturefile = $featurefilename . "\[". $romimage . "\-$reservedbit\]";
+				}
+				my $flag=1;
+				my $featureflag;
+				if ($feature =~ /^FEATURE$/i) {
+					$featureflag = 1;
+				}
+				else {
+					$featureflag = 0;
+				}
+
+				my $i;
+ 				# loop to see if name of feature file already added to this romimage in array
+				for($i=0;$i<$featurefilecount && $flag;$i++) {
+					$flag=0 if($featurefilearray[$romimage][$i]{cfgfile} eq $targetfeaturefile);
+				}
+			
+				if($flag) { # adds feature file if not yet listed for this romimage in array
+					$featurefilearray[$romimage][$featurefilecount++]={cfgfile=>$targetfeaturefile, cfgdir=>$dir};
+					$i=$featurefilecount;
+				}
+
+				$featureslist[$featurescount]= {feature=>$featurevalue, include=>$featureflag, rom=>$romimage, cfgfile=>$i-1};
+				
+				# Store the value of 'SF' in 'featureslist' array
+				$featureslist[$featurescount]->{SF} = $featureflags{SF} if (defined $featureflags{SF}) ;
+				# Store the value of 'UD' in 'featureslist' array
+				$featureslist[$featurescount]->{UD} = $featureflags{UD} if (defined $featureflags{UD}) ;
+				$featurescount++;
+			}
+		}
+
+		# Create Feature File
+		for(my $i=0;$i<scalar @featurefilearray;$i++) {
+			my $j=0;
+			while(defined $featurefilearray[$i][$j])
+			{
+				my $targetfeaturefile = $workdir.$featurefilearray[$i][$j]{cfgfile}; 
+				if (!(&featuresutil::createFeatureFile($i,$j,$targetfeaturefile,\@featureslist,$featuremanager)))  {
+					$featurefilearray[$i][$j]{cfgfile}= undef;
+					exit(1) if($strict);					
+				}
+				$j++;
+			}
+		} 
+		my $flag=1;
+        	my $imageIdx=0;
+
+		# Add feature files to ROM image, adds lines to obey file to specify existing locations
+		# of feature files and target locations. 
+		
+		# features.dat will be written to the end of rom/rofs
+		my @lastFLs = ();
+		my $lastRomIndex = 0 ;
+		
+		foreach $line (@obydata) {
+			if($line =~/^\s*ROM_IMAGE\[(\d)\]/i) {
+				my $index=$1;
+						
+				if($lastRomIndex != $index) {
+					foreach my $fl(@lastFLs) {
+						push @newobydata,$fl ;
+					}
+					@lastFLs = ();
+					$lastRomIndex = $index ;
+				}
+				push @newobydata, "\n" . $line . "\n";	
+				my $j=0;
+				while(defined $featurefilearray[$index][$j]) {
+					$flag = 0 if($index == 0);
+					# Put in feature files for current ROM_IMAGE
+					my $targetfeaturefile = $featurefilearray[$index][$j]{cfgfile};
+					# Rom images will not have mangled name for feature files
+				 					
+					# Rofsbuild will set attribute 'exattrib=U' in the entry record when this field is used.
+					# File Server when asked for a directory listing would notice the attribute and will return the 
+					# list with mangled names. Hence, mangled name for feature files should not be put in ROM_IMAGE.
+					my $exattribute = "" ;					
+					if (defined $targetfeaturefile ) {
+						$exattribute = "exattrib=U" if($index > 0);
+						push @lastFLs, "ROM_IMAGE[$index] data=" . $workdir . $targetfeaturefile . " \"". $featurefilearray[$index][$j]{cfgdir} .$featurefilename .  "\"\t\t" . $exattribute . "\n";
+						$featurefilearray[$index][$j]{cfgfile} = undef ;
+					}
+					$j++;
+				}
+			}
+			elsif($line !~ /^\s*(FEATURE)\s*/i && $line !~ /^\s*(EXCLUDE_FEATURE)\s*/i && $line !~/^\s*defaultfeaturedb\s*=?\s*(\S+)/i) {
+				# Put in all other lines except the FEATURE and EXCLUDE_FEATURE keywords
+				push @newobydata, $line;
+			}
+			else {
+				push @newobydata, " "; 
+			}
+			 
+		}
+		foreach my $fl(@lastFLs) {
+			push @newobydata,$fl ;
+		}
+		if($flag) { 
+			# Put in feature files for ROM_IMAGE[0] if it is the only ROM_IMAGE
+			my $k=0;
+			while(defined $featurefilearray[0][$k])
+			{ 
+				my $targetfeaturefile = $featurefilearray[0][$k]{cfgfile};
+				if (defined $targetfeaturefile)
+				{
+					push @newobydata, "data=" . $workdir . $targetfeaturefile . " \"" . $featurefilearray[0][$k]{cfgdir} . $targetfeaturefile . "\"\n";
+					$featurefilearray[0][$k]{cfgfile} = undef ;
+				}
+				$k++;
+			}
+		}
+	}
+	elsif ($enforceFeatureManager && $noFeatureManager && $preBuiltFeaturesDataFile) {
+        print "Valid: $preBuiltFeaturesDataFile\n";
+		if (-e $preBuiltFeaturesDataFile)  { 
+			my $flag = 1;
+			foreach my $line (@obydata)
+			{
+				# Put in the pre-built features data file in ROM_IMAGE[0] 
+				if($line =~/^\s*ROM_IMAGE\[1\]/i)
+				{
+					push @newobydata, "data=$preBuiltFeaturesDataFile" . " \"" . $dir . $featurefilename . "\"\n";
+					$flag =0;
+				}
+				push @newobydata, $line;
+			}
+			if($flag)
+			{ 
+				# Put in the pre-built features data file in ROM_IMAGE[0] if it is the only ROM_IMAGE
+				push @newobydata, "data=$preBuiltFeaturesDataFile" . " \"" . $dir . $featurefilename . "\"\n";
+			}
+		}
+		else
+		{
+			print "Error: File \"$preBuiltFeaturesDataFile\" doesn't exist.\n";
+			exit(1);
+		}
+	}
+	elsif ($enforceFeatureManager) {
+	    print "Error: no feature data file or pre-built feature data file is provided!";
+	    exit(1);
+	}
+	
+		my $output ;
+	if(&is_windows) {
+		if($outputoby =~ /^[\\\/]/ || $outputoby =~ /^[a-zA-Z]:/)  {
+			$output = $outputoby ;
+		}
+		else {
+			$output = $workdir.$outputoby;
+		}
+	}
+	else {
+		if($outputoby =~ /^[\/]/ )  {
+			$output = $outputoby ;
+		}
+		else {
+			$output = $workdir.$outputoby;
+		}
+	} 
+	unlink $output if(-e $output);
+	print "* Writing $output...\n" if($opt_v);
+	unless(open FOUT, ">$output"){
+		print "Error: Can not write to $output.\n";
+		exit(1);
+	}
+	foreach(@newobydata){
+		chomp ;
+		print FOUT "$_\n";
+	} 
+	close FOUT ; 
+	print "* Done.\n" if($opt_v);
+}
+
+# make sure that all the absolute feature variant paths include a
+# drive letter. This is required because cpp will not work with
+# absolute paths starting with slashes.
+sub addDrivesToFeatureVariantPaths
+{
+	return unless $featureVariant{'VALID'};
+
+	my $current = &get_epocdrive;
+	my $drive = $1 if ($current =~ /^(.:)/);
+
+	# pre-include file
+	my $HRH = $featureVariant{'VARIANT_HRH'};
+	$featureVariant{'VARIANT_HRH'} = $drive . $HRH if ($HRH =~ /^[\\\/]/);
+
+	# ROM include path
+	my $dirRef = $featureVariant{'ROM_INCLUDES'};
+	return unless $dirRef;
+	my $i = 0;
+
+	foreach my $dir (@$dirRef)
+	{
+		$$dirRef[$i] = $drive . $dir if ($dir =~ /^[\\\/]/);
+		$i++;
+	}
+}
+#
+# Process the given absolute path
+# Add backslash at the end if required
+# @param - path to be processed
+#
+sub processPath
+{
+	my ($path) = shift;
+	
+	return if( $$path =~ /(\\$)/ );
+	return if( $$path =~ /(\/$)/ );
+	$$path .= "/";
+}
+
+# Main block for buildrom module invocation
+
+
+# Processes the buildrom command line parameters.
+&process_cmdline_arguments; 
+if(scalar(@xmlDBFile) > 0) { 
+	&processPath(\$epocroot);
+	&processPath(\$thisdir);
+	&features::set_DefaultPath($epocroot, \$thisdir, \$thisdir, \$thisdir, \$thisdir);
+	if(&features::open_Database(@xmlDBFile)) {  
+		&features::generate_Obeyfile($workdir);	 
+	}
+}
+#Preprocessing phase
+&preprocessing_phase; 
+# Creates feature registry configuration file/features data file.
+&featurefile_creation_phase;
+
+
+1;