Merge tag 'v3.0.0-20150401' into debian
v3.0.0-20150401
Michael Grünewald
9 years ago
0 | INDEX -- Guide through the Makefile Collection | |
1 | ||
2 | Author: Michael Grünewald | |
3 | Date: Fri Feb 10 2006 16:50:40 GMT | |
4 | ||
5 | ||
6 | Project infrastructure | |
7 | ||
8 | Files and directories that are artifacts of the project | |
9 | infrastructure. | |
10 | ||
11 | AUTHORS Contributors to BSD Make Pallàs scripts. | |
12 | COPYING License, in english | |
13 | COPYING-FR License, in french | |
14 | INDEX This file | |
15 | INSTALL See README.md for installation | |
16 | README.md General introduction | |
17 | Makefile.in Master build directives | |
18 | Library/Make Build directives library | |
19 | Library/Ancillary | |
20 | Developement scripts | |
21 | Library/Logo Logo | |
22 | test Test suite | |
23 | support Ancillary programs needing installation | |
24 | ||
25 | ||
26 | Project tier-1 | |
27 | ||
28 | Libraries of directives providing a complete functionality and a | |
29 | satisfying documentation. | |
30 | ||
31 | ocaml OCaml projects | |
32 | See ocaml.prog.mk, ocaml.lib.mk. ocaml.toplevel.mk, | |
33 | ocaml.pack.mk and ocaml.manual.mk. | |
34 | ||
35 | texmf Produce TeX documents | |
36 | See tex.doc.mk and latex.doc.mk | |
37 | ||
38 | ||
39 | Project tier-2 | |
40 | ||
41 | Libraries of directives providing a incomplete functionality or a | |
42 | unsatisfying documentation. | |
43 | ||
44 | ||
45 | bps Generic macros (subdir, project, etc.) | |
46 | See bps.subdir.mk and bps.project.mk | |
47 | ||
48 | Needs proper documentation and test cases in order to | |
49 | move to tier-1. | |
50 | ||
51 | www Produce offline sites with a SGML normaliser | |
52 | See www.sgml.mk and www.files.mk | |
53 | ||
54 | Needs proper documentation and test cases in order to | |
55 | move to tier-1. | |
56 | ||
57 | noewb Prepare LaTeX macros with noweb | |
58 | See noweb.latex.mk | |
59 | ||
60 | Needs proper documentation and test cases in order to | |
61 | move to tier-1. | |
62 | ||
63 | misc Miscellaneous | |
64 | ||
65 | Do not use a `misc` library but useful names in order | |
66 | to move to tier-1. | |
67 | ||
68 | Needs proper documentation and test cases in order to | |
69 | move to tier-1. |
0 | INDEX -- Guide through the Makefile Collection | |
1 | ||
2 | Author: Michael Grünewald | |
3 | Date: Fri Feb 10 2006 16:50:40 GMT | |
4 | ||
5 | ||
6 | Project infrastructure | |
7 | ||
8 | Files and directories that are artifacts of the project | |
9 | infrastructure. | |
10 | ||
11 | AUTHORS Contributors to BSD Make Pallàs scripts. | |
12 | COPYING License, in english | |
13 | COPYING-FR License, in french | |
14 | INDEX This file | |
15 | INSTALL See README.md for installation | |
16 | README.md General introduction | |
17 | Makefile.in Master build directives | |
18 | Library/Make Build directives library | |
19 | Library/Ancillary | |
20 | Developement scripts | |
21 | Library/Logo Logo | |
22 | test Test suite | |
23 | support Ancillary programs needing installation | |
24 | ||
25 | ||
26 | Project tier-1 | |
27 | ||
28 | Libraries of directives providing a complete functionality and a | |
29 | satisfying documentation. | |
30 | ||
31 | ocaml OCaml projects | |
32 | See ocaml.prog.mk, ocaml.lib.mk. ocaml.toplevel.mk, | |
33 | ocaml.pack.mk and ocaml.manual.mk. | |
34 | ||
35 | texmf Produce TeX documents | |
36 | See tex.doc.mk and latex.doc.mk | |
37 | ||
38 | ||
39 | Project tier-2 | |
40 | ||
41 | Libraries of directives providing a incomplete functionality or a | |
42 | unsatisfying documentation. | |
43 | ||
44 | ||
45 | bps Generic macros (subdir, project, etc.) | |
46 | See bps.subdir.mk and bps.project.mk | |
47 | ||
48 | Needs proper documentation and test cases in order to | |
49 | move to tier-1. | |
50 | ||
51 | www Produce offline sites with a SGML normaliser | |
52 | See www.sgml.mk and www.files.mk | |
53 | ||
54 | Needs proper documentation and test cases in order to | |
55 | move to tier-1. | |
56 | ||
57 | noewb Prepare LaTeX macros with noweb | |
58 | See noweb.latex.mk | |
59 | ||
60 | Needs proper documentation and test cases in order to | |
61 | move to tier-1. | |
62 | ||
63 | misc Miscellaneous | |
64 | ||
65 | Do not use a `misc` library but useful names in order | |
66 | to move to tier-1. | |
67 | ||
68 | Needs proper documentation and test cases in order to | |
69 | move to tier-1. |
0 | # Installation of BMake | |
1 | ||
2 | If you are working in hostile wilderness and do not have access to an | |
3 | appropriately packaged compatible **make** program, you may try the | |
4 | **bmake** program found at crufty's. | |
5 | ||
6 | Let us review together the installation procedure. | |
7 | ||
8 | ||
9 | ## Download | |
10 | ||
11 | We downlad the files `bmake.tar.gz` and `mk.tar.gz` distributed by | |
12 | their author: | |
13 | ||
14 | http://void.crufty.net/ftp/pub/sjg/bmake.tar.gz | |
15 | http://void.crufty.net/ftp/pub/sjg/mk.tar.gz | |
16 | ||
17 | In the sequel, we assume that the tarballs were downloaded to | |
18 | `~/distfiles`. | |
19 | ||
20 | ||
21 | ## Explode | |
22 | ||
23 | Point your shell to a working directory and explode the tarballs with | |
24 | ||
25 | ```console | |
26 | % tar xzf ~/distfiles/bmake.tar.gz | |
27 | % tar xzfC ~/distfiles/mk.tar.gz bmake | |
28 | ``` | |
29 | ||
30 | ## Build and install | |
31 | ||
32 | The tarballs are shipped with a _build and install_ script, that will | |
33 | use `/usr/local` as installation prefix. | |
34 | ||
35 | ```console | |
36 | % ./bmake/boot-strap --prefix=/usr/local --install | |
37 | ``` | |
38 | ||
39 | It is possible to change this prefix, as in | |
40 | ||
41 | ```console | |
42 | % ./bmake/boot-strap --prefix=${HOME} --install | |
43 | ``` | |
44 | ||
45 | If the command completes succesfully, the `bmake` program is then | |
46 | installed under the given prefix *PREFIX* and the standard macros | |
47 | shipped with the program are in `${PREFIX}/share/mk`. If appropriate, | |
48 | use the same installation prefix for BSD Make Pallas Scripts when you | |
49 | later install them. | |
50 | ||
51 | ||
52 | ## Portability | |
53 | ||
54 | The portability of **bmake** is excellent, I only experienced problems | |
55 | while trying to build it with an obsolete GCC on Solaris 10. Versions | |
56 | of GCC newer as 3.6 seem to build **bmake** without error. |
0 | # Installation | |
1 | ||
2 | ## Requirements | |
3 | ||
4 | BSD Owl Scripts works at least in the following | |
5 | versions of the **make** program: | |
6 | ||
7 | - FreeBSD 9.0 and newer with he base system program `make`; | |
8 | - Mac OS X 10.4 and newer with the third-party program `bmake`; | |
9 | - Debian 7.0 and newer with the third-party program `bmake`. | |
10 | ||
11 | Some special features require extra software being installed on the | |
12 | system where BSD Owl Scripts is used. This is advertised in | |
13 | the corresponding documentation. | |
14 | ||
15 | ||
16 | *How to install a compatible version of make on FreeBSD?* | |
17 | On FreeBSD, the version of **make** provided in the base system can be | |
18 | used and no additional package is required. | |
19 | ||
20 | *How to install a compatible version of make on Mac OS X or Linux?* | |
21 | On Mac OS X or Linux, the adequate version of the **make** program is | |
22 | usually packaged as **bmake** and can readily be installed using | |
23 | MacPorts on Mac OS X or **aptitude** on Debian. If a package is not | |
24 | available for your distribution, this is not a problem for **bmake** | |
25 | is very portable and [easy to install][install-bmake]. | |
26 | ||
27 | *Other dependencies* | |
28 | Depending on the exact set of features we want to use, we may need to | |
29 | install the following software packages: graphicsmagick, awk, m4, | |
30 | ocaml, texlive-latex-base, gnupg, ocaml-findlib, opensp. Their exact | |
31 | name can very from packaging system to packaging system. | |
32 | ||
33 | ||
34 | ## Site-wide installation procedure | |
35 | ||
36 | First of all, acquire the latest tarball `bsdowl-3.0.0-20150314.tar.xz` | |
37 | and its signature `bsdowl-3.0.0-20150314.tar.xz.sig` that you should | |
38 | verify—alternatively, download the tip of the | |
39 | [development branch][branch/master] or of the | |
40 | [release branch][branch/release]. | |
41 | Point a root shell to the directory containing the tarball: | |
42 | ||
43 | ```console | |
44 | # tar xJf bsdowl-3.0.0-20150314.tar.xz | |
45 | # cd bsdowl-3.0.0-20150314 | |
46 | ``` | |
47 | ||
48 | You now have to choose an installation prefix, say `/usr/local`, where | |
49 | the directives and a few helper scripts are installed: | |
50 | ||
51 | ```console | |
52 | # ./configure --prefix=/usr/local | |
53 | # make -r all | |
54 | # make -r install | |
55 | ``` | |
56 | ||
57 | To let BSD Make know about bsdowl, you then need to | |
58 | ensure that `/usr/local/bin` is listed in the path for each system | |
59 | user and that `/usr/local/share/mk` is listed in the search path | |
60 | for your compatible make program, this is usually done by adding the | |
61 | line | |
62 | ||
63 | ```makefile | |
64 | .MAKEFLAGS: -I /usr/local/share/mk | |
65 | ``` | |
66 | ||
67 | To the file `/etc/make.conf`. | |
68 | ||
69 | ||
70 | ## User-specific installation procedure | |
71 | ||
72 | First of all, acquire the latest tarball `bsdowl-3.0.0-20150314.tar.xz` | |
73 | and its signature `bsdowl-3.0.0-20150314.tar.xz.sig` that you should | |
74 | verify—alternatively, download the tip of the | |
75 | [development branch][branch/master] or of the | |
76 | [release branch][branch/release]. | |
77 | Point a user shell to the directory containing the tarball: | |
78 | ||
79 | ```console | |
80 | % tar xJf bsdowl-3.0.0-20150314.tar.xz | |
81 | % cd bsdowl-3.0.0-20150314 | |
82 | % ./configure --prefix=${HOME} | |
83 | % env MAKEFLAGS= make -r all | |
84 | % env MAKEFLAGS= make -r install | |
85 | ``` | |
86 | ||
87 | To let BSD Make know about bsdowl, you then need to | |
88 | ensure that `${HOME}/bin` is listed in your path and that the | |
89 | `MAKEFLAGS` variable contains `-I ${HOME}/share/mk`. If you | |
90 | are using `bash` or `sh` you can achieve this by appending the lines | |
91 | ||
92 | ```sh | |
93 | PATH="${HOME}/bin:${PATH}" | |
94 | MAKEFLAGS="${MAKEFLAGS}${MAKEFLAGS:+ }-I ${HOME}/share/mk" | |
95 | export PATH | |
96 | export MAKEFLAGS | |
97 | ``` | |
98 | ||
99 | to your `~/.profile` or `~/.bashrc` file, depending on your | |
100 | configuration. If you are using **tcsh** you can achieve this by | |
101 | appending the following lines | |
102 | ||
103 | ```tcsh | |
104 | set -f path = ( $path $HOME/bin ) | |
105 | ||
106 | if ( $?MAKEFLAGS ) then | |
107 | set makeflags = ( $MAKEFLAGS ) | |
108 | else | |
109 | set makeflags = () | |
110 | endif | |
111 | ||
112 | set makeflags = ( $makeflags "-I ${HOME}/share/mk" ) | |
113 | setenv MAKEFLAGS "$makeflags" | |
114 | unset makeflags | |
115 | ``` | |
116 | ||
117 | to your `~/.cshrc` or `~/.tcshrc`, depending on your configuration. | |
118 | These two suggestions will work in typical cases but some special | |
119 | configuration will require arrangements. | |
120 | ||
121 | ||
122 | [install-bmake]: INSTALL.bmake.md | |
123 | [branch/master]: https://github.com/michipili/bsdowl/tree/master | |
124 | [branch/release]: https://github.com/michipili/bsdowl/tree/release |
13 | 13 | # are also available at |
14 | 14 | # http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt |
15 | 15 | |
16 | PROJECT= bsdowl | |
16 | PACKAGE= bsdowl | |
17 | 17 | OFFICER= michipili@gmail.com |
18 | VERSION= 3.0.0-20150314 | |
18 | VERSION= 3.0.0-20150401 | |
19 | 19 | |
20 | 20 | SUBDIR+= bps |
21 | 21 | SUBDIR+= ocaml |
3 | 3 | |
4 | 4 | This collection of BSD Make directives aims at providing a highly |
5 | 5 | portable build system targetting modern UNIX systems and supporting |
6 | common or less command languages. | |
6 | common or less command languages. This is a build system, which means | |
7 | that it can be used to organise fairly complex projects. | |
7 | 8 | |
8 | It can already be used to: | |
9 | - Preparation and publication of TeX documents; | |
10 | - Development of TeX macros with NOWEB; | |
11 | - Development of OCaml software; | |
12 | - Maintainance of a FreeBSD workstation configuration files; | |
13 | - Preparation of a static website with ONSGMLS. | |
9 | ||
10 | ## Applicative level features | |
11 | ||
12 | BSD Owl Scripts assists developers in the production, installation and | |
13 | distribution of projects comprising the following types of products: | |
14 | ||
15 | - C programs, compiled for several targets | |
16 | - C libraries, static and shared, compiled for several targets | |
17 | - Shell scripts | |
18 | - Python scripts | |
19 | - OCaml programs | |
20 | - OCaml libraries, with **ocamldoc** documentation | |
21 | - OCaml plugins | |
22 | - TeX documents, prepared for several printing devices | |
23 | - METAPOST figures, with output as PDF, PS, SVG or PNG, | |
24 | either as part of a TeX document or as standalone documents | |
25 | ||
26 | Each item is linked to a project example found in our extensive | |
27 | testsuite. | |
28 | ||
29 | ||
30 | ## Build-system level features | |
31 | ||
32 | BSD Owl Scripts offers developers a rich set of features easing | |
33 | project management: | |
34 | ||
35 | - Support of compilation profiles | |
36 | - Support of the parallel mode (at the directory level) | |
37 | - Support of separate trees for sources and objects | |
38 | - Support of architecture-dependant compilation options | |
39 | - Support **GNU autoconf** | |
40 | - Production of GPG-signed tarballs | |
41 | - Developer subshell, empowered with project-specific scripts | |
42 | - Literate programming using **noweb** | |
43 | - Preprocessing with **m4** | |
44 | ||
45 | ||
46 | ## Compatibility list | |
14 | 47 | |
15 | 48 | It is well tested under: |
16 | - Mac OS X, version 10.6.8 and above | |
17 | - FreeBSD, version 9.0 and above | |
18 | - Debian Jessie and newer | |
49 | - Mac OS X, version 10.6.8 and above; | |
50 | - FreeBSD, version 9.0 and above; | |
51 | - Debian Jessie and newer. | |
19 | 52 | |
20 | It is hoped to function well under several other operating systems | |
21 | such as NetBSD, OpenBSD and other Linuces. See our | |
22 | [compatibility list][wiki/Compatibility] on the wiki. | |
23 | ||
24 | This README contains enough information to get you started. You | |
25 | will find more details on the [wiki][wiki]. | |
26 | ||
27 | The _Highlights_ section emphasizes important features of BSD Make | |
28 | Pallàs Scripts. The _Installation_ details the installation procedure | |
29 | using the sources. Finally the _First Steps_ demonstrate the use of BSD | |
30 | Make Pallàs Scripts to prepare TeX documents and OCaml programs. | |
31 | ||
32 | If you are not at all familiar with makefiles you can quickly learn | |
33 | the basics with de Boor's | |
34 | [classical tutorial][4]. | |
35 | It is also nice to feel confident while interacting with the shell, if | |
36 | this is not the case | |
37 | [UNIX Power Tools][5] | |
38 | could help you. | |
39 | ||
40 | ||
41 | # Highlights | |
42 | ||
43 | ## Compatibility | |
44 | ||
45 | We aim at providing a highly portable build system targetting modern | |
46 | UNIX systems. It is already well tested under: | |
47 | - Mac OS X, version 10.6.8 and above | |
48 | - FreeBSD, version 9.0 and above | |
49 | - Debian Jessie and newer | |
50 | ||
51 | It is hoped to function well under several other operating systems | |
52 | such as NetBSD, OpenBSD or even Cygwin. See our | |
53 | [compatibility list][wiki/Compatibility] on the wiki. | |
53 | We also want to support NetBSD and OpenBSD, as soon as they will | |
54 | provide a modern version of BSD Make. | |
54 | 55 | |
55 | 56 | This means that projects managed with BSD Owl Scripts are easy to |
56 | 57 | develop and deploy in heterogeneous environment. |
57 | 58 | |
58 | 59 | |
59 | ## Advanced features | |
60 | ## Starting points | |
60 | 61 | |
61 | Here is a short list of advanced features that will make you love | |
62 | using BSD Owl Scripts for your papers written with TeX: | |
62 | - [Installation notes][start-install] | |
63 | - [Getting started with a LaTeX document][start-latex] | |
64 | - [Getting started with an OCaml program][start-ocaml] | |
63 | 65 | |
64 | - Support TeX documents split in multiple directories; | |
65 | - Support figure generation with METAPOST; | |
66 | - Support bibtex bibliographies; | |
67 | - Smart clean targets easing publication. | |
66 | If you are not at all familiar with makefiles you can quickly learn | |
67 | the basics with de Boor's [classical tutorial][start-deboor]. | |
68 | It is also nice to feel confident while interacting with the shell, if | |
69 | this is not the case [UNIX Power Tools][start-upt] could help you. The | |
70 | [documentation index][start-index] provides an overview of the files | |
71 | available in the [doc][start-doc] directory. | |
68 | 72 | |
69 | And for OCaml projects, this list is: | |
70 | ||
71 | - Support parallel mode (at the directory level); | |
72 | - Support separate trees for sources and objects; | |
73 | - Support native and byte code; | |
74 | - Smart dependencies handling avoiding “inconsistant assumptions” over | |
75 | interfaces. | |
73 | [start-doc]: ./doc | |
74 | [start-index]: doc/Index.md | |
75 | [start-install]: INSTALL.md | |
76 | [start-latex]: doc/GettingStartedLaTeX.md | |
77 | [start-ocaml]: doc/GettingStartedOCaml.md | |
78 | [start-deboor]: http://www.freebsd.org/doc/en/books/pmake/index.html | |
79 | [start-upt]: http://docstore.mik.ua/orelly/unix/upt/ | |
76 | 80 | |
77 | 81 | |
78 | 82 | ## Free software |
79 | 83 | |
80 | BSD Owl Scripts is free software: copying it and | |
81 | redistributing it is very much welcome under conditions of the | |
82 | [CeCILL-B][1] licence agreement, found in the [COPYING][2] | |
83 | and [COPYING-FR][3] files | |
84 | of the distribution. | |
84 | BSD Owl Scripts is free software: copying it and redistributing it is | |
85 | very much welcome under conditions of the [CeCILL-B][licence-url] | |
86 | licence agreement, found in the [COPYING][licence-en] and | |
87 | [COPYING-FR][licence-fr] files of the distribution. | |
85 | 88 | |
86 | ||
87 | # Installation | |
88 | ||
89 | ## Requirements | |
90 | ||
91 | BSD Owl Scripts works at least in the following | |
92 | environments: | |
93 | ||
94 | - FreeBSD 9.0 and the base system program `make`; | |
95 | - Mac OS X 10.5 and the base system program `bsdmake`; | |
96 | - Mac OS X 10.4 and the base system program `bsdmake`; | |
97 | - Debian 7.0 and the third-party program `bmake`. | |
98 | ||
99 | Some special features require extra software being installed on the | |
100 | system where BSD Owl Scripts is used. This is advertised in | |
101 | the corresponding documentation. | |
102 | ||
103 | ||
104 | ## Site-wide installation procedure | |
105 | ||
106 | First of all, acquire the latest tarball `bsdowl-2.0.tar.bz2` | |
107 | and its signature `bsdowl-2.0.tar.bz2.sig` that you should | |
108 | verify—alternatively, download the tip of the | |
109 | [development branch][branch/master] | |
110 | Point a root shell to the directory containing the tarball: | |
111 | ||
112 | # tar xjf bsdowl-2.0.tar.bz2 | |
113 | # cd bsdowl-2.0 | |
114 | ||
115 | You now have to choose an installation prefix, say `/usr/local`, where | |
116 | the directives and a few helper scripts are installed: | |
117 | ||
118 | # ./configure --prefix=/usr/local | |
119 | # make -r all | |
120 | # make -r install | |
121 | ||
122 | To let BSD Make know about bsdowl, you then need to | |
123 | ensure that `/usr/local/bin` is listed in the path for each system | |
124 | user and that `/usr/local/share/mk` is listed in the search path | |
125 | for your compatible make program, this is usually done by adding the | |
126 | line | |
127 | ||
128 | .MAKEFLAGS: -I /usr/local/share/mk | |
129 | ||
130 | To the file `/etc/make.conf`. | |
131 | ||
132 | ||
133 | ## User-specific installation procedure | |
134 | ||
135 | First of all, acquire the latest tarball `bsdowl-2.0.tar.bz2` | |
136 | and its signature `bsdowl-2.0.tar.bz2.sig` that you should | |
137 | verify—alternatively, download the tip of the | |
138 | [development branch][branch/master] | |
139 | Point a user shell to the directory containing the tarball: | |
140 | ||
141 | $ tar xjf bsdowl-2.0.tar.bz2 | |
142 | $ cd bsdowl-2.0 | |
143 | $ ./configure --prefix=${HOME} | |
144 | $ env MAKEFLAGS= make -r all | |
145 | $ env MAKEFLAGS= make -r install | |
146 | ||
147 | To let BSD Make know about bsdowl, you then need to | |
148 | ensure that `${HOME}/bin` is listed in your path and that the | |
149 | `MAKEFLAGS` variable contains `-I ${HOME}/share/mk`. If you | |
150 | are using `bash` or `sh` you can achieve this by appending the lines | |
151 | ||
152 | PATH="${HOME}/bin:${PATH}" | |
153 | MAKEFLAGS="${MAKEFLAGS}${MAKEFLAGS:+ }-I ${HOME}/share/mk" | |
154 | export PATH | |
155 | export MAKEFLAGS | |
156 | ||
157 | to your `~/.profile` or `~/.bashrc` file, depending on your | |
158 | configuration. If you are using tcsh you can achieve this by | |
159 | appending the following lines | |
160 | ||
161 | set -f path = ( $path $HOME/bin ) | |
162 | ||
163 | if ( $?MAKEFLAGS ) then | |
164 | set makeflags = ( $MAKEFLAGS ) | |
165 | else | |
166 | set makeflags = () | |
167 | endif | |
168 | ||
169 | set makeflags = ( $makeflags "-I ${HOME}/share/mk" ) | |
170 | setenv MAKEFLAGS "$makeflags" | |
171 | unset makeflags | |
172 | ||
173 | to your `~/.cshrc` or `~/.tcshrc`, depending on your configuration. | |
174 | These two suggestions will work in typical cases but some special | |
175 | configuration will require arrangements. | |
176 | ||
177 | ||
178 | # First steps | |
179 | ||
180 | ## Getting started with a LaTeX document | |
181 | ||
182 | Here is how BSD Owl Scripts can help you to write your new | |
183 | article. First of all, create a directory to hold your files and put | |
184 | your first version of your TeX source there. We assume for this | |
185 | example that you called it `mylastarticle.tex`. Along your file, | |
186 | create a `Makefile` with the following contents: | |
187 | ||
188 | DOCS= mylastarticle.tex | |
189 | TEXDEVICE= pdf | |
190 | .include "latex.doc.mk" | |
191 | ||
192 | Then you can `make` your document and `make clean` it. The line | |
193 | setting `TEXDEVICE` tells BSD Owl Scripts that you want to | |
194 | actually use `pdflatex` but if you are happy with DVI output you can | |
195 | leave this line aside. If your document requires a bibliography | |
196 | prepared by `bibtex` just set `USE_BIBTEX` to `yes` as in | |
197 | ||
198 | DOCS= mylastarticle.tex | |
199 | USE_BIBTEX= yes | |
200 | TEXDEVICE= pdf | |
201 | .include "latex.doc.mk" | |
202 | ||
203 | This will automatically process your bibliography database with | |
204 | `bibtex`. If your bibliography database does not lie in the same | |
205 | directory as your article, you should tell BSD Owl Scripts its | |
206 | location: | |
207 | ||
208 | DOCS= mylastarticle.tex | |
209 | USE_BIBTEX= yes | |
210 | BIBINPUTS= ${HOME}/share/texmf/bib | |
211 | TEXDEVICE= pdf | |
212 | .include "latex.doc.mk" | |
213 | ||
214 | Note that `make clean` will not remove the compiled bibliography, so | |
215 | that you can `clean` your directory before sending it to an editor or | |
216 | the arXiv. To get rid of the compiled bibliography, use the more | |
217 | powerful `make realclean` mantra. | |
218 | ||
219 | BSD Owl Scripts can also take care of your METAPOST figures, | |
220 | If you use the `grahicx` package in LaTeX, all you need to do is to | |
221 | list your metapost source files in the `FIGS` variable: | |
222 | ||
223 | DOCS= mylastarticle.tex | |
224 | FIGS= desargues.mp | |
225 | FIGS+= conics.mp | |
226 | TEXDEVICE= pdf | |
227 | .include "latex.doc.mk" | |
228 | ||
229 | and METAPOST wil be called automatically the next time you `make` your | |
230 | document. Please be sure to set | |
231 | ||
232 | outputtemplate := "%j-%c.mps"; | |
233 | ||
234 | in your METAPOST sources. As for bibliographies, making `clean` will | |
235 | not remove your pictures but making `realclean` will. | |
236 | ||
237 | ||
238 | ## Getting started with an OCaml program | |
239 | ||
240 | Here is how BSD Owl Scripts can help you to compile a simple | |
241 | OCaml program `wordcount`, your own implementation of the UNIX `wc(1)` | |
242 | utility. | |
243 | ||
244 | We first assume that the source code is a single file `wordcount.ml` | |
245 | and then consider a more complex case. | |
246 | ||
247 | ||
248 | ### The first time | |
249 | ||
250 | Create a directory to hold your files and put your source there. | |
251 | Along the source, create a `Makefile` with the following content: | |
252 | ||
253 | PROGRAM= wordcount | |
254 | .include "ocaml.prog.mk" | |
255 | ||
256 | ### Building | |
257 | ||
258 | You can now `make` your program and produce a `wordcount` binary. The | |
259 | complete output of the make process looks like this: | |
260 | ||
261 | $ make | |
262 | make depend | |
263 | ocamldep wordcount.ml > .depend | |
264 | make build | |
265 | ocamlc -c -o wordcount.cmo wordcount.ml | |
266 | ocamlc -o wordcount.cb wordcount.cmo | |
267 | cp wordcount.cb wordcount | |
268 | make doc | |
269 | ||
270 | When you call `make` without argument it is the same thing as | |
271 | `make all` which decomposes as `make depend` and `make build` as you | |
272 | see. You can test your program, edit it and re-`make` it. | |
273 | ||
274 | ||
275 | ### Installing | |
276 | ||
277 | Once you are satisfied with the results, you can install it with `make | |
278 | install`. It will call `su` to gain root privileges and install your | |
279 | program under `/usr/local/bin` a value deduced from *PREFIX* | |
280 | ||
281 | $ make install | |
282 | ===> Switching to root credentials for target (install) | |
283 | Password: | |
284 | /usr/bin/install -c -d /usr/local/bin | |
285 | install -o root -g wheel -m 555 wordcount /usr/local/bin | |
286 | ||
287 | You can check the value of the *PREFIX* variable, or any other | |
288 | variable, with `make -V` as in | |
289 | ||
290 | $ make -V PREFIX | |
291 | /usr/local | |
292 | ||
293 | If you want to install your program to another location like | |
294 | `${HOME}/bin` you only need to change the *PREFIX*. You can make the | |
295 | change permanent by adding a `PREFIX=${HOME}` line to your `Makefile`: | |
296 | ||
297 | PROGRAM= wordcount | |
298 | PREFIX= ${HOME} | |
299 | .include "ocaml.prog.mk" | |
300 | ||
301 | The order of variable declarations is not important but they have to | |
302 | come before the `.include` line. It is also possible to use | |
303 | `PREFIX=${HOME}` just once by adding it on the command line without | |
304 | editing the `Makefile`: | |
305 | ||
306 | make PREFIX=${HOME} install | |
307 | /usr/bin/install -c -d /home/michael/bin | |
308 | install -o michael -g michael -m 550 wordcount /home/michael/bin | |
309 | ||
310 | Note that since you have write access to the *PREFIX* directory, it is | |
311 | not necessary to gain root privileges for this installation. | |
312 | ||
313 | ||
314 | ### Cleaning | |
315 | ||
316 | Last you can remove object code from the directory with | |
317 | ||
318 | $ make clean | |
319 | rm -f wordcount.cmo wordcount.cmi wordcount.cb wordcount | |
320 | ||
321 | If you look closely, you will notice that the `.depend` file is not | |
322 | removed: | |
323 | ||
324 | $ ls -A | |
325 | .depend Makefile wordcount.ml | |
326 | ||
327 | This is on purpose, and if you also want to get rid of the `.depend` | |
328 | file you can use the more powerful mantra | |
329 | ||
330 | $ make realclean | |
331 | rm -f wordcount.cmo wordcount.cmi wordcount.cb wordcount | |
332 | rm -f .depend | |
333 | ||
334 | ||
335 | ### Several files and auxilary libraries | |
336 | ||
337 | As a consequence _Zawinski's Law of Software Envelopment_ you decided | |
338 | to build a mail reader in your `wordcount` program. Your code source | |
339 | now consists of your main file `wordcount.ml` a library | |
340 | `mailreader.ml` relying on the `unix.cma` library. Here is the | |
341 | corresponding `Makefile`: | |
342 | ||
343 | ||
344 | PROGRAM= wordcount | |
345 | SRCS+= mailreader.ml | |
346 | SRCS+= wordcount.ml | |
347 | LIBS+= unix | |
348 | .include "ocaml.prog.mk" | |
349 | ||
350 | While dependencies between modules are computed with `ocamldep` so | |
351 | that modules are compiled as needed, the order in which the files are | |
352 | listed in *SRCS* is used by the linker. It is thus important to list | |
353 | files in an order suited to the linking phase. | |
354 | ||
355 | ||
356 | ### Features highlight | |
357 | ||
358 | Here is a list of more advanced features that you may find useful when | |
359 | developping OCaml projects. | |
360 | ||
361 | - Compilation of bytecode and native executables; | |
362 | - Support of ocamlfind to link against 3rd party packages; | |
363 | - Support of ocamldoc to generate module documentation; | |
364 | - Support of ocamlprof to generate profiling information; | |
365 | - Support of debugging symbols; | |
366 | - Support of ocamllex and ocamlyacc to generate lexers and parsers; | |
367 | - Support parallel mode (at the directory level); | |
368 | - Support separate trees for sources and objects; | |
369 | - Support native and byte code; | |
370 | - Smart dependencies handling avoiding “inconsistant assumptions” over | |
371 | interfaces. | |
372 | ||
373 | These features are described in the documentation. | |
89 | [licence-url]: http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html | |
90 | [licence-en]: COPYING | |
91 | [licence-fr]: COPYING-FR | |
374 | 92 | |
375 | 93 | |
376 | 94 | ## Last words |
381 | 99 | the first time on GNA (gna.org). One year later the history was |
382 | 100 | converted to git and subversion was only marginally used. In 2013, |
383 | 101 | publication on the GNA server was abandoned and the project was |
384 | published on GitHub and BitBucket. | |
102 | published on GitHub and BitBucket, then on GitHub only. | |
385 | 103 | |
386 | 104 | Pallàs Athéné is a Greek goddess of wisdom, mother of sciences and |
387 | 105 | arts. This software is gently dedicated to her. |
388 | 106 | |
389 | 107 | |
390 | 108 | Michael Grünewald in Bonn, on January 20, 2014 |
391 | ||
392 | [1]: http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html | |
393 | [2]: COPYING | |
394 | [3]: COPYING-FR | |
395 | [4]: http://www.freebsd.org/doc/en/books/pmake/index.html | |
396 | [5]: http://docstore.mik.ua/orelly/unix/upt/ | |
397 | ||
398 | [wiki]: https://github.com/michipili/bsdowl/wiki | |
399 | [wiki/Compatibility]: https://github.com/michipili/bsdowl/wiki/Compatibility | |
400 | ||
401 | [branch/master]: https://github.com/michipili/bsdowl/tree/master |
204 | 204 | .if !target(__<bps.init.mk>__) |
205 | 205 | __<bps.init.mk>__: |
206 | 206 | |
207 | .include "bps.bpsconfig.mk" | |
207 | .sinclude "bps.bpsconfig.mk" | |
208 | 208 | |
209 | 209 | .MAIN: all |
210 | 210 | |
212 | 212 | |
213 | 213 | # Input the package configuration file, if any. |
214 | 214 | .if defined(SRCDIR) && !empty(SRCDIR) |
215 | .sinclude "${SRCDIR}/Makefile.build" | |
215 | .sinclude "${SRCDIR}/Makefile.local" | |
216 | 216 | .sinclude "${SRCDIR}/Makefile.config" |
217 | 217 | .if ${SRCDIR} != ${.CURDIR} |
218 | 218 | RELDIR:= ${.CURDIR:S@^${SRCDIR}@@} |
219 | 219 | .sinclude "${SRCDIR}/${MAKEINITRC}" |
220 | 220 | .endif |
221 | 221 | .else |
222 | .sinclude "Makefile.build" | |
222 | .sinclude "Makefile.local" | |
223 | 223 | .sinclude "Makefile.config" |
224 | 224 | .endif |
225 | 225 | |
312 | 312 | # Identify user running make |
313 | 313 | # |
314 | 314 | |
315 | .if target(__<bps.bpsconfig.mk>__) | |
315 | 316 | .if !defined(UID) |
316 | 317 | UID!= ${ID} -u |
317 | 318 | .endif |
322 | 323 | |
323 | 324 | .if !defined(GROUP) |
324 | 325 | GROUP!= ${ID} -n -g |
326 | .endif | |
327 | .else | |
328 | UID= 0 | |
329 | USER= 0 | |
330 | GROUP= 0 | |
325 | 331 | .endif |
326 | 332 | |
327 | 333 |
199 | 199 | AC_SUBST([WITH_TESTSUITE_METAPOST]) |
200 | 200 | AC_SUBST([MINGW32CC]) |
201 | 201 | AC_SUBST([MINGW32AR]) |
202 | AC_SUBST([VERSION], [$(${BSDMAKE} -V VERSION)]) | |
202 | 203 | AC_CONFIG_FILES([Makefile.config bps/bps.bpsconfig.mk testsuite/Makefile.inc]) |
203 | 204 | AC_OUTPUT |
204 | 205 |
0 | bsdowl (3.0.0-20150314-1) UNRELEASED; urgency=medium | |
0 | bsdowl (3.0.0-20150401-1) UNRELEASED; urgency=medium | |
1 | 1 | |
2 | * Update package to 3.0.0-20141203. | |
3 | * Update package to 3.0.0-20141228. | |
4 | * Update package to 3.0.0-20140228, which should have been | |
5 | 3.0.0-20150228. | |
6 | * Update package to 3.0.0-20150314. | |
2 | * Update package to 3.0.0-201500401. | |
7 | 3 | |
8 | 4 | -- Michael Grünewald <michipili@gmail.com> Fri, 20 Mar 2015 16:10:41 +0100 |
9 | 5 |
0 | # Handling architectures | |
1 | ||
2 | ## Detecting the architecture with autoconf | |
3 | ||
4 | In order to detect the architecture of the host where you build your | |
5 | package with `autoconf` we suggest the following setup: | |
6 | ||
7 | 1. Prepare a directory `Library/Autoconf` in your source directory. | |
8 | 2. Copy the files `install-sh`, `config.guess` and `config.sub` | |
9 | shipped with `automake`. | |
10 | 3. Add the statement `AC_CONFIG_AUX_DIR([Library/Autoconf])` to your | |
11 | `configure.ac`. | |
12 | 4. Add the statement `AC_CANONICAL_BUILD()` to your `configure.ac`. | |
13 | 5. Analyse the content of the variables `build`, and its three individual | |
14 | parts `build_cpu`, `build_vendor`, and `build_os` to map this | |
15 | triple to the architecture classification used by your package. | |
16 | 6. Use the `AC_SUBST` macro to define appropriately the | |
17 | `ARCHITECTURE_NATIVE` variable. | |
18 | ||
19 | ||
20 | ## Using architecture specific settings | |
21 | ||
22 | Architecture specific configuration files can be stored in the | |
23 | directory pointed to by the variable `PACKAGELIBRARYARCHITECTURE` whose | |
24 | implicit value is `${SRCDIR}/Library/Configuration`. | |
25 | ||
26 | If the variable `ARCHITECTURE` is defined then a file | |
27 | `${ARCHITECTURE}.mk` containing architecture-specific settings must | |
28 | exist in the architecture specific configuration file library. This | |
29 | file is then processed by each module of the package. An error is | |
30 | triggered if this file does not exist. | |
31 | ||
32 | If a [configuration](Configuration) is used and the variable | |
33 | `CONFIGURATION` is also defined, then a file | |
34 | `${CONFIGURATION}_${ARCHITECTURE}.mk` might exist in the directory | |
35 | pointed to by the variable `PACKAGELIBRARYCONFIGURATION`. This file is | |
36 | optional. | |
37 | ||
38 | ||
39 | ## Using a cross-compiler | |
40 | ||
41 | If available, a cross-compiler can be used to cross-compile a package. | |
42 | By repeatedly calling `make build` with distinct values of | |
43 | `ARCHITECTURE`, the same package can be built for several | |
44 | architectures. | |
45 | ||
46 | To do so, we only need to be sure that the [OBJDIR](Objdir) mechanism | |
47 | is configured so that the variable `${ARCHITECTUREDIR}` is part of the | |
48 | objdir-path and of `DESTDIR` if we also use the `install` target. | |
49 | ||
50 | ||
51 | ## Troubleshooting | |
52 | ||
53 | The command `make display-architecture` prepares a report giving the | |
54 | values of the variables used when handling architectures. |
0 | # Concepts of our build system | |
1 | ||
2 | Our build system allows the compilation and installation of simple and | |
3 | complex pieces of software. The description of the software bing built | |
4 | involves packages, modules and products. | |
5 | ||
6 | ||
7 | ## Software packages | |
8 | A *software package* or shortly *package* is the largest hierarchical | |
9 | unit of the description of the software that should be built. The | |
10 | complete description of a software packages consists of all the | |
11 | programs, libraries, documents that should be built and copied to the | |
12 | target system in order to install the software. This description also | |
13 | accounts for extra steps that should be taken to integrate the | |
14 | software to its host environment, like triggering scripts indexing | |
15 | documentation and similar steps. | |
16 | ||
17 | Other common names for *software package* are *project* or *solution*. | |
18 | The name *software package* or *package* is also used by the | |
19 | GNU Autotools, it should not be confused with *packages* | |
20 | used by *package management software* such as *pkg* on FreeBSD or | |
21 | *apt* on Debian. | |
22 | ||
23 | ||
24 | ## Modules | |
25 | A *module* is the smallest hierarchical unit of the description of the | |
26 | software that should be built, it sits just above files in that | |
27 | hierarchy. Typical examples of modules consists of a C program | |
28 | together with its manual pages, an OCaml library with its ocamldoc | |
29 | generated documentation, a LaTeX class, or package documentation. | |
30 | ||
31 | It is worth to note that a simple software package may consist of a | |
32 | single module. Also, each module can provide its own documentation | |
33 | products but the software package as a whole may contain extra modules | |
34 | producing documentation artifacts whose scope is not limited to a | |
35 | specific module but may embrace several of them—typically the | |
36 | full software package. | |
37 | ||
38 | Software modules can depend on external programs, packages and | |
39 | libraries. They also can depend on other modules found within the | |
40 | sofware package being built. | |
41 | ||
42 | ||
43 | ## Products | |
44 | The *products* of a *module* are file system artifacts, like a single | |
45 | file or a subtree of the file system. These products are the actual | |
46 | artifacts representing the software package in the host system. The | |
47 | installation procedure of the software package usually copies products | |
48 | at appropriate places of the file-system but it may require to execute | |
49 | additional actions, like the execution of scripts. |
0 | # Using BSD Owl on Cygwin | |
1 | ||
2 | On UNIX systems it is traditional *not to use* spaces in file names or | |
3 | system identifiers such as user names or group names. Not only bsdowl | |
4 | but also various versions of make, including BSD Make, were written | |
5 | with this tradition in mind, and it is illusory to adapt these tools | |
6 | to work correctly on a Cygwin environment where groups identifiers | |
7 | like `Domain Users` exist or directories like `Program Files (x86)` | |
8 | are part of the path. | |
9 | ||
10 | We can however try to sanitize the Cygwin environment by doing the | |
11 | following arrangements: | |
12 | ||
13 | 1. Use the `id` command to determine your `uid` and your `gid`. | |
14 | 2. Determine a sanitized path like deduced from your actual PATH by removing | |
15 | elements having a space in their name. | |
16 | 3. Set `USE_SWITCH_CREDENTIALS=no` to avoid using `su` to gain root credentials. | |
17 | ||
18 | For 2. we may start with `/usr/local/bin:/usr/bin` and add further | |
19 | path elements as needed. See also below *Dealing with Program Files* | |
20 | to add path elements under `Program Files` and `Program Files (x86)` | |
21 | to your path. | |
22 | ||
23 | We can define an alias in our `~/.profile` to put these setting at our | |
24 | fingertips, such as: | |
25 | ||
26 | alias bmake='env USE_SWITCH_CREDENTIALS=no USER=500 GROUP=500 PATH=/usr/local/bin:/usr/bin /usr/local/bin/bmake' | |
27 | ||
28 | Adapt the numerical values for USER and GROUP to reflect your actual | |
29 | `uid` and `gid` as reported by the `id` program. Adapt the PATH and | |
30 | the path to the actual `bmake` program as required. | |
31 | ||
32 | ||
33 | ## Dealing with Program Files | |
34 | ||
35 | Assume your PATH contains the following items: | |
36 | ||
37 | /usr/local/bin | |
38 | /usr/bin | |
39 | /cygdrive/c/Windows/System32 | |
40 | /cygdrive/c/Windows/System32/Wbem | |
41 | /usr/local/texlive/2014/bin/i386-cygwin | |
42 | /cygdrive/c/Program Files/TortoiseGit/bin | |
43 | /cygdrive/c/Program Files (x86)/GitExtensions | |
44 | /cygdrive/c/Program Files (x86)/Java/jre7/bin | |
45 | /usr/lib/lapack | |
46 | ||
47 | The two items | |
48 | ||
49 | /cygdrive/c/Program Files (x86)/GitExtensions | |
50 | /cygdrive/c/Program Files (x86)/Java/jre7/bin | |
51 | ||
52 | are problematic because of the whitespaces they contain. We can use | |
53 | symbolic links to safely add these paths to our PATH: | |
54 | ||
55 | mkdir /opt | |
56 | ln -s "/cygdrive/c/Program Files (x86)/GitExtensions" /opt/GitExtensions | |
57 | ln -s "/cygdrive/c/Program Files (x86)/Java/jre7" /opt/jre7 | |
58 | ||
59 | After this setup, we can use the following alias to start bmake in a | |
60 | safe setting: | |
61 | ||
62 | alias bmake='env USE_SWITCH_CREDENTIALS=no USER=500 GROUP=500 PATH=/usr/local/bin:/usr/bin:/cygdrive/c/Windows/System32:/cygdrive/c/Windows/System32/Wbem:/usr/local/texlive/2014/bin/i386-cygwin:/cygdrive/c/Program Files/TortoiseGit/bin:/opt/GitExtensions:/opt/jre7/bin:/usr/lib/lapack /usr/local/bin/bmake' |
0 | # Configuration profiles | |
1 | ||
2 | Configuration profiles can be defined to build a software package | |
3 | using different options. | |
4 | ||
5 | A common application is to build with a _Debug_ configuration profile | |
6 | when elaborating the software package and build with a _Release_ | |
7 | configuration profile when time has come to prepare software packages. | |
8 | The first profile can build objects with debugging symbols and other | |
9 | useful similar information while the second can produce an optimised | |
10 | version of the product programs. A second applications is to compare | |
11 | several configuration profiles to experimentally determine which leads | |
12 | to the most efficient build according to a given benchmark. | |
13 | ||
14 | ||
15 | ## Defining a configuration profile | |
16 | ||
17 | Configuration files can be stored in the directory pointed to by the | |
18 | variable `PACKAGELIBRARYCONFIGURATION` whose implicit value is | |
19 | `${SRCDIR}/Library/Configuration`. | |
20 | ||
21 | If the variable `CONFIGURATION` is defined then a file | |
22 | `${CONFIGURATION}.mk` containing the corresponding settings must exist | |
23 | in the configuration specific configuration file library. This file | |
24 | is then processed by each module of the package. An error is | |
25 | triggered if this file does not exist. | |
26 | ||
27 | ||
28 | ## Working with several configuration profiles | |
29 | ||
30 | To work with several configuration profiles, it is advised that the | |
31 | [OBJDIR](Objdir) mechanism is configured so that the variable | |
32 | `${CONFIGURATIONDIR}` is part of the objdir-path and of `DESTDIR` or | |
33 | `PREFIX` if we also want to use the `install` target. | |
34 | ||
35 | It is then possible to build concurrently the software package using | |
36 | several distinct configuration profiles and to benchmark the obtained | |
37 | products to compare them. |
0 | # Develop OCaml Software | |
1 | ||
2 | On this page, you will learn how to use **BSD Owl Scripts** to: | |
3 | ||
4 | - Compile and install simple OCaml programs. | |
5 | - Compile and install simple OCaml libraries. | |
6 | - Prepare and install documentation generated with **ocamldoc**. | |
7 | - Prepare and install a custom toplevel. | |
8 | - Generate lexers and parsers with **ocamllex** and **ocamlyacc**. | |
9 | - Use third party libraries in your programs. | |
10 | - Generate objects with debugging symbols. | |
11 | - Generate objects with profiling information. | |
12 | - Use **autoconf** in your project. | |
13 | - Organise a complex project in several directories. | |
14 | - Produce GPG-signed tarballs. | |
15 | - Simultaneously build a project with various configurations. | |
16 | ||
17 | ||
18 | ## Compile and install simple OCaml programs | |
19 | ||
20 | We assume we have a written really simple program **wordcount**, our | |
21 | own implementation of the Unix™ `wc(1)` utility. The source code is | |
22 | held by a single file `wordcount.ml`. | |
23 | ||
24 | ||
25 | ### The first time | |
26 | ||
27 | We create a directory to hold our files and put our source there. | |
28 | Along the source, we prepare a `Makefile` with the following content: | |
29 | ||
30 | ```makefile | |
31 | PROGRAM= wordcount | |
32 | .include "ocaml.prog.mk" | |
33 | ``` | |
34 | ||
35 | ||
36 | ### Building | |
37 | ||
38 | We can now `make` our program and produce a `wordcount` binary. The | |
39 | complete output of the make process looks like this: | |
40 | ||
41 | ```console | |
42 | make configure | |
43 | make depend | |
44 | ocamldep wordcount.ml > .depend | |
45 | make build | |
46 | ocamlc -c -o wordcount.cmo wordcount.ml | |
47 | ocamlc -o wordcount.byte wordcount.cmo | |
48 | cp wordcount.byte wordcount | |
49 | make doc | |
50 | make test | |
51 | ``` | |
52 | ||
53 | When we call `make` without argument it is the same thing as | |
54 | `make all` which decomposes as the sequence: | |
55 | ||
56 | make configure | |
57 | make depend | |
58 | make build | |
59 | make doc | |
60 | make test | |
61 | ||
62 | Some steps are not connected to any shell commands in the special case | |
63 | taken as example, but they can have command attached to them in more | |
64 | complicated projects. We can test our program, edit it and re-`make` | |
65 | it. | |
66 | ||
67 | ||
68 | ### Installing | |
69 | ||
70 | Once we are satisfied with the results, we can install it with | |
71 | `make install`. The program **make** will call **su** to gain | |
72 | root privileges and install the program under `/usr/local`, | |
73 | the value of *PREFIX* | |
74 | ||
75 | ```console | |
76 | % make install | |
77 | ===> Switching to root credentials for target (install) | |
78 | Password: | |
79 | /usr/bin/install -c -d /usr/local/bin | |
80 | install -o root -g wheel -m 555 wordcount /usr/local/bin | |
81 | ``` | |
82 | ||
83 | We can verify the value of the *PREFIX* variable, or any other | |
84 | variable, with `make -V` as in | |
85 | ||
86 | ```console | |
87 | % make -V PREFIX | |
88 | /usr/local | |
89 | ``` | |
90 | ||
91 | If we want to install our program to another location like | |
92 | `${HOME}/bin` we only need to change the *PREFIX*. The prefix | |
93 | selection is usually left to the `configure` script of a project, | |
94 | but, for this simple example, we will only add a `PREFIX=${HOME}` | |
95 | assignment to our `Makefile`: | |
96 | ||
97 | ```makefile | |
98 | PROGRAM= wordcount | |
99 | PREFIX= ${HOME} | |
100 | .include "ocaml.prog.mk" | |
101 | ``` | |
102 | ||
103 | The order of variable declarations is not important but they have to | |
104 | come before the `.include` line. While this step can sometimes be | |
105 | skipped, it is a good habit to `make clean` after changing the | |
106 | configuration of a package. | |
107 | ||
108 | ```console | |
109 | % make clean install | |
110 | … | |
111 | /usr/bin/install -c -d /home/michael/bin | |
112 | install -o michael -g michael -m 550 wordcount /home/michael/bin | |
113 | ``` | |
114 | ||
115 | Note that since we have write access to the *PREFIX* directory, it is | |
116 | not necessary to gain root privileges for this installation. | |
117 | ||
118 | ||
119 | ### Cleaning | |
120 | ||
121 | Once we are done, we can remove object code from the directory with | |
122 | ||
123 | ```console | |
124 | % make clean | |
125 | rm -f wordcount.cmo wordcount.cmi wordcount.cb wordcount | |
126 | ``` | |
127 | ||
128 | If we look closely, we will notice that the `.depend` file is not | |
129 | removed: | |
130 | ||
131 | ```console | |
132 | % ls -A | |
133 | .depend Makefile wordcount.ml | |
134 | ``` | |
135 | ||
136 | This is on purpose, and if we also want to get rid of the `.depend` | |
137 | file we can use the more powerful mantra | |
138 | ||
139 | ```console | |
140 | % make realclean | |
141 | rm -f wordcount.cmo wordcount.cmi wordcount.cb wordcount | |
142 | rm -f .depend | |
143 | ``` | |
144 | ||
145 | ||
146 | ### Several source files | |
147 | ||
148 | If our program consists of several files `ancillary.ml` and | |
149 | `application.ml`, we need to list them in the *SRCS* variable, as in: | |
150 | ||
151 | ```makefile | |
152 | PROGRAM= wordcount | |
153 | SRCS+= ancillary.ml | |
154 | SRCS+= application.ml | |
155 | .include "ocaml.prog.mk" | |
156 | ``` | |
157 | ||
158 | When we list explicitly source files in the *SRCS* variable, we are | |
159 | not obliged to use the same name for our source file and our program, | |
160 | so if we decided to use the name `main.ml` instead of `wordcount.ml` | |
161 | our `Makefile` would be | |
162 | ||
163 | ```makefile | |
164 | PROGRAM= wordcount | |
165 | SRCS= main.ml | |
166 | .include "ocaml.prog.mk" | |
167 | ``` | |
168 | ||
169 | While dependencies between modules are computed with `ocamldep` so | |
170 | that modules are compiled as needed, the order in which the files are | |
171 | listed in *SRCS* is used by the linker. It is thus important to list | |
172 | files in an order suited to the linking phase. | |
173 | ||
174 | ||
175 | ### Interfaces without implementation | |
176 | ||
177 | If our implementation files are accompanied by interface files, these | |
178 | are automatically detected and handled appropriately. It is also | |
179 | possible to compile a program against a module without implementation, | |
180 | by listing the implementation file in the *SRCS* variable. With the | |
181 | `Makefile` | |
182 | ||
183 | ```makefile | |
184 | PROGRAM= wordcount | |
185 | SRCS+= ancillary.mli | |
186 | SRCS+= application.ml | |
187 | .include "ocaml.prog.mk" | |
188 | ``` | |
189 | ||
190 | we can compile `application.ml` using the interface defined in | |
191 | `ancillary.mli` without having implemented the interface. Of course, | |
192 | we will not be able to link `wordcount` but this allows to experiment | |
193 | with the interfaces before deciding to implement it. | |
194 | ||
195 | ||
196 | ## Compile and install simple OCaml libraries | |
197 | ||
198 | We now assume that we have a really simple OCaml library `newton` | |
199 | consisting of an implementation file `newton.ml` and an interface file | |
200 | `newton.mli`. | |
201 | ||
202 | ||
203 | ### The first time | |
204 | ||
205 | The corresponding `Makefile` is then | |
206 | ||
207 | ```makefile | |
208 | LIBRARY= newton | |
209 | SRCS+= newton.ml | |
210 | .include "ocaml.lib.mk" | |
211 | ``` | |
212 | ||
213 | Note that it is mandatory to list all implementation files in the | |
214 | *SRCS* variable: in contrast to the module `ocaml.prog.mk` used to | |
215 | compile OCaml programs, the module `ocaml.lib.ml` does not try to | |
216 | automatically add the obvious `newton.ml` to our library. This is | |
217 | because libraries are essentially archive files and we are expected to | |
218 | explicitely list files that are to be put in the archive. | |
219 | ||
220 | ||
221 | ### Building | |
222 | ||
223 | As for programs, we can then `make` the library: | |
224 | ||
225 | ```console | |
226 | % make | |
227 | make configure | |
228 | make depend | |
229 | ocamldep newton.ml newton.mli > .depend | |
230 | make build | |
231 | ocamlc -c -o newton.cmo newton.ml | |
232 | ocamlc -a -o newton.cma newton.cmo | |
233 | make doc | |
234 | make test | |
235 | ``` | |
236 | ||
237 | ||
238 | ### Installing | |
239 | ||
240 | we can now test our library and if we are satisfied, decide to | |
241 | install it with `make install`. The library will be installed in | |
242 | `${LIBDIR}` that is | |
243 | ||
244 | ```console | |
245 | % make -V LIBDIR | |
246 | /usr/local/lib/ocaml | |
247 | ``` | |
248 | ||
249 | unless we selected another *PREFIX* as described above in _Compile | |
250 | and install simple OCaml programs._ Alternatively, we can define a | |
251 | *PACKAGE* name and library files will go in | |
252 | `${PREFIX}/lib/ocaml/site-lib/${PACKAGE}` as in the following example: | |
253 | ||
254 | ```console | |
255 | % make PACKAGE=mypackage install | |
256 | ===> Switching to root credentials for target (install) | |
257 | Password: | |
258 | /usr/bin/install -c -d /usr/local/lib/ocaml/site-lib/mypackage | |
259 | install -o root -g wheel -m 444 newton.cma /usr/local/lib/ocaml/site-lib/mypackage | |
260 | install -o root -g wheel -m 444 newton.cmi /usr/local/lib/ocaml/site-lib/mypackage | |
261 | ``` | |
262 | ||
263 | ||
264 | ### Cleaning | |
265 | ||
266 | Finally, we can `make clean` or `make distclean` our working | |
267 | directory. | |
268 | ||
269 | ||
270 | ### Ad-hoc tests | |
271 | ||
272 | Assume that we have written a simple program `test_newton.ml` that | |
273 | we use to test our library. We can then use a command line like | |
274 | ||
275 | ``` | |
276 | % make && ocaml newton.cma test_newton.ml | |
277 | ``` | |
278 | ||
279 | to rebuild our library and run our test with a single command line. | |
280 | However each developer action should be doable in a single | |
281 | command, which allows to focus on the task _run the test_ instead of | |
282 | of the steps involved in the task. Here is how we can define an | |
283 | ad-hoc `test` target in the `Makefile`: | |
284 | ||
285 | ```makefile | |
286 | LIBRARY= newton | |
287 | SRCS+= newton.ml | |
288 | ||
289 | test: newton.cma .PHONY | |
290 | ocaml newton.cma test_newton.ml | |
291 | ||
292 | .include "ocaml.lib.mk" | |
293 | ``` | |
294 | ||
295 | The two new lines read as “in order to perform the _test_ please | |
296 | refresh `newton.cma` and call `ocaml newton.cma test_newton.ml`. The | |
297 | `.PHONY` keyword tells `make(1)` that the target _test_ will not | |
298 | produce a file called `test`, but rather defines a task to perform. | |
299 | We can then `make test`: | |
300 | ||
301 | ```console | |
302 | % make test | |
303 | ocamlc -c -o newton.cmi newton.mli | |
304 | ocamlc -c -o newton.cmo newton.ml | |
305 | ocamlc -a -o newton.cma newton.cmo | |
306 | ocaml newton.cma test_newton.ml | |
307 | 06 1.00000000 | |
308 | 05 2.00000000 | |
309 | 04 1.66666667 | |
310 | 03 1.61904762 | |
311 | 02 1.61803445 | |
312 | 01 1.61803399 | |
313 | 00 1.61803399 | |
314 | ``` | |
315 | ||
316 | The lines starting with numbers are the output of the test, it | |
317 | computes the golden ratio using Newton's method. | |
318 | ||
319 | ||
320 | ### META file | |
321 | ||
322 | If we have prepared a META file so that our library can be found by | |
323 | `ocamlfind(1)` we only need to include `ocaml.meta.mk` right before | |
324 | the `ocaml.lib.mk`. If for some reason, we prefer having the `META` | |
325 | file in its own directory, a sample `Makefile` would be | |
326 | ||
327 | ```makefile | |
328 | LIBDIR?= ${PREFIX}/lib/ocaml/site-lib${PACKAGEDIR} | |
329 | .include "ocaml.meta.mk" | |
330 | ``` | |
331 | ||
332 | ||
333 | ### Packed modules | |
334 | ||
335 | We might prefer producing a packed module instead of a library. The | |
336 | setup is very similar to the one we use for a library: | |
337 | ||
338 | ```makefile | |
339 | PACK= libNewton | |
340 | SRCS+= newton.ml | |
341 | .include "ocaml.pack.mk" | |
342 | ``` | |
343 | ||
344 | ## Prepare and install documentation | |
345 | ||
346 | The generation of documentation with **ocamldoc** is supported. We | |
347 | build over the first **newton** library example and assume the file | |
348 | `newton.mli` contains documentation annotations that can be used by | |
349 | `ocamldoc`. We can edit our `Makefile` as follows: | |
350 | ||
351 | ```makefile | |
352 | LIBRARY= newton | |
353 | SRCS+= newton.ml | |
354 | USES+= ocamldoc:odoc,html | |
355 | ||
356 | ODOC_NAME= newtontk | |
357 | ODOC_TITLE= Newton's method | |
358 | .include "ocaml.lib.mk" | |
359 | ``` | |
360 | ||
361 | Setting `USES+=ocamldoc:odoc,html` tells `ocaml.lib.mk` it should use | |
362 | `ocamldoc` to generate on-line documentation, the *ODOC_NAME* is an | |
363 | identifiant used to construct file names for the output, and the value | |
364 | of *ODOC_TITLE* is used as title in the generated documentation. This | |
365 | latter variable is not mandatory and if we feel lazy, we can left it | |
366 | uninitialised. We are now ready to `make` everything, which will | |
367 | rebuild the library and generate the documentation: | |
368 | ||
369 | ```console | |
370 | % make | |
371 | make depend | |
372 | make build | |
373 | ocamlc -c -o newton.cmi newton.mli | |
374 | ocamlc -c -o newton.cmo newton.ml | |
375 | ocamlc -a -o newton.cma newton.cmo | |
376 | make doc | |
377 | ocamldoc -t "Newton's method" -dump newtontk.odoc newton.ml newton.mli | |
378 | rm -R -f newtontk_html.temp newtontk_html | |
379 | mkdir newtontk_html.temp | |
380 | ocamldoc -t "Newton's method" -html -d newtontk_html.temp newton.ml newton.mli | |
381 | mv newtontk_html.temp newtontk_html | |
382 | ``` | |
383 | ||
384 | The documentation generation step has two products, an `ocamldoc` dump | |
385 | that we can use in other `ocamldoc` runs with the `-load` option and a | |
386 | directory `${ODOC_NAME}_html` holding the HTML generated | |
387 | documentation. We can tune the products we want to generate by | |
388 | setting appropriately the arguments of the `USES+=ocamldoc` assignment | |
389 | `ocaml.odoc.lib` file. There we will also see how to tune the | |
390 | generated output by adding a custom CSS file or a charset other than | |
391 | ISO-8859-1 in our input files. | |
392 | ||
393 | If we want to rebuild the library without rebuilding the | |
394 | documentation, we can use the `build` target instead of the `all` | |
395 | target implied by an empty list of arguments to `make`, as in | |
396 | ||
397 | ``` | |
398 | % make build | |
399 | ocamlc -c -o newton.cmi newton.mli | |
400 | ocamlc -c -o newton.cmo newton.ml | |
401 | ocamlc -a -o newton.cma newton.cmo | |
402 | ``` | |
403 | ||
404 | Conversely `make doc` will only regenerate the documentation. | |
405 | ||
406 | ||
407 | ## Prepare and install a custom toplevel | |
408 | ||
409 | Here is an example of `Makefile` that will allow you to prepare a | |
410 | toplevel linked against the `unix` and `str` libraries and the | |
411 | `initialise_toplevel` module: | |
412 | ||
413 | TOPLEVEL = toplevel | |
414 | SRCS = initialise_toplevel.ml | |
415 | LIBS = unix | |
416 | LIBS+= str | |
417 | .include "ocaml.toplevel.mk" | |
418 | ||
419 | There is an interface to options several of `opcamlmktop` please refer | |
420 | to the `ocaml.toplevel.mk` file. | |
421 | ||
422 | **Note** We would like to provide a more capable and useful toplevel | |
423 | production support. See this ticket: | |
424 | ||
425 | https://bitbucket.org/michipili/bsdowl/issue/7/powerful-ocamltoplevelmk | |
426 | ||
427 | ||
428 | ## Generate lexers and parsers | |
429 | ||
430 | The standard tools **ocamllex** and **ocamlyacc** are supported by | |
431 | **BSD Owl Scripts**. In order to interpret and compile lexers and | |
432 | parsers, we only need to list them as sources of our program as in | |
433 | the following example: | |
434 | ||
435 | ```makefile | |
436 | PROGRAM= minibasic | |
437 | ||
438 | SRCS = main.ml | |
439 | SRCS+= basic_types.ml | |
440 | SRCS+= basic_parser.mly | |
441 | SRCS+= basic_lexer.mll | |
442 | ||
443 | .include "ocaml.prog.mk" | |
444 | ``` | |
445 | ||
446 | If we wrote interface files for the generated implementation files, | |
447 | these will automatically be generated. | |
448 | ||
449 | ||
450 | ## Use third party libraries | |
451 | ||
452 | Linking against third party libraries distributed with a `META` file | |
453 | compatible with **ocamlfind** is supported through the *EXTERNAL* | |
454 | variable: | |
455 | ||
456 | ```makefile | |
457 | PROGRAM= wordcount | |
458 | ||
459 | SRCS+= extras.ml | |
460 | SRCS+= wordcount.ml | |
461 | ||
462 | EXTERNAL+= ocaml.findlib:str | |
463 | ||
464 | .include "ocaml.prog.mk" | |
465 | ``` | |
466 | ||
467 | Predicates can be added with the *PREDICATES* variable, they are | |
468 | passed to **ocamlfind** with the `-p` flag. | |
469 | ||
470 | Libraries which are not supporting **ocamlfind** can also be used, | |
471 | with a little more work. | |
472 | ||
473 | ```makefile | |
474 | PROGRAM= golden_ratio | |
475 | ||
476 | SRCS= main.ml | |
477 | ||
478 | EXTERNAL+= ocaml.findlib:nums | |
479 | EXTERNAL+= ocaml.lib:newton | |
480 | EXTERNAL+= ocaml.lib:fibonacci | |
481 | ||
482 | .include "ocaml.prog.mk" | |
483 | ``` | |
484 | ||
485 | In order to link our program against these libraries, **BSD Owl | |
486 | Scripts** still needs to know which archives to use and where to find | |
487 | them. This information is usually determined by the `configure` | |
488 | script and written to the file `Makefile.config` in the following format: | |
489 | ||
490 | ```makefile | |
491 | _EXTERNAL_ocaml.lib_newton_DIR=/usr/local/lib/newton | |
492 | _EXTERNAL_ocaml.lib_newton_BYTE=newton.cma | |
493 | _EXTERNAL_ocaml.lib_newton_NATIVE=newton.cmxa | |
494 | ||
495 | _EXTERNAL_ocaml.lib_fibonacci_DIR=/usr/local/lib/ | |
496 | _EXTERNAL_ocaml.lib_fibonacci_BYTE=fibonacci.cma | |
497 | _EXTERNAL_ocaml.lib_fibonacci_NATIVE=fibonacci.cmxa | |
498 | ``` | |
499 | ||
500 | ||
501 | ## Generate objects with debugging symbols | |
502 | ||
503 | Generation of objects containing debugging symbols is controlled by | |
504 | the `USES+= debug` knob. When it is used, all objects, | |
505 | executables and libraries are compiled or linked with the `-g` flag. | |
506 | ||
507 | ||
508 | ## Generate objects with profiling information | |
509 | ||
510 | Generation of objects containing debugging symbols is controlled by | |
511 | the `USES+= profile` knob. When it is used, all objects, | |
512 | executables and libraries are compiled or linked with profiling | |
513 | front-ends of the OCaml compiler. | |
514 | ||
515 | ||
516 | ## Use autoconf in our project | |
517 | ||
518 | We show how to use **autoconf** to let the user configure | |
519 | installation paths for our program. The `./configure` script | |
520 | generated by the following `configure.ac` will produce a | |
521 | file `Makefile.config` | |
522 | and a `standardDirectory.ml` file by replacing variables in | |
523 | `Makefile.config.in` and `standardDirectory.ml.in`. | |
524 | ||
525 | ``` | |
526 | AC_INIT([program.ml]) | |
527 | AC_CONFIG_FILES([standardDirectory.ml]) | |
528 | AC_CONFIG_FILES([Makefile.config]) | |
529 | AC_OUTPUT | |
530 | ``` | |
531 | ||
532 | It is better to produce an auxiliary `Makefile.config` file with | |
533 | `autoconf` instead of the primary `Makefile` so that the project tree | |
534 | remains in a usable state, even if it is not configured. | |
535 | ||
536 | There is `autoconf` macros available for OCaml-based projects, that | |
537 | will identify OCaml tools, and test for the availability of libraries: | |
538 | ||
539 | http://forge.ocamlcore.org/projects/ocaml-autoconf/ | |
540 | ||
541 | ||
542 | ## Organise a complex project | |
543 | ||
544 | We show how to use **BSD Owl Scripts** to organise the build of a | |
545 | small project consisting of two libraries and a program: a first | |
546 | library `newton` provides a service to compute the golden ratio using | |
547 | Newton's method, a second library `fibonacci` offers a computation | |
548 | method based on Fibonacci numbers. The `golden_ratio` program uses | |
549 | these two service to compare the approximations. | |
550 | ||
551 | ||
552 | ### Simple aggregate and delegate pattern | |
553 | ||
554 | First, create a master directory and three subdirectories `newton`, | |
555 | `fibonacci` and `golden_ratio` holding our software components. | |
556 | Along with the sources, these folder contain `Makefile`s as described | |
557 | in _Compile and install simple OCaml libraries_ and _Use third party | |
558 | libraries_ above. Once we are done, create the master `Makefile` in | |
559 | the master directory: | |
560 | ||
561 | ```makefile | |
562 | SUBDIR+= fibonacci | |
563 | SUBDIR+= newton | |
564 | SUBDIR+= golden_ratio | |
565 | ||
566 | .include "generic.subdir.mk" | |
567 | ``` | |
568 | ||
569 | The special `generic.subdir.mk` will delegate most targets to the | |
570 | subdirectories listed in *SUBDIR*. Thus we can `make` to produce | |
571 | libraries and program, `make install` and `make clean` also work | |
572 | similarly. | |
573 | ||
574 | ||
575 | ### Projects | |
576 | ||
577 | Besides delegating the common targets `all`, `install` and `clean` | |
578 | (for the most importants), there is much more project related tasks | |
579 | that can be handled my `Makefiles`. We provide a directives file | |
580 | `generic.project.mk` which is much more powerful than `generic.subdir.mk` and | |
581 | can be used to support our project development by automating other | |
582 | tasks. We can turn the previous `generic.subdir.mk`-based `Makefile` | |
583 | into a project in two steps. | |
584 | ||
585 | We first add declaration of a *PACKAGE*, a *VERSION* and an | |
586 | *OFFICER* variables—and of course editing the `.include` line: | |
587 | ||
588 | ``` | |
589 | PACKAGE= golden_ratio | |
590 | VERSION= 1.0.0 | |
591 | OFFICER= michipili@gmail.com | |
592 | ||
593 | SUBDIR+= fibonacci | |
594 | SUBDIR+= newton | |
595 | SUBDIR+= golden_ratio | |
596 | ||
597 | .include "generic.project.mk" | |
598 | ``` | |
599 | ||
600 | The *OFFICER* identifies the GPG-key of the release office, which is | |
601 | used to sign release tarballs. After this first step, we replace the | |
602 | assignements to *SUBDIR* as follows: | |
603 | ||
604 | ``` | |
605 | PACKAGE= golden_ratio | |
606 | VERSION= 1.0.0 | |
607 | OFFICER= michipili@gmail.com | |
608 | ||
609 | MODULE= ocaml.lib:fibonacci | |
610 | MODULE+= ocaml.lib:newton | |
611 | MODULE+= ocaml.prog:golden_ratio | |
612 | ||
613 | .include "generic.project.mk" | |
614 | ``` | |
615 | ||
616 | The *MODULE* variable is similar to *SUBDIR* in that it implements a | |
617 | delegate pattern. But besides implementing this pattern, it is aware | |
618 | of the products produced by the modules it enumerates and uses it to | |
619 | generate adequate linking information for libraries and programs. | |
620 | ||
621 | ||
622 | ### Preparing project tarballs | |
623 | ||
624 | Issuing `make dist` will `distclean` the master directory and prepare | |
625 | source tarballs in *PROJECTDISTDIR* for several archive formats. The | |
626 | name of the archive is deduced from *PROJECT* and *VERSION*. | |
627 | ||
628 | Some files present in the source directory can be filtered out from | |
629 | the tarball distribution by adding them to the *PROJECTDISTEXCLUDE* | |
630 | variable. | |
631 | ||
632 | Additional files that should be copied in the distribution | |
633 | directory—as a `ChangeLog` or `README`—can be specified in | |
634 | *PROJECTDIST*. | |
635 | ||
636 | ||
637 | Finally, it will try to sign tarballs with GPG, using the key | |
638 | identified by *OFFICER*. The signature file are stored in | |
639 | *PROJECTDISTDIR* along the distfiles produced in the last step. | |
640 | Additional files that should be signed can be specified in | |
641 | *PROJECTDISTSIGN*. | |
642 | ||
643 | ||
644 | ### Entering developer subshell | |
645 | ||
646 | The developer subshell is a normal interactive shell where some | |
647 | environement variables are set up to ease development. They are most | |
648 | useful if our project defines a project library, which is located in | |
649 | the `Library` directory inside the project master directory, or in any | |
650 | other location specified by *PROJECTLIBRARY*. | |
651 | ||
652 | If the project library contains a `Make` or `Mk` directory, or if the | |
653 | project master directory contains a `Mk` subdirectory, these are added | |
654 | to the lookup path of `make`. Thus, it is very easy to | |
655 | [define a library](ProjectLibrary) of `Makefile` for the various products of | |
656 | our project. | |
657 | ||
658 | If the project library contains an `Ancillary` directory, it added to | |
659 | the path, so that the `${PROJECTLIBRARY}/Ancillary` is a convenient | |
660 | place to [store scripts](ProjectLibrary) used in our project. | |
661 | ||
662 | ||
663 | ### Manage compilation configurations | |
664 | ||
665 | It is common to use several configuration sets when working on a | |
666 | project: sometimes the classical triad _debug_, _profile_ and | |
667 | _release_ are enough, sometimes more complicated setups are required. | |
668 | While there is no special provision (yet) for managing the compilation | |
669 | configurations in a project it is easy to implement. Here is how to: | |
670 | ||
671 | - Define several compilation setups. | |
672 | - Simultaneously prepare products with different distinct setups. | |
673 | ||
674 | Assume we have three compilation setups _debug_, _profile_ and | |
675 | _release._ For each of these setup we create a corresponding | |
676 | `Makefile`, so `Makefile.debug`, `Makefile.profile` and | |
677 | `Makefile.release` stored in *PROJECTLIBRARYMAKE*. | |
678 | ||
679 | Once we have created these files, we only need to export | |
680 | ||
681 | MAKEINITRC=Makefile.debug | |
682 | ||
683 | to work in the _debug_ compilation setup, for instance. Before | |
684 | changing this environment variable, it is advisable to `clean` our | |
685 | project tree—or to take advantage of the more advanced feature | |
686 | `MAKEOBJDIR`. | |
687 | ||
688 | The simultaneous build of our products with distinct compilation | |
689 | setups is achieved by adding these lines to our | |
690 | master `Makefile` (before the `.include` line): | |
691 | ||
692 | ```makefile | |
693 | PROJECTSETUP= debug profile release | |
694 | ||
695 | universe: | |
696 | .for setup in ${PROJECTSETUP} | |
697 | ${ENVTOOL} MAKEINITRC=Makefile.${setup} MAKEOBJDIR=${.CURDIR}/obj/${setup} ${MAKE} all | |
698 | .endfor | |
699 | ``` | |
700 | ||
701 | Issuing `make universe` will then create an `obj` directory containing | |
702 | subdirectories `debug`, `profile` and `release` holding compilation | |
703 | products. | |
704 | ||
705 | Depending on our workflow, there might be more useful ways to combine | |
706 | these features together. | |
707 | ||
708 | ||
709 | ### Prepare and install documentation for complex projects | |
710 | ||
711 | We can use `ocamldoc` to generate the documentation of a large | |
712 | project, which sources span across several directories. | |
713 | ||
714 | First, we require `ocamldoc` to generate an *ocamldoc dump* for each | |
715 | subpackage, which is achieved by parametrising the *ODOC_FORMAT* | |
716 | variable. Here is how the `Makefile` of the `newton` library in our | |
717 | `golden_ratio` project now looks like: | |
718 | ||
719 | ```makefile | |
720 | LIBRARY= newton | |
721 | SRCS+= newton.ml | |
722 | ||
723 | USES+= ocamldoc:odoc | |
724 | ODOC_NAME= newtontk | |
725 | ODOC_TITLE= Newton's method | |
726 | ||
727 | .include "ocaml.lib.mk" | |
728 | ``` | |
729 | ||
730 | The implicit format list used for `USES+= ocamldoc` is `odoc,html` so | |
731 | that the above setting merely inhibits the production of HTML | |
732 | documentation for `newton`. This documentation artefact is not useful | |
733 | anymore, since it is a subset of the global documentation whose | |
734 | production we are organising. | |
735 | ||
736 | In the project master directory, create a `manual` directory and | |
737 | create a `Makefile` there along these lines: | |
738 | ||
739 | ```makefile | |
740 | ODOC_TITLE= Golden Ratio | |
741 | ||
742 | .include "ocaml.manual.mk" | |
743 | ``` | |
744 | ||
745 | As a final step, integrate the `manual` directory to our project by | |
746 | appending it to the *MODULE* list in our master `Makefile`. Making | |
747 | `all` or `doc` will from now on produce HTML documentation! The `all` | |
748 | target is split as `configure depend build doc test` so, if we want | |
749 | to skip documentation generation, we can use `make build` instead of | |
750 | `make all` or `make`. |
0 | # Develop Shell Scripts | |
1 | ||
2 | This page describes the features of **BSD Owl Scripts** that are | |
3 | useful when developping shell scripts and shell routines. After | |
4 | reading this page, you will know: | |
5 | ||
6 | - How to install a simple shell program. | |
7 | - How to configure resource directories in shell programs. | |
8 | - How to test your shell program without installing it. | |
9 | - How to install shell libraries. | |
10 | ||
11 | Minimal examples for a program and a library can be found under | |
12 | [testsuite/script/test_shell][example-showconfig]. The | |
13 | [Anvil][example-anvil] project provides a more complete example. | |
14 | ||
15 | ||
16 | ## Install a simple shell program | |
17 | ||
18 | As a shell program is nothing more than a regular text file coming | |
19 | with the whole *sha-bang* and installed somewhere in the path, there | |
20 | is little processing required before installing these files. | |
21 | ||
22 | A simple `Makefile` to install a shell program looks like: | |
23 | ||
24 | ```Makefile | |
25 | PROGRAM= simple-shell-program.sh | |
26 | .include "shell.prog.mk" | |
27 | ``` | |
28 | ||
29 | This will install `simple-shell-program.sh` as `simple-shell-program` | |
30 | in `${BINDIR}`. The `PROGRAM` variable can enumerate several programs | |
31 | to install, ending with `.sh`, `.bash`, `.ksh`, `.csh`, `.awk` or | |
32 | `.sed`. If a file `simple-shell-program.1` or `simple-shell-program.8` | |
33 | is found, it will also be installed as a compressed manual page. | |
34 | ||
35 | ||
36 | ## Configure resource directories in shell programs | |
37 | ||
38 | There is one processing actually taking place before shell programs | |
39 | are installed: variables like `@prefix@` are expanded to their values | |
40 | as known to `make(1)`. These values are typically declared in the file | |
41 | `Makefile.config` found at the root of the project, this file is expected | |
42 | to be produced from a `Makefile.config.in` model by `./configure`. The | |
43 | variable `REPLACESUBST` contains the list of `@`-style variables which | |
44 | should be replaced by their values as known by `make(1)`. The variable | |
45 | `REPLACESUBST` already contains the `PACKAGE` and `VERSION` variables, and | |
46 | the standard directory variables. This mechanism can be used to | |
47 | convey values found by the `./configure` script to our program. An | |
48 | important example can be the path to the interpreter, since shells | |
49 | other than the Bourne shell do not need to have an installation path | |
50 | which is consistent across all operating systems. | |
51 | ||
52 | Note that this variable expansion also takes place in the prepraration | |
53 | of manual pages. | |
54 | ||
55 | ||
56 | ## Test your shell program without installing it | |
57 | ||
58 | As a shell-script developer, we do not want to repeatedly install a | |
59 | script in order to test it. Rather, we would like to test it without | |
60 | installing it, and especially to run the script in a controlled | |
61 | environment for automated testing. This problem can nicely be solved | |
62 | by using the shell `:` operator and the `:=` replacement modificator, | |
63 | as in the following example: | |
64 | ||
65 | ```sh | |
66 | : ${prefix:=@prefix@} | |
67 | : ${exec_prefix:=@exec_prefix@} | |
68 | : ${bindir:=@bindir@} | |
69 | … | |
70 | ``` | |
71 | ||
72 | With these declarations, the installed version of the script will use | |
73 | the values supplied by the `./configure` script while a special | |
74 | environment can easily be crafted for test purpposes, so that running | |
75 | the script does not require installation. | |
76 | ||
77 | Note that allowing the user to supersede directory variables in the | |
78 | environment might rise a security issue. The `sudo(8)` command can be | |
79 | used to delegate privileges while maintaining a controlled | |
80 | environment. | |
81 | ||
82 | ||
83 | ## Install shell libraries | |
84 | ||
85 | A simple `Makefile` requiring the installation of the shell routine | |
86 | library `simple-library.subr` looks like: | |
87 | ||
88 | ```Makefile | |
89 | LIBRARY= simple-library.subr | |
90 | .include "shell.lib.mk" | |
91 | ``` | |
92 | ||
93 | The files enumerated by `LIBRARY` are installed to `${SUBRDIR}` which | |
94 | defaults to `${SHAREDIR}`. If a file `simple-library.subr.3` or | |
95 | `simple-library.subr.8` is found, it is installed as a manual page. | |
96 | ||
97 | The replacement of `@`-style variables _does not happen_ when | |
98 | libraries of shell routines are processed — but it still happens for | |
99 | manual pages. The recommanded calling convention for libraries, is | |
100 | that the library client prepares all variables required by the library | |
101 | to run correctly. The library can use `:` constructs and `:?` | |
102 | replacement modifiers to ensure it runs in a sane environment. | |
103 | ||
104 | ||
105 | ## Other useful resources | |
106 | ||
107 | - *UNIX Shell Programming, 2nd edition* by Lowell Jay Arthur. | |
108 | - [Shellcheck][shell-check], an online linter for shell scripts. | |
109 | - A [list of obsolete or deprecated shell constructs][shell-obsolete] | |
110 | ||
111 | [example-anvil]: https://github.com/michipili/anvil | |
112 | [example-showconfig]: https://github.com/michipili/bsdowl/blob/master/testsuite/script/test_shell/showconfig.sh | |
113 | [shell-check]: http://www.shellcheck.net | |
114 | [shell-obsolete]: http://wiki.bash-hackers.org/scripting/obsolete |
0 | # Notes for developing BSD Owl Scripts | |
1 | ||
2 | A nice feature of **BSD Owl Scripts** is its *developer subshell*. At | |
3 | the root directory of any package which is developed with **BSD Owl | |
4 | Scripts** the special command | |
5 | ||
6 | ```console | |
7 | % make subshell | |
8 | ``` | |
9 | ||
10 | starts a *developer subshell*, it is a shell whose environment has | |
11 | been adjusted so that **BSD Make** and **BSD Owl Scripts** still can | |
12 | find the root directory of the package, its configuration, specific | |
13 | Makefiles and a lot of other files. | |
14 | ||
15 | This subshell is handy to work on a single module of the package. It | |
16 | is also customary to open several developer subshells, one visiting a | |
17 | module and another visiting the corresponding tests. | |
18 | ||
19 | Taking advantage of the developer subshell functionality requires to | |
20 | work in a sanitised environment. It is mandatory that your | |
21 | `~/.profile` or your `~/.cshrc` do not *prepend* the path to a **BSD | |
22 | Owl Script** installation to *MAKEFLAGS*. So, for instance, the Bourne | |
23 | profile snippet | |
24 | ||
25 | ```sh | |
26 | MAKEFLAGS="${MAKEFLAGS}${MAKEFLAGS:+ }-I ${HOME}/share/mk" | |
27 | export MAKEFLAGS | |
28 | ``` | |
29 | ||
30 | is safe, even if you installed **BSD Owl Scripts** in | |
31 | `${HOME}/share/mk`, but the snippet | |
32 | ||
33 | ```sh | |
34 | MAKEFLAGS="-I ${HOME}/share/mk${MAKEFLAGS:+ }${MAKEFLAGS}" | |
35 | export MAKEFLAGS | |
36 | ``` | |
37 | ||
38 | is not safe, because **BSD Owl Scripts** files in `${HOME}/share/mk` | |
39 | will shadow those in your working copy. |
0 | # Download BSD Owl Scripts | |
1 | ||
2 | You can get a distribution tarball suitable for installation from the | |
3 | [release area](https://github.com/michipili/bsdowl/releases). | |
4 | ||
5 | If you are interested in modifying the software, you can clone the GIT | |
6 | repository: | |
7 | ||
8 | ``` | |
9 | https://github.com/michipili/bsdowl.git | |
10 | ``` | |
11 | ||
12 | If you are running a UNIX like system for which BSD Make *is not | |
13 | available* as a package, you should consider [building it from source](BMake). | |
14 | For this, you should download | |
15 | [bmake.tar.gz](http://void.crufty.net/ftp/pub/sjg/bmake.tar.gz) | |
16 | and | |
17 | [mk.tar.gz](http://void.crufty.net/ftp/pub/sjg/mk.tar.gz) | |
18 | distributd by Simon J. Garrety. | |
19 | ||
20 | FreeBSD, NetBSD, OpenBSD and most Linux Distributions already provides | |
21 | BSD Make, wether as part of the base system or as a third party | |
22 | package. | |
23 | ||
24 | It seems that BSD Make is also packaged for Cygwin, but some users | |
25 | experienced troubles with that package. |
0 | # Getting started with a LaTeX document | |
1 | ||
2 | After reading this document, you will know how to use **BSD Owl | |
3 | Scripts** to support you in the preparation and maintenance of | |
4 | **LaTeX** documents and especially: | |
5 | ||
6 | - How to produce a PDF file out of your manuscript. | |
7 | - How to prepare a document using a bibliography. | |
8 | - How to prepare a document featuring METAPOST figures. | |
9 | ||
10 | This covers only the simplest use cases, the guide | |
11 | “[Production of LaTeX documents][latex-doc]” gives a deeper exposition | |
12 | of the features found in **BSD Owl Scripts** and their use. | |
13 | ||
14 | [latex-doc]: LaTeXDocument.md | |
15 | ||
16 | ||
17 | ## Produce a PDF file out of our manuscript | |
18 | ||
19 | We assume that we just created a manuscript `mylastarticle.tex` and | |
20 | will now prepare our system to let **BSD Owl Scripts** prepare the | |
21 | final PDF file. | |
22 | ||
23 | Along with our file `mylastarticle.tex` we create a `Makefile` with | |
24 | the following contents: | |
25 | ||
26 | ```makefile | |
27 | DOCS= mylastarticle.tex | |
28 | .include "latex.doc.mk" | |
29 | ``` | |
30 | ||
31 | Then we can `make` our document and `make clean` after this. | |
32 | ||
33 | ||
34 | ## Prepare a document using a bibliography | |
35 | ||
36 | If our document requires a bibliography prepared by **bibtex** we just | |
37 | need to add `USES+=bibtex` to our `Makefile`: | |
38 | ||
39 | ```makefile | |
40 | DOCS= mylastarticle.tex | |
41 | USES+= bibtex | |
42 | .include "latex.doc.mk" | |
43 | ``` | |
44 | ||
45 | This will automatically process our bibliography database with | |
46 | **bibtex.** If our bibliography database does not lie in the same | |
47 | directory as our article, we should tell **BSD Owl Scripts** where | |
48 | that database is located. For this, we use the `BIBINPUTS` variable: | |
49 | ||
50 | ```makefile | |
51 | DOCS= mylastarticle.tex | |
52 | USES+= bibtex | |
53 | BIBINPUTS= ${HOME}/share/texmf/bib | |
54 | .include "latex.doc.mk" | |
55 | ``` | |
56 | ||
57 | Note that `make clean` will not remove the compiled bibliography, so | |
58 | that we can `clean` your directory before sending it to an editor or | |
59 | the arXiv. To get rid of the compiled bibliography, we can use the | |
60 | more powerful `make realclean` mantra. | |
61 | ||
62 | **BSD Owl Scripts** can also take care of our **METAPOST** figures. If | |
63 | we use the `grahicx` package in **LaTeX.** all we need to do is to | |
64 | enumerate our metapost source files in the `FIGS` variable: | |
65 | ||
66 | ```makefile | |
67 | DOCS= mylastarticle.tex | |
68 | FIGS= desargues.mp | |
69 | FIGS+= conics.mp | |
70 | .include "latex.doc.mk" | |
71 | ``` | |
72 | ||
73 | The next time we `make` our document, **METAPOST** will be called | |
74 | automatically. Please note that **BSD Owl Scripts** runs **METAPOST** | |
75 | with the following options: | |
76 | ||
77 | ``` | |
78 | -s 'prologues=3' | |
79 | -s 'outputtemplate="%j-%c.mps"' | |
80 | ``` | |
81 | ||
82 | With a similar intent as for bibliographies, making `clean` will not | |
83 | remove your pictures but making `realclean` will. |
0 | # Getting started with an OCaml program | |
1 | ||
2 | Here is how **BSD Owl Scripts** can help you to compile a simple OCaml | |
3 | program `wordcount`, your own implementation of the UNIX `wc(1)` | |
4 | utility. After reading this page, you will know: | |
5 | ||
6 | - How to compile a simple OCaml program. | |
7 | - How to install that program. | |
8 | - How to clean compilation products. | |
9 | - How to compile a more complex OCaml program using ocamlfind | |
10 | ||
11 | A minimal example for an OCaml program can be found under | |
12 | [testsuite/ocaml/test_program[example-program]. The | |
13 | [Gasoline][example-gasoline] project provides a more complete example. | |
14 | ||
15 | For this guide, we first assume that the source code is a single file | |
16 | `wordcount.ml` and then consider a more complex case. | |
17 | ||
18 | [example-gasoline]: https://github.com/michipili/gasoline | |
19 | [example-program]: ../testsuite/ocaml/test_program/TestProgram.mk | |
20 | ||
21 | ||
22 | ## Compile a simple OCaml program | |
23 | ||
24 | We create a directory to hold our files and put our source there. | |
25 | Along the source, we create a `Makefile` with the following content: | |
26 | ||
27 | ```makefile | |
28 | PROGRAM= wordcount | |
29 | .include "ocaml.prog.mk" | |
30 | ``` | |
31 | ||
32 | We can now `make` our program to produce a `wordcount` binary. The | |
33 | complete output of the make process looks like this: | |
34 | ||
35 | ```console | |
36 | make configure | |
37 | make depend | |
38 | (cd /Users/michael/Workshop/bsdowl-ocaml && ocamldep wordcount.ml) | cat > .depend | |
39 | make build | |
40 | ocamlc -c -o wordcount.cmo wordcount.ml | |
41 | ocamlc -o wordcount.byte wordcount.cmo | |
42 | cp wordcount.byte wordcount | |
43 | make doc | |
44 | make test | |
45 | ``` | |
46 | ||
47 | When we call `make` without argument it is the same thing as `make | |
48 | all` which decomposes as `make configure`, `make depend`, | |
49 | `make build`, `make doc` and `make test` as we see. In this example, | |
50 | the `make configure`, `make doc` and `make test` steps are not bound | |
51 | to any recipe or shell command, but it would be the case in more | |
52 | elaborated examples. | |
53 | ||
54 | We can now test our program, edit it and re-`make` it as needed. | |
55 | ||
56 | ||
57 | ## Install a simple OCaml program | |
58 | ||
59 | Once we are satisfied with the results, we can install it | |
60 | with `make install`. It will call `su` to gain root privileges | |
61 | and install our program under `/usr/local/bin`, a value deduced | |
62 | from *PREFIX* | |
63 | ||
64 | ```console | |
65 | % make install | |
66 | ===> Switching to root credentials for target (install) | |
67 | Password: | |
68 | /usr/bin/install -c -d /usr/local/bin | |
69 | install -o root -g wheel -m 555 wordcount /usr/local/bin | |
70 | ``` | |
71 | ||
72 | We can examine the value of the *PREFIX* variable, as any other | |
73 | variable, with `make -V`: | |
74 | ||
75 | ```console | |
76 | % make -V PREFIX | |
77 | /usr/local | |
78 | ``` | |
79 | ||
80 | If we want to install our program to another location like | |
81 | `${HOME}/bin` we only need to change the *PREFIX*. The prefix | |
82 | selection is usually left to the `configure` script of a project, | |
83 | but, for this simple example, we will only add a `PREFIX=${HOME}` | |
84 | assignment to our `Makefile`: | |
85 | ||
86 | ```makefile | |
87 | PROGRAM= wordcount | |
88 | PREFIX= ${HOME} | |
89 | .include "ocaml.prog.mk" | |
90 | ``` | |
91 | ||
92 | The order of variable declarations is not important but they have to | |
93 | come before the `.include` line. While this step can sometimes be | |
94 | skipped, it is a good habit to `make clean` after changing the | |
95 | configuration of a package. | |
96 | ||
97 | ||
98 | ```console | |
99 | % make clean install | |
100 | … | |
101 | /usr/bin/install -c -d /home/michael/bin | |
102 | install -o michael -g michael -m 550 wordcount /home/michael/bin | |
103 | ``` | |
104 | ||
105 | Note that since we have write access to the *PREFIX* directory, it is | |
106 | not necessary to gain root privileges for this installation. | |
107 | ||
108 | ||
109 | ## Clean compilation products | |
110 | ||
111 | Once we are done, we can remove object code from the directory with | |
112 | ||
113 | ```console | |
114 | % make clean | |
115 | rm -f wordcount.cmo wordcount.cmi wordcount.cb wordcount | |
116 | ``` | |
117 | ||
118 | If we look closely, we will notice that the `.depend` file is not | |
119 | removed: | |
120 | ||
121 | ```console | |
122 | % ls -A | |
123 | .depend Makefile wordcount.ml | |
124 | ``` | |
125 | ||
126 | This is on purpose, and if we also want to get rid of the `.depend` | |
127 | file we can use the more powerful mantra | |
128 | ||
129 | ```console | |
130 | % make realclean | |
131 | rm -f wordcount.cmo wordcount.cmi wordcount.cb wordcount | |
132 | rm -f .depend | |
133 | ``` | |
134 | ||
135 | ||
136 | ## Compile a more complex OCaml program using ocamlfind | |
137 | ||
138 | As a consequence _Zawinski's Law of Software Envelopment_ we decided | |
139 | to build a mail reader in our `wordcount` program. Our code source | |
140 | now consists of our main file `wordcount.ml` and a library | |
141 | `mailreader.ml` relying on the `lwt.unix` library. Here is the | |
142 | corresponding `Makefile`: | |
143 | ||
144 | ```makefile | |
145 | PROGRAM= wordcount | |
146 | SRCS+= mailreader.ml | |
147 | SRCS+= wordcount.ml | |
148 | ||
149 | EXTERNAL= ocaml.findlib:github.unix | |
150 | ||
151 | .include "ocaml.prog.mk" | |
152 | ``` | |
153 | ||
154 | While dependencies between modules are computed with `ocamldep` so | |
155 | that modules are compiled as needed, the order in which the files are | |
156 | listed in *SRCS* is used by the linker. It is thus important to list | |
157 | files in an order suited to the linking phase. | |
158 | ||
159 | ||
160 | ## Features highlight | |
161 | ||
162 | Here is a list of more advanced features that we may find useful when | |
163 | developping OCaml projects: | |
164 | ||
165 | - Compilation of bytecode and native executables; | |
166 | - Support of ocamlfind to link against 3rd party packages; | |
167 | - Support of ocamldoc to generate module documentation; | |
168 | - Support of ocamlprof to generate profiling information; | |
169 | - Support of debugging symbols; | |
170 | - Support of ocamllex and ocamlyacc to generate lexers and parsers; | |
171 | - Support parallel mode (at the directory level); | |
172 | - Support separate trees for sources and objects; | |
173 | - Support native and byte code; | |
174 | - Smart dependencies handling avoiding “inconsistant assumptions” over | |
175 | interfaces. | |
176 | ||
177 | These features are described in the documentation. |
0 | # Documentation index | |
1 | ||
2 | ||
3 | ## Short guides | |
4 | ||
5 | - [Getting started with a LaTeX document](GettingStartedLaTeX) | |
6 | - [Getting started with an OCaml program](GettingStartedOCaml) | |
7 | ||
8 | ||
9 | ## Starting points for users | |
10 | ||
11 | The file [README](../README.md) contains instructions to | |
12 | [download](Download) and [install](../INSTALL.md) the package and your | |
13 | are now probably interested in getting started: | |
14 | ||
15 | - Learn how to [Prepare LaTeX documents](LaTeXDocument) documents, | |
16 | with support for METAPOST figures, bibliographies, and documents | |
17 | spreading acroess several files or directories (like a thesis). | |
18 | ||
19 | - Useful scripts support you if you | |
20 | [develop OCaml Software](DevelopOCamlSoftware) taking care of the | |
21 | compilation of programs, libraries and toplevels. Dependencies are | |
22 | automatically generated with `ocamldep` and parallel builds are | |
23 | supported. | |
24 | ||
25 | - As a UNIX user you are likely to | |
26 | [develop shell scripts and libraries](DevelopShellScripts) or to | |
27 | have several [configuration files](ManageDotFiles) so we help you | |
28 | taking care of them. | |
29 | ||
30 | ||
31 | ## Starting points for developers and porters | |
32 | ||
33 | Be sure to [setup your environment appropriately](Developer) and to | |
34 | read the [short description of concepts](Concepts) for our build | |
35 | system. Happy hacking! |
0 | # Producing LaTeX documents | |
1 | ||
2 | On this page, you will learn how to use **BSD Owl Scripts** to: | |
3 | ||
4 | - Produce simple LaTeX documents and publish them on the file system. | |
5 | - Install or publish LaTeX documents. | |
6 | - Produce LaTeX documents in various output formats. | |
7 | - Produce *drafts* of LaTeX documents. | |
8 | - Produce documents having more than one source file. | |
9 | - Produce documents including METAPOST figures. | |
10 | - Produce standalone figures with METAPOST. | |
11 | - Produce documents including BibTeX bibliographies | |
12 | - Produce an index for a LaTeX document. | |
13 | - Produce documents having parts that need to be automatically | |
14 | generated, like tables or database reports. | |
15 | - Deal with documents whose source spans across several directories. | |
16 | - Deal with a huge number of documents. | |
17 | ||
18 | There is a useful program called **latexmk** whose functionality | |
19 | partially overlaps what **BSD Owl Scripts** offers. These tools are | |
20 | however built under distinct, complementary perpsectives. Indeed | |
21 | **latexmk** focuses on the very production of a document, while | |
22 | **BSD Owl Scripts** allows to integrate the production of this document | |
23 | in the context of the production of a full project. The integration of | |
24 | **latexmk** in **BSD Owl Scripts** is planned. | |
25 | ||
26 | ||
27 | ## Foreword — Working with TeX or LaTeX | |
28 | ||
29 | There is multiple TeX formats in use, *plain TeX* and *LaTeX* are | |
30 | examples of such formats. The LaTeX format enjoys a wide community of | |
31 | users, so the module `latex.doc.mk` is used in examples. However most | |
32 | of the following also applies to the module `tex.doc.mk` supporting | |
33 | *plain TeX*. It is easy to write a customised version of | |
34 | `latex.doc.mk` to support other TeX formats, if required. | |
35 | Some paragraphs in the sequel document mechanisms specific to | |
36 | `latex.doc.mk`, they are explicitly identified as such. | |
37 | ||
38 | ||
39 | ## Produce simple LaTeX documents | |
40 | ||
41 | Assume the file `script.tex` holds our | |
42 | manuscript. We put it in a directory dedicated to our document, and | |
43 | create a `Makefile` file (note the leading capital) with the following | |
44 | content: | |
45 | ||
46 | ```makefile | |
47 | DOCUMENT= script.tex | |
48 | .include "latex.doc.mk" | |
49 | ``` | |
50 | ||
51 | Our document's directory now contains the `paper.tex` file and the | |
52 | `Makefile` described above. We visit this directory with our shell | |
53 | and issue the `make` command: | |
54 | ||
55 | ```console | |
56 | % make | |
57 | make build | |
58 | ===> Multipass job for script.pdf (aux) | |
59 | latex script.tex | |
60 | This is pdfeTeX, Version 3.141592-1.21a-2.2 (Web2C 7.5.4) | |
61 | entering extended mode | |
62 | (./script.tex | |
63 | LaTeX2e <2003/12/01> | |
64 | ... | |
65 | ``` | |
66 | ||
67 | If our manuscript has no error, we end up with the following | |
68 | _object files_ in our working directory: | |
69 | ||
70 | ```console | |
71 | % ls | |
72 | Makefile script.log | |
73 | script.aux script.tex | |
74 | script.pdf script.toc | |
75 | ``` | |
76 | ||
77 | Once we are done with these objects, we can clean the directory | |
78 | with the `make clean` mantra: | |
79 | ||
80 | ```console | |
81 | % make clean | |
82 | rm -f script.pdf script.log script.aux script.toc | |
83 | ``` | |
84 | ||
85 | Cleaning the directory is an optional step, but it prevents our | |
86 | storage and your archive media to end up filled with unused data, that | |
87 | can be quickly recreated on demand. While DVI files are usually very | |
88 | small, a few hundred kilobytes, the PS or PDF objects are often much | |
89 | larger. | |
90 | ||
91 | ||
92 | ## Install or publish documents | |
93 | ||
94 | Before we clean up your working directory with the `make clean` | |
95 | mantra, we may wish to store the document we created in some | |
96 | adequate place of the local file system. This step is called | |
97 | _installation_ of our document, because it is analogous to the | |
98 | installation of a program we freshly compiled. We can require the | |
99 | installation of our document with the `make install` command, but we | |
100 | must first tell make which place is actually adequate. This is done by | |
101 | assigning the _DOCDIR_ variable with the path to the directory | |
102 | we want our files to be copied to, as displayed by the following | |
103 | `Makefile`: | |
104 | ||
105 | ```makefile | |
106 | DOCUMENT= script.tex | |
107 | DOCDIR= ${HOME}/doc/report | |
108 | .include "latex.doc.mk" | |
109 | ``` | |
110 | ||
111 | We can then proceed with the `make install` command: | |
112 | ||
113 | ```console | |
114 | % make install | |
115 | install -d /home/michi/doc/report | |
116 | install -o michi -g michi -m 440 script.pdf /home/michi/doc/report | |
117 | ``` | |
118 | ||
119 | In comparison with the manual approach for storing the object in a | |
120 | safe place with the _cp_ command, we save retyping the target | |
121 | directory name the next time we update our document. But delegating | |
122 | this easy step to the `Makefile` has other benefits: | |
123 | ||
124 | - It eases the organisation of our document sources library. | |
125 | - It scales to a large number of documents, see _Working with a large | |
126 | number of documents_ below. | |
127 | - In draft-mode, a time stamp identifying the compilation time or the | |
128 | last modification time is automatically added to the file name, see | |
129 | below. | |
130 | ||
131 | ||
132 | ## Produce LaTeX documents in various output formats | |
133 | ||
134 | The TeX tool chain is capable of producing electronic documents in | |
135 | several formats. Commonly used formats are DVI, PostScript (PS) and | |
136 | PDF. The _TEXDEVICE_ variable governs the format of documents produced | |
137 | with the help of latex.doc.mk. Its value is usually _pdf_, so | |
138 | that `latex.doc.mk` will produce a PDF file from our source. Other | |
139 | possible values are _ps_ or _dvi_. If we configured a | |
140 | PostScript printer _TEXPRINTER_ with the **texconfig** program, we | |
141 | also can use _TEXPRINTER.ps_ as a value in _TEXDEVICE,_ it will | |
142 | instruct `dvips` to use the settings for _TEXPRINTER_ when translating | |
143 | our DVI file to PostScript. It is also possible to list several | |
144 | output formats in _TEXDEVICE,_ like _dvi pdf ps.TEXPRINTER1 ps.TEXPRINTER2_. | |
145 | ||
146 | ||
147 | ### Produce drafts of LaTeX documents | |
148 | ||
149 | Some formats or macros need our manuscript to be processed several | |
150 | times by TeX or LaTeX before we obtain the final version of our | |
151 | document. The `latex.tex.mk` module enforces multipass treatment of | |
152 | the manuscript, because LaTeX needs this to produce correct cross | |
153 | references created with _label_ and _ref_ commands within our | |
154 | document. The `doc.tex.mk` module will not do multiple treatment of | |
155 | our manuscript unless we set the variable _MULTIPASS_ to a list of | |
156 | names, each element giving its name to a pass. The choice of these | |
157 | names does not have a real importance, as they are only displayed to | |
158 | the user. | |
159 | ||
160 | In the early stages of existence of a document, updates are likely to | |
161 | be frequent and it is thus desirable to avoid the lengthy multiple | |
162 | passes processing. **BSD Owl Scripts** has a draft mode for this. | |
163 | To enable the draft mode, we add a statement `USES+= draft` to | |
164 | our `Makefile`, as shown by the following example: | |
165 | ||
166 | ```makefile | |
167 | DOCUMENT= script.tex | |
168 | USES+= draft | |
169 | .include "latex.doc.mk" | |
170 | ``` | |
171 | ||
172 | When we have finished polishing your manuscript, we can remove the | |
173 | `USES+= draft` assignment from the `Makefile`, our paper is then ready for a | |
174 | last _make_ run producing the final version of our document. If we | |
175 | are satisfied with it, we can _install_ it. | |
176 | ||
177 | When working on a document, it might be useful to keep copies of the | |
178 | objects we produced at some special point of your work. For instance, | |
179 | picture ourselves sending a copy of our work to a friend. Our friend | |
180 | will read our paper with attention and send us back his comments, | |
181 | but in the meanwhile, we kept on improving our document. When we | |
182 | receive the comments of our friend, we will compare them to the | |
183 | document we sent him. It is therefore useful to keep a copy of it. | |
184 | The best way to do this is to use a [RCS][wikipedia-rcs], | |
185 | a special software keeping track of the various revisions of a file. | |
186 | Those who do not use such a system and want to try one might be | |
187 | interested in **git**, especially if they are relying on EMails to | |
188 | organise your collaborative work. | |
189 | ||
190 | When working with the `USES+= draft` setting, the name of installed | |
191 | documents is modified to display the time when `make install` was run. | |
192 | This should help to identify the produced version. If we use a **git** | |
193 | or **subversion** to keep track of the revision of our files, | |
194 | we should modify the `USES+= draft` statement to | |
195 | `USES+= draft:git` or `USES+= draft:svn`. If we do so, the time of | |
196 | the last commit and its identifier (the short hash for **git** and the | |
197 | revision number for **subversion**) is used to identify the produced version. | |
198 | This is much more useful than the time at which `make install` was run | |
199 | since it unambiguously identifies a state of our repository. | |
200 | ||
201 | [wikipedia-rcs]: http://en.wikipedia.org/wiki/Revision_Control_System | |
202 | ||
203 | ||
204 | ## Produce documents having more than one source file | |
205 | ||
206 | If we are working on a complex document, we certainly will split | |
207 | our sources into several files. Usually one file per chapter, or per | |
208 | section, plus a main file containing the preamble and many | |
209 | _input_ statements to instruct LaTeX to read all of the files | |
210 | representing the document's contents. | |
211 | ||
212 | Assume that our document is split into a main file `galley.tex` | |
213 | and two other files `part1.tex` and `part2.tex`. Our `galley.tex` | |
214 | certainly looks like this: | |
215 | ||
216 | ```latex | |
217 | \documentclass{article} | |
218 | \begin{document} | |
219 | \input{part1} | |
220 | \input{part2} | |
221 | \end{document} | |
222 | ``` | |
223 | ||
224 | A suitable `Makefile` is then: | |
225 | ||
226 | ```makefile | |
227 | DOCUMENT= galley.tex | |
228 | SRCS= part1.tex | |
229 | SRCS+= part2.tex | |
230 | .include "latex.doc.mk" | |
231 | ``` | |
232 | ||
233 | ||
234 | ## Produce documents including METAPOST figures | |
235 | ||
236 | Modules `latex.doc.mk` and `tex.doc.mk` comes with a nice support for | |
237 | [METAPOST][metapost-home]. This is something worth noting, since | |
238 | METAPOST is often the right tool to be used for drawing figures | |
239 | appearing in TeX documents, but support for it is missing in many GUI | |
240 | editors for LaTeX. | |
241 | ||
242 | These modules assume that METAPOST source does not manipulate the | |
243 | values of the variables `prologues`, `outputtemplate` and | |
244 | `outputformat`. They set-up these variables so that: | |
245 | ||
246 | ```metapost | |
247 | prologues := 3; | |
248 | outputtemplate := "%j-%c.mps"; | |
249 | ``` | |
250 | ||
251 | These setting are appropriate when working with modern versions of | |
252 | METAPOST and the *graphicx* LaTeX package. The first declaration | |
253 | parametrises the inclusion of fonts in the output, while the second | |
254 | reconfigures the names used for output. | |
255 | ||
256 | Assume we prepared illustrations for our article with METAPOST, | |
257 | and split our illustrations into two files `illustr1.mp` and | |
258 | `illustr2.mp`. To let `latex.doc.mk` handle the production of our | |
259 | figures, we add _SRCS_ statements to your `Makefile`: | |
260 | ||
261 | ```makefile | |
262 | DOCUMENT= galley.tex | |
263 | SRCS= part1.tex | |
264 | SRCS+= part2.tex | |
265 | SRCS+= illustr1.mp | |
266 | SRCS+= illustr2.mp | |
267 | .include "latex.doc.mk" | |
268 | ``` | |
269 | ||
270 | We then type in _make_ at the shell prompt. The `latex.doc.mk` will | |
271 | figure out how many illustrations are present in each file, and | |
272 | produce the image files required by our _TEXDEVICE._ For instance, if | |
273 | our _TEXDEVICE_ is _pdf,_ and `illustr1.mp` contains two figures | |
274 | introduced by `beginfig(1)` and `beginfig(2)`, we end up with four files | |
275 | ||
276 | ```console | |
277 | % ls *.{mps,pdf} | |
278 | illustr1-1.mps | |
279 | illustr1-1.pdf | |
280 | illustr1-2.mps | |
281 | illustr1-2.pdf | |
282 | ``` | |
283 | ||
284 | The files ending in `.mps` are intermediary files in PostScript format, | |
285 | and the remaining ones are PDF files suited for inclusion | |
286 | in our document. | |
287 | ||
288 | Using the _graphicx_ package, inclusion is as easy as it should be: | |
289 | ||
290 | ```latex | |
291 | \includegraphics{illustr1-1}% | |
292 | ``` | |
293 | ||
294 | _Discovering METAPOST._ It seems that many people do not know about | |
295 | METAPOST. For those interested in discovering it, the first good news | |
296 | is that this program is included by many (if not all) TeX | |
297 | distributions, hence it is probably already available on their system. | |
298 | The second good news is that they can easily find plenty of | |
299 | information and examples of its use on the WWW. For instance, the | |
300 | [TeX users group][metapost-tug] has a page on its website devoted to | |
301 | this tool. The list they will find there is pretty long, so let me add that | |
302 | I especially like the [introduction written by André Heck][metapost-heck], | |
303 | it might also be a good starting point for them. | |
304 | ||
305 | [metapost-heck]: http://staff.science.uva.nl/~heck/Courses/mptut.pdf | |
306 | [metapost-home]: http://cm.bell-labs.com/who/hobby/MetaPost.html | |
307 | [metapost-tug]: http://www.tug.org/metapost.html | |
308 | ||
309 | ||
310 | ## Produce standalone figures with METAPOST | |
311 | ||
312 | The module `mpost.doc.mk` allows the creation of METAPOST pictures in | |
313 | the following formats: Encapuslated PostScript, PDF, PNG and SVG. | |
314 | Assume that we prepared two series of illustrations in files | |
315 | `illustr1.mp` and `illustr2.mp` and we want to produce them in each of | |
316 | the aforementioned formats. The corresponding `Makefile` is: | |
317 | ||
318 | ```makefile | |
319 | DOCUMENT= illustr1.mp | |
320 | DOCUMENT+= illustr2.mp | |
321 | MPDEVICE= eps pdf png svg | |
322 | .include "mpost.doc.mk" | |
323 | ``` | |
324 | ||
325 | ||
326 | ## Produce documents including BibTeX bibliographies | |
327 | ||
328 | **BSD Owl Scripts** support the preparation of bibliographies with BibTeX. | |
329 | First, we must be sure that the program TeX will find the | |
330 | bibliographic databases we enumerated in our document with | |
331 | _bibliography_ statements. It is customary to gather these bibliographic | |
332 | databases in some directory, for instance _${HOME}/share/bib_. To let | |
333 | BibTeX find these files, it is enough to add _${HOME}/share/bib_ to | |
334 | the content of the variable _BIBINPUTS_. If our bibliographic | |
335 | databases are scattered among several directories, we just need to | |
336 | let each of them appear in the value of the variable _BIBINPUTS_: | |
337 | ||
338 | ```makefile | |
339 | DOCUMENT= galley.tex | |
340 | SRCS= part1.tex | |
341 | SRCS+= part2.tex | |
342 | BIBINPUTS= ${HOME}/share/bib | |
343 | BIBINPUTS+= ${.CURDIR}/morebib | |
344 | USES+= bibtex | |
345 | .include "latex.doc.mk" | |
346 | ``` | |
347 | ||
348 | We note that the _make clean_ mantra will leave intact the BBL file | |
349 | produced by BibTeX. This is because we sometimes need to send this | |
350 | file to our publisher rather than an unprocessed BibTeX database. | |
351 | Hence the _make clean_ or _make distclean_ will leave our document's | |
352 | directory in the state we want to have it when we want to | |
353 | redistribute it. To get rid of the BBL file as well, we need to use | |
354 | the more powerful mantra _make realclean_. | |
355 | ||
356 | ||
357 | ## Produce an index for a LaTeX document | |
358 | ||
359 | If an index must be prepared for a LaTeX document with the program | |
360 | `makeindex` a `USES+=index` statement must be added to the `Makefile`, | |
361 | as displayed by the following example: | |
362 | ||
363 | ```makefile | |
364 | DOCUMENT= galley.tex | |
365 | SRCS= part1.tex | |
366 | SRCS+= part2.tex | |
367 | USES+= index | |
368 | .include "latex.doc.mk" | |
369 | ``` | |
370 | ||
371 | ||
372 | ## Several documents in the same directory | |
373 | ||
374 | While it is often a good idea to reserve a directory for each of | |
375 | your documents, we might have some reasons to keep several documents | |
376 | in the same directory. We have your reasons and they are probably | |
377 | good ones, so **BSD Owl Scripts** will do its best to help us. | |
378 | ||
379 | We assume that we have two documents whose sources are living in the | |
380 | same directory, let's say an article and an abridged version of this | |
381 | article. These manuscripts share a macro file `macro.tex`, but are otherwise | |
382 | rather independent from LaTeX's point of view. The text of the article | |
383 | is split across two files, `section1.tex` and `section2.tex`. The | |
384 | abridged version has just one text file `summary.tex`. | |
385 | The `Makefile` we use looks like this: | |
386 | ||
387 | ```makefile | |
388 | DOCUMENT= article.tex | |
389 | DOCUMENT+= summary.tex | |
390 | ||
391 | SRCS= macros.tex | |
392 | ||
393 | SRCS.article.tex= section1.tex | |
394 | SRCS.article.tex+= section2.tex | |
395 | ||
396 | .include "latex.doc.mk" | |
397 | ``` | |
398 | ||
399 | ||
400 | ## Produce documents having automatically generated parts | |
401 | ||
402 | Assume we are working on a document containing a table whose | |
403 | content is likely to change several times and will need to be | |
404 | updated. Such a table could be a budget: when the corresponding | |
405 | project evolves, so does the budget. It can be quite tedious to | |
406 | type in a table in LaTeX, and updating it might even be trickier. | |
407 | In such a situation, it is a good idea to write a program | |
408 | reading the raw data of our table and writing a LaTeX table | |
409 | displaying our data and everything we want to compute from it. Such | |
410 | a program is usually very easy to write, because we only need to deal | |
411 | with text files all of the time. The **awk** programming language | |
412 | could be a natural choice here but actually, almost any programming | |
413 | language would fit pretty neatly. | |
414 | ||
415 | So we have gathered the raw data of our table in the file `table.raw` | |
416 | and written a small filter `gentable` that will read that table data | |
417 | and write for us a LaTeX table on its standard output. In our | |
418 | manuscript, we use the name _table_ to refer to the file containing | |
419 | the generated table. Here is our `Makefile`: | |
420 | ||
421 | ```makefile | |
422 | DOCUMENT= galley.tex | |
423 | ||
424 | table.tex: gentable table.raw | |
425 | ./gentable < table.raw > table.tex | |
426 | ||
427 | REALCLEANFILES+= table.tex | |
428 | ||
429 | .include "latex.doc.mk" | |
430 | ``` | |
431 | ||
432 | If we send your files to someone else, he will maybe not want to | |
433 | run our program `gentable`, so it is better to list `table.tex` in | |
434 | _REALCLEANFILES_ rather than in _CLEANFILES_: we can clean your directory | |
435 | with `make clean`, archive its contents and send the archive to someone | |
436 | else without handling the generated `table.tex` in a special way. | |
437 | ||
438 | Of course, we can compute some text or a METAPOST picture, or | |
439 | pretty-print a piece of code, or whatever, instead of generating a | |
440 | table! | |
441 | ||
442 | Note that if you take advantage of the [OBJDIR](Objdir) feature of | |
443 | **BSD Owl Scripts**, the production rule for `table.tex` should actually be: | |
444 | ||
445 | ```makefile | |
446 | table.tex: gentable table.raw | |
447 | ${.CURDIR}/gentable < ${.ALLSRC:M*.raw} > ${.TARGET} | |
448 | .include "latex.doc.mk" | |
449 | ``` | |
450 | ||
451 | The special variables _.CURDIR,_ _.ALLSRC_ and _.TARGET_ are aware of | |
452 | the mechansisms involved in the use of [OBJDIR](Objdir). | |
453 | ||
454 | ||
455 | ## Deal with documents whose source spans across several directories | |
456 | ||
457 | Some workflows may prescribe that our source files are not located | |
458 | in a single directory, but disseminated across the file system. | |
459 | ||
460 | A reason for doing this could be that our organisation uses a custom | |
461 | document class for its letters, where some picture appears. We do | |
462 | not want to copy the picture file in each of the folders hosting our | |
463 | letters, nor do we want to have a symbolic link to the picture in | |
464 | each of our directories because the file is irrelevant to our work: | |
465 | we just want to not even know anything about the existence of this | |
466 | picture. The solution to this | |
467 | problem is to rely on the _TEXINPUTS_ variable, its content is a list | |
468 | of directories searched by TeX for its input files. | |
469 | ||
470 | Another reason motivating the dissemination of source files in | |
471 | several directories could be the preparation of a large document such as a | |
472 | book. If the files for each chapter are in separated directories, it | |
473 | is easy to process an isolated chapter with LaTeX during the | |
474 | preparation of the manuscript, for the purpose of proofreading. | |
475 | TeX must find all these files when it processes the main file | |
476 | including all the chapters, which is achieved by setting _TEXINPUTS_ | |
477 | to an appropriate value, as explained in the sequel. | |
478 | ||
479 | We can set the _TEXINPUTS_ variable in our environment or in our | |
480 | `Makefile`, or even write a custom `Makefile` template including this | |
481 | setting. The role of this variable for TeX is pretty similar | |
482 | to the role of the _PATH_ environment variable for the shell. | |
483 | ||
484 | Assume that the picture visually impersonating our organisation | |
485 | is saved in _${HOME}/share/texmf/tex/organisation/visual.eps_. | |
486 | In order to let TeX look for files in the folder containing the | |
487 | picture, we add a _TEXINPUTS_ statement to our _Makefile_, like | |
488 | this: | |
489 | ||
490 | ```makefile | |
491 | DOCUMENT= galley.tex | |
492 | TEXINPUTS= ${HOME}/share/texmf/organisation | |
493 | .include "latex.doc.mk" | |
494 | ``` | |
495 | ||
496 | If we now run _make_ in the folder containing this `Makefile`, we | |
497 | will see an output similar to the following in our terminal: | |
498 | ||
499 | ```console | |
500 | % make | |
501 | make build | |
502 | ===> Multipass job for galley.pdf (aux) | |
503 | env TEXINPUTS=".:${HOME}/share/texmf/organization:" pdflatex galley.tex | |
504 | This is pdfeTeX, Version 3.141592-1.21a-2.2 (Web2C 7.5.4) | |
505 | … | |
506 | ``` | |
507 | ||
508 | Let us take a look at the _TEXINPUTS_ assignment which is part of the | |
509 | `env` command. Its difference with respect to the declaration in the | |
510 | `Makefile` above means that TeX will also look for files in the | |
511 | current directory (this is what the initial dot stands for) and all | |
512 | standard TeX locations (this is what the final colon stands for). | |
513 | ||
514 | If we want to have absolute control on the value of _TEXINPUTS_, we | |
515 | must add the assignment _USES+=texinputs:strict_ in our `Makefile`. | |
516 | If it reads this statement **BSD Owl Scripts** will refrain from | |
517 | adding the initial dot and the final colon to our `TEXINPUTS` | |
518 | declaration. | |
519 | ||
520 | The supporting macros for METAPOST also understand _TEXINPUTS_ and | |
521 | _USES+=texinputs:strict_. There is an analogous variable _MPINPUTS_ | |
522 | governing the look up of METAPOST input files, it is accompanied with an | |
523 | _USES+=mpinputs:strict_ option. If we want to have our TeX program and | |
524 | our METAPOST program to be run with different values for _TEXINPUTS_, | |
525 | we can pass the correct value to METAPOST through the _MPTEXINPUTS_ | |
526 | variable, this variable is also accompanied by an | |
527 | _USES+=mptexinputs:strict_ option. | |
528 | ||
529 | ||
530 | ## Deal with a huge number of documents | |
531 | ||
532 | We demonstrate how to use the `bps.subdir.mk` module to organise a | |
533 | collection of documents. For the purpose of the example, we assume | |
534 | that we are preparing an electronic journal and want to distribute | |
535 | each article of the journal as a separate electronic document. We use | |
536 | the following simple organisation: | |
537 | ||
538 | 1. We prepare a directory holding each issue of our journal, for | |
539 | instance `~/journal`. | |
540 | ||
541 | 2. Each issue of the journal is represented by a subdirectory. | |
542 | ||
543 | 3. Each article of the journal is represented by a subdirectory of the | |
544 | directory corresponding to the issue it belongs to. | |
545 | ||
546 | Assume we already have several articles, as demonstrated by the | |
547 | following commnad output: | |
548 | ||
549 | ```console | |
550 | % find ./journal -type f | |
551 | ./journal/issue-2013-1/01-galdal/Makefile | |
552 | ./journal/issue-2013-1/01-galdal/article.tex | |
553 | ./journal/issue-2013-1/02-arathlor/Makefile | |
554 | ./journal/issue-2013-1/02-arathlor/article.tex | |
555 | ./journal/issue-2013-2/01-mirmilothor/Makefile | |
556 | ./journal/issue-2013-2/01-mirmilothor/article.tex | |
557 | ./journal/issue-2013-2/02-eoron/Makefile | |
558 | ./journal/issue-2013-2/02-eoron/article.tex | |
559 | ./journal/issue-2013-2/03-echalad/Makefile | |
560 | ./journal/issue-2013-2/03-echalad/article.tex | |
561 | ``` | |
562 | ||
563 | Names like `galdal`, `arathlor` are the names of fictional authors of | |
564 | articles of our journal. Each submission has a directory containing | |
565 | the text `article.tex` of the article and a `Makefile` similar to | |
566 | those described on this page which can be used to build the matching | |
567 | article. | |
568 | ||
569 | Each of these `Makefile`s can actually be as simple as | |
570 | ||
571 | ```Makefile | |
572 | DOCUMENT= article.tex | |
573 | .include "latex.doc.mk" | |
574 | ``` | |
575 | ||
576 | To orchestrate the preparation of all our articles with | |
577 | **BSD Owl Scripts** we just need to write additional `Makefile`s: | |
578 | ||
579 | ``` | |
580 | ./journal/Makefile | |
581 | ./journal/issue-2013-1/Makefile | |
582 | ./journal/issue-2013-2/Makefile | |
583 | ./journal/issue-2013-3/Makefile | |
584 | ``` | |
585 | ||
586 | Each `Makefile` basically contains the list of subdirectories where | |
587 | _make_ should descend to actually `build`, `install` or `clean`. So | |
588 | the file `./journal/Makefile` should contain: | |
589 | ||
590 | ```makefile | |
591 | PACKAGE= journal | |
592 | ||
593 | SUBDIR= issue-2013-1 | |
594 | SUBDIR+= issue-2013-2 | |
595 | SUBDIR+= issue-2013-3 | |
596 | .include "bps.subdir.mk" | |
597 | ``` | |
598 | ||
599 | The file `./journal/issue-2013-1/Makefile` should contain: | |
600 | ||
601 | ```makefile | |
602 | SUBDIR= 01-galdal | |
603 | SUBDIR+= 02-arathlor | |
604 | .include "bps.subdir.mk" | |
605 | ``` | |
606 | ||
607 | The remaining files `./journal/issue-2013-2/Makefile` and | |
608 | `./journal/issue-2013-3/Makefile` can be similarly prepared. With | |
609 | these settings, the targets `all`, `build`, `clean`, `distclean`, | |
610 | `realclean` and `install` are delegated to `Makefile`s found in the | |
611 | subdirectories listed by _SUBDIR_. | |
612 | ||
613 | The variable `SUBDIR_PREFIX` can be used to define a customised | |
614 | installation path for each article, so that the `Makefile` building a | |
615 | document could be | |
616 | ||
617 | ```Makefile | |
618 | DOCUMENT= article.tex | |
619 | DOCDIR= ${HOME}/publish/journal${SUBDIR_PREFIX} | |
620 | .include "latex.doc.mk" | |
621 | ``` | |
622 | ||
623 | With this setting, the document | |
624 | `./journal/issue-2013-1/01-galdal/article.pdf` will be installed as | |
625 | `${HOME}/publish/journal/issue-2013-1/01-galdal/article.pdf` and so | |
626 | on. It is possible to tweak this in all possible ways to use | |
627 | arbitrary naming schemes for installed articles. |
0 | ORR | |
1 | # Introducing Make | |
2 | ||
3 | Work on Unix systems has a strong emphasis on files, and a typical work | |
4 | session with such a system involves the creation of files | |
5 | _(sources)_ and the invocation of many data processing | |
6 | procedures _(recipes)_ yielding intermediary and final files | |
7 | _(objects)_ as output of their work. Most of the work is | |
8 | usually performed through the use of a shell. | |
9 | ||
10 | The Make program is a utility whose input is a workflow declaring | |
11 | tasks (_targets_ in Make's parlance) and means to achieve them, | |
12 | and whose invocation yields execution of the given tasks. | |
13 | ||
14 | This presentation emphasizes that Make is a day-to-day companion of | |
15 | the UNIX operator, as it can be used to systematize a large part of | |
16 | its work. You can read more about the Make program and | |
17 | especially on the FreeBSD Make program by reading the | |
18 | [paragraphs dedicated to Make](http://www.freebsd.org/doc/en_US.ISO8859-1/books/developers-handbook/tools-make.html) | |
19 | in the | |
20 | [FreeBSD Developer's Handbook](http://www.freebsd.org/doc/en_US.ISO8859-1/books/developers-handbook/index.html), | |
21 | and the | |
22 | [PMake tutorial](http://www.freebsd.org/doc/en_US.ISO8859-1/books/pmake/index.html) | |
23 | (the PMake program is the venerable ancestor of FreeBSD Make). | |
24 | ||
25 | ||
26 | # Make scripts | |
27 | ||
28 | Make's input is usually not a static specification of the workflow graph, | |
29 | but instead a parametrized specification of the graph, it is then | |
30 | possible to generalize specifications in order to manage many similar | |
31 | situations with the same specification. We call these generic | |
32 | specifications _Make scripts,_ it is possible to gather them in | |
33 | libraries of scripts solving problems occuring in related | |
34 | situations. | |
35 | ||
36 | BSD Owl Scripts is a collection of such | |
37 | libraries. They can be used to ease the development of OCaml | |
38 | software, the production of TeX and LaTeX documents, and a couple of | |
39 | other things. | |
40 | ||
41 | ||
42 | # BSD Make | |
43 | ||
44 | Make is not the name of a well defined program, but rather the | |
45 | name of a large brotherhood. Each of the brother has its own strengths | |
46 | and weaknesses, and also its own dialect used to prepare its input | |
47 | specification. BSD Make Pallàs scripts can be used with three of these | |
48 | brothers, all of them being descendants of the make program in | |
49 | BSD4.4. These programs are: | |
50 | ||
51 | - FreeBSD's make; | |
52 | - MAC OS-X's bsdmake; | |
53 | - NetBSD's bmake. | |
54 | ||
55 | Users of Linux based system are likely to be equipped with GNU | |
56 | Make. This version of Make is a piece of a larger puzzle, the | |
57 | autotools; without these autotools, it is not so useful. However, | |
58 | NetBSD's bmake works fine under many Linux based systems. You can get | |
59 | source files for it at | |
60 | [Simon J. Gerraty's](http://void.crufty.net/ftp/pub/sjg/). |
0 | # Installation of man pages | |
1 | ||
2 | The library `bps.man.mk` defines targets to build and install manual pages and | |
3 | hooks them to the build and installation processes. | |
4 | ||
5 | The list of manual pages to install must be conveyed by the *MAN* | |
6 | variable. Other variables can be used to configure the process, as | |
7 | described in `bps.man.mk`. | |
8 | ||
9 | Modules building a program or a library or any product documented by a | |
10 | manual page should lookup for manual pages to automatically add them | |
11 | to the *MAN* variable. For instance, a module building a program | |
12 | `wordcount` should look for files `wordcount.1` and `wordcount.8` and | |
13 | add them to *MAN* if they exist. |
0 | # Configuration files | |
1 | ||
2 | As a UNIX user you are likely to have several configuration files for | |
3 | your applications. As these files are commonly stored under your home | |
4 | directory and prefixed with a dot, let us call them *dotfiles*. If you | |
5 | consider using a [RCS](http://en.wikipedia.org/wiki/RCS) to keep track | |
6 | of the revisions you do to your files you will also need an | |
7 | installation procedure. This procedure is provided by BSD Make Pallàs | |
8 | Scripts. | |
9 | ||
10 | This setting is also very useful in you want to use the same | |
11 | configuration files on different systems. | |
12 | ||
13 | ||
14 | ## Using GIT and BSD Owl Scripts | |
15 | ||
16 | Use the following procedure to get started managing the revisions of | |
17 | your files with `git`. | |
18 | ||
19 | **Step 1.** Create a directory `dotfiles`. | |
20 | ||
21 | ```console | |
22 | % mkdir dotfiles | |
23 | ``` | |
24 | ||
25 | **Step 2.** Intitalise this directory as a git repository. | |
26 | ||
27 | ```console | |
28 | % cd dotfiles | |
29 | % git init | |
30 | ``` | |
31 | ||
32 | **Step 3.** Copy your dotfiles there, `~/.profile` as `dot.profile` | |
33 | and so on. | |
34 | ||
35 | ```console | |
36 | % cp ~/.profile dot.profile | |
37 | % cp ~/.emacs dot.emacs | |
38 | ``` | |
39 | ||
40 | **Step 4.** Create a `Makefile` as explained in the documentation of | |
41 | `conf.dotfile.mk`. | |
42 | ||
43 | ```makefile | |
44 | ### Makefile -- dotfiles | |
45 | ||
46 | DOTFILE= dot.profile | |
47 | DOTFILE+= dot.emacs | |
48 | ||
49 | .include "misc.dotfile.mk" | |
50 | ``` | |
51 | ||
52 | **Step 5.** Register your files and commit them. | |
53 | ||
54 | ```console | |
55 | % git add dot.* Makefile | |
56 | % git commit -m "Import my dotfiles" | |
57 | ``` | |
58 | ||
59 | **Step 6.** Edit your files and register your changes in git. | |
60 | ||
61 | **Step 7.** Install your files with `make install`. | |
62 | ||
63 | **Step 8.** Repeat steps 6 and 7 as needed. | |
64 | ||
65 | Note that on your system, you may have to use another `make` program, | |
66 | such as `pmake` under Debian or `bsdmake` under Mac OS X, as detailed | |
67 | in the [installation procedure](../INSTALL.md). |
0 | # Using NOWEB to write TeX or LaTeX macros | |
1 | ||
2 | Norman Ramsey's [NOWEB](http://www.cs.tufts.edu/~nr/noweb/) literate | |
3 | programming tool can be used to write TeX or LaTeX macros. | |
4 | ||
5 | ## The Makefile | |
6 | ||
7 | The Makefile must declare several variables: | |
8 | ||
9 | - _NOWEB_ enumerates your NOWEB files; | |
10 | - _NOTANGLE_ enumerates the code files that need to be | |
11 | generated from the NOWEB files; | |
12 | - _NOWEAVE_ |
0 | # Description of software packages | |
1 | ||
2 | ## Simple packages | |
3 | ||
4 | A [package](BuildConcepts) consists of one or several modules. Because | |
5 | our system is non bureaucratic, an isolated module is automatically | |
6 | promoted to a package. | |
7 | ||
8 | ||
9 | ## Package identification | |
10 | ||
11 | **PACKAGE** | |
12 | The name of a package. | |
13 | ||
14 | It must be a sequence of characters `[-+_A-Za-z0-9]`. | |
15 | ||
16 | ||
17 | **VERSION** | |
18 | The version of a package. | |
19 | ||
20 | It should have the form `MAJOR.MINOR.PATCHLEVEL` or | |
21 | `MAJOR.MINOR.PATCHLEVEL-IDENTIFIER` (for pre-releases). | |
22 | It defaults to 0.1.0-current. | |
23 | ||
24 | **OFFICER** | |
25 | The release engineering officer. | |
26 | ||
27 | This is the GPG identity used to sign the tarballs. It defaults to | |
28 | `${EMAIL}` if this environment variable is set or to | |
29 | `${USER}@${HOST}`. | |
30 | ||
31 | ||
32 | ## Modules and external dependencies | |
33 | ||
34 | ||
35 | **MODULE** | |
36 | The list of modules belonging to the package. | |
37 | ||
38 | The list consists of pairs `module:path` where `module` is a BSD Owl | |
39 | module like `ocaml.prog` or `latex.doc` or `c.lib` and path is the | |
40 | path to the directory corresponding to the module with respect to | |
41 | `${SRCDIR}`, the root of our source tree. | |
42 | ||
43 | ||
44 | **EXTERNAL** | |
45 | The list of external dependencies of the package. | |
46 | ||
47 | The list consists of pair `consumer:resource` where `consumer` is a | |
48 | keyword identifying the type of the external resource and `resource` | |
49 | is its symbolic name. | |
50 | ||
51 | ||
52 | ## Environment | |
53 | ||
54 | **DESTDIR** | |
55 | A directory to prepend to PREFIX, only when copying files. | |
56 | ||
57 | Usually not set. Useful to install in a file system whose root is not | |
58 | the root of the full file system. | |
59 | ||
60 | ||
61 | **PREFIX** | |
62 | The installation prefix of the package. | |
63 | ||
64 | Usually `/usr /usr/local`, `/opt/local` or `/home/joeuser`. It | |
65 | must be set at configuration time. | |
66 | ||
67 | ||
68 | **EXEC_PREFIX** | |
69 | The installation prefix for binaries of the package. | |
70 | ||
71 | ||
72 | **BINDIR** | |
73 | The directory for installing executable programs that users can run. | |
74 | ||
75 | ||
76 | **SBINDIR** | |
77 | The directory for installing executable programs used by sysadmins. | |
78 | ||
79 | ||
80 | **LIBEXECDIR** | |
81 | The directory for installing executable programs to be run by other programs. | |
82 | ||
83 | ||
84 | **DATAROOTDIR** | |
85 | The root of the hierarchy for read-only architecture-independent data files. | |
86 | ||
87 | ||
88 | **DATADIR** | |
89 | The directory for installing idiosyncratic read-only | |
90 | architecture-independent data files for this program. | |
91 | ||
92 | ||
93 | **SYSCONFDIR** | |
94 | The directory for installing read-only data files that pertain to a | |
95 | single machine–that is to say, files for configuring a host. | |
96 | ||
97 | ||
98 | **SHAREDSTATEDIR** | |
99 | The directory for installing architecture-independent data files | |
100 | which the programs modify while they run. | |
101 | ||
102 | ||
103 | **LOCALSTATEDIR** | |
104 | The directory for installing data files which the programs modify | |
105 | while they run, and that pertain to one specific machine. | |
106 | ||
107 | ||
108 | **RUNSTATEDIR** | |
109 | The directory for installing data files which the programs modify | |
110 | while they run, that pertain to one specific machine, and which need | |
111 | not persist longer than the execution of the program—which is | |
112 | generally long-lived, for example, until the next reboot | |
113 | ||
114 | ||
115 | **INCLUDEDIR** | |
116 | The directory for installing header files to be included by user | |
117 | programs with the C ‘#include’ preprocessor directive. | |
118 | ||
119 | ||
120 | **DOCDIR** | |
121 | The directory for installing documentation files (other than Info) for | |
122 | this package. | |
123 | ||
124 | ||
125 | **INFODIR** | |
126 | The directory for installing the Info files for this package. | |
127 | ||
128 | ||
129 | **LIBDIR** | |
130 | The directory for object files and libraries of object code. | |
131 | ||
132 | ||
133 | **LOCALEDIR** | |
134 | The directory for installing locale-specific message catalogues for this | |
135 | package. | |
136 | ||
137 | ||
138 | **MANDIR** | |
139 | The top-level directory for installing the man pages for this package. | |
140 | ||
141 | ||
142 | **MAKEOBJDIR** | |
143 | The location where build products should be placed. | |
144 | ||
145 | We want to support three settings: | |
146 | - the dirty setting where objects are stored in the source tree | |
147 | - the flat setting where objects are stored in a | |
148 | package/configuration/architecture specific directory | |
149 | - the hierarchical setting where objects are stored in a | |
150 | package/configuration/architecture specific file hierarchy replicating | |
151 | the source tree. | |
152 | ||
153 | In the flat and in the hierarchical setting, the actual value is | |
154 | CONFIGURATION dependant. | |
155 | ||
156 | ||
157 | ## Installation method | |
158 | ||
159 | Credential switch with su, sudo. | |
160 | ||
161 | Should we support jails, chroot, ssh? It is probably not a serious | |
162 | limitation to require users to log on the remote host and perform | |
163 | there an actual installation. | |
164 | ||
165 | Note that some systems do not have a root user (e.g. Cygwin), this | |
166 | should be detected at configuration time. See #60. | |
167 | ||
168 | ||
169 | ## Build Configuration | |
170 | ||
171 | A *build configuration* or *configuration* is a name like `Debug` or | |
172 | `Release` which is used to read a file under Library/Configuration | |
173 | where compilation flags can be adjusted. | |
174 | ||
175 | A target architecture can also be specified for tools supporting | |
176 | cross-compilation. This is done using a target triplet (actually 4let) | |
177 | as described by Autotools. | |
178 | ||
179 | **CONFIGURATION** | |
180 | The name of the configuration used. |
0 | # Package your software for Debian | |
1 | ||
2 | This document covers the preparation of Debian packages for your | |
3 | software package using **BSD Owl Scripts.** After reading this document, | |
4 | you will know: | |
5 | ||
6 | - How to configure your environment to start writing packages. | |
7 | - How to write the first version of your package. | |
8 | - How to update your package. | |
9 | ||
10 | We assume that the package: | |
11 | ||
12 | - is built and installed using **BSD Owl Scripts;** | |
13 | - uses **git** as a source control management system. | |
14 | ||
15 | We take as an example the preparation of a Debian package for | |
16 | **[Anvil 0.3.0][anvil].** This special example also | |
17 | ||
18 | - uses **GNU Autoconf** to discover the system it is running on; | |
19 | - has a `release` branch holding the latest release; | |
20 | - uses tags similar to `v1.0.0` to identify versions. | |
21 | ||
22 | It should be easy to adapt the provided instructions to match other | |
23 | settings. | |
24 | ||
25 | ||
26 | **See Also:** | |
27 | [Debian New Maintainers' Guide][debian-maintainer], | |
28 | [Packaging with git][debian-git]. | |
29 | ||
30 | ||
31 | ## Clone the repository | |
32 | ||
33 | We clone the repository and let our shell visit it. | |
34 | ||
35 | ```console | |
36 | % git clone git@github.com:michipili/anvil.git | |
37 | % cd anvil | |
38 | ``` | |
39 | ||
40 | ||
41 | ## Create the Debian branch | |
42 | ||
43 | We cut out a `debian` branch off the `release` branch. This branch | |
44 | should hold all files required by Debian to produce a package. | |
45 | ||
46 | ``` console | |
47 | % git checkout -b debian origin/release | |
48 | ``` | |
49 | ||
50 | As detailed below in the section *Staying up to date*, subsequent | |
51 | releases happening on the `release` branch are to be merged on the | |
52 | `debian` branch in order to prepare packages for the newer version. | |
53 | ||
54 | ||
55 | ## Create the Debian directory | |
56 | ||
57 | The `debian` directory is used by the build system as a repository for | |
58 | configuration files but also as a work directory. We use the | |
59 | `dh_make` program to initialise this directory. | |
60 | ||
61 | ```console | |
62 | % dh_make --native -p anvil_0.3.0 | |
63 | % git add debian | |
64 | % git commit -m "Create the Debian directory" | |
65 | ``` | |
66 | ||
67 | **See Also:** | |
68 | [Debian New Maintainers' Guide, Chapter 2][debian-maintainer-chap2], | |
69 | [dh-make(1)][debian-man-dh-make]. | |
70 | ||
71 | ||
72 | ||
73 | ## Cleanup the Debian directory | |
74 | ||
75 | The `dh_make` program fills the `debian` directory with a lot of | |
76 | templates. Most of the templates contain comments and are described | |
77 | in the [Debian New Maintainers' Guide][debian-maintainer]. After a | |
78 | quick inspection, we remove those which are not relevant. | |
79 | ||
80 | ```console | |
81 | % cd debian | |
82 | % git rm README* | |
83 | % git rm anvil.cron.d.ex | |
84 | % git rm anvil.default.ex | |
85 | % git rm init.d.ex | |
86 | % git rm manpage.* menu.ex {pre,post}{inst,rm}.ex | |
87 | % git commit -m "Cleanup the Debian directory" | |
88 | ``` | |
89 | ||
90 | ||
91 | ## Edit the control file | |
92 | ||
93 | The control file holds most of the package meta-information. The | |
94 | contents of this file is described in details in | |
95 | [Chapter 4][debian-maintainer-control] of *Debian New Maintainer's Guide.* | |
96 | We proceed to the following actions: | |
97 | ||
98 | - Set the Section | |
99 | - Set Build-Depends | |
100 | - Set Homepage | |
101 | - Set Vcs-Git | |
102 | - Set Vcs-Browser | |
103 | - Set Depends | |
104 | - Set Description | |
105 | ||
106 | When we are done, we commit the resulting control file. | |
107 | ||
108 | ||
109 | ## Edit the copyright file | |
110 | ||
111 | The copyright file contains, as its name suggests, copyright | |
112 | information for the files found in the package. In the simplest | |
113 | cases, it is essentially a copy of the licence agreement. The | |
114 | [Chapter 4][debian-maintainer-control] of *Debian New | |
115 | Maintainer's Guide* describes how to prepare this file. | |
116 | ||
117 | When we are done, we commit the resulting copyright file. | |
118 | ||
119 | ||
120 | ## Edit the changelog file | |
121 | ||
122 | This is a third file with other meta-information. The most important | |
123 | information it contains is the version information. It is also | |
124 | described in [Chapter 4][debian-maintainer-changelog] of *Debian New | |
125 | Maintainer's Guide* describes how to prepare this file. | |
126 | ||
127 | ||
128 | ## Edit the rules file | |
129 | ||
130 | The rules file is a GNU Makefile describing how to actually compile | |
131 | the software. All packages using **BSD Owl Scripts** will have a | |
132 | rules file similar to the following: | |
133 | ||
134 | ```Makefile | |
135 | #!/usr/bin/make -f | |
136 | MAKETOOL=bmake -r -I/usr/share/bsdowl DESTDIR=$$(pwd)/debian/anvil | |
137 | ||
138 | %: | |
139 | dh $@ | |
140 | ||
141 | override_dh_auto_configure: | |
142 | autoconf | |
143 | dh_auto_configure | |
144 | ||
145 | override_dh_auto_build: | |
146 | ${MAKETOOL} build | |
147 | ||
148 | override_dh_auto_install: | |
149 | ${MAKETOOL} install | |
150 | dh_installman | |
151 | ||
152 | override_dh_auto_clean: | |
153 | ${MAKETOOL} distclean | |
154 | ||
155 | override_dh_auto_test: | |
156 | : Do nada | |
157 | ``` | |
158 | ||
159 | It assumes that the `configure` script is not under version control, | |
160 | otherwise the target `override_dh_auto_configure` can be removed. It | |
161 | also assumes that our software package can be distcleaned without | |
162 | having been configured before. | |
163 | ||
164 | ||
165 | ## Edit documentation index | |
166 | ||
167 | The file anvil.doc-base is a documentation index that should briefly | |
168 | describe installed documents. The program `dh_make` created a | |
169 | template that we need to edit, then commit. | |
170 | ||
171 | ||
172 | ## Edit the watch file | |
173 | ||
174 | The watch file is used to automatically detect new versions of the | |
175 | software, which is not mandatory but still nice to have. | |
176 | ||
177 | ``` | |
178 | version=3 | |
179 | opts=pgpsigurlmangle=s/$/.sig/ https://github.com/michipili/anvil/releases (?:.*/)?anvil-([\d\.]+).tar.(?:gz|bz2|xz) | |
180 | ``` | |
181 | ||
182 | ||
183 | ## Configure git-buildpackage | |
184 | ||
185 | ||
186 | Finally we configure the git buildpackage subcommand, to match the | |
187 | conventions used in our repository, which are slightly different from | |
188 | the default conventions. We create the file `gbp.conf` with the | |
189 | following contents: | |
190 | ||
191 | ||
192 | ``` | |
193 | [DEFAULT] | |
194 | upstream-branch = release | |
195 | upstream-tag = v%(version)s | |
196 | debian-branch = debian | |
197 | debian-tag = debian/v%(version)s | |
198 | ``` | |
199 | ||
200 | Once we commit this file, the package can finally be created with `git | |
201 | buildpackage`. | |
202 | ||
203 | ||
204 | ## Staying up to date | |
205 | ||
206 | Once a version 0.4.0 of our **anvil** software package is merged into | |
207 | the `release` branch, producing an updated package can be as easy as: | |
208 | ||
209 | ```console | |
210 | % git checkout debian | |
211 | % git merge --no-commit --no-ff release | |
212 | % dch -v 0.4.0-1 | |
213 | % git add debian/changelog | |
214 | % git commit | |
215 | % git buildpackage | |
216 | ``` | |
217 | ||
218 | If the upstream package evolves a lot, one can expect more work to be | |
219 | ncessary. | |
220 | ||
221 | ||
222 | [anvil]: https://github.com/michipili/anvil | |
223 | [debian-git]: https://wiki.debian.org/PackagingWithGit#Using_the_upstream_repo | |
224 | [debian-maintainer-chap2]: https://www.debian.org/doc/manuals/maint-guide/first.en.html#dh-make | |
225 | [debian-maintainer-changelog]: https://www.debian.org/doc/manuals/maint-guide/dreq.en.html#changelog | |
226 | [debian-maintainer-control]: https://www.debian.org/doc/manuals/maint-guide/dreq.en.html#control | |
227 | [debian-maintainer-copyright]: https://www.debian.org/doc/manuals/maint-guide/dreq.en.html#copyright | |
228 | [debian-maintainer]: https://www.debian.org/doc/manuals/maint-guide/index.en.html | |
229 | [debian-man-dh-make]: http://manpages.debian.org/cgi-bin/man.cgi?query=dh_make |
66 | 66 | .endif |
67 | 67 | |
68 | 68 | .if !defined(OCAMLROOTDIR) |
69 | OCAMLROOTDIR!= 2>/dev/null ${OCAMLCI} -where | |
69 | OCAMLROOTDIR!= 2>/dev/null ${OCAMLWHERE} -where | |
70 | 70 | .endif |
71 | 71 | |
72 | 72 | .if defined(OCAMLROOTDIR) |