Configure script
View on WikipediaWhen installing a package on a Unix or Unix-like environment, a configure script is a shell script that generates build configuration files for a codebase to facilitate cross-platform support. It generates files tailoring for the host system – the environment on which the codebase is built and run.
Even though there are no standards for such a script, the pattern is so ubiquitous that many developers are familiar with and even expect a script named configure that has this functionality. The script can be and originally was hand-coded. Today, multiple tools are available for generating a configure script based on special configuration files. One commonly used tool is Autotools which generates a Bash script.
Obtaining a software package as source code and compiling it locally is a common scenario on Unix and Unix-like environments. Typically, this process involves the following steps:
- Generate build configuration files
- Build the code
- Install the result to an accessible location
A configure script accomplishes the first step by generating a makefile that is configured for the host system. This includes using the libraries of the host as required by the codebase.
Use
[edit]After navigating a command-line shell to the directory that contains the source code, the following commands are typically executed:[1]
./configure
make
make install
For the Autotools, the configure script logs status and errors to file config.log, and the command ./configure --help outputs command line help information.
Often, a document with instructions is included with the codebase; often in a file named INSTALL. It can be helpful if the configure script fails.
Generating
[edit]Autotools simplifies some of the challenges of cross-platform software development.[2] These tools query the host system for environment settings, platform architecture, and the existence and location of required build and runtime dependencies. They store the gathered information in configure.ac to be read by configure during the installation phase.
In new development, library dependency checking can be accomplished via pkg-config via the m4 macro, PKG_CHECK_MODULES. Before pkg-config gained popularity, separate m4 macros were created to locate files known to be included in the distribution of libraries depended upon.
History
[edit]The first program to come with a configure script was rn by Larry Wall in 1984. The script was written by hand and produced a jocular running commentary when executed. It still survives as part of the build system of the trn program.[3]
Since then, an ecosystem of tools have been developed to automate the creation of configure scripts, of which the most common is Autoconf.
References
[edit]- ^ "Compiling Linux Software from Source Code". Control-Escape's Linux Help Engine. Retrieved 20 November 2010.
- ^ "Autoconf - GNU Project - Free Software Foundation (FSF)". GNU Operating System. Retrieved 20 November 2010.
- ^ "Configure script of trn". GitHub. Retrieved 10 December 2020.
Configure script
View on Grokipediaconfigure.ac or configure.in, using M4 macros to specify feature tests and conditional logic; Autoconf then processes this input with the GNU M4 macro processor (version 1.4.6 or later required; 1.4.13 or later recommended) to output the executable script.[1] Upon invocation, the script supports standard command-line options for customization, including --prefix to set installation directories, --enable-feature and --disable-feature to toggle optional components, --with-package to integrate external dependencies, and variables like CC to override tools, while also handling cross-compilation via --host and --target specifications.[2] This mechanism can cache test results in config.cache (when using the --config-cache option) to speed up subsequent runs and generates config.status to embed results for reproducible output file generation, while ensuring generated files include markers indicating their automated origin, facilitating maintenance and debugging in large-scale open-source projects.[1]
Overview
Definition and origins
A configure script is an executable shell script, typically written in the Bourne shell (sh) or Bash, designed to probe the host system during the software build process on Unix-like operating systems. It performs a series of tests to detect system characteristics, such as the presence of specific compilers, libraries, headers, and utilities, and generates customized configuration files—like Makefiles or config.h headers—that adapt the source code to the target environment. This mechanism ensures that the software can be compiled and installed portably across diverse Unix variants without manual intervention for each platform.[2][4] The origins of the configure script date to 1984, when Larry Wall incorporated the first known example into his rn Usenet newsreader program. Released that year, rn included a hand-written configuration script that automatically detected the host Unix version and any deviations from expected standards, adjusting the build parameters accordingly to facilitate installation on varying systems. This manual approach laid the groundwork for automated tools like GNU Autoconf, introduced in 1991, which generate configure scripts from declarative inputs.[5][6] In its basic operation, the configure script executes prior to the compilation phase, outputting files that define variables and settings based on the detected environment, thereby enabling source code portability. For instance, an early hand-coded script might check for the availability of the GNU Compiler Collection (GCC) and set the appropriate compiler variable, falling back to the system's default if necessary:#!/bin/sh
if which gcc >/dev/null 2>&1; then
CC=gcc
echo "Using GCC compiler."
else
CC=cc
echo "Using default cc compiler."
fi
echo "CC = $CC" >> Makefile
Such checks exemplify how the script embeds conditional logic to resolve dependencies, a practice that became foundational for subsequent build tools.[2]
Role in build systems
The configure script serves as a foundational component in the traditional "configure-make-install" triad prevalent in open-source software projects, where it executes prior to the make phase to generate customized Makefiles tailored to the host environment by incorporating system-specific details.[2] A primary function of the configure script is to enhance portability by detecting operating system features, including the presence of libraries, header files, and compiler capabilities, thereby accommodating variations between systems such as Linux, BSD, and Solaris without requiring modifications to the core source code. For instance, in GNU build systems, it identifies the system type (e.g., i686-pc-linux-gnu) using auxiliary scripts like config.guess and config.sub, and adjusts build parameters accordingly to handle platform-specific quirks. This detection mechanism supports cross-compilation scenarios through options like --host and --target, enabling builds for one architecture on another, which is crucial for embedded systems and multi-platform distributions.[2] The benefits of employing a configure script in build systems include significant reductions in manual configuration efforts, as it automates the resolution of dependencies and environmental variables to produce reproducible builds across different machines. In GNU projects, for example, it sets key variables such as CFLAGS for compiler flags or LIBS for linker libraries based on detected features, ensuring software compiles reliably on diverse architectures while minimizing errors from overlooked system differences. This automation not only accelerates development workflows but also promotes consistency in open-source ecosystems by standardizing the adaptation process.[2]Generation
Autoconf tool
Autoconf is a GNU tool within the Autotools suite designed to generate portable configure scripts from declarative input files, enabling software packages to adapt automatically to various POSIX-like systems without manual intervention.[7] It produces shell scripts that detect system features, such as compiler capabilities and library availability, to facilitate cross-platform builds.[1] Initial development of Autoconf began in 1991, with the first stable release (version 1.0) occurring in July 1992.[8][9] As a prerequisite, Autoconf relies on the GNU M4 macro processor (version 1.4.8 or later required) to expand macros during script generation.[1] It integrates with other Autotools components, such as Automake for Makefile creation and Libtool for library management, to provide a complete ecosystem for automating software builds. The core process involves Autoconf reading an input file namedconfigure.ac (or configure.in), which contains M4 macros defining configuration checks, and expanding them into a portable Bourne shell script called configure.[1] This output script incorporates extensive feature tests to ensure compatibility across diverse environments.
A basic invocation to generate the configure script uses the autoreconf wrapper, which orchestrates Autoconf and related tools: autoreconf -f -i. This command forces regeneration and installs necessary auxiliary files from configure.ac.[10]
Input files and macros
The primary input file for generating a configure script using Autoconf isconfigure.ac, a declarative script written in the M4 macro language that specifies system checks, feature probes, and output actions through a sequence of macro invocations.[11] This file, sometimes referred to by its legacy name configure.in, serves as the blueprint for the resulting shell script, allowing developers to define portable detection logic without embedding imperative shell code.[12] The M4-based structure ensures that the input remains concise and readable, with macros expanding into the necessary runtime tests during script generation.[13]
Key macros in configure.ac form the core of this declarative system, each handling specific aspects of configuration. The AC_INIT macro must be called first to initialize essential package metadata, including the package name, version, and optional bug report email; for instance, AC_INIT([GNU Project], [1.0], [[email protected]]) sets variables like PACKAGE_NAME and PACKAGE_VERSION for use in outputs.[14] Following initialization, macros like AC_PROG_CC locate and verify a suitable C compiler, setting the CC output variable to the detected tool (such as gcc or cc) and ensuring it supports required standards.[15] For library detection, AC_CHECK_LIB probes for a specific library by attempting to link a test program calling a given function, adding -llibrary to LIBS if successful; its syntax is AC_CHECK_LIB([library], [function], [action-if-found], [action-if-not-found]).[16]
The sequential nature of macro calls in configure.ac defines the order of probes, with each macro potentially setting shell variables or cache results for subsequent use. For example, AC_FUNC_MALLOC tests whether the system's malloc function returns a non-null pointer for a zero-size allocation, defining HAVE_MALLOC=1 and providing a replacement implementation if the check fails, as cached in ac_cv_func_malloc_0_nonnull.[17] Similarly, AC_CHECK_HEADERS verifies the presence of header files like stdlib.h by attempting compilation. The script concludes with AC_OUTPUT, which generates and executes config.status to produce substituted files such as Makefiles, using variables accumulated from prior macros.[18]
A representative snippet of configure.ac illustrates this structure:
AC_INIT([MyProject], [1.0])
AC_PROG_CC
AC_CHECK_HEADERS([stdlib.h])
AC_FUNC_MALLOC
AC_CHECK_LIB([m], [pow])
AC_OUTPUT([Makefile])
This sequence initializes the project, sets up the compiler, checks for standard headers and the malloc function, probes for the math library, and finally outputs the Makefile with substitutions.
Execution and features
Invoking the script
The configure script is typically invoked from the root directory of the extracted source code package, after unpacking it from a distribution archive such as a tarball using a command liketar -xvf package.tar.gz. This placement ensures that the script can locate necessary files and perform its checks relative to the source tree. Build tools such as make must be installed on the system beforehand, as the configuration process prepares the environment for subsequent compilation steps.[19]
To execute the script, ensure it has executable permissions by running chmod +x configure if necessary, then issue the command ./configure [options] in a Bourne-compatible shell environment, such as sh or bash. The script is designed for POSIX-like systems and relies on a standard shell for its operations, producing verbose output during checks while appending detailed logs—including compiler outputs and test results—to config.log in the current directory for debugging purposes if any checks fail.[20][21][19]
A common example is ./configure --prefix=/usr/local, which specifies the installation directory prefix; upon successful completion, this is followed by make to compile the software and make install to deploy it to the designated location. Options can be viewed via ./configure --help for customization, such as setting cache files or source directories, but the basic form suffices for standard setups.[22]
System detection mechanisms
The configure script employs a variety of probing methods to detect system features during its execution, primarily by attempting to compile and link small code snippets using the host system's compiler and linker. These tests are implemented through low-level Autoconf macros such asAC_TRY_COMPILE, which checks if a given source code fragment compiles successfully without linking, often to verify the availability of headers or compiler-specific features. For instance, to detect the presence of a header file like <pthread.h>, the script uses AC_CHECK_HEADER, which invokes AC_TRY_COMPILE with a minimal program that includes the header and a simple statement, reporting success if compilation succeeds. Similarly, AC_TRY_LINK extends this by also attempting to link the object file, useful for verifying function availability or basic library linkage.[23]
To check for libraries, the script utilizes macros like AC_CHECK_LIB, which constructs a test program calling a specific function from the library and attempts to link it with the corresponding flag, such as -lpthread for the POSIX threads library. A representative example is detecting the pthread library: the script compiles and links a small C program that includes <pthread.h> and calls pthread_create, appending -lpthread to the linker flags; if successful, it sets a shell variable like HAVE_PTHREADS=yes and may add the flag to LIBS for subsequent builds. These probes are non-intrusive, relying on the system's build tools, and are typically wrapped in higher-level macros like AC_SEARCH_LIBS to try multiple library names or paths systematically. Failed compilations or linkages are diagnosed by examining compiler error messages, ensuring the script adapts to diverse environments without requiring user intervention.[23]
The configure script supports an optional caching mechanism to optimize repeated executions, which can store the results of these probes in a cache file to avoid redundant tests on the same system. This is facilitated by macros such as AC_CACHE_CHECK, which assigns a unique cache variable (e.g., ac_cv_header_pthread_h) to each test result and checks/sets it as needed; within a single run, it uses shell variables for efficiency, while a cache file enables reuse across invocations. By default, no cache file is used (equivalent to --cache-file=/dev/null), so all probes are performed each time. Caching to a file can be enabled with --cache-file=FILE (e.g., --config-cache for config.cache), or disabled explicitly with --no-cache; the cache file, if used, is sourced at the start and updated only at the end of a successful run, just before generating output files. The --no-create option allows the script to perform all detections and caching but aborts without creating Makefiles or other outputs, useful for dry runs or verification. This system significantly reduces execution time in iterative development or when configuring multiple packages on the same host.[24]
Error handling during these detections is robust, with detailed diagnostics logged to config.log for every test invocation, including the exact compiler commands, input code snippets, and full output from failed compilations or linkages. This log captures environmental variables, include paths, and linker flags used, enabling users to troubleshoot issues like missing dependencies or incompatible toolchains by inspecting the verbose error traces. For example, a failed pthread detection would record the compilation attempt, such as gcc -c conftest.c -o conftest.o followed by the error (e.g., "undefined reference to pthread_create'"), without halting the entire script unless configured to do so via AC_MSG_ERROR`.[25]
Cross-compilation support modifies these mechanisms when the --host option specifies a target different from the build system, entering a mode where runtime execution tests (e.g., AC_TRY_RUN) are disabled to prevent attempting to run unexecutable binaries. Instead, the script relies on compilation and linkage probes or user-provided defaults, setting the cross_compiling variable to yes and adjusting variables like host and host_alias accordingly; for instance, ./configure --host=arm-linux would probe using an ARM cross-compiler for library detections while caching results for the target environment. This ensures portability but requires careful macro selection to avoid unreliable assumptions in cross scenarios.[26]
Output and customization
Generated files
The configure script primarily generates several key files to facilitate the build process of a software package. Among these, the most central output isconfig.status, a shell script that records the configuration options and results from the configure invocation, enabling subsequent reconfiguration without rerunning the full set of system probes. This file is created during the execution of configure and serves as the mechanism for instantiating other output files by applying substitutions and actions defined in the input template.[27]
One of the primary outputs is the Makefile, generated from template files such as Makefile.in through variable substitution using the AC_CONFIG_FILES macro in configure.ac. The configure script replaces placeholders in the form @VAR@—defined via the AC_SUBST macro in the configure.ac input file—with their corresponding values, such as replacing @CC@ with the detected compiler like gcc. For instance, in a typical package, this might produce src/Makefile with paths adapted to the installation prefix specified via the --prefix option, ensuring build rules reflect the target environment without hardcoding system-specific details. Similarly, config.h is generated from config.h.in using the AC_CONFIG_HEADERS macro, incorporating preprocessor defines based on detection results, such as #define HAVE_STDLIB_H 1 if the standard library header is present on the system.[28][27]
These generated files are designed such that the build system avoids unnecessary regeneration to preserve custom or manually edited content; for example, if a Makefile already exists and is newer than its .in template and other dependencies, make will skip invoking config.status unless explicitly forced (e.g., with make -B), preserving user modifications in non-standard setups. Regeneration of outputs can be performed efficiently using config.status --recheck, which reruns the configure script's detection mechanisms—such as those for system features—with the original arguments but without fully reinstantiating files, updating config.status only as needed. This approach leverages the prior configuration state to minimize redundant checks while ensuring outputs remain consistent with any changes in the build environment.[29][27]
Common options
The configure script accepts a variety of command-line options to customize the build process, allowing users to specify installation locations, enable or disable features, and override default settings. These options are typically defined in the input file (configure.ac) using macros such as AC_ARG_ENABLE for feature toggles and AC_ARG_WITH for package dependencies, which generate corresponding help text and handling logic in the script. Running./configure --help displays a comprehensive list of all available options for a specific script, including package-specific ones alongside standard flags.[30]
Among the most commonly used options is --prefix=DIR, which sets the base directory for installing files, defaulting to /usr/local if unspecified; this affects paths for binaries, libraries, and data files in the generated Makefiles.[30] Feature-related options include --enable-FEATURE to activate optional components (e.g., debugging support) and --disable-FEATURE to deactivate them, with the script's behavior for each depending on the package's configure.ac definitions. Similarly, --with-PACKAGE[=ARG] specifies the location or configuration of external dependencies (e.g., --with-libxml=/usr), while --without-PACKAGE excludes them entirely, aiding in dependency management during configuration.[30]
For advanced customization, --cache-file=FILE enables or directs the use of a cache file to store configuration results, accelerating subsequent runs by avoiding redundant system probes.[30] The --srcdir=DIR option supports out-of-tree builds by pointing to the source directory when running configure from a separate build directory.[30] Users can also override environment variables like the compiler with CC=compiler ./configure, allowing specification of tools such as CC=gcc-12 for targeted builds.[30]
A practical example is ./configure --enable-shared --without-gtk, which configures the build to produce shared libraries while omitting the GTK dependency, useful for creating lighter installations or avoiding unavailable libraries.[30] These options collectively enable flexible adaptation of the build to diverse environments without modifying source code.