== Download and installation === Obtaining the Waf file The Waf project is located on https://waf.io[waf.io]. The current Waf version requires an interpreter for the Python programming language such as http://www.python.org[cPython] 2.5 to 3.5, http://pypy.org[Pypy] or http://www.jython.org[Jython] >= 2.5. ==== Downloading and using the Waf binary The Waf binary is a python script which may be executed directly from a writable folder; no installation is required. Just rename it as +waf+ if necessary: [source,shishell] --------------- $ wget https://waf.io/waf-{version} $ mv waf-{version} waf $ python waf --version waf {version} (54dc13ba5f51bfe2ae277451ec5ac1d0a91c7aaf) --------------- The +waf+ file has its own library compressed as a binary stream in the same file. Upon execution, the library is uncompressed in a hidden folder in the directory of the Waf file. The folder will be re-created if removed. This scheme enables different Waf versions to be executed from the same folders: [source,shishell] --------------- $ ls -ld .waf* .waf-{version}-2c924e3f453eb715218b9cc852291170 --------------- NOTE: The binary file requires http://docs.python.org/library/bz2.html[bzip2] compression support, which may be unavailable in some self-compiled cPython installations. ==== Building Waf from source Building Waf requires a Python interpreter having a version number in the range 2.6-3.5. The source code is then processed to support Python 2.5. [source,shishell] --------------- $ wget https://waf.io/waf-{version}.tar.bz2 $ tar xjvf waf-{version}.tar.bz2 $ cd waf-{version} Configuring the project Setting top to : /home/user/waf Setting out to : /home/user/waf/build Checking for program 'python' : /usr/bin/python Waf: Entering directory `/waf-{version}/build' [1/1] Creating waf Waf: Leaving directory `/waf-{version}/build' 'build' finished successfully (0.726s) --------------- For older Python interpreters, the +waf+ file may be created with gzip compression instead of bzip2: [source,shishell] --------------- $ python waf-light --zip-type=gz --------------- Additional extensions can be added to the waf file and redistributed as part of it. For instance, the source distribution contains several extension in testing phase under the folder 'waflib/extras'. Passing a relative path to the __--tools_ switch will include the corresponding file, while passing an absolute path can refer to any file on the filesystem, and non-python files in particular (they will end up in the local the 'waflib/extras/' folder). Here is a short example: [source,shishell] --------------- $ python waf-light --tools=swig,msvs --------------- ==== Custom initializers Extension that provide an initialization may also be used to execute custom functions before the regular execution. Assuming that a file named `aba.py` is present in the current directory: [source,python] --------------- def foo(): from waflib.Context import WAFVERSION print("This is Waf %s" % WAFVERSION) --------------- The following will create a custom waf file that will import and execute the function 'foo' before calling the waf library. [source,shishell] --------------- $ python waf-light --make-waf --tools=msvs,$PWD/aba.py --prelude=$'\tfrom waflib.extras import aba\n\taba.foo()' $ ./waf --help This is Waf {version} [...] --------------- A return statement may also be added, please consult the contents of waf-light to learn more about it. Various from the https://github.com/waf-project/waf/tree/master/build_system_kit/[build system kit] thus illustrate how to create custom build systems derived from Waf. === Using the Waf file ==== Permissions and aliases Since the waf file is a python script, it is usually executed by calling +python+ on it: [source,shishell] --------------- $ python waf --------------- On unix-like systems, it is usually much more convenient to set the executable permissions and avoid calling +python+ each time: [source,shishell] --------------- $ chmod 755 waf $ ./waf --version waf {version} (54dc13ba5f51bfe2ae277451ec5ac1d0a91c7aaf) --------------- If the command-line interpreter supports aliases, it is recommended to set one instead of retyping commands: [source,shishell] --------------- $ alias waf=$PWD/waf $ waf --version waf {version} (54dc13ba5f51bfe2ae277451ec5ac1d0a91c7aaf) --------------- Else, the execution path may be modified to point at the location of the waf binary: [source,shishell] --------------- $ export PATH=$PWD:$PATH $ waf --version waf {version} (54dc13ba5f51bfe2ae277451ec5ac1d0a91c7aaf) --------------- For convenience purposes on Windows systems, a https://github.com/waf-project/waf/tree/master/utils/waf.bat[waf.bat file] is provided to detect the presence of the Python application. It assumes that it is residing in the same folder as the waf file. In the next sections of the book, we assume that either an alias or the execution path have been set in a way that +waf+ may be called directly. ==== Local waflib folders Although the waf library is unpacked automatically from the waf binary file, it is sometimes necessary to keep its files in a visible folder, which may even be kept in a source control tool (subversion, git, etc). For example, the +waf-light+ script does not contain the waf library, yet it is used to create the +waf+ script by using the directory +waflib+. Another alternative for Waf developers is to point the environment variable _WAFDIR_ to the folder containing the directory named `waflib`. The following diagram represents the process used to find the +waflib+ directory: image::waflib{PIC}["Waflib discovery"{backend@docbook:,width=450:},align="center"] ==== Portability concerns By default, the recommended Python interpreter is cPython, for which the supported versions are 2.5 to 3.5. For maximum convenience for end-users, a copy of the http://www.jython.org[Jython] interpreter (version >= 2.5) might even be redistributed along with a copy of the Waf executable. WARNING: Unless a _WAFDIR_ is set, the 'waf' script must reside in a writable folder to unpack its cache files.