1Nest Labs Build - GNU Autotools
2===============================
3
4[![Build Status][nlbuild-autotools-travis-svg]][nlbuild-autotools-travis]
5
6[nlbuild-autotools-travis]: https://travis-ci.org/nestlabs/nlbuild-autotools
7[nlbuild-autotools-travis-svg]: https://travis-ci.org/nestlabs/nlbuild-autotools.svg?branch=master
8
9# Introduction
10
11The Nest Labs Build - GNU Autotools (nlbuild-autotools) provides a
12customized, turnkey build system framework, based on GNU autotools, for
13standalone Nest Labs (or other) software packages that need to support
14not only building on and targeting against standalone build host
15systems but also embedded target systems using GCC-based or
16-compatible toolchains.
17
18In addition, nlbuild-autotools endeavors to make it easy to support:
19
20  * Unit and Functional Tests (via 'make check')
21  * Code Coverage (via 'make coverage')
22  * Code Formatting (via 'make pretty' or 'make pretty-check')
23  * Documentation
24  * Distribution Generation (via 'make dist' or 'make docdist')
25
26# Users and System Integrators
27
28## Getting Started
29
30This project is typically subtreed (or git submoduled) into a target
31project repository and serves as the seed for that project's build
32system.
33
34Assuming that you already have a project repository established in
35git, perform the following in your project repository:
36
37```
381. % git remote add nlbuild-autotools ssh://<PATH_TO_REPOSITORY>/nlbuild-autotools.git
392. % git fetch nlbuild-autotools
40```
41
42You can place the nlbuild-autotools package anywhere in your project;
43however, by convention, "third_party/nlbuild-autotools/repo" is recommended:
44
45```
463. % mkdir third_party
474. % git subtree add --prefix=third_party/nlbuild-autotools/repo --squash --message="Add subtree mirror of repository 'ssh://<PATH_TO_REPOSITORY>/nlbuild-autotools.git' branch 'master' at commit 'HEAD'." nlbuild-autotools HEAD
48```
49
50At this point, you now have the nlbuild-autotools package integrated
51into your project. The next step is using the
52nlbuild-autotools-provided examples as templates. To do this, a
53convenience script has been provided that will get you started. You
54can tune and customize the results, as needed, for your project. From
55the top level of your project tree:
56
57```
585. % third_party/nlbuild-autotools/repo/scripts/mkskeleton -I third_party/nlbuild-autotools/repo --package-description "My Fantastic Package" --package-name "mfp"
59```
60
61## Supported Build Host Systems
62
63For Linux users, you likely already have GNU autotools installed through your system's distribution (e.g. Ubuntu). However, if your GNU autotools packages are incomplete or downrevision relative to what's required from nlbuild-autotools, nlbuild-autotools can be built and installed or can be downloaded and expanded in your local nlbuild-autotools tree.
64
65The nlbuild-autotools system supports and has been tested against the
66following POSIX-based build host systems:
67
68  * i686-pc-cygwin
69  * i686-pc-linux-gnu
70  * x86_64-apple-darwin
71  * x86_64-unknown-linux-gnu
72
73### Build and Install {#Build_and_Install}
74
75Simply invoke `make tools` at the top-level of your nlbuild-autotools
76tree or, for example, from your package or project in which you have
77integrated nlbuild-autotools:
78
79```
80make -C third_party/nlbuild-autotools/repo tools
81```
82
83### Download and Expand
84
85Alongside nlbuild-autotools distributions are pre-built
86architecture-independent and -dependent distributions of the form:
87
88  * nlbuild-autotools-common-_version_.tar.{gz,xz}
89  * nlbuild-autotools-_host_-_version_.tar.{gz,xz}
90
91Find and download the appropriate pair of nlbuild-autotools-common and
92nlbuild-autotools-_host_ for your system and then expand them from the
93top-level of your nlbuild-autotools tree with a command similar to the
94following example:
95
96```
97% tar --directory tools/host -zxvf nlbuild-autotools-common-1.1.tar.gz
98% tar --directory tools/host -zxvf nlbuild-autotools-x86_64-unknown-linux-gnu-1.1.tar.gz
99```
100
101Please see the [FAQ](#FAQ) section for more background on why this package
102provides options for these pre-built tools.
103
104## Package Organization
105
106The nlbuild-autotools package is laid out as follows:
107
108| Directory                            | Description                                                                              |
109|--------------------------------------|------------------------------------------------------------------------------------------|
110| autoconf/                            | GNU autoconf infrastructure provided by nlbuild-autotools.                               |
111| autoconf/m4/                         | GNU m4 macros for configure.ac provided by nlbuild-autotools.                            |
112| automake/                            | GNU automake Makefile.am header and footer infrastructure provided by nlbuild-autotools. |
113| automake/post/                       | GNU automake Makefile.am footers.                                                        |
114| automake/post.am                     | GNU automake Makefile.am footer included by every makefile.                              |
115| automake/pre/                        | GNU automake Makefile.am headers.                                                        |
116| automake/pre.am                      | GNU automake Makefile.am header included by every makefile.                              |
117| examples/                            | Example template files for starting your own nlbuild-autotools-based project.            |
118| scripts/                             | Automation scripts for regenerating the build system and for managing package versions.  |
119| tools/                               | Qualified packages of and pre-built instances of GNU autotools.                          |
120| tools/host/                          | Pre-built instances of GNU autotools (if installed).                                     |
121| tools/host/i686-pc-cygwin/           | Pre-built instances of GNU autotools for 32-bit Cygwin (if installed).                   |
122| tools/host/i686-pc-linux-gnu/        | Pre-built instances of GNU autotools for 32-bit Linux (if installed).                    |
123| tools/host/x86_64-apple-darwin/      | Pre-built instances of GNU autotools for 64-bit Mac OS X (if installed).                 |
124| tools/host/x86_64-unknown-linux-gnu/ | Pre-built instances of GNU autotools for 64-bit Linux (if installed).                    |
125| tools/packages/                      | Qualified packages for GNU autotools.                                                    |
126## Internal Package Dependencies and Repositories
127
128Your package may have dependencies on other packages that can either
129be inlined into your package or can be specified externally. If your
130package has such dependencies, nlbuild-autotools contains support to
131facilitate easy standalone tests and a successful 'make distcheck'
132target (which effectively reqires 'configure' with no arguments to
133produce a successful build) without incurring the costs of inlining
134these dependencies into your own package.
135
136nlbuild-autotools supports this by providing a means to pull down
137external git package repositories that your package depends on using
138either git clone (default) or git submodules when you use and support
139--with-<package>=internal as a location for your dependent packages.
140
141The example 'Makefile-bootstrap' has been provided as infrastructure to
142make this easy for you as a package maintainer and for your package
143users. The bootstrap makefile supports both the generic 'repos' target
144to pull down all repositories on which your project depends as well as
145relative path targets to where those repositories might live in your
146project when they are internal (e.g,
147third_party/package/repo).
148
149Consequently, you can, for example, invoke:
150
151```
152% make -f Makefile-bootstrap repos
153```
154
155or
156
157```
158% make -f Makefile-bootstrap third_party/package/repo
159```
160
161to pull down all repositories or just the repository, for example,
162placed at 'third_party/package/repos'.
163
164The bootstrap makefile generated for your package is yours to edit and
165extend. In fact, hooks have been added so that you can do
166package-specific work, including recursively pulling down repositories
167for other packages.
168
169However, an even better and easier approach for your package users is
170to integrate the bootstrap makefile repository process into your
171configure script such that when an "internal" package location is
172detected, it invokes the bootstrap makefile to perform this work on
173behalf of the user. For example:
174
175```
176# Depending on whether my-package has been configured for an internal
177# location, its directory stem within this package needs to be set
178# accordingly. In addition, if the location is internal, then we need
179# to attempt to pull it down using the bootstrap makefile.
180
181if test "${nl_with_my_package}" = "internal"; then
182    maybe_my_package_dirstem="my-package/repo"
183    my_package_dirstem="third_party/${maybe_my_package_dirstem}"
184
185    AC_MSG_NOTICE([attempting to create internal ${my_package_dirstem}])
186    ${MAKE-make} --no-print-directory -C ${ac_confdir} -f Makefile-bootstrap ${my_package_dirstem}
187
188    if test $? -ne 0; then
189        AC_MSG_ERROR([failed to create ${my_package_dirstem}. Please check your network connection or the correctness of 'repos.conf'])
190    fi
191else
192    maybe_my_package_dirstem=""
193fi
194
195AC_SUBST(MY_PACKAGE_SUBDIRS, [${maybe_my_package_dirstem}])
196AM_CONDITIONAL([PACKAGE_WITH_MY_PACKAGE_INTERNAL], [test "${nl_with_my_package}" = "internal"])
197```
198
199Note, the use of AC_SUBST on MY_PACKAGE_SUBDIRS to provide a mechanism
200to conditionally populate SUBDIRS in the appropriate automake file
201locations such that GNU autoconf does not generate syntax errors about
202the potential absence of the subdirectory at bootstrap time.
203
204Of course, in either case, network connectivity is required to reach
205the external git server hosting the packages on which your project
206depends.
207
208In addition to the 'repos' target, the bootstrap makefile also
209supports the 'clean-repos' target that undoes the work of the 'repos'
210target. When using either the 'clone' or 'submodule' pull methods, it
211will clean-up all of the synchronized repositories. When using the
212'submodule' pull method, it also is careful to ensure it does not
213disturb existing git or git submodule state your project might be
214using.
215
216The infrastructure all works, of course, whether you are working in or
217out of git and whether you have colocated or non-colocated source and
218build directories.
219
220### Configuration
221
222This dependent repository feature of nlbuild-autotools uses a file,
223'repos.conf', at the top level of your project source directory to
224determine what external project repositories your package might want
225to pull down, the location of their git server, the branch you want to
226pull, and the location in your project in which you want to place
227them.
228
229The format of 'repos.conf' _almost_ precisely follows that used by git
230submodules with two notable additions, the 'pull' section and the
231'commit' key. The 'pull' section allows you to optionally specify the
232'method' key as 'clone' or 'submodule' (defaulting to 'clone' when the
233key is not present). This selects whether 'git clone' or 'git
234submodule' is used to pull down repositories. The 'commit' key allows
235you to specify not only what branch to checkout but, more precisely,
236what commit or tag to checkout rather than just _HEAD_ of a
237branch. More information is available in 'Makefile-bootstrap' or with
238`man gitmodules` or `git help gitmodules`.
239
240# FAQ {#FAQ}
241
242Q: Why does nlbuild-autotools have an option for its own built versions
243   of GNU autotools rather than leveraging whatever versions exist on
244   the build host system?
245
246A: Some build host systems such as Mac OS X may not have GNU autotools
247   at all. Other build host systems, such as Linux, may have different
248   distributions or different versions of those distributions in which
249   the versions of GNU autotools are apt to be different.
250
251   This differences lead to different primary and secondary autotools
252   output and, as a consequence, a divergent user and support
253   experience. To avoid this, this package provides a pre-built,
254   qualified set of GNU autotools along with a comprehensive,
255   standalone set of scripts to drive them without reliance on those
256   versions of the tools on the build host system.
257
258Q: When I rebootstrap my package, I see that a number of files related to
259   nlbuild-autotools have unexpectedly changed. Why is this happening?
260
261A: From time to time, the packages that comprise GNU autotools change
262   upstream. Frequently, common host operating systems (e.g., Ubuntu) take
263   a stable snapshot of the current autotools for a major release (e.g.,
264   Ubuntu 14). On the next major release (e.g., Ubuntu 16), another snapshot
265   is taken.
266
267   If your package was first bootstrapped with one version of
268   autotools and those bootstrap-generated files checked-in but you
269   later bootstrap with another version of autotools, then you will
270   likely observe this behavior.
271
272   There are two solutions to this problem. First, to ensure a
273   consistent set of bootstrap-generated files, you can build the
274   autotools included with nlbuild-autotools. The bootstrap process
275   will always prefer to use those versions rather than those
276   available on the build host when they are available. See the
277   section [Build and Install](#Build_and_Install) for more
278   information.
279
280   The second way to ensure a consistent set of bootstrap-generated
281   files is to not check them in. This does, however, require that
282   package users, rather than package maintainers, perform the
283   bootstrap process and does require that package users, rather than
284   package maintainers, have autotools available on the build host.
285
286## Maintainers
287
288If you are maintaining nlbuild-autotools, you have several key things to know:
289
2901. Generating nlbuild-autotools distributions
2912. Generating optional nlbuild-autotools prebuilt binary distributions.
2923. Upgrading GNU autotools packages.
293
294### Generating Distributions
295
296To generate a nlbuild-autotools distribution, simply invoke:
297
298```
299% make dist
300```
301
302The package version will come from tags in the source code control
303system, if available; otherwise, from '.default-version'. The version
304can be overridden from the PACKAGE_VERSION or VERSION environment
305variables.
306
307The resulting archive will be at the top of the package build
308directory.
309
310### Generating Optional Prebuilt Binary Distributions
311
312To generate an optional nlbuild-autotools prebuilt binary
313distribution, simply invoke:
314
315```
316% make toolsdist
317```
318
319The package version will come from the source code control system, if
320available; otherwise, from `.default-version`. The version can be
321overridden from the _PACKAGE_VERSION_ or _VERSION_ environment variables.
322
323The resulting archives will be at the top of the package build
324directory.
325
326### Upgrading GNU Autotools Packages
327
328To change or upgrade GNU autotools packages used by nlbuild-autotools,
329edit the metadata for each package in tools/packages/_package_/
330_package_.{url,version}.
331
332# Versioning
333
334nlbuild-autools follows the [Semantic Versioning guidelines](http://semver.org/)
335for release cycle transparency and to maintain backwards compatibility.
336
337# License
338
339nlbuild-autools is released under the [Apache License, Version 2.0 license](https://opensource.org/licenses/Apache-2.0).
340See the `LICENSE` file for more information.
341