This document describes how to sever a project using autotools from the autotools machinery, leaving equivalent bare Makefiles and a tiny configuration system for them in place.

Motivation

In early April 2024, an extremely serious compromise of ssh(1) using Trojan code - inserted by a trusted committer into the LZMA library - was spotted only weeks before it might have entered general distribution. It is not easy to hide a back door in publicly auditable open-source code, but the attacker exploited the fact that nobody ever wants to look at or touch autotools recipes and their generated scripts if they can possibly avoid it.

This brought into sharp focus problems with autotools that have been accumulating for decades. Autotools recipes are notoriously difficult to read and modify. The two-phase build (generation of a Makefile which is then executed to build the project) makes debugging arduous. Programmers inexperienced with autotools can’t audit a recipe at all, and those with enough experience tend to have developed a powerful flinch reflex that keeps them from actually doing it.

This makes the jungle of recipe and intermediate-product files in an autotools recipe ideal places to hide exploit components. Attempting to add anti-Trojaning checks would only add more complications, so the path of sanity is simply to scrap autotools for a simpler build flow.

The challenge, then, is how best to burn away the jungle foliage without breaking project builds.

Background

An autotools run has two products: a config.h file and a Makefile. There are a great many complications around the specifications used to generate these products that need not be described here.

The config.h file is a list of preprocessor #defines meant to be used in the guards of preprocessor #ifdef/#endif and #ifndef/#endif sections. These are typically used for select inclusion of header files and code that support platform-specific portability shims and sometimes optional features.

The Makefile is the final form of the build recipe - what you actually run make(1) against to generate your binaries and other artifacts such as rendered forms of documentation. The most important platform dependency in the Makefile is usually the details of how to invoke your compiler and linker. The recipe may also test for optional or variant libraries to be linked into your binaries.

At generation time, autotools scripts perform an elaborate sequence of checks to discover the capabilities of the host system. When autotools was first fielded, it was not uncommon for the config.h files of large projects to set dozens of guard #defines.

The important thing to know is that config.h/Makefile generation is complex mainly because of API portability issues that have been mostly obsolesced by increasing standardization around C99/C11 and SuSv2 (the Single Unix Standard, version 2, descended from POSIX). Standardization on GNU Make has also addressed some (though not all) of the portability issues in Makefiles.

Goals

In this HOWTO, we will describe ways to abolish config.h entirely and transform each of your autotools-generated product Makefiles into equivalent bare Makefiles that support the same build actions and are more amenable to being read and modified. Once this process is complete, all the specifications and scripts previously used to generate config.h and the Makefile can be discarded (and the conversion tool will do this for you).

For simple projects, this transformation is nearly trivial. If your project is not simple, jumping this gap may require significant skill and judgement. The conversion procedure is structured in such a way that you don’t have to commit to the entire process in one go, but can do it in decomposable steps.

Caveat: this tool is not really suitable for use by packagers. It’s intended for project development groups, requiring a policy commitment only they can make.

Commitment

The commitment you have to make to start this process is this: you are going to throw away the 20th century. All ancient portability shims will be discarded. From now on, you will assume that C has bools, that memcpy(3) exists, that terminals speak termios(3), that you have stdarg(3) support, that mkdir has -p, and generally that your shell environment includes POSIX-standard tools. This is what we need to do to banish autotools.

Unix programmers have very conservative instincts. We tend to cling to ancient porting kludges as though we might at any point suddenly need to build our code on a MicroVAX from 1989. In reality, the standardization people won their war in the mid-2000s, and the xz Trojan has revealed that carrying around all that historical baggage is an actual liability that we need to get shut of.

It is not insignificant that tossing out this baggage lightens your project’s maintainance load. Bugs accumulate around these kludges.

Tradeoffs

Your benefit is that the your build recipe will be greatly simplified, and become more auditable, reducing your vulnerability to stealthily-inserted code.

