Fact-checked by Grok 2 weeks ago

configure script

A configure script is a script automatically generated by , a component of the GNU Autotools suite, to configure software source code packages for building on various POSIX-compliant systems. Its primary purpose is to probe the host environment for system-specific details, such as available compilers, libraries, header files, and functions, and to produce tailored output files—including Makefiles from Makefile.in templates and configuration headers like config.h—to enable portable compilation without requiring manual user intervention. Within the broader GNU build system, the configure script integrates with tools like and Libtool to create a standardized, flexible for . Developers write a template file, typically named configure.ac or configure.in, using M4 macros to specify feature tests and conditional logic; 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. 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. 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.

Overview

Definition and origins

A configure script is an executable , typically written in the (sh) or , designed to probe the host system during the software build process on 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. The origins of the configure script date to 1984, when incorporated the first known example into his Usenet newsreader program. Released that year, 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 , introduced in 1991, which generate configure scripts from declarative inputs. 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 portability. For instance, an early hand-coded script might check for the availability of the (GCC) and set the appropriate compiler variable, falling back to the system's default if necessary:
sh
#!/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.

Role in build systems

The configure script serves as a foundational component in the traditional "configure-make-install" triad prevalent in projects, where it executes prior to the make phase to generate customized Makefiles tailored to the host environment by incorporating system-specific details. 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 , BSD, and without requiring modifications to the core source code. For instance, in 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. The benefits of employing a configure script in build systems include significant reductions in manual configuration efforts, as it automates the of dependencies and environmental variables to produce across different machines. In 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.

Generation

Autoconf tool

is a 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. It produces shell scripts that detect system features, such as capabilities and availability, to facilitate cross-platform builds. Initial development of began in 1991, with the first stable release (version 1.0) occurring in July 1992. As a prerequisite, relies on the GNU M4 macro processor (version 1.4.8 or later required) to expand macros during script generation. It integrates with other Autotools components, such as for Makefile creation and Libtool for library management, to provide a complete for automating software builds. The core process involves reading an input file named configure.ac (or configure.in), which contains M4 macros defining configuration checks, and expanding them into a portable script called configure. 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 and related tools: autoreconf -f -i. This command forces regeneration and installs necessary auxiliary files from configure.ac.

Input files and macros

