Adding autosetup support to a project
Introduction
This guide explains how to add autosetup support to a project. Be sure to read the user-level documentation first, including the download instructions. The examples can also be very helpful.
Project-Local or System-Wide Install?
Before version 0.6.7 of autosetup, the only options to install autosetup as part of a project. As explained below, this has the advantage of allowing your project to configure without requiring any additional tools. It also solves the version problems since your project ships with exactly the version of autosetup it requires.
Since version 0.6.7, as autosetup has stabilised, a system-wide installation of autosetup is now supported. While this has the advantage of not requiring a copy of autosetup to be shipped with each project, open-source, standalone projects are still encouraged to include a project-local copy of autosetup.
See Using a system-wide install for further details. The remainder of this page assumes a project-local install.
The Moving Parts
autosetup is deployed directly into the source tree of a project. (This approach was inspired by waf, and means that there are no dependency issues with different versions of autosetup since an appropriate version is part of the project.)
Within a project, autosetup consists of three main parts at the top of the tree.
- The
autosetup/
directory - The
auto.def
file - The
configure
wrapper script
These are all created by autosetup --install --init=make
. Here are the files
in a typical installation.
auto.def
configure
autosetup/LICENSE
autosetup/README.autosetup
autosetup/autosetup
autosetup/autosetup-config.guess
autosetup/autosetup-config.sub
autosetup/autosetup-find-tclsh
autosetup/autosetup-test-tclsh
autosetup/cc-db.tcl
autosetup/cc-lib.tcl
autosetup/cc-shared.tcl
autosetup/cc.tcl
autosetup/default.auto
autosetup/jimsh0.c
autosetup/pkg-config.tcl
autosetup/system.tcl
autosetup/tmake.auto
autosetup/tmake.tcl
The auto.def file
This file controls the configuration process. A trivial version is created by autosetup --install
,
which must be edited to add the options and tests required for the project.
The configure
script
This tiny wrapper script is created by autosetup --install
and does not need to be modified.
The autosetup/ directory
This directory contains autosetup. Normally nothing needs to be modified in this directory,
however it is possible to add custom modules if necessary as: autosetup/<modulename>.tcl
The core of autosetup is the Tcl script autosetup/autosetup
with the remaining files
as support files.
Note that a single-file version of a Tcl interpreter, autosetup/jimsh0.c
is included and automatically used in case no suitable interpreter
is found.
Configuration Description — auto.def
The configuration process is controlled by the auto.def
file.
This file consists of the following sections.
- module
use
declarations (must be first) - user
options
declaration (must be second) - checks for features and options
- output file generation based on checks, including template-based generation
A typical, simple auto.def file is:
use cc options { shared => "build a shared library" lineedit=1 => "disable line editing" utf8 => "enabled UTF-8 support" with-regexp regexp => "use regexp" } cc-check-types "long long" cc-check-includes sys/un.h dlfcn.h cc-check-functions ualarm sysinfo lstat fork vfork cc-check-function-in-lib sqlite3_open sqlite3 if {[opt-bool utf8] && [have-feature fork]} { msg-result "Enabling UTF-8" define JIM_UTF8 } make-config-header config.h make-template Makefile.in
The auto.def
file is written in Tcl. See Tcl Scripting
for more information on the syntax and language features of Tcl.
module use
autosetup contains some core configuration support, but support
for additional features is provided by optional modules. Some modules
such as system
, cc
and cc-shared
are very common and will
almost always be included, while additional modules may be included
as required. See Modules for more information on how
modules can be created.
A typical use
declaration is:
# The C/C++ compiler will be used and shared libraries may be needed use cc cc-shared
Note that the system
module is automatically included by the cc
module.
options declaration
Options allow the user to provide control of the build. Options may be used to specify: * where the build is installed * the toolchain to use * features to enable or disable * the location of required external components * and anything else which may affect how the build is performed
Note: Every auto.def must have an options
declaration
immediately after any use
declarations, even if it is empty. This
ensures that configure --help
behaves correctly.
Options are declared as follows.
options { boolopt => "a boolean option which defaults to disabled" boolopt2=1 => "a boolean option which defaults to enabled" stringopt: => "an option which takes an argument, e.g. --stringopt=value" stringopt2:=value => "an option where the argument is optional and defaults to 'value'" optalias booltopt3 => "a boolean with a hidden alias. --optalias is not shown in --help" boolopt4 => { Multi-line description for this option which is carefully formatted. } }
The =>
syntax is used to indicate the help description for the
option. If an option is not followed by =>
, the option is not
displayed in --help
but is still available.
If the first character of the help description is a newline (as for
boolopt4
), the description will not be reformatted.
String options can be specified multiple times by the user, and all given values are available. If there is no default value, the value must be specified.
Within auto.def
, options can be checked with the commands opt-bool
and opt-val
.
configure --help
automatically displays appropriately formatted help for the declared options.
The example above gives.
$ ./configure --help ...standard help... Local Options: --boolopt a boolean option which defaults to disabled --disable-boolopt2 a boolean option which defaults to enabled --stringopt= an option which takes an argument, e.g. --stringopt=value --stringopt2?=value? an option where the argument is optional and defaults to 'value' --booltopt3 a boolean with a hidden alias. --optalias is not shown in --help --boolopt4 Multi-line description for this option which is carefully formatted.
See Options for how options are specified on the autosetup
command line.
Testing Features and Options
autosetup maintains a single set of name/value pairs (defines) which represent the build
environment. Some of these values are set automatically by autosetup, some are set
by modules, some are set based on feature tests and others are set explicitly in auto.def
.
Some example values are:
srcdir=.
target=x86_64-apple-darwin10.7.0
HAVE_STDLIB_H=1
CC=arm-linux-gcc
SIZEOF_LONG_LONG=8
These defines, or configuration variables fall into three broad categories:
- Standard system defines are lower case, such as
srcdir
,host_alias
andprefix
- Commands, libraries and flags which would typically be substituted in a Makefile are
uppercase, such as
CC
,LIBS
andCFLAGS
- Feature tests are boolean values in uppercase, always start with HAVE_ and have the value 0 or 1.
For example,
HAVE_STDLIB_H
,HAVE_REGCOMP
andHAVE_LONG_LONG
. Note that a standard naming convention is used such that a test forstdlib.h
setsHAVE_STDLIB_H
, a test for the functionregcomp
setsHAVE_REGCOMP
and a test for the typelong long
definesHAVE_LONG_LONG
In addition, cc-check-sizeof
sets a numeric value and uses the SIZEOF_ prefix rather than the HAVE_ prefix.
The goal of the testing section of auto.def
is to set defines based on the
development environment and the user options. autosetup provides a number of convenient commands
for setting defines (see the command reference for full details).
Direct Definition
The define
and define-feature
commands directly define a value. Note that define-feature
automatically applies the feature naming convention.
define VERSION 1.1.3 if {[opt-bool utf8]} { define USE_UTF8 } define-feature regcomp
These definitions are often made based on user options, which may
be checked with opt-bool
and opt-val
.
Feature Test Commands
The cc-xxx
commands run the C or C++ compiler and define features based on the results.
cc-check-types "long long" cc-check-includes sys/un.h dlfcn.h cc-check-functions ualarm sysinfo lstat fork vfork cc-check-tools ar ranlib strip cc-with {-includes sys/socket.h} { cc-check-members "struct msghdr.msg_control" }
User Specified Variables
Any name=value parameters specified on the configure
command line are automatically
set as configuration variables.
Output File Generation
In order for the feature and option checks to be useful, output files must be created to control the build. autosetup provides support for two common mechanisms.
1. Template Substitution — make-template
The make-template
command creates a file from a template by
applying substitutions based on the configuration variables. For
example, any instance of @CC@
is replaced with the value of CC
(e.g. arm-linux-gcc
) in the output file.
This approach is ideal for creating a Makefile from a template, Makefile.in.
2. Header File Generation — make-config-header
The make-config-header
command creates a C/C++ header file based on the configuration variables.
By default, every true feature test is defined in the generated header file. It is also possible
to output only a subset of the configuration variables, and also to include string variables
in addition to boolean variables.
A typical generated header file is:
#ifndef _AUTOCONF_H
#define _AUTOCONF_H
#define HAVE_BACKTRACE 1
#define HAVE_DLFCN_H 1
#define HAVE_DLOPEN 1
#define HAVE_FORK 1
#define HAVE_GETADDRINFO 1
#define HAVE_GETEUID 1
#define HAVE_INET_NTOP 1
#define HAVE_LONG_LONG 1
/* #undef HAVE_SYSINFO */
#define HAVE_SYSLOG 1
#define TCL_PLATFORM_OS "Darwin"
#define TCL_PLATFORM_PLATFORM "unix"
#define SIZEOF_LONG_LONG 8
#endif
It is also easy to create other file formats based on configuration variables. For example, to produce configuration files in the Linux kconfig format. It is also possible to output configuration variables in Makefile format.