<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Chapter 9. More Than One Recipe</title><meta name="generator" content="DocBook XSL Stylesheets V1.71.1"><link rel="start" href="index.html" title="A-A-P Recipe Executive"><link rel="up" href="tutorial.html" title="Part I. Tutorial"><link rel="prev" href="tutor-actions.html" title="Chapter 8. Filetypes and Actions"><link rel="next" href="tutor-pipe.html" title="Chapter 10. Commands in a Pipe"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><table width="100%" id="navtable"><tbody><tr><td align="left" class="left" width="33%"><b><a href="http://www.a-a-p.org">A-A-P home page</a></b></td><td align="center" class="center" width="34%"><b><a href="index.html">A-A-P Recipe Executive</a></b></td><td align="right" class="right" width="33%"></td></tr><tr><td align="left" class="left"><a accesskey="p" href="tutor-actions.html">Prev</a></td><td align="center" class="center">Tutorial</td><td align="right" class="right"><a accesskey="n" href="tutor-pipe.html">Next</a></td></tr></tbody></table><hr><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="tutor-include"></a>Chapter 9. More Than One Recipe</h2></div></div></div><p> When you are working on a project that is split up in several directories it is convenient to use one recipe for each directory. There are several ways to split up the work and use a recipe from another recipe. </p><h2><a name="id2630484"></a>Children</h2><p> A large program can be split in several parts. This makes it easy for several persons to work in parallel. You then need to allow the files in each part to be compiled separately and also want to build the complete program. A convenient way to do this is putting files in separate directories and creating a recipe in each directory. The recipe at the top level is called the parent. Here is an example that includes two recipes in subdirectories, called the children: </p><pre class="programlisting"> 1 :child core/main.aap # sets Core_obj 2 :child util/main.aap # sets Util_obj 3 4 :program theprog : core/$*Core_obj util/$*Util_obj </pre><p> In the first two lines the child recipes are included. These specify how the source files in each directory are to be compiled and assign the list of object files to <code class="literal">Core_obj</code> and <code class="literal">Util_obj</code>. This parent recipe then defines how the object files are linked together to build the program "theprog". </p><p> In line 4 a special mechanism is used. Assume that <code class="literal">Core_obj</code> has the value "main.c version.c". Then "core/$*Core_obj" will expand into "core/main.c core/version.c". Thus "core/" is prepended to each item in <code class="literal">Core_obj</code>. This is called rc-style expansion. You can remember it by thinking of the "*" to multiply the items. </p><p> An important thing to notice is that the parent recipe does not need to know what files are present in the subdirectories. Only the child recipes contain the list of files. Thus when a file is added, only one recipe needs to be changed. The "core/main.aap" recipe contains the list of files in the "core" directory: </p><pre class="programlisting"> 1 Source = main.c 2 version.c 3 4 CPPFLAGS += -I../util 5 6 _top.Core_obj = `src2obj(Source)` 7 8 all: $_top.Core_obj </pre><p> Variables in a child recipe are local to that recipe. The <code class="literal">CPPFLAGS</code> variable that is changed in line 4 will remain unchanged in the parent recipe and other children. That is desired here, since finding header files in "../util" is only needed for source files used in this recipe. </p><p> The <code class="literal">Core_obj</code> variable we do want to be available in the parent recipe. That is done by prepending the "_top" scope name. The generic way to use a scope is: </p><div class="literallayout"><p> {scopename} . {variablename} </p></div><p> Several scope names are defined, such as "_recipe" for the current recipe and "_top" for the toplevel recipe. The full list of scope names can be found in the reference manual, chapter <a href="ref-varscope.html" title="Chapter 34. Variables and Scopes">Chapter 34, <i>Variables and Scopes</i></a>"Recipe Syntax and Semantics". When a variable is used without a scope name, it is looked up in the local scope and surrounding scopes. Thus the variables from the parent recipe are also available in the child. But when assigning to a variable without a scope, it is always set in the local scope only. To make the variable appear in another scope you must give the scope name. </p><p> The value of <code class="literal">Core_obj</code> is set with a Python expression. The <a href="ref-python.html#python-src2obj">src2obj()</a> function takes a list of source file names and transforms them into object file names. This takes care of changing the files in <code class="literal">Source</code> to prepend $BDIR and change the file suffix to $OBJSUF. It also takes care of using the "var_BDIR" attribute if it is present. </p><p> In the last line is specified what happens when running <strong class="userinput"><code>aap</code></strong> without arguments in the "core" directory: The object files are built. There is no specification for how this is done, thus the default rules will be used. </p><p> All the files in the child recipe are defined without mentioning the "core" directory. That is because all parent and child recipes are executed with the current directory set to where the recipe is. Note the files in <code class="literal">Core_obj</code> are passed to the parent recipe, which is in a different directory. That is why the parent recipe had to prepend "core/" when using <code class="literal">Core_obj</code>. This is so that the child recipe doesn't need to know what its directory name is, only the parent recipe contains this directory name. </p><h2><a name="id2631909"></a>Sharing Settings</h2><p> Another mechanism to use a recipe is by including it. This is useful to put common variables and rules in a recipe that is included by several other recipes. Example: </p><pre class="programlisting"> CPPFLAGS += -DFOOBAR :rule %$OBJSUF : %.foo :sys foocomp $source -o $target </pre><p> This recipe adds something to <code class="literal">CPPFLAGS</code> and defines a rule to turn a ".foo" file into an object file. Suppose you want to include this recipe in all the recipes in your project. Write the above recipe as "common.aap" in the top directory of the project. Then in "core/main.aap" and "util/main.aap" put this command at the top: </p><pre class="programlisting"> :include ../common.aap </pre><p> The <code class="computeroutput">:include</code> command works like the commands in the included recipe were typed instead of the <code class="computeroutput">:include</code> command. There is no change of directory, like with the <code class="computeroutput">:child</code> command and the included recipe uses the same scope.</p><p> In the toplevel recipe you need include "common.aap" as well. Suppose you include it in the first line of the recipe, before the <code class="computeroutput">:child</code> commands. The children also include "common.aap". The <code class="literal">CPPFLAGS</code> variable would first be appended to in the toplevel recipe, then passed to the child and appended to again. That is not what is supposed to happen. </p><p> To avoid this, add the <code class="computeroutput">{once}</code> option to the <a href="ref-commands.html#cmd-include">:include</a> command. This means that the recipe is only included once and not a second time. The child recipes use: </p><pre class="programlisting"> :include {once} ../common.aap </pre><p> And the parent uses: </p><pre class="programlisting"> 1 :include {once} common.aap 2 :child core/main.aap # sets Core_obj 3 :child util/main.aap # sets Util_obj 4 5 all: theprog$EXESUF 6 7 theprog$EXESUF : core/$*Core_obj util/$*Util_obj 8 :do build $source </pre><p> You might argue that another way would be to put the <code class="computeroutput">:include</code> command at the top of the parent recipe, so that the children don't have to include "common.aap". You could do this, but then it is no longer possible to execute a child recipe by itself. </p><p> Note that using <a href="ref-commands.html#cmd-include">:include</a> like this will always use the <code class="computeroutput">_top</code> scope for the variables set in the included recipe. Be careful that the <code class="computeroutput">_recipe</code> scope isn't used in one of the child recipes. </p><h2><a name="id2632029"></a>Sharing Modules</h2><p> Sometimes a group of settings is so generally useful that you want to use it in many different projects. A typical example of such a group of settings is language support for a specific programming language. In order to add support for a new language (say, <code class="computeroutput">D</code>), you need to define actions, set variables, etc. It is tedious to use <code class="computeroutput">:include</code>, so <span class="application">Aap</span> allows you to store such settings in a <span class="emphasis"><em>module</em></span>. </p><p> A module is a recipe like any other, except it is stored in the main <span class="application">Aap</span> directory (along with the system <code class="filename">default.aap</code>). You can read a module with the <code class="computeroutput">:import</code> command. This works very much like the <code class="computeroutput">:include</code> command, except: </p><div class="orderedlist"><ol type="1"><li><p>The recipe is read from the main <span class="application">Aap</span> directory.</p></li><li><p>Each module is imported only once.</p></li></ol></div><p> </p><p> <span class="application">Aap</span> includes modules for standard languages and build systems. It does not read these recipes by default because they add additional overhead, even when you do not use the languages they specify. Therefore, support for the D language, using libtool to build libraries, and KDE support (among others) is included in modules that you can use when needed. A full list of modules can be found in <a href="user-language.html" title="Chapter 31. Adding A Language Module">Chapter 31, <i>Adding A Language Module</i></a>. </p><h2><a name="id2632124"></a>Executing a Recipe</h2><p> Besides <code class="computeroutput">:child</code> and <code class="computeroutput">:include</code> there is a third way to use another recipe: <code class="computeroutput">:execute</code>. This command executes a recipe. This works as if <span class="application">Aap</span> was run as a separate program with this recipe, except that it is possible to access variables in the recipe that has the <a href="ref-commands.html#cmd-execute">:execute</a> command. Here is an example: </p><pre class="programlisting"> :program prog : main.c common.c test: :execute test.aap test :print $TestResult </pre><p> This recipe uses the <code class="literal">:program</code> command as we have seen before. This takes care of building the "prog" program. For testing a separate recipe is used, called "test.aap". The first argument of the <code class="computeroutput">:execute</code> command is the recipe name. Further arguments are handled like the arguments of the <strong class="userinput"><code>aap</code></strong> command. In this case the target "test" is used. </p><p> The "test.aap" recipe sets the <code class="literal">TestResult</code> variable to a message that summarizes the test results. To get this variable back to the recipe that executed "test.aap" the "_parent" scope is used: </p><pre class="programlisting"> @if all_done: _parent.TestResult = All tests completed successfully. @else: _parent.TestResult = Some tests failed! </pre><p> It would also be possible to use the <code class="computeroutput">:child</code> command to reach the "test" target in it. The main difference is that other targets in "test.aap" could interfere with targets in this recipe. For example, "test.aap" could define a different "prog" target, to compile the program with specific test options. By using <code class="computeroutput">:execute</code> we don't need to worry about this. In general, the <code class="computeroutput">:child</code> command is useful when splitting up a tree of dependencies in parts, while <code class="computeroutput">:execute</code> is useful for two tasks that have no common dependencies. </p><h2><a name="id2632296"></a>Fetching a Recipe</h2><p> So far we assumed the included recipes were stored on the local system. It is also possible to obtain them from elsewhere. The example with children above can be extended like this: </p><pre class="programlisting"> 1 Origin = ftp://ftp.foo.org/recipes 2 :include {once} common.aap {fetch = $Origin/common.aap} 3 :child core/main.aap {fetch = $Origin/core.aap} 4 :child util/main.aap {fetch = $Origin/util.aap} 5 6 all: theprog$EXESUF 7 8 theprog$EXESUF : core/$*Core_obj util/$*Util_obj 9 :do build $source </pre><p> The <code class="literal">fetch</code> attribute is used to specify the URL where the recipe can be obtained from. This works just like fetching source files. Notice in the example that the file name in the URL can be different from the local file name. When <span class="application">Aap</span> reads this recipe and discovers that a child or included recipe does not exist, it will use the <code class="literal">fetch</code> attribute to download it. The <code class="literal">fetch</code> attribute can also be used with the <code class="computeroutput">:execute</code> command. </p><p> Once a recipe exists locally it will be used, even when the remote version has been updated. If you explicitly want to get the latest version of the recipes used, run <strong class="userinput"><code>aap -R</code></strong> or <strong class="userinput"><code>aap fetch</code></strong>. </p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutor-actions.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutor-pipe.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 8. Filetypes and Actions </td><td width="20%" align="center"><a accesskey="h" href="index.html"> Contents</a></td><td width="40%" align="right" valign="top"> Chapter 10. Commands in a Pipe</td></tr></table></div></body></html>