Commit 8c547ec7e1 for openssl.org

commit 8c547ec7e14e2bd988e599ff47578397d5aa6183
Author: Paul Louvel <paul.louvel@bootlin.com>
Date:   Fri Jan 23 14:22:55 2026 +0100

    feat: Disabled features are generated during configure automatically

    Reviewed-by: Matt Caswell <matt@openssl.foundation>
    Reviewed-by: Paul Dale <paul.dale@oracle.com>
    MergeDate: Fri Mar 13 15:50:43 2026
    (Merged from https://github.com/openssl/openssl/pull/30212)

diff --git a/.gitignore b/.gitignore
index 94610e62d6..d2201aaecf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,6 +59,8 @@
 /include/openssl/x509_vfy.h
 /include/openssl/core_names.h

+/apps/include/configuration.h
+
 # Auto generated parameter name files
 /crypto/params_idx.c

diff --git a/Configure b/Configure
index e87c9ea471..4a1002af78 100755
--- a/Configure
+++ b/Configure
@@ -421,11 +421,87 @@ my @dtls = qw(dtls1 dtls1_2);
 # be regexps, and will be used like this: /^no-${option}$/
 # For developers: keep it sorted alphabetically

-my @disablables = (
-    "acvp-tests",
-    "apps",
+my @disablables_protocols = (
+  "cmp",
+  "dtls",
+  "http",
+  "ocsp",
+  "ktls",
+  "tls",
+  "tls-deprecated-ec",
+  "quic",
+  "sctp",
+  "srp",
+  "srtp"
+);
+
+foreach my $proto ((@tls, @dtls))
+        {
+        push(@disablables_protocols, $proto);
+        push(@disablables_protocols, "$proto-method") unless $proto eq "tls1_3";
+        }
+
+my @disablables_algorithms = (
     "argon2",
     "aria",
+    "bf",
+    "blake2",
+    "brotli",
+    "camellia",
+    "cast",
+    "chacha",
+    "cmac",
+    "cms",
+    "comp",
+    "des",
+    "dh",
+    "dsa",
+    "hmac-drbg-kdf",
+    "ec",
+    "ec2m",
+    "ecdh",
+    "ecdsa",
+    "ecx",
+    "kbkdf",
+    "krb5kdf",
+    "gost",
+    "idea",
+    "md2",
+    "md4",
+    "md5",
+    "mdc2",
+    "ml-dsa",
+    "ml-kem",
+    "lms",
+    "ocb",
+    "poly1305",
+    "psk",
+    "pvkkdf",
+    "rc2",
+    "rc4",
+    "rc5",
+    "rmd160",
+    "scrypt",
+    "seed",
+    "siphash",
+    "slh-dsa",
+    "siv",
+    "snmpkdf",
+    "sm2",
+    "sm3",
+    "sm4",
+    "sshkdf",
+    "sskdf",
+    "x942kdf",
+    "x963kdf",
+    "whirlpool",
+    "zlib",
+    "zstd",
+);
+
+my @disablables_features = (
+    "acvp-tests",
+    "apps",
     "asan",
     "asm",
     "async",
@@ -433,21 +509,12 @@ my @disablables = (
     "autoalginit",
     "autoerrinit",
     "autoload-config",
-    "bf",
-    "blake2",
-    "brotli",
     "brotli-dynamic",
     "buildtest-c++",
     "bulk",
     "cached-fetch",
-    "camellia",
+    "dgram",
     "winstore",
-    "cast",
-    "chacha",
-    "cmac",
-    "cmp",
-    "cms",
-    "comp",
     "crypto-mdebug",
     "allocfail-tests",
     "ct",
@@ -455,23 +522,12 @@ my @disablables = (
     "demos",
     "h3demo",
     "hqinterop",
-    "hmac-drbg-kdf",
     "deprecated",
-    "des",
-    "dgram",
-    "dh",
     "docs",
-    "dsa",
     "dso",
-    "dtls",
-    "ec",
-    "ec2m",
+    "ech",
     "ec_explicit_curves",
     "ec_nistp_64_gcc_128",
-    "ecdh",
-    "ecdsa",
-    "ecx",
-    "ech",
     "egd",
     "err",
     "external-tests",
@@ -482,63 +538,26 @@ my @disablables = (
     "fips-jitter",
     "fuzz-afl",
     "fuzz-libfuzzer",
-    "gost",
-    "http",
-    "idea",
     "integrity-only-ciphers",
     "jitter",
-    "kbkdf",
-    "krb5kdf",
-    "ktls",
     "legacy",
-    "lms",
     "makedepend",
-    "md2",
-    "md4",
-    "mdc2",
-    "ml-dsa",
-    "ml-kem",
     "module",
     "msan",
     "multiblock",
     "nextprotoneg",
-    "ocb",
-    "ocsp",
     "pic",
     "pie",
     "pinshared",
-    "poly1305",
     "posix-io",
-    "psk",
-    "pvkkdf",
-    "quic",
     "unstable-qlog",
-    "rc2",
-    "rc4",
-    "rc5",
     "rdrand",
     "rfc3779",
-    "rmd160",
-    "scrypt",
-    "sctp",
     "secure-memory",
-    "seed",
     "shared",
-    "siphash",
-    "siv",
-    "slh-dsa",
-    "sm2",
     "sm2-precomp",
-    "sm3",
-    "sm4",
-    "snmpkdf",
     "sock",
-    "srp",
-    "srtp",
-    "srtpkdf",
     "sse2",
-    "sshkdf",
-    "sskdf",
     "ssl-trace",
     "static-vcruntime",
     "stdio",
@@ -547,8 +566,6 @@ my @disablables = (
     "tfo",
     "thread-pool",
     "threads",
-    "tls",
-    "tls-deprecated-ec",
     "trace",
     "ts",
     "ubsan",
@@ -556,19 +573,12 @@ my @disablables = (
     "unit-test",
     "uplink",
     "weak-ssl-ciphers",
-    "whirlpool",
-    "x942kdf",
-    "x963kdf",
-    "zlib",
     "zlib-dynamic",
-    "zstd",
     "zstd-dynamic",
-    );
-foreach my $proto ((@tls, @dtls))
-        {
-        push(@disablables, $proto);
-        push(@disablables, "$proto-method") unless $proto eq "tls1_3";
-        }
+
+);
+
+my @disablables = sort (@disablables_protocols,@disablables_algorithms,@disablables_features);

 # Internal disablables, for aliasing purposes.  They serve no special
 # purpose here, but allow scripts to get to know them through configdata.pm,
@@ -839,6 +849,11 @@ $config{ex_libs} = [ env('__CNF_LDLIBS') || () ];
 $config{openssl_api_defines}=[];
 $config{openssl_sys_defines}=[];
 $config{openssl_feature_defines}=[];
+
+$config{openssl_disabled_protocols}=[];
+$config{openssl_disabled_algorithms}=[];
+$config{openssl_disabled_features}=[];
+
 $config{options}="";
 $config{build_type} = "release";
 my $target="";
@@ -1926,6 +1941,20 @@ foreach my $what (sort keys %disabled) {
         my $macro = $disabled_info{$what}->{macro} = "OPENSSL_NO_$WHAT";
         push @{$config{openssl_feature_defines}}, $macro;

+        my @rules = (
+            [ \@disablables_protocols,  'openssl_disabled_protocols'  ],
+            [ \@disablables_algorithms, 'openssl_disabled_algorithms' ],
+            [ \@disablables_features,   'openssl_disabled_features'   ],
+        );
+
+        for my $r (@rules) {
+            my ($list, $target) = @$r;
+
+            if (grep { $what eq $_ } @$list) {
+              push @{$config{$target}}, uc $what;
+            }
+        }
+
         $skipdir{"crypto/$skipdir"} = $what
             unless $what eq 'async' || $what eq 'err' || $what eq 'dso' || $what eq 'http';
     }
diff --git a/apps/include/configuration.h.in b/apps/include/configuration.h.in
new file mode 100644
index 0000000000..71b6ff434e
--- /dev/null
+++ b/apps/include/configuration.h.in
@@ -0,0 +1,44 @@
+/*
+ * {- join("\n * ", @autowarntext) -}
+ *
+ * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef APPS_CONFIGURATION_H
+#define APPS_CONFIGURATION_H
+
+/* clang-format off */
+{-
+    my $generate_openssl_disable_array = sub {
+      my ($key) = @_;
+      my $data = $config{$key};
+      my $res = "static const char * const ${key}[] = {\n";
+
+      $res .= "\t\"\",\n";
+
+      if ($data && @$data) {
+
+          foreach (@$data) {
+              $res .= "\t\"$_\",\n";
+          }
+      }
+
+      $res .= "};\n";
+
+      return $res;
+    };
+
+    $OUT .= $generate_openssl_disable_array->('openssl_disabled_protocols');
+    $OUT .= "\n";
+    $OUT .= $generate_openssl_disable_array->('openssl_disabled_algorithms');
+    $OUT .= "\n";
+    $OUT .= $generate_openssl_disable_array->('openssl_disabled_features');
+-}
+/* clang-format on */
+
+#endif
diff --git a/apps/list.c b/apps/list.c
index 4685ebfc02..a9a55fadee 100644
--- a/apps/list.c
+++ b/apps/list.c
@@ -8,6 +8,7 @@
  */

 /* We need to use some deprecated APIs */
+#include "internal/nelem.h"
 #include "openssl/bio.h"
 #define OPENSSL_SUPPRESS_DEPRECATED

@@ -32,340 +33,11 @@
 #include "progs.h"
 #include "opt.h"
 #include "names.h"
+#include "configuration.h"

 static int verbose = 0;
 static const char *select_name = NULL;

-static const char *const disabled_features[] = {
-    "",
-#ifdef OPENSSL_NO_ASYNC
-    "ASYNC",
-#endif
-#ifdef OPENSSL_NO_ATEXIT
-    "ATEXIT",
-#endif
-#ifdef OPENSSL_NO_AUTOALGINIT
-    "AUTOALGINIT",
-#endif
-#ifdef OPENSSL_NO_AUTOERRINIT
-    "AUTOERRINIT",
-#endif
-#ifdef OPENSSL_NO_AUTOLOAD_CONFIG
-    "AUTOLOAD_CONFIG",
-#endif
-#ifdef OPENSSL_NO_CACHED_FETCH
-    "CACHED_FETCH",
-#endif
-#ifdef OPENSSL_NO_CMP
-    "CRMF",
-#endif
-#ifdef OPENSSL_NO_CMS
-    "CMS",
-#endif
-#ifdef OPENSSL_NO_COMP
-    "COMP",
-#endif
-#ifdef OPENSSL_NO_CT
-    "CT",
-#endif
-#ifdef OPENSSL_NO_DGRAM
-    "DGRAM",
-#endif
-#ifdef OPENSSL_NO_DSO
-    "DSO",
-#endif
-#ifdef OPENSSL_NO_ERR
-    "ERR",
-#endif
-#ifdef OPENSSL_NO_FIPS_SECURITYCHECKS
-    "FIPS_SECURITYCHECKS",
-#endif
-#ifdef OPENSSL_NO_FIPS_POST
-    "FIPS_POST",
-#endif
-#ifdef OPENSSL_NO_MODULE
-    "MODULE",
-#endif
-#ifdef OPENSSL_NO_MULTIBLOCK
-    "MULTIBLOCK",
-#endif
-#ifdef OPENSSL_NO_NEXTPROTONEG
-    "NEXTPROTONEG",
-#endif
-#ifdef OPENSSL_NO_PINSHARED
-    "PINSHARED",
-#endif
-#ifdef OPENSSL_NO_RDRAND
-    "RDRAND",
-#endif
-#ifdef OPENSSL_NO_RFC3779
-    "RFC3779",
-#endif
-#ifdef OPENSSL_NO_SM2_PRECOMP
-    "SM2_PRECOMP",
-#endif
-#ifdef OPENSSL_NO_SSE2
-    "SSE2",
-#endif
-#ifdef OPENSSL_NO_SSL_TRACE
-    "SSL_TRACE",
-#endif
-#ifdef OPENSSL_NO_STDIO
-    "STDIO",
-#endif
-#ifdef OPENSSL_NO_THREADS
-    "THREADS",
-#endif
-#ifdef OPENSSL_NO_THREAD_POOL
-    "THREAD_POOL",
-#endif
-#ifdef OPENSSL_NO_DEFAULT_THREAD_POOL
-    "DEFAULT_THREAD_POOL",
-#endif
-#ifdef OPENSSL_NO_SOCK
-    "SOCK",
-#endif
-#ifdef OPENSSL_NO_TS
-    "TS",
-#endif
-#ifdef OPENSSL_NO_UI_CONSOLE
-    "UI_CONSOLE",
-#endif
-#ifdef OPENSSL_NO_UPLINK
-    "UPLINK",
-#endif
-};
-static const char *const disabled_protocols[] = {
-    "",
-#ifdef OPENSSL_NO_CMP
-    "CMP",
-#endif
-#ifdef OPENSSL_NO_DTLS
-    "DTLS",
-#endif
-#ifdef OPENSSL_NO_DTLS1
-    "DTLS1",
-#endif
-#ifdef OPENSSL_NO_DTLS1_2
-    "DTLS1_2",
-#endif
-#ifdef OPENSSL_NO_HTTP
-    "HTTP",
-#endif
-#ifdef OPENSSL_NO_OCSP
-    "OCSP",
-#endif
-#ifdef OPENSSL_NO_TLS
-    "TLS",
-#endif
-#ifdef OPENSSL_NO_TLS1
-    "TLS1",
-#endif
-#ifdef OPENSSL_NO_TLS1_1
-    "TLS1_1",
-#endif
-#ifdef OPENSSL_NO_TLS1_2
-    "TLS1_2",
-#endif
-#ifdef OPENSSL_NO_TLS1_3
-    "TLS1_3",
-#endif
-#ifdef OPENSSL_NO_QUIC
-    "QUIC",
-#endif
-#ifdef OPENSSL_NO_SCTP
-    "SCTP",
-#endif
-#ifdef OPENSSL_NO_SRP
-    "SRP",
-#endif
-#ifdef OPENSSL_NO_SRTP
-    "SRTP",
-#endif
-};
-static const char *const disabled_algorithms[] = {
-    "",
-#ifdef OPENSSL_NO_ARGON2
-    "ARGON2",
-#endif
-#ifdef OPENSSL_NO_ARIA
-    "ARIA",
-#endif
-#ifdef OPENSSL_NO_BF
-    "BF",
-#endif
-#ifdef OPENSSL_NO_BLAKE2
-    "BLAKE2",
-#endif
-#ifdef OPENSSL_NO_CAMELLIA
-    "CAMELLIA",
-#endif
-#ifdef OPENSSL_NO_CAST
-    "CAST",
-#endif
-#ifdef OPENSSL_NO_CHACHA
-    "CHACHA",
-#endif
-#ifdef OPENSSL_NO_CMAC
-    "CMAC",
-#endif
-#ifdef OPENSSL_NO_CMS
-    "CMS",
-#endif
-#ifdef OPENSSL_NO_COMP
-    "COMP",
-#endif
-#ifdef OPENSSL_NO_DES
-    "DES",
-#endif
-#ifdef OPENSSL_NO_DGRAM
-    "DGRAM",
-#endif
-#ifdef OPENSSL_NO_DH
-    "DH",
-#endif
-#ifdef OPENSSL_NO_DSA
-    "DSA",
-#endif
-#ifdef OPENSSL_NO_HMAC_DRBG_KDF
-    "HMAC_DRBG_KDF",
-#endif
-#ifdef OPENSSL_NO_EC
-    "EC",
-#endif
-#ifdef OPENSSL_NO_ECDH
-    "ECDH",
-#endif
-#ifdef OPENSSL_NO_ECDSA
-    "ECDSA",
-#endif
-#ifdef OPENSSL_NO_ECX
-    "ECX",
-#endif
-#ifdef OPENSSL_NO_EC2M
-    "EC2M",
-#endif
-#ifdef OPENSSL_NO_KBKDF
-    "KBKDF",
-#endif
-#ifdef OPENSSL_NO_KRB5KDF
-    "KRB5KDF",
-#endif
-#ifdef OPENSSL_NO_GOST
-    "GOST",
-#endif
-#ifdef OPENSSL_NO_IDEA
-    "IDEA",
-#endif
-#ifdef OPENSSL_NO_MD2
-    "MD2",
-#endif
-#ifdef OPENSSL_NO_MD4
-    "MD4",
-#endif
-#ifdef OPENSSL_NO_MD5
-    "MD5",
-#endif
-#ifdef OPENSSL_NO_MDC2
-    "MDC2",
-#endif
-#ifdef OPENSSL_NO_ML_DSA
-    "ML_DSA",
-#endif
-#ifdef OPENSSL_NO_ML_KEM
-    "ML_KEM",
-#endif
-#ifdef OPENSSL_NO_OCB
-    "OCB",
-#endif
-#ifdef OPENSSL_NO_PSK
-    "PSK",
-#endif
-#ifdef OPENSSL_NO_RC2
-    "RC2",
-#endif
-#ifdef OPENSSL_NO_RC4
-    "RC4",
-#endif
-#ifdef OPENSSL_NO_RC5
-    "RC5",
-#endif
-#ifdef OPENSSL_NO_RMD160
-    "RMD160",
-#endif
-#ifdef OPENSSL_NO_SCRYPT
-    "SCRYPT",
-#endif
-#ifdef OPENSSL_NO_SEED
-    "SEED",
-#endif
-#ifdef OPENSSL_NO_SLH_DSA
-    "SLH_DSA",
-#endif
-#ifdef OPENSSL_NO_SIPHASH
-    "SIPHASH",
-#endif
-#ifdef OPENSSL_NO_SIV
-    "SIV",
-#endif
-#ifdef OPENSSL_NO_SNMPKDF
-    "SNMPKDF",
-#endif
-#ifdef OPENSSL_NO_SM2
-    "SM2",
-#endif
-#ifdef OPENSSL_NO_SM3
-    "SM3",
-#endif
-#ifdef OPENSSL_NO_SM4
-    "SM4",
-#endif
-#ifdef OPENSSL_NO_SSHKDF
-    "SSHKDF",
-#endif
-#ifdef OPENSSL_NO_SSKDF
-    "SSHKDF",
-#endif
-
-#ifdef OPENSSL_NO_POLY1305
-    "POLY1305",
-#endif
-#ifdef OPENSSL_NO_PVKKDF
-    "PVKKDF",
-#endif
-#ifdef OPENSSL_NO_WHIRLPOOL
-    "WHIRLPOOL",
-#endif
-#ifdef OPENSSL_NO_X942KDF
-    "X942KDF",
-#endif
-#ifdef OPENSSL_NO_X963KDF
-    "X963KDF",
-#endif
-#ifdef OPENSSL_NO_ZLIB
-    "ZLIB",
-#endif
-#ifdef OPENSSL_NO_BROTLI
-    "BROTLI",
-#endif
-#ifdef OPENSSL_NO_ZSTD
-    "ZSTD",
-#endif
-};
-
-#define PRINT_DISABLED(type)                                           \
-    do {                                                               \
-        if (OSSL_NELEM(disabled_##type) > 1) {                         \
-            BIO_puts(bio_out, "Disabled " #type ":\n");                \
-            for (size_t i = 1; i < OSSL_NELEM(disabled_##type); i++) { \
-                BIO_printf(bio_out, "\t- %s\n", disabled_##type[i]);   \
-            }                                                          \
-        } else {                                                       \
-            BIO_puts(bio_out, "No " #type " disabled.\n");             \
-        }                                                              \
-    } while (0)
-;
-
 /* Checks to see if algorithms are fetchable */
 #define IS_FETCHABLE(type, TYPE)                      \
     static int is_##type##_fetchable(const TYPE *alg) \
@@ -383,6 +55,21 @@ static const char *const disabled_algorithms[] = {
         TYPE##_free(impl);                            \
         return 1;                                     \
     }
+
+#define OPENSSL_HAS_DISABLED(name) (OSSL_NELEM(openssl_disabled_##name) > 1)
+
+#define OPENSSL_PRINT_DISABLED(bio, name, str)                                 \
+    do {                                                                       \
+        if (OPENSSL_HAS_DISABLED(name)) {                                      \
+            BIO_puts((bio), "Disabled " str "(s):\n");                         \
+            for (size_t i = 1; i < OSSL_NELEM(openssl_disabled_##name); i++) { \
+                BIO_printf((bio), "\t- %s\n", openssl_disabled_##name[i]);     \
+            }                                                                  \
+        } else {                                                               \
+            BIO_puts((bio), "No disabled " str "s.\n");                        \
+        }                                                                      \
+    } while (0);
+
 IS_FETCHABLE(cipher, EVP_CIPHER)
 IS_FETCHABLE(digest, EVP_MD)
 IS_FETCHABLE(mac, EVP_MAC)
@@ -1725,9 +1412,9 @@ static void list_provider_info(void)

 static void list_disabled(void)
 {
-    PRINT_DISABLED(features);
-    PRINT_DISABLED(algorithms);
-    PRINT_DISABLED(protocols);
+    OPENSSL_PRINT_DISABLED(bio_out, protocols, "protocol");
+    OPENSSL_PRINT_DISABLED(bio_out, algorithms, "algorithm");
+    OPENSSL_PRINT_DISABLED(bio_out, features, "feature");
 }

 /* Unified enum for help and list commands. */
diff --git a/configdata.pm.in b/configdata.pm.in
index fea6004d6c..a21fe686d9 100644
--- a/configdata.pm.in
+++ b/configdata.pm.in
@@ -151,55 +151,75 @@ _____
             or die "Trying to rename $buildfile.new to $buildfile: $!";
         print 'Created ',$buildfile,"\n";

+        my $create_configuration = sub {
+          my ($configuration_file, $configuration_file_in) = @_;
+
+          open CONFIGURATION, ">${configuration_file}.new"
+              or die "Trying to create ${configuration_file_in}.new: $!";
+          $tmpl = OpenSSL::Template->new(TYPE => 'FILE',
+                                        SOURCE => $configuration_file_in);
+          $tmpl->fill_in(FILENAME => $_,
+                        OUTPUT => \*CONFIGURATION,
+                        HASH => \%gendata,
+                        PREPEND => $prepend,
+                        # To ensure that global variables and functions
+                        # defined in one template stick around for the
+                        # next, making them combinable
+                        PACKAGE => 'OpenSSL::safe')
+              or die $OpenSSL::Template::ERROR;
+          close CONFIGURATION;
+        };
+
+        my $update_configuration = sub {
+          # When using stat() on Windows, we can get it to perform better by
+          # avoid some data.  This doesn't affect the mtime field, so we're not
+          # losing anything...
+          ${^WIN32_SLOPPY_STAT} = 1;
+
+          my ($configuration_file, $configuration_file_in) = @_;
+          my $update_configuration_file = 0;
+
+          if (-f $configuration_file) {
+              my $configuration_file_mtime = (stat($configuration_file))[9];
+              my $configuration_file_in_mtime = (stat($configuration_file_in))[9];
+
+              # If configuration.h.in was updated after the last configuration.h,
+              # or if configuration.h.new differs configuration.h, we update
+              # configuration.h
+              if ($configuration_file_mtime < $configuration_file_in_mtime
+                  || compare_text("${configuration_file}.new", $configuration_file) != 0) {
+                  $update_configuration_file = 1;
+              } else {
+                  # If nothing has changed, let's just drop the new one and
+                  # pretend like nothing happened
+                  unlink "${configuration_file}.new"
+              }
+          } else {
+              $update_configuration_file = 1;
+          }
+
+          if ($update_configuration_file) {
+              rename("${configuration_file}.new", $configuration_file)
+                  or die "Trying to rename ${configuration_file}.new to $configuration_file: $!";
+              print 'Created ',$configuration_file,"\n";
+          }
+        };
+
         my $configuration_h =
             catfile('include', 'openssl', 'configuration.h');
         my $configuration_h_in =
             catfile($config{sourcedir}, 'include', 'openssl', 'configuration.h.in');
-        open CONFIGURATION_H, ">${configuration_h}.new"
-            or die "Trying to create ${configuration_h}.new: $!";
-        $tmpl = OpenSSL::Template->new(TYPE => 'FILE',
-                                       SOURCE => $configuration_h_in);
-        $tmpl->fill_in(FILENAME => $_,
-                       OUTPUT => \*CONFIGURATION_H,
-                       HASH => \%gendata,
-                       PREPEND => $prepend,
-                       # To ensure that global variables and functions
-                       # defined in one template stick around for the
-                       # next, making them combinable
-                       PACKAGE => 'OpenSSL::safe')
-            or die $OpenSSL::Template::ERROR;
-        close CONFIGURATION_H;
-
-        # When using stat() on Windows, we can get it to perform better by
-        # avoid some data.  This doesn't affect the mtime field, so we're not
-        # losing anything...
-        ${^WIN32_SLOPPY_STAT} = 1;
-
-        my $update_configuration_h = 0;
-        if (-f $configuration_h) {
-            my $configuration_h_mtime = (stat($configuration_h))[9];
-            my $configuration_h_in_mtime = (stat($configuration_h_in))[9];
-
-            # If configuration.h.in was updated after the last configuration.h,
-            # or if configuration.h.new differs configuration.h, we update
-            # configuration.h
-            if ($configuration_h_mtime < $configuration_h_in_mtime
-                || compare_text("${configuration_h}.new", $configuration_h) != 0) {
-                $update_configuration_h = 1;
-            } else {
-                # If nothing has changed, let's just drop the new one and
-                # pretend like nothing happened
-                unlink "${configuration_h}.new"
-            }
-        } else {
-            $update_configuration_h = 1;
-        }

-        if ($update_configuration_h) {
-            rename("${configuration_h}.new", $configuration_h)
-                or die "Trying to rename ${configuration_h}.new to $configuration_h: $!";
-            print 'Created ',$configuration_h,"\n";
-        }
+        my $apps_configuration_h =
+            catfile('apps', 'include', 'configuration.h');
+        my $apps_configuration_h_in =
+            catfile($config{sourcedir}, 'apps', 'include', 'configuration.h.in');
+
+        $create_configuration->($configuration_h, $configuration_h_in);
+        $update_configuration->($configuration_h, $configuration_h_in);
+
+        $create_configuration->($apps_configuration_h, $apps_configuration_h_in);
+        $update_configuration->($apps_configuration_h, $apps_configuration_h_in);

         exit(0);
     }
@@ -485,3 +505,4 @@ Verbose output.
 =cut

 EOF
+#define PRINT_ENABLED(type)