if($type eq 'LOCAL')
	{
	CURRENT
	PARENT
	COMMAND_LINE
	
	if
	   exists $config_to_merge_to->{PARENT}
	&& exists $config_to_merge_to->{PARENT}{__PBS}{$key} 
	#~ && $value ne $config_to_merge_to->{PARENT}{__PBS}{$key}{VALUE}
	&& ! Compare($value, $config_to_merge_to->{PARENT}{__PBS}{$key}{VALUE})
	)
		{
		PrintWarning2
			(
			DumpTree
				(
				  {
				    'Parent\'s value' => $config_to_merge_to->{'PARENT'}{__PBS}{$key}{VALUE}
				  , 'Current value' => $value
				  }
				, "Ignoring '$key' defined at '$origin': Already defined in the subpbs'parent:"
				)
			) ;
		}
	}

NAME

PBS::Config -

SYNOPSIS

use PBS::Config;
AddConfig( CC => 'gcc', PROJECT => 'NAILARA') ;

if(GetConfig('DEBUG_FLAGS'))
	{
	....

DESCRIPTION

PBS::Config exports functions that let the user add configuration variable. The configuration are kept sorted on 5 different hierarchical levels.

1 Package name
2 Class ('CURRENT', 'PARENT', 'LOCAL', 'COMMAND_LINE', 'PBS_FORCED')
3 User defined namespaces

The package name is automatically set by PBS and is used to keep all the subpbs configuration separate. The classes are also set by PBS. They are used to define a precedence hierachy. The precedence order is CURRENT < PARENT < LOCAL < COMMAND_LINE < PBS_FORCED.

AddConfig uses the 'CURRENT' class, namespace 'User' by default. It's behaviour can be changed with argument attributes (see bellow). If a variable exists in multiple classes, the one defined in the higher order class will be returned by GetConfig.

Argument attributes

The variables passed to AddConfig can have attributes that modify the lock attribute of the variable or it's class. The attributes can be any of the following.

LOCKED
UNLOCKED
FORCE
OVERRIDE_PARENT
LOCAL

An attribute is passed by appending a ':' and the attribute to the variable name.

LOCKED and UNLOCKED

Within the class where the variable will be stored, the variable will be locked or not. When run with the following example:

AddConfig 'a' => 1 ;
AddConfig 'a' => 2 ;

AddConfig 'b:locked' => 1 ;
AddConfig 'b' => 2 ;

Pbs generates a warning message for the first ovverride and an error message for the attempt to override a locked variable:

Overriding config 'PBS::Runs::PBS_1::CURRENT::User::a' it is now:
+- ORIGIN [A1]
¦  +- 0 = PBS::Runs::PBS_1:'Pbsfiles/config/lock.pl':14 => 1
¦  +- 1 = PBS::Runs::PBS_1:'Pbsfiles/config/lock.pl':15 => 2
+- VALUE = 2

Configuration variable 'b' defined at PBS::Runs::PBS_1:'Pbsfiles/config/lock.pl':18,
wants to override locked variable:PBS::Runs::PBS_1::CURRENT::User::b:
+- LOCKED = 1
+- ORIGIN [A1]FORCE
¦  +- 0 = PBS::Runs::PBS_1:'Pbsfiles/config/lock.pl':17 => 1
+- VALUE = 1

FORCE

Within the same class, a configuration can override a locked variable. AddConfig 'b:locked' => 1 ; AddConfig 'b:force' => 2 ;

Overriding config 'PBS::Runs::PBS_1::CURRENT::User::b' it is now:
+- LOCKED = 1
+- ORIGIN [A1]
¦  +- 0 = PBS::Runs::PBS_1:'Pbsfiles/config/force.pl':14 => 1
¦  +- 1 = PBS::Runs::PBS_1:'Pbsfiles/config/force.pl':15 => 2
+- VALUE = 2

OVERRIDE_PARENT

Pbsfile should always be written without knowledge of being a subbs or not. In some exceptional circumstenses, you can override a parent variable with the 'OVERRIDE_PARENT' attribute. The configuration variable is changed in the 'PARENT' class directly.

AddConfig 'b:OVERRIDE_PARENT' => 42 ;

LOCAL

Configuration variable inheritence is present in PBS to insure that the top level Pbsfile can force it's configuration over sub Pbsfiles. This is normaly what you want to do. Top level Pbsfile should know how child Pbsfiles work and what variables it utilizes. In normal cicumstences, the top Pbsfile sets configuration variables for the whole build (debug vs dev vs release for example). Child Pbsfiles sometimes know better than their parents what configuration is best.

Let's take an example whith 3 Pbsfile: parent.pl uses child.pl which in turn uses grand_child.pl. Parent.pl sets the optimization flags with the following AddConfig call:

AddConfig OPTIMIZE_FLAG => '04' ;

The configuration variable 'OPTIMIZE_FLAG' is passed to parent.pl children. This is what we normaly want but we might know that the code build by child.pl can not be optimized with something other than 'O2' because of a compiler bug. We could use the OVVERIDE_PARENT attribute within child.pl:

AddConfig 'OPTIMIZE_FLAG:OVERRIDE_PARENT' => 'O2' ;

This would generate the right code but grand_child.pl would receive the value 'O2' within the OPTIMIZE_FLAG variable. It is possible to define local variable that override parent variable but let children get their grand parent configuration.

AddConfig 'OPTIMIZE_FLAG:LOCAL' => 'O2' ;

Here is the output from the config example found in the distribution:

[nadim@khemir PBS]$ pbs -p Pbsfiles/config/parent.pl -dc -nh -tta -nsi parent
No source directory! Using '/home/nadim/Dev/PerlModules/PerlBuildSystem-0.24'.
No Build directory! Using '/home/nadim/Dev/PerlModules/PerlBuildSystem-0.24'.
Config for 'PBS':
|- OPTIMIZE_FLAG_1 = O3
|- OPTIMIZE_FLAG_2 = O3
`- TARGET_PATH =
Overriding config 'PBS::Runs::child_1::PARENT::__PBS::OPTIMIZE_FLAG_1' it is now:
|- ORIGIN [A1]
|  |- 0 = parent: 'PBS' [./child] => O3
|  `- 1 = PBS::Runs::child_1:'./Pbsfiles/config/child.pl':1 => O2
`- VALUE = O2
Config for 'child':
|- OPTIMIZE_FLAG_1 = O2
|- OPTIMIZE_FLAG_2 = O2
`- TARGET_PATH =
Config for 'grand_child':
|- OPTIMIZE_FLAG_1 = O2
|- OPTIMIZE_FLAG_2 = O3
`- TARGET_PATH =
...

EXPORT

AddConfig AddConfigTo
GetConfig GetConfigFrom
GetConfigAsList GetConfigFromAsList

AUTHOR

Khemir Nadim ibn Hamouda. nadim@khemir.net

SEE ALSO

--no_silent_override

2 POD Errors

The following errors were encountered while parsing the POD:

Around line 659:

Unknown directive: =comment

Around line 927:

Non-ASCII character seen before =encoding in '¦'. Assuming CP1252