The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

pbs user's guide

PBS (Perl Build System) and pbs.pl.

DESCRIPTION

PBS - Set of perl modules to implement build utilities.

pbs - Front end to PBS (an alias to pbs.pl, a perl script).

pbs.pl is a script that handles command line switches and starts PBS. It runs under Linux and in Cygwin.

INTRODUCTION

pbs is a build utility in the same spirit as make. Except for the spirit, pbs and make have nothing in common. PBS is not compatible with 'make' and works completely differently!

pbs was developped to tackle the build of complex systems.

pbs neither tries to make the task easy nor fast but merely possible.

pbs is written in Perl and uses Perl exclusively for defining the system to build.

pbs has a full featured scripting language, Perl.

pbs only introduces a few new functions.

When given a system description, pbs constructs a dependency tree and checks which nodes in the tree need to be rebuild.

pbs and PBS are still under development. No guaranties of any sort follow with this software. Your ideas, remarks and critics are very welcome.

PBS strong points (compared to other build systems) are:

Architecture

  • Pure perl, simple architecture, Humanly sized code.

  • Possibility to integrate PBS into other applications.

  • Makes easy things easy and complicated ones possible.

Build system

  • Hierachical build.

  • Supports 'shadow' build directories.

  • Alternative source directories=head2 PBS strong points (compared to other build systems) are:

Architecture

  • Pure perl, simple architecture, Humanly sized code.

  • Possibility to integrate PBS into other applications.

  • Makes easy things easy and complicated ones possible.

Build system

  • Hierachical build.

  • Supports 'shadow' build directories.

  • Alternative source directories

  • A multum of switches to allow you to easily debug your build system.

  • User options can be passed to the build system, rules, dependers and builders.

  • Dynamic rules and variables.

  • A multum of switches to allow you to easily debug your build system.

  • User options can be passed to the build system, rules, dependers and builders.

  • Dynamic rules and variables.

DO I NEED TO KNOW PERL TO USE pbs?

If you have used make or other build systems before, the examples in this documentation should get you going.

A working knowledge of perl will allow you to use the advanced functionality of PBS. The Reference manual details the innner working of PBS.

SYNOPSIS

pbs all

pbs -o --build_directory /somewhere/out --sd /sd1/ --sd /sd2 --bi -- all

INPUT

pbsl takes switches and targets on the command line.

pbsl has a pletoria of switches; most are for debugging purpose (debugging of the build system).

pbsl -h displays all the accepted switches and a short description of what the switch does. Be ready for a long list.

Pbsfile

To drive PBS you write a Pbsfile (in analogy to a Makefile). Pbsfiles are packageless perl scripts.

Pbsfile can have any name you operating system supports. If no Pbsfile is given on the command line through the --p switch, pbs will load a file called Pbsfile.pl. If no Pbsfile.pl is found, pbs exits with an error message.

A Pbsfile contains configuration and rule definitions. It can also contain perl code, in fact a Pbsfile is a piece of valid perl code when run through pbs.

RULES

NO BUILT-IN RULES!

Unlike other build systems (except xmake), PBS doesn't define any Built-in rule. It is very easy to define and use libraries of rules.

The confusion brought by built-in rules is thereby avoided.

Adding a rule

Rules are the main way to control your build system. You use the function AddRule in your Pbsfile to define the build system.

AddRule takes the following parameters:

0 Rule type (optional)
1 Rule name
2 Depender definition
3 Builder definition (optional)
4 Arguments to builder (optional)
        Ex: AddRule 'exe', [exe => undef] ;

This will add the user rule named 'exe' to your build system.

Rule type (optional)

A rule type can be passed to AddRule.The type can be one of the following: =over 2

  • VIRTUAL, no file with a name matching the node should be found on the disk.

  • FORCED, the node is always build.

  • Other typed are discussed in the reference manual

Rule name

Each rule in the Pbsfile must be given a name. The name is used for debugging purpose.

Depender definition

This section describe the simplest form of a depender definition. Other definition types are described in the reference manual.

        Pbsfile:
        AddRule [VIRTUAL], 'all', ['all' => 'a.out'] ;
        AddRule 'binary', ['a.out' => 'hello.o'] ;

The above Pbsfile defines two rules, 'all' and 'binary'.

Node 'all' is virtual, that is no file on your disk should match the name 'all'. Node 'all' id dependent on node 'a.out'.

Node 'a.out' has no particular type and is expected to match a file on your hard disk. Node 'a.out' is dependent on node 'hello.o'.

