4.2 Writing A Simple Buildfile

The Foobar project installs some PHP files from a source location to a target location, creates an archive of this files and provides an optional clean-up of the build tree:

<?xml version="1.0" encoding="UTF-8"?>

<project name="FooBar" default="dist">

    <!-- ============================================  -->
    <!-- Target: prepare                               -->
    <!-- ============================================  -->
    <target name="prepare">
        <echo msg="Making directory ./build" />
        <mkdir dir="./build" />
    </target>

    <!-- ============================================  -->
    <!-- Target: build                                 -->
    <!-- ============================================  -->
    <target name="build" depends="prepare">
        <echo msg="Copying files to build directory..." />

        <echo msg="Copying ./about.php to ./build directory..." />
        <copy file="./about.php" tofile="./build/about.php" />

        <echo msg="Copying ./browsers.php to ./build directory..." />
        <copy file="./browsers.php" tofile="./build/browsers.php" />

        <echo msg="Copying ./contact.php to ./build directory..." />
        <copy file="./contact.php" tofile="./build/contact.php" />
    </target>

    <!-- ============================================  -->
    <!-- (DEFAULT)  Target: dist                       -->
    <!-- ============================================  -->
    <target name="dist" depends="build">
        <echo msg="Creating archive..." />

        <tar destfile="./build/build.tar.gz" compression="gzip">
            <fileset dir="./build">
                <include name="*" />
            </fileset>
        </tar>

        <echo msg="Files copied and compressed in build directory OK!" />
    </target>
</project>

A phing build file is normally given the name build.xml which is the default file name that the Phing executable will look for if no other file name is specified.

To run the above build file and execute the default target (assuming it is stored in the current directory with the default name) is only a matter of calling: $ phing

This will then execute the dist target. While executing the build file each task performed will print some information on what actions and what files have been affected.

To run any of the other target is only a matter of providing the name of the target on the command line. So for example to run the build target one would have to execute $ phing build

It is also possible to specify a number of additional command line arguments as described in Appendix A, Fact Sheet

4.2.1 Project Element

The first element after the document prolog is the root element named <project> on line 3. This element is a container for all other elements and can/must have the following attributes:

Table 4.1: <project> Attributes

AttributeDescriptionRequired
nameThe name of the projectNo
basedirThe base directory of the project. This attribute controls the value of the ${project.basedir} property which can be used to reference files with paths relative to the project root folder. Can be a path relative to the position of the buildfile itself. If omitted, "." will be used, which means that the build file should be located in the project's root folder. No
defaultThe default target that is to be executed if no target(s) are specified when calling this build file.Yes
descriptionThe description of the project.No
strictEnables the strict-mode for the project build process.No

See Section H.1, “Phing Projects” for a complete reference.

4.2.2 Target Element

A target can depend on other targets. You might have a target for installing the files in the build tree, for example, and a target for creating a distributable tar.gz archive. You can only build a distributable when you have installed the files first, so the distribute target depends on the install target. Phing resolves these dependencies.

It should be noted, however, that Phing's depends attribute only specifies the order in which targets should be executed - it does not affect whether the target that specifies the dependency(s) gets executed if the dependent target(s) did not (need to) run.

Phing tries to execute the targets in the depends attribute in the order they appear (from left to right). Keep in mind that it is possible that a target can get executed earlier when an earlier target depends on it, in this case the dependent is only executed once:

<target name="A" />
<target name="B" depends="A" />
<target name="C" depends="B" />
<target name="D" depends="C,B,A" />

Suppose we want to execute target D. Looking at its depends attribute, you might think that first target C, then B and then A is executed. Wrong! C depends on B, and B depends on A, so first A is executed, then B, then C, and finally D.

A target gets executed only once, even when more than one target depends on it (see the previous example).

The optional description attribute can be used to provide a one-line description of this target, which is printed by the -projecthelp command-line option.

Target attributes

You can specify one or more of the following attributes within the target element.

Table 4.2: <target> Attributes

AttributeDescriptionRequired
nameThe name of the targetYes
dependsA comma-separated list of targets this target depends on.No
ifThe name of the Property that has to be set in order for this target to be executedNo
unlessThe name of the Property that must not be set in order for this target to be executed. 

See Section H.2, “Targets” for a complete reference.

4.2.3 Task Elements

A task is a piece of PHP code that can be executed. This code implements a particular action to perform (i.e. install a file). Therefore it must be defined in the buildfile so that it is actually invoked by Phing.

These references will be resolved before the task is executed.

Tasks have a common structure:

<name attribute1="value1" attribute2="value2" ... />

where name is the name of the task, attributeN is the attribute name, and valueN is the value for this attribute.

There is a set of core tasks (see Appendix B, Core tasks) along with a number of optional tasks. It is also very easy to write your own tasks (see Chapter 6, Extending Phing).

Tasks can be assigned an id attribute:

<taskname id="taskID" ... />

By doing this you can refer to specific tasks later on in the code of other tasks.

4.2.4 Property Element

Properties are essentially variables that can be used in the buildfile. These might be set in the buildfile by calling the property task, or might be set outside Phing on the command line (properties set on the command line always override the ones in the buildfile). A property has a name and a value only. Properties may be used in the value of task attributes. This is done by placing the property name between " ${ " and " } " in the attribute value. For example, if there is a BC_BUILD_DIR property with the value 'build', then this could be used in an attribute like this: ${BC_BUILD_DIR}/en . This is resolved to build/en.

Built-in Properties

Phing provides access to system properties as if they had been defined using a <property> task. For example, ${os.name} expands to the name of the operating system. See Appendix A, Fact Sheet for a complete list