But there are some drawbacks to this procedure.

  • You sacrifice portability to ancient big-iron Unixes.

  • De-obfuscation does not make the converted bare makefile as readable as one might ideally wish; makemake prioritizes provable correctness of the transformation over a more aggressive approach that might improve this.

One thing that might look like a negative but isn’t is that some make targets related to cleaning up autotools debris (distclean-hdr, maintainer-clean, maintainer-clean-am, maintainer-clean-generic, and maintainer-clean-recursive) go away.

Steps

Make a branch in your repository so you can experiment safely.

Here is a summary of the process:

  1. Obtain all prerequisites.

  2. Do a normal (in-tree) build of your project (your de-obfuscated file will support out-of-tree builds, but the conversion build needs to be in-tree). Later steps will use the config.h and the Makefile; no other autotools build products or scripts will be needed.

  3. Run deconfig in your top-level directory, capturing the patch it outputs.

  4. Eyeball the patch to be sure it looks sane. Notice that it creates a new file, config.mk, and probably a second named tests.mk.

  5. Apply the patch, then test your build. If it doesn’t run normally, most likely deconfig has a bug that should be reported. It is also possible, though very unlikely, that the failure reveals a POSIX conformance problem on your platform - in that case, please report it.

  6. There may be a list of symbols before the patch. If it consists of "PACKAGE" and "VERSION", you win - your transition was simple.

  7. If it wasn’t simple, audit the exception symbols and turn as as many as possible into tests resembling those in tests.mk. The ones you can’t eliminate are the ones you will have to configure by hand on each build.

  8. Run makemake in your top-level directory. If step 5 generated a test.mk, this will join a copy to the end of your new Makefile.

  9. Test your build. If it doesn’t run normally, makemake has a bug that should be reported.

  10. Save a copy of config.mk. It contains all the settings needed to make your build run. You will be able to discard it if the next step goes as planned.

  11. Run configure. This will produce a new config.mk.

  12. Compare the new config.mk to the copy you saved. If the only differences are ENABLE options (which are things you set from the configure command line) life is good.

  13. If there are other differences, time to troubleshoot.

  14. If there aren’t, do git add or equivalent to your new Makefile, then run makemake -c to clean up the autotools debris.

  15. Run "configure" and test your build.

  16. If the -D options are not overwhelming your build logs, you can remove the remaining <config.h> includes from your code and you’re done. Otherwise see below,

  17. Polish your new Makefile.

  18. Fix the documentation of your build process

The rest of this section explains these steps in more detail.

Installing Prerequisites

This is step 1.

To run this software you will need Python 3.

If you are looking at this HOWTO on the web and don’t have the autodafe tools, you don’t strictly need to clone the autodafe repository to get them. They are three small self-contained Python scripts that you can simply download.

If you do clone the project repository and install these tools locally, beware of unintentionally shipping your project without its own copy of autodafe configure because a copy was in your execution path.

The deconfig tool needs to be able to call unifdef(1).

If you need to build shared libraries, and your operating system has an installable "libtool" package, install it (this will be possible on Linux, *BSD, Mac OS, and Windows).

Note, however, that we have observed packaged versions of libtool to fail on real builds, even when it claims to be the same version as an instance made locally by autotools (observed on Ubuntu with version 2.4.6-15build2). It appears some distributions patch libtool a bit too enthusiatically. The detailed installation steps address this problem.

Conversion build

This is step 2.

The next step will use the generated config.h and the Makefile.

Your de-obfuscated file will support out-of-tree builds, but your conversion build needs to be in-tree in order to deal with an autotools trick. If you look in your Makefiike you will notice that there are no dependencies for individual .o files.

This is because the gcc command lines generated by autotools to make .o files from .c files use magic options to analyze each C file’s dependencies and dump them into a file with the same basename but an extension of .Po (or sometimes .Plo), in a hidden directory named ".deps"; then it generates include directives to pull in those hidden files.