Defining the dependencies

        Ex:
        AddRule 'rule_name',
                [
                */*.o => 
                          '*.c'
                        , 'b.c'
                        , '/somewhere/a.c2'
                        , '[path]/subdir/prefix_[basename].c3'
                ] ;

For '/path_to_a/a.o', the above depender definition will generate these dependencies :

        '/path_to_a/a.c' 
        '/path_to_a/b.c' 
        '/somewhere/a.c2'
        '/path_to_a/subdir/prefix_a.c3'

Node without dependencies

if your node has no dependencies use undef as in the example bellow,.

        AddRule [VIRTUAL], 'install',  [install => undef], \&Installer ;

WARNING! All dependers are run!

If multiple rules match a node, the sum of the dependencies returned by matching dependers will become the node dependencies. If the following rules:

        AddRule 'o_c', ['*.o' => '*.c'] ;
        AddRule 'o_s', ['*.o' => '*.s'] ;

are used on file compress.c, the dependers would generate the following dependencies: compress.c and compress.s.

Hello world!

We will now go through examples, starting withh a very simple setup to a complicated one.

A simple example

A simple file named 'hello.c' contains the well known C program. We'll use the following Pbsfile:

        AddRule [VIRTUAL], 'all', ['all' => 'a.out'] ;
        AddRule 'binary', ['a.out' => 'hello.o'] ;

Let's run pbs with the following command line:

        sh-2.05b$ pbs -tt -tno -tta all
        No source directory! Using '/home/nadim/devel/modules/PBS/pbs_users_guide/1'.
        No Build directory! Using '/home/nadim/devel/modules/PBS/pbs_users_guide/1'.
        No user defined [PBS] Build(), using DefaultBuild() with [BuiltIn, User] rules and [BuiltIn, User] configs.
        ** Depending [PBS/0] **
        
        ** Checking **
        Tree for __PBS_root_pbs_._Pbsfile.pl:
        `- ./all [H1]
           `- ./a.out [H2]
              `- ./hello.o [H3]
        
        ** Building **
        Number of nodes in the dependency tree: 3.
        Skipping build.
        Debug flag 'DEBUG_DISPLAY_TREE_NAME_ONLY' is set. Use --fb to force build.

The switches --tt --tno --tta directed pbs to display the dependency tree defined by our Pbsfile and abort. The output tells us we have 3 nodes in the dependency tree and their names. Note that the node 'hello.c' is not included in the dependency tree. pbs doesn't have any built-in rule to infere the dependency of a '.o' file on the matching '.c' file.

Let's add a rule to define that dependency:

        AddRule 'hello.o', ['hello.o' => 'hello.c'] ;

And Run pbs:

        sh-2.05b$ pbs all
        ...
        ** Building **
        Number of nodes in the dependency tree: 4.
        4 [1V] nodes scheduled for build.
        #------------------------------------------------------------------------------
        Node './hello.c' [/home/nadim/devel/modules/PBS/pbs_users_guide/1/hello.c] :
        Building /home/nadim/devel/modules/PBS/pbs_users_guide/1/hello.c : BUILD_FAILED : No Builder.
                __DIGEST_TRIGGERED (Digest file '/home/nadim/devel/modules/PBS/pbs_users_guide/1/hello.c.pbs_md5' not found)
        
        Build Done.

pbs tries to rebuild 'hello.c' because it can't find a digest file. pbs verifies files with the help of MD5 digest (see reference manual a complete discussion). 'hello.c' also includes a header file but pbs seems to ignore them. We need a set of rules to teach pbs how to compile c files. Although pbs does have any built-in rules, it comes with the rules needed to compile c files, those rules are complex and explained in another section.

Using the rules for c files

pbs uses the PbsUse directive to 'include' sets of rules or configuration. Prepending the following line to your Pbsfile includes the set of rules needed to compile c files:

        PbsUse('Rules/C') ;

Let's run pbs with our new Pbsfile:

        sh-2.05b$ pbs all
        ...
        ** Depending [PBS/0] **
        In Pbsfile : ./Pbsfile.pl, while at rule 4:hello.o, node './hello.o'
            ./hello.c already inserted by rule 0:o_cs_meta, Ignoring duplicate dependency.
        Configuration variable 'CC' doesn't exist. Aborting.
        Died at '/home/nadim/devel/modules/PBS/PBSLib/Rules/C_depender.pm' line 353.

pbs first complains about a duplicate dependency. 'hello.c' is defined as a dependency to 'hello.o' by the rule 'hello.o' and the rule 'o_cs_meta'. This is a warning. The set of rule we included automatically generates dependencies from '.o' file to '.c' files. We will eliminate the warning by removing our rule from the Pbsfile.

pbs then complains about the variable 'CC' not being defined. 'CC' is the standard variable used to point to the c compiler. You would declare that variable depending on what system you use. pbs comes with a simple configuration file we can use.

We add the following line in our Pbsfile and remove the 'hello.o' rule:

        PbsUse('Configs/gcc') ;
        

Running pbs gives this output:

AUTHOR

Khemir Nadim ibn Hamouda. <nadim@khemir.net>

COPYRIGHT and LICENSE

3 POD Errors

The following errors were encountered while parsing the POD:

Around line 62:

You forgot a '=back' before '=head4'

Around line 93:

'=item' outside of any '=over'

Around line 174:

'=item' outside of any '=over'