For Aap version 1.071
Copyright © 2002-2003 Stichting NLnet Labs
The license for copying, using, modifying, distributing, etc this documentation and the A-A-P files can be found in Appendix A, License.
2004 Oct 02 19:08:59 GMT
Abstract
This is the documentation for version 1.071 of the Recipe Executive, commonly known as the "aap" command. It is part of the A-A-P project.
The web site of A-A-P can be found here: http://www.a-a-p.org/
The HTML version of this manual can be read on-line: http://www.a-a-p.org/exec/index.html As a single file: http://www.a-a-p.org/exec/exec.html.
The PDF version of this manual can be found here: http://www.a-a-p.org/exec/exec.pdf
The plain text version of this manual: http://www.a-a-p.org/exec/exec.txt.
Table of Contents
List of Tables
Table of Contents
Aap is a program that builds (compiles and links) other programs, much like the venerable make(1) program. However, Aap uses the power of Python to make the "recipes" (instructions on how to build a program) more readable and more flexible. Aap can also replace the age-old autotools and make toolchain.
Aap does not trade power for complexity. For many programs, you need only list the name of the program, the sources and libraries it needs, and Aap does the rest. A powerful module system makes adding new programming languages to Aap's repertoire fairly straightforward.
Aap supports C, C++, D, Qt's moc, KDE's dcopidl, and libtool.
To start using Aap you must have two applications:
Python version 1.5 or later
Aap
Python is often installed already. Try this:
python -V
If you get a "Command not found" error you still need to install Python. Help for this can be found on the Python web site: www.python.org/download/.
For obtaining and installing Aap look here: www.a-a-p.org/download.html.
A summary for the impatient:
Create a directory called "aap/Exec".
Download the latest Aap zip archive and unpack it in the new directory.
Run "./aap install" or "aap install".
To check if your Aap program is working, type this command:
aap --help
You should get a list of the command line arguments. Note that there are two dashes before "help". You can read details about the command line arguments in Chapter 32, Aap Command Line Arguments.
Most programming languages start with a short example that prints a "hello world" message. With Aap, this is also possible. In a file called main.aap, enter the following:
:print Hello, World!
|
Now run Aap by entering aap at the command line. Aap will respond something like this:
% aap
Hello, World!
Aap: No target on the command line and no $TARGET, build rules or "all" target in a recipe
As you can see, Aap outputs the desired text, but also prints an error message. This is because Aap is not a programming language, but a language for describing how to compile and build programs (written in other languages). In other words, if you have written a "hello world" program in some language, then you can use Aap to compile that program.
Suppose you have written a "hello world" program in C, and the sources are stored in a file called hello.c. Aap already knows about the C language (and several others), so the instructions to Aap about how to compile this program are very short. Instructions for Aap are stored in a file with the extension .aap. Such a file is called a recipe.
This is the recipe for compiling such a program with Aap:
:program hello : hello.c
|
Write this text in a file main.aap, in the same directory as hello.c. Now invoke Aap to compile hello.c into the program hello:
% ls
hello.c main.aap
% aap
1 Aap: Creating directory "/home/mool/tmp/build-FreeBSD4_5_RELEASE"
2 Aap: cc -I/usr/local/include -g -O2 -E -MM hello.c > build-FreeBSD4_5_RELEASE/hello.c.aap
3 Aap: cc -I/usr/local/include -g -O2 -c -o build-FreeBSD4_5_RELEASE/hello.o hello.c
4 Aap: cc -L/usr/local/lib -g -O2 -o hello build-FreeBSD4_5_RELEASE/hello.o
You see the commands Aap uses to compile the program:
A directory is created to write the intermediate results in. This directory is different for each platform, thus you can compile the same program for different systems without cleaning up.
Dependencies are figured out for the source file. Aap will automatically detect dependencies on included files and knows that if one of the included files changed compilation needs to be done, even when the file itself didn't change. In this example, Aap uses the C compiler with the -MM option to determine the included files.
The "hello.c" program file is compiled into the "hello.o" object file (on MS-Windows that would be "hello.obj").
The "hello.o" object file is linked to produce the "hello" program (on MS-Windows this would be "hello.exe", the ".exe" is added automatically).
The same simple recipe not only specifies how to build the "hello" program, it can also be used to install the program:
% aap install PREFIX=try
Aap: Creating directory "try/bin/"
Aap: Copied "test/hello" to "try/bin/hello"
Aap: /usr/bin/strip 'try/bin/hello'
The PREFIX variable specifies where to install the program. The default is /usr/local. For the example we use the try directory, which doesn't exist. Aap creates it for you.
Other ways that this recipe can be used:
aap uninstall undo installing the program
aap clean cleanup the generated files
aap cleanALL cleanup all files (careful!)
See the reference manual for details about :program.
When you have several files with source code you can specify them as a list:
:program myprogram : main.c
version.c
help.c
|
There are three source files: main.c, version.c and help.c. Notice that it is not necessary to use a line continuation character, as you would have to do in a Makefile. The list ends at a line where the indent is equal to or less than what the assignment started with. The amount of indent for the continuation lines is irrelevant, so long as it's more than the indent of the first line.
The Makefile-style line continuation with a backslash just before the line break can also be used, by the way.
Indents are very important, just like in a Python script. Make sure your tabstop is always set to the standard value of eight, otherwise you might run into trouble when mixing tabs and spaces!
When you give a list of files to :program, Aap will determine dependencies and compile each of the source files in turn, and then link them all together into an executable.
Sometimes it is convenient to have an abbreviation for a long list of files. Aap supports this through variables (just like the make command and the shell).
An assignment has the form:
variablename = expression
The variable name is the usual combination of letters, digits and underscore. It must start with a letter. Upper and lower case letters can be used and case matters. To see this in action, write this recipe in a file with the name try.aap:
foo = one
Foo = two
FOO = three
:print $foo $Foo $FOO
|
Aap normally reads the recipe from main.aap, but you can tell it to read a different file if you want to. Use the -f flag for this. Now execute the recipe:
% aap -f try.aap
one two three
Aap: No target on the command line and no build rules or "all" target in a recipe
The :print command prints its argument. You can see that a variable name preceded with a dollar is replaced by the value of the variable. The three variables that only differ by case each have a different value. Aap also complains that there is nothing to build, just like in the hello world example.
If you want text directly after the variable's value, for example, to append an extension to the value of a variable, the text may be impossible to distinguish from a variable name. In these cases you must put parenthesis around the variable name, so that Aap knows where it ends:
all:
MakeName = Make
:print $(MakeName)file # 'f' can be in a variable name
:print $(MakeName).txt # '.' can be in a variable name
:print $MakeName-more # '-' is not in a variable name
|
% aap -f try.aap
Makefile
Make.txt
Make-more
%
All Aap commands, except the assignment, start with a colon. That makes them easy to recognize.
Some characters in the expression have a special meaning. The :print command also handles a few arguments in a special way. To avoid the special meaning use the $(x) form, where "x" is the special character. For example, to print a literal dollar use $($). See the user manual for a complete list.
Someone who sees this recipe would like to know what it's for. This requires adding comments. These start with a "#" character and extend until the end of the line (like in a Makefile and Python script).
It is also possible to associate a comment with a specific item:
# A-A-P recipe for compiling "myprogram"
:program myprogram { comment = MyProgram is really great } :
main.c # startup stuff
version.c # just the date stamp
help.c # display a help message
|
Now run Aap with a "comment" argument:
% aap comment
target "myprogram": MyProgram is really great
target "clean": delete generated files that are not distributed
target "cleanmore": delete all generated files
target "cleanALL": delete all generated files, AAPDIR and build-* directories
target "install": install files
target "uninstall": delete installed files
%
The text inside curly braces is called an attribute. In this case the attribute name is "comment" and the attribute value is "MyProgram is really great". An attribute can be used to attach extra information to a file name. We will encounter more attributes later on.
Let's go back to the "Hello world" example and find out what happens when you change a source file. Use this hello.c file:
#include <stdio.h>
#include "hello.h"
main()
{
printf("Hello %s\n", world);
}
|
The included "hello.h" file defines "world":
#define world "World!"
|
If you run Aap, the "hello" program will be built as before. If you run Aap again you will notice that nothing happens. Aap remembers that "hello.c" was already compiled. Now try this:
% touch hello.c
% aap
%
If you have been using the "make" program you would expect something to happen. But Aap checks the contents of the file, not the timestamp. A signature of "hello.c" is computed and if it is still the same as before Aap knows that it does not need to be compiled, even though "hello.c" is newer than the "hello" program.
Aap uses the mechanism of dependencies. When you use the :program command Aap knows that the target depends on the sources. When one of the sources changes, the commands to build the target from the sources must be executed. This can also be specified explicitly:
hello$EXESUF : $BDIR/hello$OBJSUF
:do build $source
$BDIR/hello$OBJSUF : hello.c
:do compile $source
|
The generic form of a dependency is:
target : list-of-sources
build-commands
The colon after the target is important, it separates the target from the sources. It is not required to put a space before it, but there must be a space after it. We mostly put white space before the colon, so that it is easy to spot. There could be several targets, but that is unusual.
There are two dependencies in the example. In the first one the target is "hello$EXESUF", the source file is "$BDIR/hello$OBJSUF" and the build command is ":do build $source". This specifies how to build the "hello$EXESUF" program from the "$BDIR/hello$OBJSUF" object file. The second dependency specifies how to compile "hello.c" into "$BDIR/hello$OBJSUF" with the command ":do compile $source". The "BDIR" variable holds the name of the platform-dependent directory for intermediate results, as mentioned in the first example of this chapter. In case you need it, the $EXESUF variable Aap is empty on Unix and ".exe" on MS-Windows.
The relation between the two dependencies in the example is that the source of the first one is the target in the second one. The logic is that Aap follows the dependencies and executes the associated build commands. In this case "hello$EXESUF" depends on "$BDIR/hello$OBJSUF", which then depends on "hello.c". The last dependency is handled first, thus first hello.c is compiled by the build command of the second dependency, and then linked into "hello$EXESUF" by the build command of the first dependency.
Now change the "hello.h" file by replacing "World" with 'Universe":
#define world "Universe!"
|
If you now run Aap with "aap hello" or "aap hello.exe" the "hello" program will be built. But you never mentioned the "hello.h" file in the recipe. How did Aap find out the change in this file matters? When Aap is run to update the "hello" program, this is what will happen:
The first dependency with "hello$EXESUF" as the target is found, it depends on "$BDIR/hello$OBJSUF".
The second dependency with "$BDIR/hello$OBJSUF" as the target is found. The source file "hello.c" is recognized as a C program file. It is inspected for included files. This finds the "hello.h" file. "stdio.h" is ignored, since it is a system file. "hello.h" is added to the list of files that the target depends on.
Each file that the target depends on is updated. In this case "hello.c" and "hello.h". No dependency has been specified for them and the files exist, thus nothing happens.
Aap computes signatures for "hello.c" and "hello.h". It also computes a signature for the build commands. If one of them changed since the last time the target was built, or the target was never built before, the target is considered "outdated" and the build commands are executed.
The second dependency is now finished, "$BDIR/hello$OBJSUF" is up-to-date. Aap goes back to the first dependency.
Aap computes a signature for "$BDIR/hello$OBJSUF". Note that this happens after the second dependency was handled, it may have changed the file. It also computes a signature for the build command. If one of them changed since the last time the target was built, or the target was never built before, the target is considered "outdated" and the build commands are executed.
Now try this: Append a comment to one of the lines in the "hello.c" file. This means the file is changed, thus when invoking Aap it will compile "hello.c". But the program is not built, because the produced intermediate file "$BDIR/hello$OBJSUF" is still equal to what it was the last time. When compiling a large program with many dependencies this mechanism avoids that adding a comment may cause a snowball effect. (Note: some compilers include line numbers or a timestamp in the object file, in that case building the program will happen anyway).
Suppose you have a number of sources files that are used to build two programs. You need to specify which files are used for which program. Here is an example:
1. Common = help.c util.c 2. 3. all : foo bar 4. 5. :program foo : $Common foo.c 6. 7. :program bar : $Common bar.c |
This recipe defines three targets: "all", "foo" and "bar". "foo" and "bar are programs that Aap can build from source files. But the "all" target is not a file. This is called a virtual target: A name used for a target that does not exist as a file. Let's list the terminology of the items in a dependency:
Table 2.1. items in a dependency
| source | item on the right hand side of a dependency |
| source file | source that is a file |
| virtual source | source that is NOT a file |
| target | on the left hand side of a dependency |
| target file | target that is a file |
| virtual target | target that is NOT a file |
| node | source or target |
| file node | source or target that is a file |
| virtual node | source or target that is NOT a file |
Aap knows the target with the name "all" is always used as a virtual target. There are a few other names which Aap knows are virtual, see Table 37.1. For other targets you need to specify it with the "{virtual}" attribute.
The first dependency has no build commands. This only specifies that "all" depends on "foo" and "bar". Thus when Aap updates the "all" target, this dependency specifies that "foo" and "bar" need to be updated. Since the "all" target is the default target, this dependency causes both "foo" and "bar" to be updated when Aap is started without an argument. You can use "aap foo" to build "foo" only. The dependencies for "all" and "bar" will not be used then.
The two files help.c and util.c are used by both the "foo" and the "bar" program. To avoid having to type the file names twice, the "Common" variable is used.
Not everything you want to build is a program. Your recipe might need too build a library or a libtool archive. In these cases, :lib, :dll or :ltlib provide the same level of automation as :program does for programs. The :produce command is more generic, you can use this to build various kinds of things.
If all else fails, you can use Aap like the make program and explicitly list the commands you need to build your project.
If you are maintaining a web site it is often a good idea to edit the files on your local system. After trying out the changes you then need to upload the changed files to the web server. A-A-P can be used to identify the files that changed and upload these files only. This is called publishing.
Here is an example of a recipe:
Files = index.html
project.html
links.html
images/logo.png
:attr {publish = scp://user@ftp.foo.org/public_html/%file%} $Files
|
That's all. You just need to specify the files you want to publish and the URL that says how and where to upload them to. Now "aap publish" will find out which files have changed and upload them:
% aap publish
Aap: Uploading ['/home/mool/www/foo/index.html'] to scp://user@ftp.foo.org/public_html/index.html
Aap: scp '/home/mool/www/vim/index.html' 'user@ftp.foo.org:public_html/index.html'
Aap: Uploaded "/home/mool/www/vim/index.html" to "scp://user@ftp.foo.org/public_html/index.html"
%
The first time you execute the recipe all files will be uploaded. Aap will create the "images" directory for you. If you had already uploaded the files and want to avoid doing it again, first run the recipe with: "aap publish --touch". Aap will compute the signatures of the files as they are now and remember them. Only files that are changed will be uploaded from now on.
The :attr command uses its first argument as an attribute and further arguments as file names. It will attach the attribute to each of the files. In this case the "publish" attribute is added, which specifies the URL where to upload a file to. In the example the "scp" protocol is used, which is a good method for uploading files to a public server. "ftp" can be used as well, but this means your password will go over the internet, which is not safe. The special item "%file%" is replaced with the name of the file being published.
It is common for HTML files to consist of a standard header, a body with the useful info and a footer. You don't want to manually add the header and footer to each page. When the header changes you would have to make the same change in many different files. Instead, use the recipe to generate the HTML files.
Let's start with a simple example: Generate the index.html file. Put the common header, containing a logo and navigation links, in "header.part". The footer, containing contact info for the maintainer, goes in "footer.part". The useful contents of the page goes in "index_body.part". Now you can use this recipe to generate "index.html" and publish it:
Files = index.html
images/logo.png
:attr {publish = scp://user@ftp.foo.org/public_html/%file%} $Files
all: $Files
publish: $Files
:publishall
index.html: header.part index_body.part footer.part
:cat $source >! $target
|
Notice that only the published files are put in the "Files" variable. These files get a "publish" attribute, which tells Aap that these are the files that need to be uploaded. The ".part" files are not published, thus they do not get the "publish" attribute.
Three dependencies follow. The "all" target is the virtual target we have seen before. It specifies that the default work for this recipe is to update the files in the "Files" variable. This means you don't accidentally upload the files by running "aap" without arguments. The normal way of use is to run "aap", check if the produced HTML file looks OK, then use "aap publish" to upload the file.
For "index.html" a target is specified with a build command. The :cat command concatenates the source files. "$source" stands for the source files used in the dependency: "header.part, "index_body.part" and "footer.part". The resulting text is written to "$target", which is the target of the dependency, thus "index.html". The ">!" is used to redirect the output of the :cat command and overwrite any existing result. This works just like the Unix "cat" command.
In the dependency with the "publish" target the :publishall command is used. This command goes through all the files which were given a "publish" attribute with the :attr command. Note that this does not work:
# This won't work.
Files = index.html {publish = scp://user@ftp.foo.org/public_html/%file%}
|
Using a "publish" attribute in an assignment will not make it used with the :publishall command.
Your web site contains several pages, thus you need to specify how to generate each HTML page. This quickly becomes a lot of typing. We would rather specify once how to make a "xxx.html" file from a "xxx_body.part" file, and then give the list of names to use for "xxx" (if you have assocations with the name "xxx_body.part" that is your own imagination! :-). This is how it's done:
Files = *.html
images/*.png
:attr {publish = scp://user@ftp.foo.org/public_html/%file%} $Files
all: $Files
publish: $Files
:publishall
:rule %.html : header.part %_body.part footer.part
:cat $source >! $target
|
This is very similar to the example that only generates the "index.html" file. The first difference is in the value of "Files": It contains wildcards. These wildcards are expanded when they are used where a file name is expected. The expansion is not done in the assignment! More about that later. In the three places where $Files is used the wildcard expansion results in a list of all "*.html" files in the current directory and all "*.png" files in the "images" directory.
The second difference is that there is no specific dependency for the "index.html" file but a :rule command. It looks very much the same, but the word "index" has been replaced by a percent character. You could read the rule command as a dependency where the "%" stands for "anything". In the example the target is "anything.html" and in the sources we find "anything_body.part". Obviously these two occurrences of "anything" are the same word.
If you have made HTML pages, you know they contain a title. We ignored that until now. The following recipe will handle a title, stored in the file "xxx_title.part". You also need a file "start.part", which contains the HTML code that goes before the title.
Files = *.html
images/*.png
:attr {publish = scp://user@ftp.foo.org/public_html/%file%} $Files
all: $Files
publish: $Files
:publishall
:rule %.html : start.part %_title.part header.part %_body.part footer.part
:cat $source >! $target
|
Notice that "%" is now used three times in the :rule command. It stands for the same word every time.
After writing this recipe you can forget what changes you made to what file. A-A-P will take care of generating and uploading those HTML files that are affected. For example, if you change "header.part", all the HTML files are generated and uploaded. If you change "index_title.part" only "index.html" will be done.
There is one catch: You must create an (empty) xxx.html file the first time, otherwise it will not be found with "*.html". And you have to be careful not to have other "xxx.html" files in this directory. You might want to explicitly specify all the HTML files instead of using wildcards.
The same problem with wildcards happens for the image files. There is a solution for this: use the get_html_images() function. You can find an example in the section called “Publishing images for HTML files”.
A similar recipe is actually used to update the A-A-P website. It's a bit more complicated, because not all pages use the same header.
Open source software needs to be distributed. This chapter gives a simple example of how you can upload your files and make it easy for others to download and install your program.
To make it easy for others to obtain the latest version of your program, you give them a recipe. That is all they need. In the recipe you describe how to download the files and compile the program. Here is an example:
1 Origin = ftp://ftp.mysite.org/pub/theprog
2
3 :recipe {fetch = $Origin/main.aap}
4
5 Source = main.c
6 version.c
7 Header = common.h
8
9 :attr {fetch = $Origin/%file%} $Source $Header
10
11 :program theprog : $Source
|
The first line specifies the location where all the files can be found. It is good idea to specify this only once. If you would use the text all over the recipe it is more difficult to read and it would be more work when the URL changes.
Line 3 specifies where this recipe can be obtained. After obtaining this recipe once, it can be updated with a simple command:
% aap refresh
Aap: Updating recipe "main.aap"
Aap: Attempting download of "ftp://ftp.mysite.org/pub/theprog/main.aap"
Aap: Downloaded "ftp://ftp.mysite.org/pub/theprog/main.aap" to "/home/mool/.aap/cache/98092140.aap"
Aap: Copied file from cache: "main.aap"
%
The messages from Aap are a bit verbose. This is just in case the downloading is very slow, you will have some idea of what is going on.
Lines 5 to 7 define the source files. This is not different from the examples that were used to compile a program, except that we explicitly mention the header file used.
Line 9 specifies where the files can be fetched from. This is done by giving the source and header files the fetch attribute. The :attr command does not cause the files to be fetched yet. When a file is used somewhere and it has a fetch attribute, then it is fetched. Thus files that are not used will not be fetched.
A user of your program stores this recipe as main.aap and runs aap without arguments. What will happen is:
Dependencies will be created by the :program command to build "theprog" from main.c and version.c.
The target "theprog" depends on main.c and version.c. Since these files do not exist and they do have a fetch attribute, they are fetched.
The main.c file is inspected for dependencies. It includes the common.h file, which is automatically added to the list of dependencies. Since common.h does not exist and has a fetch attribute, it is fetched as well.
Now that all the files are present they are compiled and linked into "theprog".
You need to upload the files mentioned in the recipe above. This needs to be repeated each time one of the files changes. This is essentially the same as publishing a web site. You will need to upload both the source files and the recipe itself. The {publish} attribute can be used for this. You can add the following two lines to the recipe above in order to upload all the files:
URL = scp://user@ftp.mysite.org//pub/theprog/%file%
:attr {publish = $URL} $Source $Header main.aap
|
Now you can use aap publish to upload your source files as well.
A-A-P provides a way to build two variants of the same application. You just need to specify what is different about them. A-A-P will then take care of putting the resulting files in a different directory, so that you don't have to recompile everything when you toggle between two variants.
For the details see :variant in the reference manual.
Quite often you want to compile an application for release with maximal optimizing. But the optimizer confuses the debugger, thus when stepping through the program to locate a problem, you want to recompile without optimizing. Here is an example:
1 Source = main.c version.c gui.c 2 3 :variant Build 4 release 5 OPTIMIZE = 4 6 Target = myprog 7 debug 8 DEBUG = yes 9 Target = myprogd 10 11 :program $Target : $Source |
Write this recipe as "main.aap" and run Aap without arguments. This will build "myprog" and use a directory for the object files that ends in "-release". The release variant is the first one mentioned, that makes it the default choice.
The first argument for the :variant command is Build. This is the name of the variable that specifies what variant will be selected. The names of the alternatives are specified with a bit more indent in lines 4 and 7. For each alternative two commands are given, again with more indent. Note that the indent not only makes it easy for you to see the parts of the :variant command, they are essential for Aap to recognize them.
To select the "debug" variant the Build variable must be set to "debug". A convenient way to do this is by specifying this on the command line:
% aap Build=debug
This will build the "myprogd" program for debugging instead of for release. The DEBUG variable is recognized by Aap. The object files are stored in a directory ending in "-debug". Once you finished debugging and fixed the problem in, for example, "gui.c", running Aap to build the release variant will only compile the modified file. There is no need to compile all the C files, because the object files for the "release" variant are still in the "-release" directory.
You can extend the Build variant with more items, for example "profile". This is useful for alternatives that exclude each other. Another possibility is to add a second :variant command. Let us extend the example with a selection of the user interface type.
1 Source = main.c version.c gui.c 2 3 :variant Build 4 release 5 OPTIMIZE = 4 6 Target = myprog 7 debug 8 DEBUG = yes 9 Target = myprogd 10 11 Gui ?= motif 12 :variant Gui 13 console 14 motif 15 Source += motif.c 16 gtk 17 Source += gtk.c 18 19 DEFINE += -DGUI=$Gui 20 21 :program $Target : $Source |
The :variant command in line 12 uses the Gui variable to select one of "console", "motif" or "gtk". Together with the earlier :variant command this offers six alternatives: "release" with "console", "debug" with "console", "release" with "motif", etc. To build "debug" with "gtk" use this command:
% aap Build=debug Gui=gtk
In line 11 an optional assignment "?=" is used. This assignment is skipped if the Gui variable already has a value. Thus if Gui was given a value on the command line, as in the example above, it will keep this value. Otherwise it will get the value "motif".
![]() | Environment variables |
|---|---|
Environment variables are not used for variables in the recipe, like make does. When you happen to have a Gui environment variable, this will not influence the variant in the recipe. This is especially useful if you are not aware of what environment variables are set and/or which variables are used in the recipe. If you intentionally want to use an environment variable this can be specified with a Python expression (see the next chapter). | |
In line 15, 17 and 19 the append assignment "+=" is used. This appends the argument to an existing variable. A space is inserted if the value was not empty. For the variant "motif" the result of line 15 is that Source becomes "main.c version.c gui.c motif.c".
The "motif" and "gtk" variants each add a source file in line 15 and 17. For the console version no extra file is needed. The object files for each combination of variants end up in a different directory. Ultimately you get object files in each of the six directories ("SYS" stands for the platform being used):
| directory | contains files |
|---|---|
| build-SYS-release-console | main, version, gui |
| build-SYS-debug-console | main, version, gui |
| build-SYS-release-motif | main, version, gui, motif |
| build-SYS-debug-motif | main, version, gui, motif |
| build-SYS-release-gtk | main, version, gui, gtk |
| build-SYS-debug-gtk | main, version, gui, gtk |
See the user manual for more examples of using variants.
In various places in the recipe Python commands and expressions can be used. Python is a powerful and portable scripting language. In most recipes you will only use a few Python items. But where needed you can do just about anything with it.
(Almost) anywhere you have a value, such as a text string, you can use a Python expression instead. For instance, you could use a Python expression to retrieve the value of an environment variable for use in a recipe, or use an expression to compute some strange value.
Expressions are written between backticks (` `) and must be valid Python expressions. Some examples:
1 myhome = `os.environ.get("HOME")`
2 label = `"L"+str(17*22)`
|
The first example line shows how to retrieve an environment variable by using Python's built-in os.environ module. The second shows how you can use Python to compute something within an Aap recipe. It doesn't do anything useful, but it uses Python to compute the value L374, and then Aap assigns that value to the variable label.
![]() | Note |
|---|---|
| Using environment variables is probably not portable. | |
When a recipe needs to work both on Unix and on MS-Windows you quickly run into the problem that the compiler does not use the same arguments. Here is an example how you can handle that.
1 @if OSTYPE == "posix": 2 INCLUDE += -I/usr/local/include 3 @else: 4 INCLUDE += -Ic:/vc/include 5 6 all: 7 :print INCLUDE is "$INCLUDE" |
The first and third line start with the "@" character. This means a Python command follows. The other lines are normal recipe lines. You can see how these two kinds of lines can be mixed.
The first line is a simple "if" statement. The OSTYPE variable is compared with the string "posix". If they compare equal, the next line is executed. When the OSTYPE variable has a different value the line below @else: is executed. Executing this recipe on Unix:
% aap
INCLUDE is "-I/usr/local/include"
%
OSTYPE has the value "posix" only on Unix and Unix-like systems. Executing the recipe on MS-Windows, where OSTYPE has the value "mswin":
C:> aap
INCLUDE is "-Ic:/vc/include"
C:>
Note that the Python conditional commands end in a colon. Don't forget to add it, you will get an error message! The indent is used to form blocks, thus you must take care to align the "@if" and "@else" lines.
You can include more lines in a block, without the need for extra characters, such as { } in C:
@if OSTYPE == "posix":
INCLUDE += -I/usr/local/include
LDFLAGS += -L/usr/local
@else:
INCLUDE += -Ic:/vc/include
LDFLAGS += -Lc:/vc/lib
|
In Aap commands a variable without a scope is searched for in other scopes. Unfortunately, this does not happen for variables used in Python. To search other scopes you need to prepend "_no." before the variable name. Changing the above example to print the result from Python:
@if OSTYPE == "posix":
INCLUDE += -I/usr/local/include
@else:
INCLUDE += -Ic:/vc/include
all:
@print 'INCLUDE is "%s"' % _no.INCLUDE
|
Python has a "for" loop that is very flexible. In a recipe it is often used to go over a list of items. Example:
1 @for name in [ "solaris", "hpux", "linux", "freebsd" ]: 2 fname = README_$name 3 @if os.path.exists(fname): 4 Files += $fname 5 all: 6 :print $?Files |
The first line contains a list of strings. A Python list uses square brackets. The lines 2 to 4 are executed with the name variable set to each value in the list, thus four times. The indent of line 5 is equal to the @for line, this indicates the "for" loop has ended.
Note how the name and fname variables are used without a dollar in the Python code. You only put a dollar before a variable name in the argument of an Aap command. Not in Python code and not on the left hand side of an assignment.
In line 2 the fname variable is set to "README_" plus the value of name. The os.path.exists() function in line 3 tests if a file exists. Assuming all four files exist, this is the result of executing this recipe:
% aap
README_solaris README_hpux README_linux README_freebsd
%
When the number of Python lines gets longer, the "@" characters become annoying. It is easier to put the lines in a block. Example:
:python
Files = ''
for name in [ "solaris", "hpux", "linux", "freebsd" ]:
fname = "README_" + name
if os.path.exists(fname):
if Files:
Files = Files + ' '
Files = Files + fname
all:
:print $Files
|
This does the same thing as the above recipe, but now using Python commands. As usual, the :python block ends where the indent is equal to or less than that of the :python line.
When using the :python command, make sure you get the assignments right. Up to the "=" character the Python assignment is the same as the recipe assignment, but what comes after it is different.
In many places a Python expression can be used. For example, the glob() function can be used to expand wildcards:
Source = `glob("*.c")`
|
Python users know that the glob() function returns a list of items. Aap automatically converts the list to a string, because all Aap variables are strings. A space is inserted in between the items and quotes are added around items that contain a space.
![]() | Using glob() is dangerous |
|---|---|
It is actually a bit dangerous to get the list of source files with the glob() function, because a "test.c" file that you temporarily used will accidentally be included. It is often better to list the source files explicitly. | |
Why use glob() when you can use wildcards directly? The difference is that the expansion with glob() takes place immediately, thus $Source will get the expanded value. When using wildcards directly the expansion is done when using the variable, but that depends on where it is used. For example, the :print command does not do wildcard expansion:
pattern = *.c
expanded = `glob(pattern)`
all:
:print pattern $pattern expands into $expanded
|
When "foo.c" and "bar.c" exist, the output will be:
% aap
pattern *.c expands into foo.c bar.c
%
The following example turns the list of source files into a list of header files:
Source = `glob("*.c")`
Header = `sufreplace(".c", ".h", Source)`
all:
:print Source is "$Source"
:print Header is "$Header"
|
Running Aap in a directory with "main.c" and "version.c"?
% aap
Source is "version.c main.c"
Header is "version.h main.h"
%
The sufreplace() function takes three arguments. The first argument is the suffix which is to be replaced. The middle argument is the replacement suffix. The last argument is the name of a variable that is a list of names, or a Python expression. In this example each name in Source ending in ".c" will be changed to end in ".h".
The User manual Chapter 21, Using Python has more information. Documentation about Python can be found on its web site: http://www.python.org/doc/
CVS is often used for development of Open Source Software. A-A-P provides facilities to obtain the latest version of an application and for checking in changes you made.
For downloading a whole module you only need to specify the location of the CVS server and the name of the module. Here is an example that obtains the A-A-P Recipe Executive:
CVSROOT = :pserver:anonymous@cvs.a-a-p.sf.net:/cvsroot/a-a-p
all:
:fetch {fetch = cvs://$CVSROOT} Exec
|
Write this recipe as "main.aap" and run aap. The directory "Exec" will be created and all files in the module obtained from the CVS server:
% aap
Aap: CVS checkout for node "Exec"
Aap: cvs -d:pserver:anonymous@cvs.a-a-p.sf.net:/cvsroot/a-a-p checkout 'Exec'
cvs server: Updating Exec
U Exec/Action.py
U Exec/Args.py
[....]
%
If there is a request for a password just hit enter (mostly there is no password).
The :fetch command takes care of obtaining the latest version of the items mentioned as arguments. Usually the argument is one module, in this example it is "Exec". That CVS needs to be used is specified with the fetch attribute. This is a kind of URL, starting with "cvs://" and then the CVS root specification. In the example the CVSROOT variable was used. This is not required, it just makes the recipe easier to understand.
If the software has been updated, you can get the latest version by running "aap" again. CVS will take care of obtaining the changed files.
Note that all this only works when you have the "cvs" command installed. When it cannot be found Aap will ask you want Aap to install it for you. Whether this works depends on your system.
Firewalls may block the use of a CVS connection. Some servers have setup another way to connect, so that firewalls will not cause problems. This uses port 80, normally used for http connections. Here is the above example using a different "pserver" address:
CVSROOT = :pserver:anonymous@cvs-pserver.sf.net:80/cvsroot/a-a-p
all:
:fetch {fetch = cvs://$CVSROOT} Exec
|
This doesn't always work through a proxy though. If you have problems connecting to the CVS server, try reading the information at this link.
You are the maintainer of a project and want to distribute your latest changes, so that others can obtain the software with a recipe as used above. This means you need to checkin your files to the CVS server. This is done by listing the files that need to be distributed and giving them a commit attribute. Example:
CVSUSER_FOO = johndoe
CVSROOT = :ext:$CVSUSER_FOO@cvs.foo.sf.net:/cvsroot/foo
Files = main.c
common.h
version.c
:attr {commit = cvs://$CVSROOT} $Files
|
Write this as "cvs.aap" and run aap -f cvs.aap revise . What will happen is:
Files that you changed since the last checkin will be checked in to the CVS server.
Files that you added to the list of files with a commit attribute will be added to the CVS module.
Files that you removed from the list of files with a commit attribute will be removed from the CVS module.
This means that you must take care the Files variable lists exactly those files you want to appear in the CVS module, nothing more and nothing less. Be careful with using something like *.c, it might find more files that you intended.
Note: This only works when the CVS module was already setup. Read the CVS documentation on how to do this. The A-A-P user manual has useful hints as well.
In the example the CVSUSER_FOO variable is explicitly set, thus this recipe only works for one user. Better is to move this line to your own default recipe, e.g., "~/.aap/startup/default.aap". Then the above recipe does not explicitly contain your user name and can also be used by others.
Once you tested this recipe and it works, you can easily distribute your software with aap -f cvs.aap revise. You don't have to worry about the exact CVS commands to be used. However, don't use this when you want to checkin only some of the changes you made. And the example does not work well when others are also changing the same module.
The User manual Chapter 18, Version Control has more information about version control and Chapter 19, Using CVS about using CVS.
A-A-P can recognize what the type of a file is, either by looking at the file name or by inspecting the contents of the file. The filetype can then be used to decide how to perform an action with the file.
Suppose you are using the "foo" programming language and want to use A-A-P to compile your programs. Once this is has been setup you can compile "hello.foo" into the "hello" program with a simple recipe:
:program hello : hello.foo
|
You need to explain Aap how to deal with "foo" files. This is done with a recipe:
:filetype
suffix foo foo
:action compile foo
:sys foocomp $?FOOFLAGS $source -o $target
:route foo object
compile
|
For Unix, write this recipe as "/usr/local/share/aap/startup/foo.aap" or "~/.aap/startup/foo.aap". The recipes in these "startup" directories are always read when Aap starts up.
Now try it out, using the simple recipe at the top as "main.aap":
% aap
Aap: foocomp hello.foo -o build-FreeBSD4_5_RELEASE/hello.o
Aap: cc -L/usr/local/lib -g -O2 -o hello build-FreeBSD4_5_RELEASE/hello.o
%
The "foo.aap" recipe does three things:
The :filetype command is used to tell A-A-P to recognize your "hello.foo" file as being a "foo" file.
The :action command is used to specify how the "foocomp" compiler is used to compile a "foo" program into an object file. The user can set the FOOFLAGS variable to options he wants to use. The convention is that the option variable is in uppercase, starts with the filetype and ends in "FLAGS".
The :route command is used to specify which actions are to be used to turn a "foo" file into an "object" file.
The :filetype command is followed by the line "suffix foo foo". The first word "suffix" means that recognizing is done by the suffix of the file name (the suffix is what comes after the last dot in the name). The second word is the suffix and the third word is the type. Quite often the type is equal to the suffix, but not always. Here are a few more examples of lines used with :filetype:
:filetype
suffix fooh foo
suffix bash sh
|
It is also possible to recognize a file by matching the name with a pattern, checking the contents of the file or using a Python script. See the user manual.
The lower half of "foo.aap" specifies the compile action for the "foo" filetype:
:action compile foo
:sys foocomp $source -o $target
|
The :action command has two arguments. The first one specifies the kind of action that is being defined. In this case "compile". This action is used to make an object file from a source file. The second argument specifies the type of source file this action is used for, in this case "foo".
Below the :action line the build commands are specified. In this case just one, there could be more. The :sys command invokes an exteral program, "foocomp", and passes the arguments. In an action $source is expanded to the source of the action and $target to the target. These are obtained from the :do command that invokes the action. Example:
:do compile {target = `src2obj("main.foo")`} main.foo
|
This :do command invokes the compile action, specified with its first argument. The target is specified as an attribute to the action, the source is the following argument "main.foo". When executing the :do command the filetype of "main.foo" is detected to be "foo", resulting in the compile action for "foo" to be invoked. In the build command of the action $source and $target are replaced, resulting in:
:sys foocomp main.foo -o `src2obj("main.foo")`
|
Note that in many cases $target is passed implicitly from a dependency and does not appear in the :do command argument.
When building a program you often want to include the date and time when it was built. A simple way of doing this is creating a source file "version.c" that contains the timestamp. This file needs to be compiled every time your program is built. Here is an example how this can be done:
1 :program prog : main.c work.c
2
3 :attr prog {filetype = myprog}
4
5 :action build myprog object
6 version_obj = `src2obj("version.c")`
7 :do compile {target = $version_obj} version.c
8 :do build {filetype = program} $source $version_obj
|
The target "prog" is explicitly given a different filetype in line 3. The default filetype for a program is "program", here it is set to "myprog". This allows us to specify a different build action for "prog".
Write the recipe as "main.aap" (without the line numbers) and execute it with aap. The first time all the files will be compiled and linked together. Executing aap again will do nothing. Thus the timestamp used in "version.c" will not be updated if the files were not changed. If you now make a change in "main.c" and run aap you will see that both "main.c" and "version.c" are compiled.
The :action command in line 5 has three arguments. The first one "build" is the kind of action, like before. The second argument "myprog" specifies the target filetype, the third one "object" the source filetype. Thus the template is:
:action kind-of-action target-filetype source-filetype
This order may seem a bit strange. Remember that putting the target left of the source also happens in a dependency and an assignment.
There are three commands for the build action, lines 6 to 8. The first one assigns the name of the object file for "version.c" to version_obj. "version.c" was not included in the :program command at the top, it is compiled here explicitly in line 7. This is what makes sure "version.c" is compiled each time "prog" is built. The other source files will be compiled with the default rules for :command.
Finally the :do build command in line 8 invokes the build action to link all the object files together. Note that the filetype for the build action is explicitly defined to "program". This is required for this :do command to use the default action for a program target. Otherwise the action would invoke itself, since the filetype for $target is "myprog".
For more information about customizing filetype detection and actions see Chapter 28, Customizing Filetype Detection and Actions.
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.
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:
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 |
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 Core_obj and Util_obj. This parent recipe then defines how the object files are linked together to build the program "theprog".
In line 4 a special mechanism is used. Assume that Core_obj 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 Core_obj. This is called rc-style expansion. You can remember it by thinking of the "*" to multiply the items.
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:
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 |
Variables in a child recipe are local to that recipe. The CPPFLAGS 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.
The Core_obj 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:
{scopename} . {variablename}
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 Chapter 34, Variables and Scopes"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.
The value of Core_obj is set with a Python expression. The src2obj() function takes a list of source file names and transforms them into object file names. This takes care of changing the files in Source to prepend $BDIR and change the file suffix to $OBJSUF. It also takes care of using the "var_BDIR" attribute if it is present.
In the last line is specified what happens when running aap 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.
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 Core_obj are passed to the parent recipe, which is in a different directory. That is why the parent recipe had to prepend "core/" when using Core_obj. 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.
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:
CPPFLAGS += -DFOOBAR
:rule %$OBJSUF : %.foo
:sys foocomp $source -o $target
|
This recipe adds something to CPPFLAGS 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:
:include ../common.aap
|
The :include command works like the commands in the included recipe were typed instead of the :include command. There is no change of directory, like with the :child command and the included recipe uses the same scope.
In the toplevel recipe you need include "common.aap" as well. Suppose you include it in the first line of the recipe, before the :child commands. The children also include "common.aap". The CPPFLAGS 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.
To avoid this, add the {once} option to the :include command. This means that the recipe is only included once and not a second time. The child recipes use:
:include {once} ../common.aap
|
And the parent uses:
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
|
You might argue that another way would be to put the :include 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.
Note that using :include like this will always use the _top scope for the variables set in the included recipe. Be careful that the _recipe scope isn't used in one of the child recipes.
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, D), you need to define actions, set variables, etc. It is tedious to use :include, so Aap allows you to store such settings in a module.
A module is a recipe like any other, except it is stored in the main Aap directory (along with the system default.aap). You can read a module with the :import command. This works very much like the :include command, except:
The recipe is read from the main Aap directory.
Each module is imported only once.
Aap 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 Chapter 31, Adding A Language Module.
Besides :child and :include there is a third way to use another recipe: :execute. This command executes a recipe. This works as if Aap was run as a separate program with this recipe, except that it is possible to access variables in the recipe that has the :execute command. Here is an example:
:program prog : main.c common.c
test:
:execute test.aap test
:print $TestResult
|
This recipe uses the :program 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 :execute command is the recipe name. Further arguments are handled like the arguments of the aap command. In this case the target "test" is used.
The "test.aap" recipe sets the TestResult 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:
@if all_done:
_parent.TestResult = All tests completed successfully.
@else:
_parent.TestResult = Some tests failed!
|
It would also be possible to use the :child 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 :execute we don't need to worry about this. In general, the :child command is useful when splitting up a tree of dependencies in parts, while :execute is useful for two tasks that have no common dependencies.
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:
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
|
The fetch 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 Aap reads this recipe and discovers that a child or included recipe does not exist, it will use the fetch attribute to download it. The fetch attribute can also be used with the :execute command.
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 aap -R or aap fetch.
A selection of commands can be connected together with a pipe. This means the output of one command is the input for the next command. It is useful for filtering text from a variable or file and writing the result in a variable or file.
This example shows how you can change the timestamp in a file. It is done in-place.
all:
:print Setting date in foobar.txt.
:cat foobar.txt
| :eval re.sub('Last Change: .*\n', 'Last Change: ' + DATESTR + '\n', stdin)
>! foobar.txt
|
Lets see how this works:
% cat foobar.txt
This is example text for the A-A-P tutorial.
Last Change: 2002 Feb 29
The useful contents would start here.
% aap
Setting date in foobar.txt.
% cat foobar.txt
This is example text for the A-A-P tutorial.
Last Change: 2002 Oct 21
The useful contents would start here.
%
The last command in the example consists of three parts. First comes the :cat command. It reads the "foobar.txt" file and passes it throught the pipe to the next command. "cat" is short for "concatenate". This is one of the good-old Unix commands that actually does much more than the name suggests. In this example nothing is concatenated. Below you will see examples where it does.
The second part of the example is the :eval command. This is used to read the text coming in through the pipe and modify it with a Python expression. In this case the expression is a "re.sub()" function call. This Python function takes three arguments: A pattern, a replacement string and the text to operate on. All occurences of the pattern in the text are changed to the replacement string. The pattern "Last Change: .*\n" matches a line with the date that was inserted previously. The replacement string contains DATESTR, which is an Aap variable that contains today's date as a string, e.g., "2002 Oct 19". The text to operate on is stdin. This is the variable that holds the text that is coming in through the pipe.
The third and last part >! foobar.txt redirects the output of the :eval command back to the file "foobar.txt". Using just ">" would cause an error, since the file already exists.
Note that in a Unix shell command this pipe would not work: The "foobar.txt" would be overwritten before it was read. In Aap this does not happen, the commands in the pipe are executed one by one. That makes it easier to use, but it does mean the text is kept in memory. Don't use pipes for a file that is bigger than half the memory you have available.
Changing a file in-place has the disadvantage that the normal dependencies don't work, since there is no separate source and target file. Often it is better to use a file "foobar.txt.in" as source, change it like in the example above and write it as a new file. The recipe would be:
foobar.txt: foobar.txt.in
:print Setting date in $target.
:cat $source
| :eval re.sub('Last Change: .*\n', 'Last Change: ' + DATESTR + '\n', stdin)
>! $target
|
Sometimes you need to generate a file from several pieces. Here is an example that concatenates two files and puts a generated text line in between.
manual.html: body.html footer.html
@import time
:eval time.strftime("%A %d %B %Y", time.localtime(time.time()))
| :print $(lt)BR$(gt)Last updated: $stdin$BR
| :cat body.html - footer.html >! $target
|
There are quite a few items here that need to be explained. First of all, the "@import time" line. This is a Python command to load the "time" module. So far we used modules that Aap has already loaded for you. This one isn't, and since we use the "time" module in the next :eval command it needs to be loaded explicitly.
The Python function "strftime()" formats the date and time in a specified format. See the Python documentation for the details. In this case the resulting string looks like "Monday 21 October 2002".
The output of the :eval command is piped into a :print command. The variable stdin contains the output of the previous command. Note that "$(lt)" is used instead of "$lt". The meaning is exactly the same: the value of the lt variable. Without the extra parenthesis it would read "$ltBR", which would be the value of the "ltBR" variable.
The resulting text is:
<BR>Last updated: Monday 21 October 2002\n
Note that the first "BR" is the HTML code for a line break, while the "$Br" at the end is the Aap variable that contains a line break (here displayed as "\n").
Finally, the :cat command concatenates the file "body.html", the output of the :print command and the file "footer.html". Thus the "-" stands for where the pipe input is used. The result is redirected to target, which is "manual.html".
The generated date in the previous example could be used elsewhere in the recipe. Since we don't want to repeat a complicated expression the result of the :eval command should be redirected to a variable, like this:
@import time
:eval time.strftime("%A %d %B %Y", time.localtime(time.time()))
| :assign Datestamp
manual.html: body.html footer.html
:print $(lt)BR$(gt)Last updated: $Datestamp$Br
| :cat body.html - footer.html >! $target
|
The :assign command takes the input from the pipe and puts it in the variable mentioned as its argument, which is "Datestamp" here. Actually, the same can be done with a normal assignment and a Python expression in backticks, but we intentionally wanted to show using a pipe here.
It is also possible to completely generate a file from scratch. Here is an example that generates a C header file:
1 :include config.aap 2 pathdef.c: config.aap 3 :print Creating $target 4 :print >! $target /* pathdef.c */ 5 :print >> $target /* This file is automatically created by main.aap */ 6 :print >> $target /* DO NOT EDIT! Change main.aap only. */ 7 :print >> $target $#include "vim.h" 8 :print >> $target char_u *default_vim_dir = (char_u *)"$VIMRCLOC"; 9 :print >> $target char_u *all_cflags = (char_u *)"$CC -c -I$srcdir $CFLAGS"; |
The first :print command displays a message, so that it's clear "pathdef.c" is being generated. The next line contains ">!" to overwrite an existing file. It doesn't matter if the file already existed or not, it now only contains the line "/* pathdef.c */". The third and following lines contain ">>". This will cause each line to be appended to "pathdef.c".
In the example the VIMRCLOC and srcdir variables are defined in the recipe "config.aap". That is why this file is used as a source in the dependency. Also note the use of "$#" in line 7. Since "#" normally starts a comment it cannot be used directly here. "$#" is a special item that results in a "#" in the :print output. This is the resulting file:
/* pathdef.c */
/* This file is automatically created by main.aap */
/* DO NOT EDIT! Change main.aap only. */
#include "vim.h"
char_u *default_vim_dir = (char_u *)"/usr/local/share/vim61";
char_u *all_cflags = (char_u *)"cc -c -I. -g -O2";
The list of ">>" redirections is quite verbose. Fortunately there is a shorter way:
1 :include config.aap 2 pathdef.c: config.aap 3 :print Creating $target 4 text << EOF 5 /* pathdef.c */ 6 /* This file is automatically created by main.aap */ 7 /* DO NOT EDIT! Change main.aap only. */ 8 $#include "vim.h" 9 char_u *default_vim_dir = (char_u *)"$VIMRCLOC"; 10 char_u *all_cflags = (char_u *)"$CC -c -I$srcdir $CFLAGS"; 11 EOF 12 :print $text >! $target |
In line 4 "text << EOF" is used. This is called a block assignment. The following lines, up to the matching "EOF" line, are assigned to the variable text. You can use something else than "EOF" if you want to. It must be a word that does not appear inside of the text as a line on its own. White space before and after the word is ignored.
The indent of the text in the block assignment is removed. The indent of the first line is used, the same amount of indent is removed from the following lines. Thus if the second line has two more spaces worth of indent than the first line, it will have an indent of two spaces in the result. Half a tab is replace with four spaces when necessary (a tab always counts for up to eight spaces).
When an application already exists but for your system it requires a few tweaks, a port recipe can do the work. This can also be used for applications that work fine but you want to apply a number of patches or to add a feature. The recipe can be distributed, so that others can install the application without knowing the details. This works very much like the FreeBSD ports system.
This chapter is specifically for doing the port. If you are only interested in another kind of building you might want to skip this chapter.
Since A-A-P is prepared for doing all the work, usually you only need to specify the relevant information, such as where to find the files involved. Here is an example:
1 # A-A-P port recipe for Vim 6.1 plus a few patches.
2 RECIPEVERSION = 1.0
3
4 PORTNAME = vim
5 LASTPATCH = 003
6 PORTVERSION = 6.1.$LASTPATCH
7 MAINTAINER = Bram@vim.org
8
9 CATEGORIES = editors
10 PORTCOMMENT = Vim - Vi IMproved, the text editor
11 PORTDESCR << EOF
12 This is the description for the Vim package.
13 A very nice editor, backwards compatible to Vi.
14 You can find all info on http://www.vim.org.
15 EOF
16
17 :recipe {fetch = http://www.a-a-p.org/ports/vim/main.aap}
18
19 WRKSRC = vim61
20 BUILDCMD = make
21 TESTCMD = make test
22 INSTALLCMD = make install DESTDIR=$PKGDIR
23 PREFIX = /usr/local
24
25 MASTER_SITES ?= ftp://ftp.vim.org/pub/vim
26 ftp://ftp.us.vim.org/pub/vim
27 PATCH_SITES = $*MASTER_SITES/patches
28
29 DISTFILES = unix/vim-6.1.tar.bz2
30
31 version1 = `range(1, int(LASTPATCH) + 1)`
32 PATCHFILES = 6.1.00$*version1
33
34 #>>> automatically inserted by "aap makesum" <<<
35 do-checksum:
36 :checksum $DISTDIR/vim-6.1.tar.bz2 {md5 = 7fd0f915adc7c0dab89772884268b030}
37 :checksum $PATCHDISTDIR/6.1.001 {md5 = 97bdbe371953b9d25f006f8b58b53532}
38 :checksum $PATCHDISTDIR/6.1.002 {md5 = f56455248658f019dcf3e2a56a470080}
39 :checksum $PATCHDISTDIR/6.1.003 {md5 = 0e000edba66562473a5f1e9b5b269bb8}
40 #>>> end <<<
|
Well, that is the longest example we have had so far. Let's go through it from top to bottom.
1 # A-A-P port recipe for Vim 6.1 plus a few patches. 2 RECIPEVERSION = 1.0 |
RECIPEVERSION tells Aap what version of Aap this recipe was written for. If in the future the recipe format changes, this line causes Aap to interpret it as Aap version 1.0 would do.
4 PORTNAME = vim |
Setting PORTNAME to the name of the port is what actually triggers Aap to read this recipe as a port recipe. It makes the other settings to be used to set up a whole range of targets and build commands. The result is that you can do aap install to install the application, for example. Note that PORTNAME does not include the version number.
5 LASTPATCH = 003 6 PORTVERSION = 6.1.$LASTPATCH 7 MAINTAINER = Bram@vim.org 8 9 CATEGORIES = editors 10 PORTCOMMENT = Vim - Vi IMproved, the text editor 11 PORTDESCR << EOF 12 This is the description for the Vim package. 13 A very nice editor, backwards compatible to Vi. 14 You can find all info on http://www.vim.org. 15 EOF |
In lines 5 to 15 a number of informative items about the port are specified. These are used in various places. LASTPATCH is not a standard item, it is used here to only have to define the patchlevel in one place.
17 :recipe {fetch = http://www.a-a-p.org/ports/vim/main.aap}
|
The :recipe command specifies where to obtain the recipe itself from. We have seen this before, nothing special here.
19 WRKSRC = vim61 20 BUILDCMD = make 21 TESTCMD = make test |
The assignments in lines 19 to 21 specify how building is to be done. WRKSRC is the directory below which the source files are unpacked. The default is "$PORTNAME-$PORTVERSION". The archive used for Vim uses "vim61" instead, thus this needs to be specified. The "CMD" variables set the commands to be used to build the application. The default is to use Aap. Since Vim uses "make" this needs to be specified.
22 INSTALLCMD = make install DESTDIR=$PKGDIR 23 PREFIX = /usr/local |
Installing a port is done by creating a binary package and installing that package. This makes it possible to copy the package to another system and install it there without the need to compile from sources. Lines 22 and 23 specify how to do a "fake install" with Vim. This copies all the files that are to be installed to a specific directory, so that it is easy to include them in the package. PREFIX specifies below which directory Vim installs its files.
25 MASTER_SITES ?= ftp://ftp.vim.org/pub/vim 26 ftp://ftp.us.vim.org/pub/vim 27 PATCH_SITES = $*MASTER_SITES/patches |
MASTER_SITES and PATCH_SITES specify the sites where the Vim files can be downloaded from. The first is for the archives, the second for the patches. Note the use of "$*" in line 27, this causes "/patches" to be appended to each item in MASTER_SITES instead of appending it once at the end of the whole list.
29 DISTFILES = unix/vim-6.1.tar.bz2 |
DISTFILES is set to the name of the archive to download. This is appended to items in MASTER_SITES to form the URL.
31 version1 = `range(1, int(LASTPATCH) + 1)` 32 PATCHFILES = 6.1.00$*version1 |
Lines 32 and 33 specify the list of patch file names. The Python function "range()" is used, this returns a list of numbers in the specified range (up to and excluding the upper number). Note the user of "int()" to turn the patch number in LASTPATCH into an int type, all Aap variables are strings.
for three patch files this could also have been typed, but when the number of patches grows this mechanism is easier. The example only works up to patch number 009. To make it work for numbers from 100 up to 999:
version1 = `range(1, 10)`
version2 = `range(10, 100)`
version3 = `range(100, int(LASTPATCH) + 1)`
PATCHFILES = 6.1.00$*version1 6.1.0$*version2 6.1.$*version3
|
34 #>>> automatically inserted by "aap makesum" <<<
35 do-checksum:
36 :checksum $DISTDIR/vim-6.1.tar.bz2 {md5 = 7fd0f915adc7c0dab89772884268b030}
37 :checksum $PATCHDISTDIR/6.1.001 {md5 = 97bdbe371953b9d25f006f8b58b53532}
38 :checksum $PATCHDISTDIR/6.1.002 {md5 = f56455248658f019dcf3e2a56a470080}
39 :checksum $PATCHDISTDIR/6.1.003 {md5 = 0e000edba66562473a5f1e9b5b269bb8}
40 #>>> end <<<
|
Finally the "do-checksum" target is defined. This part was not typed, but added to the recipe with aap makesum. This is done by the port recipe maintainer, when he has verified that the files are correct. When a user later uses the recipe Aap will check that the checksums match, so that problems with downloading or a cracked distribution file are found and reported.
The port recipe specifies which source files and patches to download, thus it has to be adjusted for each version. This is good for a stable release, but when you are releasing a new version every day it is a lot of work. Another method is possible when the files are available from a CVS server. Adding these lines to the recipe will do it:
CVSROOT ?= :pserver:anonymous@cvs.vim.sf.net:/cvsroot/vim
CVSMODULES = vim
CVSTAG = vim-6-1-$LASTPATCH
|
The first line specifies the cvsroot to use. This is specific for the cvs program. CVSMODULES is the name of the module to checkout. Mostly it is just one name, but you can specify several. Specifying CVSTAG is optional. If it is defined, like here, a specific version of the application is obtained. When it is omitted the latest version is obtained.
Much more about the port recipe can be found in Chapter 22, Porting an Application.
Table of Contents
Executing recipes is a two step process:
recipe processing
Read and parse the toplevel recipe, child recipes and included recipes. Commands at the recipe level are executed. Build commands (commands for dependencies, rules, actions, etc.) are stored.
target building
Build each of the specified targets, following dependencies. Build commands are executed.
Generally, one can say that in the first step the specification for the building is read and stored. In the second step the actual building is done.
In a simple recipe the first step is used to set variables and define dependencies. In the second step the dependencies are followed and their commands are executed to build the specified target.
:print executed during the first step
target1 : source1 source2
:print executed during the second step
|
An exception is when Aap was started to execute a command directly. The recipe processing step will still be done, but instead of building a target the specified command is executed. Example, using the recipe above:
% aap -c ':print $BDIR'
executed during the first step
build-FreeBSD4_5_RELEASE
%
A recipe used for building an application often has these parts:
You are free to use this structure or something else, of course. This is an explanation that you can use as a base. Many times you will be able to use this structure as a starting point and make small modifications where it is needed.
Now let us look into each part in more detail.
global settings, include recipes with project and/or user settings
When the recipe is part of a project, it's often useful to move settings (and rules) that apply to the whole project to one file. Then use the :include command in every recipe that can be used to build something.
User preferences (e.g. configuration choices) should be in a separate file that the user edits (using a template).
automatic configuration
Find out properties of the system and handle user preferences. This may result in building the application in a different way. See Chapter 24, Using Autoconf.
specify variants
Usually debug and release, but can include many more choices (type of GUI, small or big builds, etc.). This changes the value of BDIR. See Chapter 14, Variants.
build rules and actions
Rules that define dependencies and build commands that apply to several files, defined with :rule commands. Actions can be defined for what is not included in the default actions or to overrule the defaults actions to do a different way of building.
explicit dependencies
Dependencies and build commands that apply to specific files. Use these where the automatic dependency checking doesn't work and for exceptions.
high level build commands
:program, :dll, etc. can be used for standard programs, libraries, etc. This comes last, so that explicitly defined dependencies for building some of the items can be used.
For larger projects sections can be moved to other recipes. How you want to do this depends on whether these sub-recipes need to be executed by themselves and who is going to maintain each recipe. More about that below.
Since commands at the recipe level are executed in the first step, some building may already be done. Especially the :update command gives you a powerful mechanism. This means you can already build a target halfway the first step. Note that only dependencies that have already been encountered will be used then.
A good use for the :update command at the recipe level is to generate a recipe that you want to include. Useful for automatic configuration. You would do something like this:
config.aap : config.aap.in
:print executing the configuration script...
:sys ./conf.sh < $source > $target
:update config.aap
:include config.aap
|
First a dependency is specified with build commands for the included recipe. In this case the "config.aap.in" file is used as a template. The command :update config.aap invokes building "config.aap". If it is outdated (config.aap.in was changed since config.aap was last build) the build commands are executed. If "config.aap" is up-to-date nothing happens. Then the :include config.aap includes the up-to-date "config.aap" recipe.
In the second step commands of dependencies are executed. One of these commands may be :execute. This means another recipe is read and targets are build. These are again the first and second step mentioned before, but now nested inside the second step. Here is an example that executes a recipe when "docfile.html" is to be build:
docfile.html :
:execute docs/main.aap $target
|
This construction is useful when you do not want to read the other recipe in the first step. Either because it is a large recipe that is not always needed, because the recipe does not always exist, or because the recipe must first be build by other commands. Here is an example of using a depencency on a recipe:
docfile.html : docs/main.aap
:execute docs/main.aap $target
docs/main.aap: docs/main.aap.in
:cd docs
:sys ./conf.sh < main.aap.in > main.aap
|
The :execute command can also be used at the recipe level. This means another recipe is executed during the first step. A good example for this is building an application in different variants:
# build the GTK version
:execute main.aap Gui=GTK myprog
:move myprog myprog-GTK
# build the Motif version
:execute main.aap Gui=Motif myprog
:move myprog myprog-Motif
|
There are many ways to split up a project into multiple recipes. If you are building one application, you mostly build the whole application, using a toplevel recipe. This recipe specifies the configuration, specifies variants and sets variables for choices. Separate recipes are used to handle specific tasks. For example, you can move related sources to a sub-directory and put a recipe in that directory to build those sources. For this situation you use the :child command.
When a project gets bigger, and especially when working together with several people, you may want to be able to split the project up in smaller pieces, which each can be build separately. To avoid replicating commands, you should put the configuration, variants and setting variables in a separate recipe. Each recipe can use the :include command to use this recipe. You need to take care that the recipe is not included twice, because commands like :route give an error when repeated and appending to variables must only be done once. Aap will read a recipe only the first time it is included when you add the {once} argument to the :include command.
The two-step processing of recipes is part of all the work that Aap does. There are a few other steps. This is what happens when Aap is run:
Read the startup recipes, these define default rules and variables. These recipes are used:
| - default.aap from the distribution |
| - all recipes in system and user Aap directories (see below) |
Recipe processing: Read the recipe main.aap or the one specified with the "-f" argument and check for obvious errors. Then execute the toplevel items in the recipe. Dependencies and rules are stored. Also read included and child recipes and execute the toplevel items in them.
Apply the clever stuff to add missing dependencies and rules. This adds a "clean" rule only if the recipe didn't specify one, for example.
Target building. The first of the following that exists is used:
| - targets specified on the command line |
| - items specified with :program, :dll and :lib |
| - the "all" target |
If the "finally" target is specified, execute its build commands. Each recipe can have its own "finally" target, they are all executed.
The startup recipes are read from directories that depend on the system. For Unix systems files in two directories are used:
| - /usr/local/share/aap/startup/*.aap |
| - ~/.aap/startup/*.aap |
For other systems one directory is used, the first one that can be found from this list:
| - $HOME/aap/startup/*.aap |
| - $HOMEDRIVE/$HOMEPATH/aap/startup/*.aap |
| - c:/aap/startup/*.aap |
$HOME, $HOMEDRIVE and $HOMEPATH are environment variables, not Aap variables.
Variables with uppercase letters are generally used to pass choices and options to actions. For example, $CC is the name of the C compiler and $CFLAGS optional arguments for the C compiler. The list of predefined variables is in the reference manual here.
To avoid clashing with an existing or future variable that is defined by Aap, use one or more lower case letters or prepend "MY". Examples:
$n
$sources
$FooFlags
$MYPROG
|
Also be careful with chosing a name for a user scope, it must be different from all variables used in recipes! Prepending "s_" is recommended. Examples:
$s_debug.CFLAGS
$s_ovr.msg
|
Some characters in expressions have a special meaning. And a command like :print also handles a few arguments in a special way. This table gives an overview of which characters you need to watch out for when using the :print command:
Table 12.1. Special characters in the ":print" command
| :print argument | resulting character |
|---|---|
| $($) | $ |
| $(`) | ` (backtick) |
| $(#) | # |
| $(>) | > |
| $(<) | < |
| $(|) | | |
Example:
all:
:print tie $(#)2 $(`)green$(`) $(|) price: $($) 13 $(<) incl vat $(>)
|
Write this in the file "try.aap". Executing it results in:
% aap -f try.aap
tie #2 `green` | price: $ 13 < incl vat >
%
Aap parses the recipe into a sequence of lines. A line is a sequence of characters terminated by a newline. You can escape the newline with a backslash to continue a logical line over more than one physical line, as follows:
1 One line 2 A longer line \ 3 that continues \ 4 over three physical lines. |
You can always use backslash continuations to continue lines in Aap. Indentation does not matter.
In many constructions, Aap also supports Python-style line continuations, where a line is continued by increasing the indentation of subsequent physical lines. The above example would look different with Python-style continuation:
1 One line 2 A longer line 3 that continues 4 over three physical lines. |
As you can see, the "block" of lines with an increased amount of indentation is considered to belong to the line above it.
Python-style line continuations are supported in all Aap constructions except when the command cannot be recognized if the linebreak comes early. For example, in dependencies the colon separating the targets from the sources cannot be in a continuation line. This does not work:
myprog
: mysource
:print This Does Not Work!
|
It is also not possible to split a dependency by indent when it does not have build commands:
myprog :
mysource
this = Does Not Work
|
You must use a backslash in this situation:
myprog : \
mysource
this = OK
|
There are several methods to specify build commands to update a target:
A dependency
This is more or less the same as how this is used in a Makefile: One or more targets, a colon and any number of sources. This specifies that the target(s) depends on the source(s). When build commands are given these are the commands to build the target(s) from the source(s). Without build commands the dependency is only used to check if the target is outdated and needs to be build.
A rule
Specified with a :rule command. A "%" in the target(s) and source(s) stands for any string. This is used to specify a dependency that is to be used for files that match the pattern.
An action
Specified with a :action command. Unlike dependencies and rules an action does not specify a build dependency. It must be invoked by other build commands with the :do command.
Nearly all recipe commands can be used in the build commands. But these are not allowed, they can only be used at the recipe level:
| a dependency specification |
| :rule |
| :route |
| :totype |
| :clearrules |
| :delrule |
| :program |
| :dll |
| :lib |
| :recipe |
| :variant |
In short: all commands that define dependencies cannot be used in build commands. But don't forget you can use :execute to do just about anything.
The commands :program, :lib, :dll and :ltlib are called production commands because they explicitly state what things Aap should produce and what sources are involved. Everything the production commands can do, can be done by hand with dependencies as well, but the automation the production commands provide is quite useful. This section discusses how the production commands can be used and the variables that affect them.
The form of each of the production commands is :command targets : sources. It is unusual to have more than one target, since both targets would be built from the same sources, but it is allowed. The list of sources should list the actual, original sources, i.e. only files that are actually written by the programmer and that exist on disk. It is these sources that will be packaged together for distributing the program or library in source form.
Each production command transforms all of the sources into objects using compile actions. The sources are transformed into object files of a particular type — e.g. libraries use files with type "libobject". Once all of the sources have been compiled, a build action is invoked to turn the object files into the target. The table below lists the production commands and the actions used.
Some of the production commands can use different programs to produce the final product, depending on settings in the recipe. In particular, you may need to chose to link a program with the compiler or through libtool, depending on whether your program links to any libtool libraries or not. The alternatives are listed in the table below as well. To select an alternative form to build the final product, set the filetype of the target to a specific value, e.g.
:program myProgram { filetype=ltprogram } : source.c
|
This example uses the ltprogram alternative build command to build the program "myProgram."
| Command | Object Type | Build Command | Build Alternatives |
|---|---|---|---|
| :program | object | build |
|
| :lib | libobject | buildlib | (normal) Uses the ar utility to link all the objects into a static library. Uses $ARFLAGS. |
| :dll | dllobject | builddll | (normal) Uses the C compiler to link the objects into a dynamic (shared) library. The object files are different from regular library objects, and use a different extension. Uses $SHLINK, and $LDFLAGS, as well as $SHLINKFLAGS. |
| :ltlib | ltobject | buildltlib | (normal) Uses the libtool utility to link the objects together. Uses $LDFLAGS. |
In case you do want to have Aap figure out how to turn source files in to objects and then combine them into a target, but the target is not one of the types mentioned above, you can use the :produce command.
The production commands understand a wide variety of attributes. Let us return to the generic form of a production command:
:command targets : sources
|
There are four places attributes can be inserted in this command, as follows (we have split the command across several lines for clarity):
1 :command { command-attributes }
2 targets { per-target-attributes } :
3 { source-global-attributes }
4 sources { per-source-attributes }
|
There is one commonly-used command-attribute: installvar. The production commands add their targets to the variable named in this attribute. This defaults to the "normal" variable, as listed in Table 17.2. Assigning an empty value, through { installvar = }, prevents a target from being installed at all. This is useful for internal helper programs and libraries used during the build process.
![]() | Note |
|---|---|
| You should use { installvar = INSTALL_LTLIB } for program targets that have filetype ltprogram, since they need to be installed as if they are libtool libraries, not programs. | |
![]() | Warning |
|---|---|
| It is a bad idea (excepting ltprograms, which belong in INSTALL_LTLIB) to add targets to the wrong install variable, since the install action that gets called for it will be wrong then as well. | |
A slightly less-used command-attribute is objecttype, which changes the object file type from the default, (dllobject, for instance, for shared libraries), to something else. For programs that need to be linked by libtool, you may also want to force the object files used in the program to be compiled with libtool, since mixing non-libtool objects and libtool libraries can cause problems. For this, use the { objecttype = ltobject } as well, so that libtool programs will usually have build commands like:
:program { filetype = ltprogram } { objecttype = ltobject } ...
|
The attributes assigned in the per-target-attributes are used in the build and install actions of the target. Typical attributes assigned here are installdir and keepdir. Variables that affect the build step can be assigned too, such as var_LIBS and var_LDFLAGS.
The attributes for sources are used for the compile steps of the build process, and useful attributes here are var_INCLUDE (if one source file needs special include files) and filetype. The attributes in the source-global-attributes position apply to all the sources in the list, and per-source-attributes apply only to the source file immediately preceding the attribute.
An example that uses all of these settings is:
1 :ltlib { installvar = } conduit_knotes.la
2 { add_LIBS = -lkdeui } :
3 { add_INCLUDE = -I$BDIR/knotes }
4 knotes/KNotesIface.h { filetype=stub } { var_LTOBJSUF=_stub.lo }
5 knotes/knotes-factory.cc
|
Here we see a libtool library that is not installed (line 1), which must be linked with an additional library (line 2). All of the sources are compiled with an extra include directory (line 3). The first source file (line 4) has additional complications and uses a different compile action due to its filetype. The last source file (line 5) is compiled with normal flags extended only by the source-global-attribute on line 3.
When a target is to be build Aap first searches for an explicit dependency with build commands that produces the target. This dependency may come from a high level build command such as :program. When such a dependency is not found then the rules defined with :rule are checked:
All the matching rules without commands are used, but only if the source already exists. Thus this cannot be used to depend on a file that is still to be created.
One rule with commands will be selected, in this order of preference:
| A rule for which the sources exist. |
| A rule for which one of the sources does not exist and was not defined with the {sourceexists} option. |
If there are multiple matches, the rule with the longest pattern is used. Thus if you have these two rules:
:rule test/%.html : test/%.in
:do something
:rule %.html : %.in
:do something-else
|
The first one will be used for a file "test/foo.html", the second one for a file "./foo.html". If there are two with an equally long pattern, this is an error.
TRICK: When the source and target in a rule are equal, it is skipped. This avoids that a rule like this becomes cyclic:
:rule %.jpg : path/%.jpg
:copy $source $target
|
Sometimes it is useful to execute commands when a target does NOT require updating. For example, to give a message. And sometimes commands need to be executed no matter if the target is outdated. For example to add an attribute to the target.
You can add sections to build commands of rules and dependencies. Three kinds of sections are possible:
| >always - always executed. |
| >build - executed when building the target. |
| >nobuild - executed when NOT building the target. |
The sections can be used in arbitrary order and may appear multiple times. All section headers must have the same amount of indent. The commands in the sections must have more indent than the section headers.
Example:
foo.out : foo.in
>always
# Always attach an attribute to the target
:attr {output = yes} $target
>build
# Only when $target requires updating
:copy $source $target
>nobuild
# Only when $target does not require updating
:print $target is up-to-date
|
When a dependency with build commands has more than one target, this means that the build commands will produce all these targets. This makes it possible to specify build commands that produce several files at the same time. Here is an example that compiles a file and at the same time produces a documentation file:
foo.o foo.html : foo.src
:sys srcit $source -o $(target[0]) --html $(target[1])
|
People used to "make" must be careful, they might expect the build commands to be executed once for each target. Aap doesn't work that way, because the above example would be impossible. To run commands on each target this must be explicitly specified. Example:
dir1 dir2 dir3 :
@for item in target_list:
:mkdir $item
|
The variable "target_list" is a Python list of the target items. Another such variable is "source_list", it is the list of source files (this excludes virtual items; "depend_list" also has the virtual items). An extreme example of executing build commands for each combination of sources and targets:
$OutputFiles : $InputFiles
@for trg in target_list:
:print start of file >! $trg
@for src in source_list:
:sys foofilter -D$trg $src >> $trg
|
When multiple targets are used and there are no build commands, this works as if each target depends on the list of sources. Thus this dependency:
t1 t2 : s1 s2 s3
|
Is equivalent to:
t1 : s1 s2 s3
t2 : s1 s2 s3
|
Thus when t1 is outdated to s1, s2 or s3, this has no consequence for t2.
When a source file includes other files, the targets that depend on the source file also depend on the included files. Thus when "foo.c" includes "foo.h" and "foo.h" is changed, the build commands to produce "foo.o" from "foo.c" must be executed, even though "foo.c" itself didn't change.
Aap detects these implied dependencies automatically for the types it knows about. Currently that is C and C++. Either by using gcc or a Python function the "#include" statements are found in the source code and turned into a dependency without build commands.
This works recursively. Thus when "foo.c" includes "foo.h" and "foo.h" includes "common.h", the dependency will look like this:
foo.c : foo.h common.h
|
For other types of files than C and C++ you can add your own dependency checker. For example, this is how to define a checker for the "tt" filetype:
:action depend tt
:sys tt_checker $source > $target
|
The "tt_checker" command reads the file "$source" and writes a dependency line in the file "$target". This is a dependency like it is used in a recipe. In a Makefile this has the same syntax, thus tools that produce dependencies for "make" will work. Here is an example:
foo.o : foo.tt foo.hh include/common.hh |
This is interpreted as a dependency on "foo.hh" and "include/common.hh". Note that "foo.o" and "foo.tt" are ignored. Tools designed for "make" produce these but they are irrelevant for Aap.
Since the build commands for ":action depend" are ordinary build commands, you can use Python commands, system commands or a mix of both to do the dependency checking.
More about customizing dependency checking in Chapter 29, Customizing Automatic Depedencies.
Most variables like $CFLAGS and $BDIR are used for all source files. Sometimes it is useful to use a different value for a group of files. This is done with an attribute that starts with "var_". What follows is the name of the variable to be overruled. Thus attribute "var_XYZ" overrules variable "XYZ".
The overruling is done for:
| dependencies |
| rules |
| actions |
The attributes of all the sources are used. In case the same attribute is used twice, the last one wins.
Another method is to use an "add_" attribute. This works like "var_", but instead of overruling the variable value it is appended. This is useful for variables that are a list of items, such as $DEFINE. Example:
:attr thefile.c {add_DEFINE = -DEXTRA=yes}
|
The value of the attribute is only appended when it does not appear yet, to avoid adding it two or more times.
Another method is to define a scope name. This scope is then used to find variables before searching other scopes, but after using the local scope. For example, to specify that the "s_opt" scope is to be used when compiling "filter.c":
OPTIMIZE = 0
DEBUG = yes
:program myprog : main.c filter.c version.c
:attr {scope = s_opt} filter.c
s_opt.OPTIMIZE = 4
s_opt.DEBUG = no
|
Note that you can set the values of the variables in the user scope after adding the scope attribute to "filter.c".
A virtual target is a target that is not an actual file. A Virtual target is used to trigger build commands without creating a file with the name of the target. Common virtual targets are "clean", "all", "publish", etc.
When a target is virtual it is always built. Aap does not remember if it was already done a previous time. However, it is only build once for an invocation of Aap. Example:
clean:
:del {r}{f} temp/*
|
To remember the signatures for a virtual target use the "remember" attribute:
version {virtual}{remember} : version.txt.in
:print $Version | :cat - $source >! version.txt
|
Now "aap version" will only execute the :print command if version.txt.in has changed since the last time this was done.
Using {remember} for one of the known virtual targets (e.g., "all" or "fetch") is unusual, except for "publish".
When using {remember} for a virtual target without a dependency, it will only be built once. This can be used to remember the date of the first invocation.
all: firsttime
firsttime {virtual}{remember}:
:print First build on $DATESTR > firstbuild.txt
|
The difference with a direct dependency on "firstbuild.txt" is that when this file is deleted, it won't be built again.
The sources for a dependency are searched for in the directories specified with $SRCPATH. The default is ". $BDIR", which means that the sources are searched for in the current directory and in the build directory. The current directory usually is the directory in which the recipe is located, but a :cd command may change this.
The "srcpath" attribute overrules using $SRCPATH for an item. Example:
:attr bar.c {srcpath = ~/src/lib}
|
To avoid using $SRCPATH for a source, so that it is only found in the current directory, make the "srcpath" attribute empty:
foo.o : src/foo.c {srcpath=}
|
When setting $SRCPATH to include the value of other variables, you may want to use "$=", so that the value of the variable is not expanded right away but when $SRCPATH is used. This is especially important when appending to $SRCPATH before a :variant command, since it changes $BDIR. Example:
SRCPATH $+= include
|
Warning: Using the search path means that the first encountered file will be used. When old files are lying around the wrong file may be picked up. Use the full path to avoid this.
When a target depends on the existence of a directory, it can be specified this way:
foodir/foo : foodir {directory}
:print >$target this is foo
|
The directory will be created if it doesn't exist. The normal mode will be used (0777 with umask applied). When a different mode is required specify it with an octal value: {directory = 0700}. The number must start with a zero.
A special kind of signature is used to check if the build commands have changed. An example:
foo.o : {buildcheck = $CFLAGS} foo.c
:sys $CC $CFLAGS -c $source -o $target
|
This defines a check for the value of $CFLAGS. When this value changes, the target is considered outdated. When something else in the build command changes, e.g., $CC, this does not cause the target to become outdated.
The default buildcheck is made from the build commands themselves. This is with variables expanded before the commands have been executed. Thus when one of the commands is ":sys $CC $CFLAGS $source" and $CC or $CFLAGS changes, the buildcheck signature changes. The :do commands are also expanded into the commands for the action specified. However, this only works when the action and filetype can be estimated. The action must be specified plain, not with a variable, and the filetype used is the first of:
a filetype attribute specified after action
if the first argument doesn't contain a "$", the filetype of this argument
the filetype of the first source argument of the dependency.
To add something to the default check for the build commands the $commands variable can be used. Example:
Version = 1.4
foo.txt : {buildcheck = $commands $Version}
:del {force} $target
:print >$target this is $target
:print >>$target version number: $Version
|
If you now change the value of $Version, change one of the :print commands or add one, "foo.txt" will be rebuilt.
To simplify this, $xcommands can be used to check the build commands after expanding variables, thus you don't need to specify $Version:
foo.txt : {buildcheck = $xcommands}
|
However, this only works when all $VAR in the commands can be expanded and variables used in Python commands are not expanded.
To avoid checking the build commands, use an empty buildcheck. This is useful when you only want the target to exist and don't care about the command used to create it:
objects : {buildcheck = }
:print "empty" > objects
|
Sometimes you might change the build commands in a recipe, which would normally mean the target should be updated, but you are sure that this isn't necessary and want to avoid executing the build commands. You can tell Aap to ignore the buildcheck once with the --contents option.
You might first want to read the tutorial for a few examples of using variants.
Here is an example how build variants can be specified. This will be used to explain how it works.
:variant Opt
some
OPTIMIZE = 2
much
OPTIMIZE = 6
*
OPTIMIZE = 1
|
"Opt" is the name of a variable. It is used to select one of the variants. Each possible value is listed in the following line and further lines with the same indent. In the example these are "some" and "much". "*" is used to accept any value, it must be the last one. The first value mentioned is the default when the variable isn't set.
You can now start Aap with various arguments to specify the kind of optimizing you want to use:
aap Opt=some will set OPTIMIZE to 2
aap Opt=much will set OPTIMIZE to 6
aap Opt=other will set OPTIMIZE to 1
aap will set OPTIMIZE to 2
Note that when "Opt" is not given a value the first entry is used, resulting in OPTIMIZE being set to 2. But when it is set to a value that isn't mentioned the last entry "*" is used.
The $BDIR variable will be adjusted for the variant used. CAREFUL: this means that using $BDIR before :variant commands will use a different value, that might not always be what you want.
Inside the :variant command the value of $BDIR has already been adjusted.
When a target that is being build starts with $BDIR and $BDIR doesn't exist, it is created. (Actually, this happens when an item in the path is "build" or starts with "build-".
$BDIR is relative to the recipe. When using ":child dir/main.aap" the child recipe will use a different build directory dir/$BDIR. Note that when building the same source file twice from recipes that are in different directories, you will get two results. Best is to always build a target from the same recipe (that makes it easier to understand the recipe anyway).
This continues the last example of the tutorial.
We happen to know that the main.c file does not depend on the GUI used. With the recipe above it will nevertheless be compiled again for every GUI version. Although this is a small thing in this example, in a bigger project it becomes more important to skip compilation when it is not needed. Here is the modified recipe:
1 Source = main.c version.c gui.c
2
3 :variant Build
4 release
5 OPTIMIZE = 4
6 Target = myprog
7 debug
8 DEBUG = yes
9 Target = myprogd
10
11 :attr {var_DEFINE = $DEFINE} {var_BDIR = $BDIR} main.c
12
13 Gui ?= motif
14 :variant Gui
15 console
16 motif
17 Source += motif.c
18 gtk
19 Source += gtk.c
20
21 DEFINE += -DGUI=$Gui
22
23 :program $Target : $Source
|
The only new line is line 11. The "main.c" file is given two extra attributes: var_DEFINE and var_BDIR. What happens is that when "main.c" is being build, Aap will check for attributes of this source file that start with "var_". The values will be used to set variables with the following name to the value of the attribute. Thus DEFINE gets the value of var_DEFINE. This means that the variable is overruled by the attribute while building "main.c".
The var_BDIR attribute is set to "$BDIR" before the second :variant command. It does not yet have the selected GUI appended there. The list of directories used is now:
| directory | contains files |
|---|---|
| build-SYS-release | main |
| build-SYS-debug | main |
| build-SYS-release-console | version, gui |
| build-SYS-debug-console | version, gui |
| build-SYS-release-motif | version, gui, motif |
| build-SYS-debug-motif | version, gui, motif |
| build-SYS-release-gtk | version, gui, gtk |
| build-SYS-debug-gtk | version, gui, gtk |
If you want to build all the variants that are possible, use a few lines of Python code. Here is an example:
1 :variant license 2 trial 3 DEFINE += -DTRIAL 4 demo 5 DEFINE += -DDEMO 6 full 7 DEFINE += -DFULL 8 9 :variant language 10 chinese 11 DEFINE += -DCHINESE 12 bulgarian 13 DEFINE += -DBULGARIAN 14 * 15 DEFINE += -DENGLISH 16 17 build: 18 :print Building with $license license for language $language. 19 :print DEFINE=$DEFINE 10 21 all: 22 @for a in ['trial', 'demo', 'full']: #license 23 @ for c in ['chinese', 'bulgarian', 'english']: #language 24 :execute main.aap build license=$a language=$c |
Invoking Aap without arguments builds the "all" target, which loops over all possible variants and invokes the :execute command with the "build" target. The reason to use the "build" target is that without it the "all" target would be built again and result in an endless loop.
This is the resulting output:
Building with trial license for language chinese.
DEFINE=-DTRIAL -DCHINESE
Building with trial license for language bulgarian.
DEFINE=-DTRIAL -DBULGARIAN
Building with trial license for language english.
DEFINE=-DTRIAL -DENGLISH
Building with demo license for language chinese.
DEFINE=-DDEMO -DCHINESE
Building with demo license for language bulgarian.
DEFINE=-DDEMO -DBULGARIAN
Building with demo license for language english.
DEFINE=-DDEMO -DENGLISH
Building with full license for language chinese.
DEFINE=-DFULL -DCHINESE
Building with full license for language bulgarian.
DEFINE=-DFULL -DBULGARIAN
Building with full license for language english.
DEFINE=-DFULL -DENGLISH
Publishing means distributing the files of your project. This is a generic mechanism. You can use it to maintain a web site or to release a new version of your application.
The most straightforward way to publish a file is with the :publish command:
:attr {publish = ftp://ftp.my.org/upload/%file%} myfile
:publish myfile
|
This uses the "publish" attribute on each of the files. When the "publish" attribute is missing the "commit" attribute is used. If both are missing this is an error.
When a file didn't change since the last time it was published, it won't be published again. This works with signatures, like building a target. The remote file is the target in this case. But Aap won't read the remote file to compute the signature, it will remember the signature from when the file was last uploaded (otherwise checking for outdated files would be slow).
In the example %file% is used. This is replaced with the name of the file being published, including the directory. This means you can use the same attribute for several files:
Files = myfile yourfile hisfile
:attr {publish = ftp://ftp.my.org/upload/%file%} $Files
:publish $Files
|
Including the directory is sometimes not what you want. To only use the last part of the path use %basename%.
Files = one/myfile two/yourfile three/hisfile
:attr {publish = ftp://ftp.my.org/common/%basename%} $Files
:publish $Files
|
The three files will be uploaded to the "common" directory. The directory names "one", "two" and "three" will not be used on the ftp server.
To publish all files with a "publish" attribute start Aap like this:
aap publish
If the "publish' target is defined explicitly it will be executed. Otherwise, all files with the "publish" attribute are given to the :publish command, just like using the :publishall command.
The "publish" attribute may consist of several items. Publishing will use all these items. This means a file can be distributed to several sites at once. This is unlike fetching, which stops as soon as the file could be obtained from one of the items.
When publishing fails for one of the sites, e.g., because the server is down, this is remembered. When you publish again, uploading is done only for that site. The destinations for which pusblishing worked will be skipped then.
Uploading files requires write access to the server. There are several methods for this, but some have the disadvantage that your password is sent as normal text over the internet. Or someone in between can change the files that you send out. There is one that provides sufficient security: scp or secure copy.
To publish a file to a server through secure copy use a URL in this form:
:publish file {publish = scp://myname@the.server.com/dir/%file%}
|
"myname" is your login name on the server "the.server.com". The "file" will be written there as "dir/file", relative to your login directory.
This requires the "scp" command, which is not a standard item. If it does not appear to exist then Aap will offer you to install it for you. If the automatic mechanism fails you will have to install it yourself. You might also want to do this if you have specific preferences for how the scp command is to be installed (versions of scp exist with different kinds of encryption).
To avoid having to type a password each time you need to use public keys. For MS-Windows you can find information here:
This is for the PuTTY version of scp, which is what Aap installs for you if you let it. For Unix try man ssh-keygen. Use "SSH protocol version 2" if possible.
You can specify the command to be executed with the $SCP variable, see the reference manual. Example:
SCP = scp -i c:/private/keyfile
|
Using "rsync" has an advantage if you have files with only a few changes. The rsync program will only transfer the differences. This adds a bit of overhead to find out what changed, thus it's a bit slower when copying whole files.
Aap uses the same secure channel as with "scp" by default. This can be changed with the $RSYNC variable, see the reference manual.
If your server does not support "scp", you might want to use "rcp". However, this is insecure, information is transferred unencoded over the internet and making a connection is not secure. Only use this when "scp" is not possible.
Using "rcp" means changing the "scp://" part of the URL to "rcp://". The $RCP variable holds the name of the command, see the reference manual.
You can also use "ftp". Some web servers require this, even though ftp sends your password as plain text over the internet, thus it is insecure. Aap uses the Python ftp library, thus an external command is not needed and there is no variable to specify the command.
When you switch to another server you need to change the "publish" attribute. The next time you invoke Aap for publishing it will automatically upload all the files to the new server.
If you didn't actually change to another server, but the URL used for the server changed, invoke Aap once with the "--contents" argument:
aap publish --contents
This will cause only files that changed to be published. It avoids that all the files with a changed "publish" attribute are published again. It will still upload files that you changed since the last upload and newly added files. But be careful: files that you once uploaded, deleted from the list of files and now added will NOT be uploaded!
When publishing a new version of an application, you might want to include a number of generated files. This reduces the number of tools someone needs to use when installing the application. For example, the "configure" script that "autoconf" produces from "configure.in" can be included.
To avoid these generated results to be generated again when the user runs aap, explicitly specify a signature file to be used and distribute this signature file together with the generated files. For example, suppose you have a directory with these files you created:
main.aap
prog.c
Additionally there is the file "version.c" that is generated by the "main.aap" recipe. It contains the date of last modification. To avoid it being generated again, include the "mysign" file in the distribution. The files to be distributed are:
mysign
main.aap
prog.c
version.c
In the "main.aap" recipe the "signfile" attribute is used for the dependency that generates version.c:
version.c {signfile = mysign} : prog.c
:print char *timestamp = "$TIMESTR"; >! $target
|
The result is that "version.c" will only be generated when "prog.c" has changed. When the "signfile" attribute would not have been used, "version.c" would have been generated after unpacking the distributed files.
The "finally" target is always executed after the other targets have been successfully built. Here is an example that uses the "finally" target to copy all files that need to be uploaded with one command.
Source = *.html
all: remote/$*Source {virtual} {remember}
CFile =
:rule remote/% : %
_recipe.CFile += $source
finally:
@if _recipe.CFile:
:copy $_recipe.CFile ftp://my.org/www
|
Warning: When the :copy command fails, aap doesn't know the targets were not made properly and won't do it again next time. Using the "publish" attribute works better.
When publishing HTML files you most likely also want to publish the image files referenced by them. You can use a wildcard to select the images files, but this may include images that are not actually used. You can explicitly specify the images, but if you miss one your locally tested web site won't work properly on the server.
A good solution is to parse the HTML files and figure out what images are used in them. However, only image files that can be found locally should be included, not ones that are on other web sites. The get_html_images() function can be used for this, as shown in an example:
Files = index.html
contact.html
forward.html
Files += `get_html_images(Files)`
:attr {publish = scp://user@ftp.foo.org/public_html/%file%} $Files
all: publish
|
Note that this still isn't perfect. Only images in plain "IMG" tags will be found and only when they use a relative path name. Thus images from Javascript or PHP code will not be included.
A convention about using the "update" and "fetch" targets makes it easy for users to know how to use a recipe. The main recipe for a project should be able to be used in three ways:
Without specifying a target.
This should build the program in the usual way. Files with a "fetch" attribute are obtained when they are missing.
With the "fetch" target.
This should obtain the latest version of all the files for the program, without building the program.
With the "update" target.
This should fetch all the files for the program and then build it. It's like the previous two ways combined.
Here is an example of a recipe that works this way:
Status = status.txt
Source = main.c version.c
Header = common.h
Target = myprog
$Target : $Source $Status
:cat $Status
:do build $source
# specify where to fetch the files from
:attr {fetch = cvs://:pserver:anonymous@cvs.myproject.sf.net:/cvsroot/myproject} $Source $Header
:attr {fetch = ftp://ftp.myproject.org/pub/%file%} $Status
|
Note that the header file "common.h" is given a "fetch" attribute, but it is not specified in the dependency. The automatic dependency checking will notice the file is used and fetch it when it's missing.
When using files that include a version number in the file name, fetching isn't needed, since these files will never change. To reduce the overhead caused by checking for changes, give these files a "constant" attribute (with a non-empty non-zero value). Example:
PATCH = patches/fix-1.034.diff {fetch = $FTPDIR} {constant}
|
To fetch all files that have a "fetch" attribute start Aap with this command:
aap fetch
When the "fetch" target is not specified in the recipe or its children, it is automatically generated. Its build commands will fetch all nodes with the "fetch" attribute, except ones with a "constant" attribute set (non-empty non-zero). To do the same manually:
fetch:
:fetch $Source $Header $Status
|
Or use the :fetchall command.
NOTE: When any child recipe defines a "fetch" target no automatic fetching is done for any of the recipes. This may not be what you expect.
When there is no "update" target it is automatically generated. It will invoke the "fetch" target and the default target(s) of the recipe. To do something similar manually:
update: fetch $Target
|
The "fetch" attribute is used to specify a list of locations where the file can be fetched from. The word at the start defines the method used to fetch the file:
| ftp | from ftp server |
| http | from http (www) server |
| scp | secure copy |
| rcp | remote copy (aka insecure copy) |
| rsync | remote sync |
| file | local file system |
| cvs | from CVS repository For a module that was already checked out the part after "cvs://" may be empty, CVS will then use the same server (CVSROOT) as when the checkout was done. |
| other | user defined |
These kinds of locations can be used:
ftp://ftp.server.name//full/path/file
ftp://ftp.server.name/relative/path/file
http://www.server.name/path/file
scp://host.name/path:path/file
rcp://host.name/path:path/file
rsync://host.name/path:path/file
cvs://:METHOD:[[USER][:PASSWORD]@]HOSTNAME[:[PORT]]/path/to/repository
file:~user/dir/file
file:///etc/fstab
For a local file there are two possibilities: using "file://" or "file:". They both have the same meaning. "file:" is preferred, because the double slash is usually used before a machine name: "method://machine/path". A file is always local, thus leaving out "//machine" is the logical thing to do.
Note that for an absolute path, relative to the root of the file system, you use either one or three slashes, but not two. Thus "file:/etc/fstab" and "file:///etc/fstab" are the file "/etc/fstab". A relative path has two or no slashes, but keep in mind that moving the recipe will make it invalid. You can also use "file:~/file" or "file://~/file" for a file in your own home directory, and "file:~jan/file" or "file://~jan/file" for a file in the home directory of user "jan".
In the "fetch" attribute the string "%file%" can be used where the path of the local target is to be inserted. This is useful when several files have a common directory. Similarly "%basename%" can be used when the last item in the path is to be used. This removes the path from the local file name, thus can be used when the remote directory is called differently and only the file name is the same. Examples:
:attr {fetch = ftp://ftp.foo.org/pub/foo/%file%} src/include/bar.h
|
Gets the file "src/include/bar.h" from "ftp://ftp.foo.org/pub/foo/src/include/bar.h".
:attr {fetch = ftp://ftp.foo.org/pub/foo/src-2.0/include/%basename%}
src/include/bar.h
|
Gets the file "src/include/bar.h" from "ftp://ftp.foo.org/pub/foo/src-2.0/include/bar.h".
To add a new fetch method, define a Python function with the name "fetch_method", where "method" is the word at the start. The function will be called with four arguments:
| dict | a dictionary with references to all variable scopes (for expert users only) |
| machine | the machine name from the url: what comes after the "scheme://" upto the first slash |
| path | the path from the url: what comes after the slash after "machine" |
| fname | the name of the file where to write the result |
The function should return a non-zero number for success, zero for failure. Or raise an IOError exception with a meaningful error. Here is an example:
:python
def fetch_foo(dict, machine, path, fname):
from foolib import foo_the_file, FooError
try:
foo_the_file(machine, path, fname)
except FooError, e:
raise IOError, 'fetch_foo() failed: %s' % str(e)
return 1
|
Note that a version control function overrules a fetch function. Thus if "foo_command()" is defined "fetch_foo" will not be called.
Remote files are downloaded when used. This can take quite a bit of time. Therefore downloaded files are cached and only downloaded again when outdated.
The cache can be spread over several directories. The list is specified with the $CACHE variable.
NOTE: Using a global, writable directory makes it possible to share the cache with other users, but only do this when you trust everybody who can login to the system! Someone who wants to do harm or make a practical joke could put a bogus file in the cache.
A cached file becomes outdated as specified with the "cache_update" attribute or the $CACHEUPDATE variable. The value is a number and a name. Possible values for the name:
| day | number specifies days |
| hour | number specifies hours |
| min | number specifies minutes |
| sec | number specifies seconds |
The default is "12 hour".
When a file becomes outdated, its timestamp is obtained. When it differs from when the file was last downloaded, the file is downloaded again. When the file changes but doesn't get a new timestamp this will not be noticed.
When fetching files the cached files are not used (but may be updated).
This section contains details about the installation of the produced programs and other items. Those other items can be libraries (produced by the :lib, :dll, or :ltlib commands), header files for the API of a library, documentation (like manpages or info files), and as a catch-all, "data."
Usually installing is done with aap install. If you do not define an "install" target in the recipe, Aap will add one for you. The default install target invokes up to 15 other install targets, one for each kind of item you can install. This makes it easy to customize the installation of some particular kind of item (e.g. libtool archives).
The default install target invokes two or three other targets: install-platform, install-shared, and (optionally, only if you define it in the recipe) install-local. Each of these invokes other install targets for specific kinds of files, as follows:
Table 17.1. Install targets
| High-level Target | Lower-level Targets | Install these Files |
|---|---|---|
| install-platform | This is for installing platform-dependent files. | |
| install-exec | Install programs (generally produced through :program command). | |
| install-sbin | Install programs for system administration. These may have additional security considerations, hence a separate target. | |
| install-lib | Install static libraries (from the :lib command). | |
| install-dll | Install shared libraries (from the :dll command). | |
| install-ltlib | Install shared libtool libraries (from the :ltlib command). These require special treatment by the libtool program, hence a separate target. | |
| install-conf | Install platform-specific configuration files (such as pkg-config files). | |
| install-platform-local | A catch-all for things that don't fit anywhere else. | |
| install-shared | This is for installing files shared between platforms. | |
| install-data | Install data for the package. This would typically include translation files, examples (if they're not in the manpage), and images used by the package. | |
| install-man | Install manpages. | |
| install-info | Install GNU-style info pages. | |
| install-include | Installs header files (also known as includes). | |
| install-shared-local | A catch-all for things that don't fit anywhere else. | |
| install-local | this is an optional target that you can define for extra installing, without changing the other install targets. |
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not everything that works locally will work remotely. |
| $PREFIX | Default is "/usr/local/" on Unix. This specifies where to install to. The installed program is aware of being installed here, $PREFIX may be put in configuration files. |
The variables are concatenated. For example, programs are installed in $DESTDIR$PREFIX$EXECDIR. Slashes are added in between where needed.
The directories that are used are automatically created when needed. Note that "uninstall" does not delete the directories!
When installing the path to a file is normally removed. Thus when you produced a program "results/myprog" it will be installed as "myprog". If you need to keep the path use the "keepdir" attribute on the file name.
INSTALL_INCLUDE += sys/myheader.h {keepdir}
|
As an alternative to {keepdir}, there is the {installdir} attribute, which explicitly sets the relative path of the file to be installed. Files with an {installdir} attribute are installed in $DESTDIR$PREFIX$targetDIR$installdir. The above setting could also be done as:
INSTALL_INCLUDE += sys/myheader.h {installdir=sys}
|
The advantage of {installdir} over {keepdir} is that the relative paths (from toplevel recipe to file and from install directory to the desired install location) need not be the same. For instance:
INSTALL_INCLUDE += api/2.2/c/myheader.h {installdir=sys}
|
The above mentioned mode variable is used to set the mode bits of the file after installing. If this is not wanted, use the {keepmode} attribute. Example:
INSTALL_DATA += myscript.sh {keepmode}
|
To use another mode for a specific file add the {mode = 0555} attribute:
INSTALL_DATA += myscript.sh {mode = 0750}
|
Installing to a remote machine should work, although setting the file mode may not always work properly, depending on the transfer method used.
Keep in mind that installation is done from the top directory. In a child recipe that is located in another directory you need to specify the path to the file to install relative to the top directory. Using the $TOPDIR variable and rc-style expansion should work. Example:
# Filenames relative to the child directory
child_INSTALL_DATA = myscript.sh myicon.png
# Now add those filenames, relative to the top
INSTALL_DATA += $TOPDIR/$*child_INSTALL_DATA
|
If you hard code the paths from the parent to the files to install, say by writing INSTALL_DATA += child/myscript.sh, then you cannot execute the child recipe by itself (as if it were a toplevel recipe), since the paths will be wrong. Using $TOPDIR, or equivalently the topdir function, is the safe way to do so.
"aap uninstall" deletes the file that "aap install" has installed. All the targets and actions have the same name with "install" replaced with "uninstall". The same variables are used.
Files that do not exist are silently skipped. Files that do exist but cannot be deleted will cause a warning message.
Sometimes your recipe offers installing optional files. You probably want to uninstall those optional files as well, without requiring the user the specify the same options again. For this you can set the $UNINSTALL_* variables. For example, if you install either the "foo" or "bar" program:
:variant What
foo
Target = foo
UNINSTALL_EXEC = bar$EXESUF
bar
Target = bar
UNINSTALL_EXEC = foo$EXESUF
:program $Target : $Sources
|
When you need to install in other directories than the ones Aap provides there are several alternatives. First of all, you could use $INSTALL_DATA and set $DATADIR to the installation directory. This works if you are otherwise not using $INSTALL_DATA.
If you have several different directories you could use this scheme:
INSTALL_ITEM1 = file1.txt file2.txt
INSTALL_DIR1 = somewhere
INSTALL_ITEM2 = file3.txt file4.txt
INSTALL_DIR2 = elsewhere
install-local:
@install_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1, '0644')
@install_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2, '0644')
uninstall-local:
@uninstall_files(_no.INSTALL_DIR1, _no.INSTALL_ITEM1)
@uninstall_files(_no.INSTALL_DIR2, _no.INSTALL_ITEM2)
|
In the Python reference chapter you can find explanations for install_files() and uninstall_files()
You could also add a command to set the protection flags of the installed files: :chmod $INSTALL_DIR1/$*INSTALL_ITEM1.
This is about using Aap with a Version Control System (VCS)
The generic form of version control commands is:
:command file ...
|
Or:
:command {attr = val} ... file ...
|
The commands use the "commit" attribute of a file to obtain the kind of version control system and its location. For example:
:attr foo.c {commit = cvs://:ext:$CVSUSER_AAP@cvs.a-a-p.sf.net:/cvsroot/a-a-p}
|
For CVS it is also possible to only specify the method. CVS will then use the same specification for the repository as used when checking the files out.
:attr foo.c {commit = cvs://}
|
These commands can be used:
| :commit | Update each file in the repository. Add it when needed. |
| :checkout | Like fetch and additionally lock for editing when possible. |
| :checkin | Like commit, but unlock file. |
| :unlock | Remove lock on file, don't change file in repository or locally. |
| :add | Add file to repository. File must exist locally. Implies a "commit" of the file. |
| :remove | Remove file from repository. File may exist locally. Implies a "commit" of the file. |
| :tag | Add a tag to the current version. Uses the "tag" attribute. |
Additionally, there is the generic command:
:verscont action {attr = val} ... file ...
|
This calls the Version control module as specified in the "commit" attribute for "action" with the supplied arguments. What happens is specific for the VCS.
this is an optional target that you can define for extra installing, without changing the other install targets.
Each of these dependencies is only added automatically if you do not define it yourself. In other words, if you do not define a dependency with install-data as a target, Aap will add such a dependency internally. Unless you need special processing for specific kinds of items, you should rarely need to define any of the install targets yourself. The exceptions are install-platform-local, install-shared-local and install-local, which you can define without disturbing Aap's normal mechanisms for installing the programs and libraries you create.
All these dependencies that Aap adds are at the toplevel. Thus there is only one of each for all the recipes in your project. See below for an example of including the path of an item. Note that this works different from the "clean" and "cleanmore" targets. These can exist multiple times, each parent and child recipe can have one.
All of Aap's default install targets operate in roughly the same fashion: specific actions are invoked for each install target. The default actions all use top-level variables named INSTALL_target which collect filenames to install. Other toplevel variables control where those files are installed (targetDIR) and what file mode is used (targetMODE). This table shows the specific settings for each of the default install targets:
Table 17.2. Settings for the install target
| target | variable | action | directory | default directory | mode | default mode |
|---|---|---|---|---|---|---|
| install-exec | $INSTALL_EXEC | installexec | $EXECDIR | bin/ | $EXECMODE | 0755 |
| install-sbin | $INSTALL_SBIN | installsbin | $SBINDIR | sbin/ | $EXECMODE | 0755 |
| install-lib | $INSTALL_LIB | installlib | $LIBDIR | lib/ | $LIBMODE | 0644 |
| install-dll | $INSTALL_DLL | installdll | $DLLDIR | lib/ | $DLLMODE | 0755 |
| install-ltlib | $INSTALL_LTLIB | No default settings for libtool libraries have been added to Aap yet. It seems likely that DLLDIR and DLLMODE will be used. | ||||
| install-conf | $INSTALL_CONF | installconf | $CONFDIR | etc/ | $CONFMODE | 0644 |
| install-data | $INSTALL_DATA | installdata | $DATADIR | share/ [a] | $DATAMODE | 0644 |
| install-man | $INSTALL_MAN | installman | $MANDIR | man/ [b] | $MANMODE | 0644 |
| install-info | $INSTALL_INFO | installinfo | $INFODIR | info/ | $INFOMODE | 0644 |
| install-include | $INSTALL_INCLUDE | installinclude | $INCLUDEDIR | include/ | $INCLUDEMODE | 0644 |
[a] A subdirectory will be added with the name $PKGNAME. You must set this variable to the name of your application! In the rare situation that you need to install into multiple directories you may set $PKGNAME to an empty string and prepend the directory name to your data files. [b] A subdirectory will be added that uses the extension of the file. For "foo.1" the directory is "man1", for "foo.2" it is "man2", and so on. | ||||||
The :program command adds its target to the $INSTALL_EXEC variable. The :lib command adds its target to the $INSTALL_LIB variable. The :dll command adds its target to the $INSTALL_DLL variable. The :ltlib command adds its target to the $INSTALL_LTLIB variable.
The "installexec" action will strip the program by default, if the "strip" program can be found. If you don't want this add the {nostrip} attribute to the program or set $STRIP to an empty value.
You can also overrule the default actions by one of your own. The install_files() function can be useful then. See the default.aap recipe for examples.
All the install targets prepend a path to the directory they install into. The directory mentioned above is appended.
| $DESTDIR | Normally empty, which means that the root directory is used. Set this when you don't want to install to the local machine, but still pretend to install in the root. Examples: "~/dummyroot", "scp://foo.org/". Yes, you can do remote installing this way! Although not |