While this is clever because it avoids anyone having to maintain those dependencies by hand, it conflicts with having a single auditable point of truth for the entire build. The makemake tool evaluates those includes and inlines the generated dependencies.

In order to do that, it needs the .Po/.Plo files to be generated by the pre-conversion build. Autotools itself has a complicated way to reconcile this with out-of-tree nuilds that makemake can’t replicate.

That’s why your conversion build needs to be in-tree. Afterwards you won’t have this problem and can do out-of-tree builds.

Deconditionalize C11/POSIX features

This is steps 3, 4, and 5.

Run deconfig against your code directory and inspect the resulting patch (you will need unifdef installed for this to work). It looks at the symbols in your config.h or config.h.in and identifies which ones are conditionalizing code that should always work on a modern C11//POSIX/SUSv2 system. Then it generates a patch that removes the unneeded code. Any <config.h> inclusions can be removed because of this cleanup is also removed.

If you see an unifdef error message during this step, your code is engaging in preprocessor abuse which you should patch out for the duration of the conversion at least. Here’s an example of code that triggers this:

/*
 * Processed with unifdef, this yields "Inappropriate #endif"
 * With unifdef -k, the message is "Obfuscated preprocessor control line"
 *
 * Removing the inner #ifdef/#endif produces "Premature EOF (#if line 1 depth 1)"
 */
#if 0 /* Disable for now. TCP Segment Offload needs
         to be enabled by stack using LCS */
#if RANDOM
    /* Only do offload if doing TAP checksum offload */
#endif
#endif

The problem is following a preprocessor with a comment that has a continuation. This is allowed by the C standard; an issue has been filed with the unifdef maintainer.

Ahead of the patch it may also generate a list of guard symbols that it can’t discard; VERSION is likely to be one of these.

The patch will also create a file named config.mk containing all the residual definitions it could extract. Your de-obfuscated Makefiles will include it to replace what config.h formerly did.

The patch will probably also generate a "tests.mk" file containing specifications for tests to be performed by autodafe configure; this will be appended to your Makefile in a later step.

Don’t add tests.mk or config.mk to your repository. The reasons not to do this will become clear as you read more steps.

To do its job, deconfig relies on a large table of features (include-file names, function names, and type names) known to be in C11 and POSIX/SuSv2. This table is not complete, and you may see it report guard symbols as portability problems that it should not. These instances should be reported to the maintainers as bugs.

Change remaining configuration symbols into tests and options

This is steps 6 and 7.

Now you need to go through the list of residual symbols from the previous step.

VERSION, PACKAGE, PACKAGE_TARNAME, PACKAGE_URL, and PACKAGE_BUGREPORT are special. If these macros occur in your code at all, you will probably want to move where they are set from config.mk to your base Makefile. Remember that in your new build flow config.mk will be clobbered and rewritten every time you run configure.

To do this, append to CFLAGS a -D option for each symbol, set from the corresponding Makefile macro.

It’s good to avoid perturbing your Makefile every time you ship a release. Here is one example of a way to do this:

VERSION=$(shell sed -n <NEWS.adoc '/::/s/^\([0-9][^:]*\).*/\1/p' | head -1)

What this does is extract VERSION from the top stanza in the NEWS file, assuming it has stanza headers like the NEWS.adoc in autodafe. You can modify the sed expression to fit your project’s conventions.

This means the project Makefile can be stable across releases, with your release stamp changing only when you update your NEWS file. If you don’t do this, you should set VERSION to something nonempty that is obviously not a version number so it will be conspicuous if you make a tarball without an intentional version.

If you have any residuals other than these, you should read the configure man page to find out how to write configuration tests.

Some residual symbols may want to be set from configure command-line options. Use CONFIG_ENABLE for this. Other residual symbols should be turned into tests that configure can run.

If you can’t figure out how to write your tests using the primitives that configure provides, write an outboard Python script to do them and call it with CHECK_SCRIPT.