The primary input file for generating a configure script using is configure.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. This file, sometimes referred to by its legacy name configure.in, serves as the blueprint for the resulting , allowing developers to define portable detection logic without embedding imperative shell code. The M4-based structure ensures that the input remains concise and readable, with macros expanding into the necessary runtime tests during script generation. 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. 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. 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]). The sequential nature of macro calls in configure.ac defines the order of probes, with each macro potentially setting variables or results for subsequent use. For example, AC_FUNC_MALLOC tests whether the system's malloc 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. 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. 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 like tar -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. 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 environment, such as sh or bash. The script is designed for POSIX-like systems and relies on a standard for its operations, producing verbose output during while appending detailed logs—including outputs and results—to config.log in the current directory for debugging purposes if any fail. 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.

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 as AC_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. To check for libraries, the script utilizes macros like AC_CHECK_LIB, which constructs a test program calling a specific from the and attempts to link it with the corresponding flag, such as -lpthread for the POSIX threads . A representative example is detecting the pthread : 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 names or paths systematically. Failed compilations or linkages are diagnosed by examining messages, ensuring the script adapts to diverse environments without requiring user intervention. The configure script supports an optional caching mechanism to optimize repeated executions, which can store the results of these probes in a to avoid redundant tests on the same . This is facilitated by macros such as AC_CACHE_CHECK, which assigns a unique (e.g., ac_cv_header_pthread_h) to each test result and checks/sets it as needed; within a single run, it uses variables for efficiency, while a enables reuse across invocations. By default, no is used (equivalent to --cache-file=/dev/null), so all probes are performed each time. Caching to a can be enabled with --cache-file=FILE (e.g., --config-cache for config.cache), or disabled explicitly with --no-cache; the , 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 runs or . This significantly reduces execution time in iterative development or when configuring multiple packages on the same host. Error handling during these detections is robust, with detailed diagnostics logged to config.log for every test invocation, including the exact 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 traces. For example, a failed pthread detection would record the compilation attempt, such as gcc -c conftest.c -o conftest.o followed by the (e.g., "undefined reference to pthread_create'"), without halting the entire [script](/page/Script) unless configured to do so via AC_MSG_ERROR`. Cross-compilation support modifies these mechanisms when the --host option specifies a different from the build system, entering a where 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 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 detections while caching results for the . This ensures portability but requires careful macro selection to avoid unreliable assumptions in cross scenarios.

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 is config.status, a 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. 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 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 header is present on the system. 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.

Common options

The configure script accepts a variety of command-line options to customize the build process, allowing users to specify 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. 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. 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. For advanced customization, --cache-file=FILE enables or directs the use of a file to store results, accelerating subsequent runs by avoiding redundant system probes. The --srcdir=DIR option supports out-of-tree builds by pointing to the source when running configure from a separate build . Users can also override environment variables like the with CC=compiler ./configure, allowing specification of tools such as CC=gcc-12 for targeted builds. A practical example is ./configure --enable-shared --without-gtk, which configures the build to produce shared libraries while omitting the dependency, useful for creating lighter installations or avoiding unavailable libraries. These options collectively enable flexible adaptation of the build to diverse environments without modifying .

History and evolution

Early development

The configure script originated in 1984 with Larry Wall's development of , a newsreader designed to handle the fragmented landscape of Unix systems. Wall hand-coded the initial Configure script as a featuring interactive question-and-answer prompts and humorous commentary to guide users through system detection, such as verifying the operating system with messages like "Congratulations! You’re not running ." This approach used conditional if-then statements to probe for hardware and software variations, including differences between and BSD derivatives, such as path separators and library locations. The script's manual construction reflected the era's need for portability across diverse Unix implementations, where even basic features like file archiving varied significantly. Early adoption of similar configure scripts extended beyond , influencing 's subsequent projects and the broader Unix software community. In 1987, Wall adapted the rn Configure for 's initial release, marking one of the first instances of this detection mechanism in a widely distributed . The script in Perl inherited rn's probing logic to detect system-specific traits, ensuring compilation across Unix variants without extensive manual intervention. Other tools, including Wall's utility for applying software updates, incorporated comparable hand-crafted detection routines, focusing on reconciling inconsistencies like V7 Unix's simpler file handling versus BSD's extensions. These scripts proliferated in distributions throughout the late 1980s and early , as developers sought to distribute portable code amid the explosion of systems. However, the manual nature of these early configure scripts posed significant challenges, as maintaining them required constant updates for emerging system differences, leading to error-prone processes and duplicated efforts across projects. For instance, the original rn Configure included specific checks for terminal handling libraries—distinguishing between in older systems and in newer BSD implementations—as well as archive formats like , which varied in command-line options and output structures. Such custom logic, often spanning hundreds of lines, became burdensome as Unix fragmentation grew, resulting in a landscape of similar yet non-standardized scripts that complicated software installation and portability. This proliferation highlighted the limitations of ad-hoc approaches, where a single overlooked system quirk could break builds on targeted platforms.

Modern developments

Autoconf has evolved significantly since version 2.13, released on January 5, 1999, which introduced support for 77 and enhanced include statements in macro processing. Subsequent releases, culminating in version 2.72 on December 22, 2023, have expanded the macro library through better integration with Gnulib, providing portable C and macros for modern standards like C23 compatibility and Y2038 safety options for 64-bit time_t handling. These updates include refined macros for testing libraries and programs, such as AC_CHECK_LIB and AC_PROG_AR, improving overall portability across POSIX-like systems. Autoconf supports cross-compilation to Windows environments, including compatibility with and for generating build files adaptable to Windows without native shells. This addresses limitations in handling Windows-specific paths and libraries. Recent enhancements include deeper integration with , originating in the late 1990s, which supplies Autoconf macros like PKG_CHECK_MODULES for automated dependency detection and flag extraction. This allows configure scripts to query package directly, streamlining library linkages without manual path specification. Additionally, autoreconf supports workflows, such as invocation in repositories to regenerate build files from source trees, ensuring consistency during clones and updates. Despite these advances, configure scripts face persistent limitations, including verbose output that floods terminals with diagnostic messages during execution, though this can be mitigated with option. On large projects, the scripts' reliance on sequential shell-based tests—compiling and running small programs for feature detection—leads to noticeable slowdowns, often taking minutes or longer without caching mechanisms. Since the 2010s, Autotools usage has declined in favor of declarative build systems like and , which offer faster configuration, better parallelization, and simpler syntax for cross-platform projects. For instance, major initiatives such as and have migrated to these alternatives, citing reduced maintenance overhead and improved performance on diverse hardware. In 2.70 and later, refinements to the AC_REQUIRE macro address macro ordering issues by enforcing explicit invocations and restricting its use in complex flows, preventing latent bugs from unordered dependencies. These changes promote safer macro expansion.