head 1.1; access; symbols; locks; strict; comment @# @; 1.1 date 2002.12.25.23.21.59; author swiergot; state Exp; branches; next ; desc @@ 1.1 log @- Initial release. - Version 0.5.9. @ text @To show how to write .builder script I will use an example - mutt.builder that builds the Mutt E-mail Client. After building we should have four packages: main package with Mutt binary, package containing User's Manual in plain text, package containing User's Manual in HTML and package with ChangeLog (its size is about 400kB). First we will prepare directory for sources and create .builder script: # mkdir /usr/src/tgz/sources/mutt # touch /usr/src/tgz/sources/mutt/mutt.builder # chmod a+x /usr/src/tgz/sources/mutt/mutt.builder # echo "#!/bin/sh" > /usr/src/tgz/sources/mutt/mutt.builder Copy Mutt's source file to the directory, ie.: # cp mutt-1.4i.tar.gz /usr/src/tgz/sources/mutt Now run your favourite text editor and open /usr/src/tgz/sources/mutt/mutt.builder. We'll start writing after "#!/bin/sh". At the beginning we have to put some variables with a few informations: name="mutt" title="Mutt" package="mutt" version="1.4i" build="1" noarch="n" build_info="" The difference between name and package is that name is constant and defines what it is, and package says how it was packed (with what compilation options and so on). Here it is only 'mutt' but later other suffixes may be added. name and package can't contain any spaces, upper case, any special characters. title is a full name of the package. If noarch is set to 'y', a package doesn't depend on architecture. Otherwise, it will be build for many processors (currently only i386). build_info tells how it was compiled, like package but more descriptive. Now it is empty but we will set it later. Next variables are descriptions of the package and some helpful informations: info="A small but very powerful text-based mail client." desc="Mutt is a small but very powerful text-based MIME mail client. It is highly configurable, and is well-suited to the mail power user with advanced features like key bindings, keyboard macros, mail threading, regular expression searches, and a powerful pattern matching language for selecting groups of messages." category="net/client/email" environment="console/curses" contact="$name@@packages.packware.gnu.pl" vendor="Packware Project" vendor_id="pw" info is a short description on what the package does (no more than 70 characters). desc is a full description. You can also write these two informations in other languages, for example: info_pl="Mały, ale bardzo potężny tekstowy klient poczty." desc_pl="Mutt jest małym, ale bardzo potężnym tekstowym klientem poczty MIME. Jest wysoce konfigurowalny i nadaje się dla zaawansowanych użytkowników ze swoimi możliwościami, jak przypisywanie klawiszy, makra klawiatury, wątkowanie, wyszukiwanie z wyrażeniami regularnymi i potężnym językiem wzorów dopasowań do zaznaczania grup wiadomości." Here the fields are in Polish. A short for the language (pl) was added to variable name after an underscore. category informs about package destination. environment tells where the package works. Sending a mail to an address mentioned in variable contact you can reach the author of the package. vendor tells who (single person or whole group) made the package. vendor_id is two or three characters that identifies the vendor. It will be used when naming the package: $package-$version-$architecture-$build$vendor_id.tgz. requires="" obsoletes="pine" conflicts="" Variable requires tells about packages that our package needs. Here it is empty because Mutt doesn't need any. And this variable doesn't apply to packages containing needed dynamically loaded libraries, such as ncurses with libncurses.so in this case. Packages mentioned in obsoletes may be replaced by our package. Variable conflicts says about packages that can't exist in the system with our package at the same time. docs_source="ABOUT-NLS,BEWARE,ChangeLog,COPYRIGHT,GPL,INSTALL,NEWS,README*" docs_cwd="" Variable docs_source contains files from the main source directory that will be put in /usr/doc/mutt-1.4i. Variable docs_cwd is similar, but pwbuilder will look for this files in the directory where mutt.builder is. strip_bin="y" reset_own="y" reset_dir="y" reset_fil="y" delete_cat="y" strip_bin set to 'y' tells pwbuilder to strip all executable binaries in the package. reset_own set to 'y' will make all files and directories have owning root.root. When reset_dir is set to 'y', all directories will have permissions reset to 755. If reset_fil is set to 'y', files modes will be set to 755 (executables) and 644 (other). If delete_cat is set to 'y', pwbuilder will remove all formatted manpages from the package. After all these lines it is time to include definitions of all functions and variables: . /usr/src/tgz/lib/builder.defs This sets the following variables: tmp (temporary directory), pkg_main (in this directory pwbuilder will put all files after compiling), src_pkg (directory that contains mutt.builder). Now we have to tell pwbuilder about sources. We will use function add_source: add_source ftp://ftp.mutt.org/pub/mutt/$name-$version.tar.gz $name-`echo $version | cut -d i -f 1` The first argument is a name of the archive. If it is an URL, a source will be downloaded if is missing. The second one is a top directory in the archive. If it is omitted, the default will be used, that means, the archive name without extension. Usually we do 'tar zxf archive123.tar.gz' and 'cd archive123' but archive with Mutt is different: 'tar zxf mutt-1.4i.tar.gz' and 'cd mutt-1.4' (without 'i' after 1.4). That's why we have to pass an argument to 'cd' as a second argument to add_source. Now we have new variable src1 set to directory name with the sources ($tmp/sources/mutt-1.4). We can add more sources with this function and directories with them will be in src2, src3 etc. Building script can ask the user about some compile-time options. We print a question with function verbose instead of echo: verbose "Do you want mutt to support POP3 servers for retrieving mail?" We read an answer using function yes_or_no: yes_or_no with_pop3 y with_pop3 (first argument) is a variable that will be set to 'y' or 'n' depending on what the user said. Second argument (here: 'y') is a default value. Even if the script have instructions to ask questions, it is still possible to execute script without any interaction. Then instead of asking the variable will be set to the default value. What we can do with the answer? Everything. Here we will pass an option to ./configure script: if [ "$with_pop3" = "y" ]; then configure_option --enable-pop build_info "With POP3. " else package_suffix nopop3 build_info "Without POP3. " fi Function configure_option is clear, I think. Function build_info adds a text passed as an argument to variable build_info. Function package_suffix adds a text passed as an argument to variable package. If we set this variable to 'mutt', now it will be set to 'mutt-nopop3'. We will use this constructions again: verbose "Do you want mutt to support IMAP for storing and retrieving mail?" yes_or_no with_imap y if [ "$with_imap" = "y" ]; then configure_option --enable-imap build_info "With IMAP. " else package_suffix noimap build_info "Without IMAP. " fi if [ "$with_pop3" = "y" -o "$with_imap" = "y" ]; then verbose "Do you want mutt to support SSL connections to IMAP and/or POP3 servers?" yes_or_no with_ssl y if [ "$with_ssl" = "y" ]; then configure_option --with-ssl build_info "With SSL." else package_suffix nossl build_info "Without SSL." fi fi Now we will add ./configure options that are always needed: configure_option --prefix=/usr configure_option --sysconfdir=/etc/mutt configure_option --with-mailpath=/var/spool/mail configure_option --with-charmaps=/usr/share/i18n/charmaps configure_option --enable-locales-fix configure_option --with-docdir=/usr/doc/$name-$version To install all files under other directory (variable pkg_main) insted of /, we usually use option DESTDIR passed to 'make install'. We use function install_option for it: install_option DESTDIR=$pkg_main There is function make_option, too. The three functions - configure_option, make_option and install_option - can take also second argument. It's a source number they apply to. Thus instruction "configure_option --prefix=/usr 2" applies to source placed in directory pointed by variable src2. Two following lines are constant. You don't need to know what they do. parent_package="$package" write_info main Before running ./configure, 'make' and 'make install' (or whatever builds our program), we need to cd to the sources directory: cd $src1 Now we can start compiling: do_configure do_make do_install Oh, we have polish manpage for Mutt in the same directory as mutt.builder: mkdir -p $pkg_main/usr/man/pl/man1 cp $src_pkg/mutt.1.pl $pkg_main/usr/man/pl/man1/mutt.1 chmod 644 $pkg_main/usr/man/pl/man1/mutt.1 Now we use function make_docs to create directory /usr/doc/mutt-1.4i and copy there files mentioned in docs_source and docs_cwd: make_docs Here is the right place to define subpackages. We do this as follows: subpackage manual subpackage manual-html subpackage changelog Obviously that's not all. I'll tell about it later and now we will finish our .builder. All we have to do is to pack all files into packages: make_package main make_package manual make_package manual-html make_package changelog 'make_package main' refers to the main package, that is to say everything that left after excluding subpackage. Other make_package directives are to make subpackage. After all it's good to remove all temporary files and directories: clean_up That's all. Now we'll complete definitions of subpackages. If we write 'subpackage some_name', then pwbuilder looks for $src_pkg/package-info-some_name and $src_pkg/package-files-some_name. The first one is the same as first variables in mutt.builder (name, title, version etc.). For subpackage changelog it will be: name="mutt-changelog" title="Mutt's ChangeLog" package="mutt-changelog" noarch="y" build_info="" parent_package="mutt" info="The ChangeLog of the Mutt Mail User Agent." desc="This is the ChangeLog of the Mutt - simple but very powerful e-mail client." category="doc/user/changelog" environment="viewer/text" parent_package tells about package from which the subpackage was excluded. We could omit this and it would be 'mutt' with suffixes set by package_suffix function, but Mutt's ChangeLog is independent of ./configure options like --with-pop or --with-imap. The same applies to variable package - we could write 'package="$parent_package-changelog"' but we didn't do it. All variables set in mutt.builder that weren't overwritten in package-info-changelog get values set in mutt.builder. I won't quote files package-info-manual and package-info-manual-html. You can see them as they were attached to pwbuilder package. How does pwbuilder know what files belongs to a subpackage? There are another files - package-files-some_name, ie. package-files-changelog. In this case it contains this: usr/doc/mutt-$version/ChangeLog Note that you can use variables set in package-info-changelog or in mutt.builder if the were not overwritten. What else? I think that's all. You know everything that is needed to write .builder script. If you have some questions, see the FAQ. If you don't find an answer, feel free to mail me. -- Jaroslaw Swierczynski @ .