You’re finished with this step when there are no more residual symbols. You can use deconfig to check this - just run it again; when it outputs nothing but a patch band that removes config.h, you have no residuals. Apply that patch to be done.

De-obfuscate your generated Makefiles

This is step 8.

To de-obfuscate your Makefiles, run this command in your top-level directory:

./makemake .

This will walk through your code tree looking for Makefiles, moving them so they are named Makefile.bak, and then filtering them and sending the output to Makefile.

The de-obfuscation transform is not very complex. It consists of (1) deleting things (macro definitions, and productions to make autotools intermediate products) that are no longer useful, and (2) selectively expending Make macros in the same way make does.

Test your build again

This is step 9.

After the preceding step, you have in theory severed your dependency on the autotools machinery. To know whether you have done so in practice, make clean followed by make; watch for compilation errors and run your normal test suite.

If your build fails with a link error, your local libtool instance might be broken. Run "makelibtool" in your build directory to generate a fresh instance, then patch your makefile to call "./libtool" rather than "libtool". Try your make again.

Any other failure at this point probably means makemake has a bug and you should file an issue with the maintainers.

If you succeed, this would be a good time to check in your changes.

Verify that configure doesn’t break your build

This is steps 10 to 14.

Your objective in this step is to satisfy yourself that configure works.

If step 3 generated a test.mk, join a copy to the end of your new Makefile. This puts the test directives where configure can see them.

Save a copy of the config.mk that deconfig generated. It contains all the settings needed to make your build run. You’ll be able to delete the saved copy when this step is done.

Run configure. This will produce a new config.mk. Test your build with it.

Clean up generated files

This is steps 15 and 16.

You can check your new Makefile into your repository now.

To finally jettison autotools, run this command in your top-level directory.

./makemake -c .

This will remove all autotools scripts and intermediate-product files except your Makefiles (which you modified in the previous step). It will remove Makefile.bak files. It doesn’t make any further changes to your Makefile.

Then you will probably want to check a copy of configure into your repository.

It’s a good idea to test your build again after this step. You’re watching for hidden dependencies on missing intermediate products.

Removing config.h versus keeping it

This is optional step 17.

If the -D options are not overwhelming your build logs, you can remove the remaining <config.h> includes from your code and you’re done.

Otherwise, add CHECK_CONFIG(config.h) to your Makefile to tell configure to generate a config.h that the existing config.h includes can use. When you do this, configure will no longer generate -D options into config.mk.

This isn’t the default behavior because it has a subtle long-term cost. It mean there are now two communication paths between your build recipe and your compilations rather than one, making the resulting flow more difficult to debug.

Clean up your Makefiles

This is optional step 18.

After the previous step, you have ensured that no relative of the xz crack is lurking in the undergrowth of your build recipe. It now consists of Makefiles that are relatively easy to inspect.

But "relatively" is not "absolutely". The productions that autotools generates for utility targets such as "clean" and "dist" can be pretty grotty; you may want to replace them with more customized and readable equivalents.

Autotools generates a large number of boilerplate utility productions for you; dist, clean, install, and uninstall are the most important of these.

While this is convenient, the generated code is bulky and ugly, making your de-obfuscated makefile more difficult to read. Moreover, it is exactly the kind of thicket in which a clever attacker might seek to hide exploit hooks.

Therefore, it is probably best if you follow up on your conversion by removing these productions and writing simpler custom ones. You’ll get some help from makemake. The -x and -e options are useful at this stage to simplify the Makefile.

You can use makemake -x as a filter to strip out targets with names that match a specified regular expression. The -x option takes a |-separated list of regular expressions. Huge amounts of ugly boilerplate disappear with, for example, "-x \'dist.|clean.|install.|uninstall.'".

Passing the empty string to makemake -x is special; it removes all autotools boilerplate (dist, clean, install, dicumentation builders, tags and cscope productions) except what is required to support the default "make all" build of the software.

