Advanced Scripting in Barabash ============================== Setting environemt variables ---------------------------- It is possible to set build parameters (called also environment variables) in four ways. They are set in following order: * in command line * setting variable globally in script * using :func:`barabash.core.set_env` function * in environment Parameters in command line ^^^^^^^^^^^^^^^^^^^^^^^^^^ Build parameters can be set in command line which executes Barabash script. Example: .. code-block:: bash ./build.py CC=/usr/bin/icc Global variables ^^^^^^^^^^^^^^^^ Build parameters can also be set as globals in Barabash script. Example:: CC = "/usr/bin/icc" objects = MapOp("objects", src, "%.o:%.c", "{CC} -c {in} -o {out}") :func:`barabash.core.set_env` function ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Beside setting build parameters as globals it is also possible to set then in a script using :func:`barabash.core.set_env` function. Example:: set_env("CC", "/usr/bin/icc") objects = MapOp("objects", src, "%.o:%.c", "{CC} -c {in} -o {out}") Parameters from environment ^^^^^^^^^^^^^^^^^^^^^^^^^^^ The last form of setting build parameters is inheriting them from process environment. This way has the lowest precedence. Example: .. code-block:: bash export CC=/usr/bin/icc ./build.py or: .. code-block:: bash CC=/usr/bin/icc ./build.py Variables in Bash actions ------------------------- Bash actions are able to use environment variables. There are two types of environment variables: * predefined variables * user defined variables The can be accessed in Bash action string using curly brackets: .. code-block:: bash "{CC} -c {in} -o {out}" Predefined variables ^^^^^^^^^^^^^^^^^^^^ There are two built-in variables: * in * out `in` and `out` are available in all operations beside :class:`barabash.core.Command`. `in` is an input to operation. In case of :class:`barabash.core.MapOp` operation `in` is a file while in :class:`barabash.core.ReduceOp` operation it is a list of files. `out` is a full path to output file of an operation. User defined variables ^^^^^^^^^^^^^^^^^^^^^^ There can be defined additional variables by user. It can be made in several ways what was already described in previous chapter. Variables' methods ^^^^^^^^^^^^^^^^^^ It is possible to modify a variable's values in Bash action using several methods. The following methods are available: * all from `os.path` module, e.g. dirname which returns the directory component of a pathname * dropext, returns filename without extension (e.g. w/o .jpg) * dropext2, drops file extensions twice (e.g. .aa.bb) These methods can be applied to all variables. In the case when a values of a variable is a list then the method is executed for each element on the list. Example:: ReduceOp("js.tar.gz", src_js, "tar -C {srcdir} -zcvf {out} {in.basename}") Another example:: """ {CC} -shared -Wl,-soname,{out.dropext} -o {out} {in} ln -f -s {out} {out.dropext} ln -f -s {out} {out.dropext2} """ Custom Operations ----------------- Custom behavior of operation can be implement by extending one of basic operation classes: * :class:`barabash.core.Operation`, * :class:`barabash.core.MapOp`, * :class:`barabash.core.ReduceOp` or * :class:`barabash.core.Command`. The following methods of these classes can be overriden to get additional behavior: * `__init__(self, ...)` * `action(self, env)` * `indirect_deps(self, env)` `__init__(self, ...)` ^^^^^^^^^^^^^^^^^^^^^ Example:: class BuildStaticLib(core.ReduceOp): def __init__(self, name, sources): objs = Compile(name + "_compile", sources) super(BuildStaticLib, self).__init__(name, objs, """{AR} cru {out} {in} {RANLIB} {out}""") In `__init__(self, ...)` there can be added some additional instructions. In the example there is injected additional operation (`Compile`) so actually the whole operation :class:`barabash.ops.BuildStaticLib` comprises two operations: compiling and linking static library. In `__init__(self, ...)` the initialzer of super class should be always run. In this case it is an initializer of :class:`barabash.core.ReduceOp` with appropriate arguments. `action(self, env)` ^^^^^^^^^^^^^^^^^^^ Beside declaring action as function or Bash script it is also possible to directly override action in Operation subclass. A helper method :func:`barabash.core.Operation.run_script` is available for executing Bash script provided as string. `indirect_deps(self, env)` ^^^^^^^^^^^^^^^^^^^^^^^^^^ Another method which can be overriden is :func:`barabash.core.Operation.indirect_deps`. It allows providing additional indirect dependencies, e.g. .h header files that are included by .c source files. Modules ------- Barabash support more complex projects by providing modules. This allows defining build sub-script for each nested component in the project. Sample nested project: .. code-block:: bash prog |--- bb-prog.py |--- main.c |--- liba | |--- main.c | |--- bb-liba.py |--- libb |--- bb-libb.py |--- b.c |--- b.h `main.c` is a top level source of a `prog` program and `bb-prog.py` is top level Barabash script. `liba` is a static library which is linked into `prog`. `libb` is a dynamic library that `prog` is linking with. `bb-prog.py`:: from barabash import include, BuildProgram, run liba = include("liba/bb-liba.py") libb = include("libb/bb-libb.py") CFLAGS = "-DAAA=1" BuildProgram("prog", "main.c", static_libs=liba.liba, shared_libs=libb.libb, external_libs=["m"]) run() :func:`barabash.core.include` function is used to include modules. Then, included modules can be referenced in operations as dependencies and inputs. `liba/bb-liba.py`:: from barabash import BuildStaticLib liba = BuildStaticLib("liba.a", "main.c") `libb/bb-libb.py`:: from barabash import BuildSharedLib libb = BuildSharedLib("libb.so.1.0", "b.c") Built-in targets ---------------- There are several built-in targets in Barabash: * `help` * `env` `help` ^^^^^^ `help` target displays all availables targets in Barabash script: .. code-block:: bash $ ./build.py help Barabash script for Barabash Barabash Help: upload-website combine-website build-docs render-website tests build-pkg upload-pkg `env` ^^^^^ `env` target display all Barabash variables that are set directly and indirectly: .. code-block:: bash $ ./build.py env AAAA=bar Barabash script for Barabash Barabash Environment: AAAA bar AR ar CC gcc COLORTERM gnome-terminal DESKTOP_SESSION ubuntu DISPLAY :0 GDMSESSION ubuntu HOME /home/godfryd LANG pl_PL.UTF-8 LOGNAME godfryd PATH /usr/sbin:/usr/bin:/sbin:/bin PWD /home/godfryd/repos/barabash2 RANLIB ranlib SHELL /bin/bash SHLVL 1 SSH_AGENT_PID 1929 SSH_AUTH_SOCK /tmp/keyring-VUwQmc/ssh TERM xterm USER godfryd USERNAME godfryd WINDOWID 62914564 XAUTHORITY /home/godfryd/.Xauthority