You don’t have to use -x on your first conversion. De-obfuscation is idempotent - makemake will do nothing to a de-obfuscated file unless you specify an -x option. (You may also see changes if you run a later version of makemake than the one you did your conversion with.)

The advantage of makemake -x over simply removing them after de-obfuscation is that if any macros become unreferenced due to removal, those settings will be removed as well.

With the -e option, you can eliminate much of the clutter produced by the autotools templating code, which generates lots of trivial macro assignments and references

Here is a use of makemake -e that specializes a Makefile for Unix rather than leaving file extensions as macros to be templated in:

makemake -e OBJEXT=o,EXEXT=,SOEXT=so

See also the FAQ on cross-platform portability at the end of this document.

Fix your build documentation

This is step 19.

You no longer have autotools as a build dependency. Document that.

If you’re building shared libraries you have a build dependency on standalone libtool instead. Document that.

If your installation instructions say to run autogen.sh or any other pre-configure script mean to set up autotools, you should delete that from your build documentation.

Advanced topics

Variables

This is the subset of autotools make macros that contain configuration information and are migrated to the top of your de-obfuscated Makefile.

Most build recipes will set only a relatively small subset of these. De-obfuscation of your generated Makefile removes unused definitions.

Identification

PACKAGE

The name of the package. You will inerit this because it was set in autotools.

VERSION

You must configure this.

PACKAGE_TARNAME

In autotools this was configured as though it were $(PACkAGE); makemake does the text substitution, though you can still set it to something else.

PACKAGE_BUGREPORT

Email address of the package maintainer.

Compilation flags

CC

Name of the C compiler

CFLAGS

+Flags to be passed to the C compiler

CPP

How to invoke the C preprocessor.

CPPFLAGS

Flags to pass the C preprocessor.

CXX

Name of the C++ compiler.

CXXFLAGS

Flags to pass the C++

CXXCPP

How to invoke the C++ compiler’s preprocessor.

LDFLAGS

Flags to pass the linker.

X_CFLAGS, X_EXTRA_LIBS, X_LIBS, X_PRE_LIBS

Flags and libraries to include in build lines when code links to X support.

F77

The name of a FORTRAN 77 compiler.

FFLAGS

Flags for FORTAN 77 invocations.

LIBS

This is a conventional make macro that aggregates libraries files for building a binary.

Platform

host_alias, host_cpu, host_os, host_vendor

Host identification strings. These are flagged as portability problems.

build_alias, build_cpu, build_os, build_vendor

Build target identification strings. These are flagged as portability problems.

target_alias

Alias of the target system type for build purposes. If this value is present in your deobfuscated file it is flagged as a portability problem.

OBJEXT

The extension for object files; .o on Unix, .obj on Windows.

EXEEXT

The extension used for object file: .o or ,obj,

Cross-build

srcdir

Where to find the sources for building the programs in the directory of the Makefile defining this macro.

builddir

Where the building of objects and binaries should be done.

Installation directories

exec_prefix

Prefix to use to when composing directory names for executables to land in.

pkgdatadir

Package data directory. The project name is generated into it.

pkglibdir

Package library directory. The project name is generated into it.

pkgincludedir

Package library directory (where its .h files should go). The project name is generated into it.

bindir

Where the project should istall its binaries.

datadir

Where to insrall architecture-independent data used by your program. Usually the same as datarootdir, but could be set to some project-specific subdirectory.

datarootdir

The root directory for architecture-independent data shared among pprograms. Not specific to your project.

docdir

Where to install the project’s documentation.

dvidir

Where to put DVI files.

htmldir

Where to install HTML files.

includedir

The include directory for .h files.

infodir

The installation directory for info files.

libdir

Where the project should install libraries that can be linked to by other programs.

libexecdir

Directory for architecture-independent executables meant to be called by programs rather than users.

localedir

Directory for locale files.

localstatedir

A directory where variable data files specific to a particular system or instance of a software package are stored. This directory typically contains data files that may change during the normal operation of the software, such as log files, temporary files, and run-time state information.

mandir

Installation directory for manual pages.

oldincludedir

A legacy location for installing .h include files. It would be very surprising if this were ever anything but ${prefix}/include.

pdfdir

Where to install PDF files.

prefix

Master prefix for constructing installation-directory names.

psdir

Where to put Postscript files.

sbindir

Where to install static binaries/

sharedstatedir

State directory shared across a networked file system common to multiple hosts.

sysconfdir

The system configuration directory, typically /etc modified by the master installation prefix.

Installation hooks

INSTALL, INSTALL_DATA, INSTALL_PROGRAM, INSTALL_SCRIPT, INSTALL_STRIP_PROGRAM

*Various places autotools generated installation commands for templating into the generated Makefile.

Distribution making

distdir

This is not a configuration macro and should not be overidden. It’s the name, composed from PACKAGE and VERSION, of the directory to build a distribution in.

top_distdir

This is not a configuration macro and should not be overridden. Unlike distdir it is not relative to the directory the makefile the definition is in, but refers to the toplevel directory of the project tree.

transform

Involved in some cryptic magic when installing/uninstalling programs. See program_transform_name

program_transform_name

Specify a sed(1) transformation that should be applied to the names of programs during the installation process. This transformation is typically used to modify the names of executable files to conform to a specific naming convention or to rename them for compatibility with the target platform’s naming conventions.

DIST_ARCHIVES

Names of compressed archives to build when making distribution tarballs.

GZIP_ENV

Quality option to pass gzip when making compressed archives.

Location

top_srcdir

This is not a configuration macro and should not be overidden. The top level of the source directory of this project. Won’t be the same as srcdir if this makefile is in a subdirectory.

top_builddir

The top level of the build directory of this project. Won’t be the same as builddir if this makefile is in a subdirectory

Frequently Asked Questions

Does this land us back in the mess autotools was written to clean up?

Autotools was written in the shadow of the Unix wars of the 1980s, when even small projects might need to have dozens of conditional-code sections to deal with quirks in the C compilers and the divergent Unix APIs of the time. The main reason going back to a simpler build flow is viable is because standardization worked. Modern Unixes, even the minor ones, are highly compliant with C99 and POSIX/SUSv2, and those standards have pretty good coverage of what programmers usually want to do.

This means that many autotools-using projects are using it to hammer down problems that have mostly disappeared out from under them. The expected number of -D options you need to pass to your compiler has plummeted.

The best way to find out if this is true for your project is to try it. The autodafe tools are designed to make experimenting relatively painless and easy to revert. You might be surprised at how small your config.mk ends up being.

How would adopting these tools change my project’s dependencies?

You’ll lose your build-time dependency on autotools.

If you are building shared libraries you will keep a build-time dependency on libtool.

Once you’ve done your conversion, you won’t need deconfig and makemake again.

If your code is pure POSIX/SUSv2 and you have no configuration options, that’s it. Otherwise you will have a build-time dependency on autodafe’s configure utility, and through that on Python 3.

Recommended practice is for you to check a copy of autodafe configure into your repository, replacing the autotools configure script you nay formerly have had there.

From the point of view of people building your software little will change unless you started with your build recipe with autogen.sh; that’s gone. The normal build sequence is stll "./configure; make".

The syntax for configure --enable options is slightly different. Otherwise the only change people building your software are likely to notice is that configure suddenly runs to completion much sooner and doesn’t spam them with progress messages.

Why bare makefiles and not My Favorite Heavyweight Build System?

I have been asked this question on X about cmake, mkmk, meson, scons, bazel, and doubtless others I have forgotten. The answers for all of them are the same.

  1. Make is everywhere, and anybody using an autotools build already has it installed.

  2. It’s much easier to transform a generated Makefile into another Makefile in a way that is provably correct than it would be to try to translate that generated Makefile into a different build-specification language. Attempting the latter would be just begging for trouble.

  3. Even if translation to a different build engine were technically feasible, gluing it into makemake would be the wrong thing to do. Better to perform an information-preserving transformation to bare makefiles (doing one thing well) that can be fed to a separate translation utility (doing another one thing well).

  4. Aside from all those objections, I (the author) have a lot of experience with heavyweight build systems, and it has soured me on them. They tend to be badly designed, over-engineered, poorly documented, and attractors of complexity and maintenance hassles. Bare makefiles have their flaws, but as of 2024 all the alternatives all still seem to be worse.

Anyone who is moved to respond to the previous complaint with "Try my favorite build system you haven’t mentioned! It is really super-duper keen and I am sure you will love it and bow before its awesomeness!" is advised against saying this to me face-to-face when I am within reach of an object I could club you to death with.

Is any of this useful if my project was never autoconfiscated?

In that case, deconfig and makemake won’t help you at all - but autodafe configure might.

The difference is that deconfig and makemake are very specific to the problem of disentanging a project from autotools. The configure tool isn’t; it might serve you well if you need a fast, simple configuration system.

Will I lose portability to platforms that aren’t Linux or *BSD?

Probably not. Most of the platform-dependency details in your build are hidden within your local compiler/linker tools. There is an exception near file extensions.

In the Makefiles generated by autotools, platform dependencies are all expressed as the values of make macros at the front of the file.

One of these these is OBJEXT, the file extension for object files - ".o" on Unix including OS/X, ".obj" under Windows). Another is EXEEXT, the file extension for executables - empty on Unix, ".exe" under Windows). A third is SOEXT, the file extension for shared libraries; ".so" on most Unixes, ".dynlib" on OS/X, ".dll" on Windows.

If you’re building binaries or shared libraries, all that should be strictly necessary is for you to set these macros to tell the generated compilation commands to do the right thing. Normally configure sets these for you.

Can I test makefile conversion without disturbing my source code?

Yes - makemake produces makefiles that should operate normally even if no deconfig patch has been applied.

Specifically: when you are running makemake against a directory, it will only strip out Makefile references to config.h and -DHAVE_CONFIG_H if it sees no config.h file in the directory top level.

One minor exception: if you are building shared libraries, be aware that makemake always changes your Makefile to look for libtool as an executable in your normal $PATH rather than in the top level of your build directory. You can easily patch your Makefile to revert this.

Note: If you have previously run deconfig and it reported no residuals, the patch it generated deleted config.h. This is how deconfig passes the informatoion that makefile referebces to config.h and -DHAVE_CONFIG_H can be removed.

Why doesn’t configure emulate ${TERRIFYING_AUTOTOOLS_FEATURE}?

Usually because it isn’t needed anymore. Autotools was designed in a more primitive time for a range of far more variegated and hostile Unix environments than exist today.

The main design objective of autodafe is to prevent supply-chain attacks that could be inserted in an autotools build, as happened with the xz Trojan. While this doesn’t constrain the once-and-done conversion tools deconfig and makemake, it creates a lot of pressure to keep configure small and simple and auditable.

If there is a ${TERRIFYING_AUTOTOOLS_FEATURE} that you need for your build, you have a couple of different options:

  1. Specify the feature and send us a request for enhancement. Fair warning that we will be resistant to these, as we want to keep the complexity and potential attack surface of configure minimal. It’s up to you to make the case that your desired feature is worth the weight.

  2. Send us a patch implementing and documenting the new test type in configure. This increases the chances that we will take it in, though it won’t eliminate our resistance to making configure more complex. It’s still up to you to justify that cost.

  3. The CHECK_SCRIPT test allows you to write a custom test as a Python script, and pass back information from it to be incorporated in the output of configure.

Revision history

0.1

Initial version

0.3

Major revision due to deconfig.

0.4

Major revision to go with de-libtoolization

0.5

Add more FAQs. Describe configure,

0.6

Automated removal of unneeded config.h files.

0.7

Document makemake -x and -e options

0.8

De-autoconfiscation steps.