[openssl-commits] [openssl] master update

Richard Levitte levitte at openssl.org
Wed Mar 2 18:15:47 UTC 2016


The branch master has been updated
       via  2ad9ef06a6aadeeb78a05ce18ace0ea5f300401b (commit)
       via  2952b9b8115bdd852fb226e918f8b6d6a4a0bea2 (commit)
       via  9c62a279fecc4ccb95ea55e1ba36470f3eab8775 (commit)
       via  8864f0de7b491b4c7f724f58200d843700c82e98 (commit)
       via  940a09bad42c673b0dccd725ae590025c9749735 (commit)
       via  98fdbce09144a8addc6682a0ffd8ac92b2ce70b1 (commit)
       via  d2b2221a04053578911d34a45026543e4c39ce0c (commit)
       via  b0b92a5bb5b40e9ee7ca751b4d9218ed8726bda0 (commit)
      from  ed49f43a0390217e1c2df0054fb7352523be9a58 (commit)


- Log -----------------------------------------------------------------
commit 2ad9ef06a6aadeeb78a05ce18ace0ea5f300401b
Author: Richard Levitte <levitte at openssl.org>
Date:   Sat Feb 27 17:14:44 2016 +0100

    Document the changes in config settings
    
    Reviewed-by: Andy Polyakov <appro at openssl.org>

commit 2952b9b8115bdd852fb226e918f8b6d6a4a0bea2
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Mar 2 10:57:05 2016 +0100

    Don't copy from %target to %config so much, see %config as a complement
    
    We copied $target{cflags}, $target{defines} and a few more to %config,
    just to add to the entries.  Avoid doing so, and let the build templates
    deal with combining the two.
    
    There are a few cases where we still fiddle with %target, but that's
    acceptable.
    
    Reviewed-by: Andy Polyakov <appro at openssl.org>

commit 9c62a279fecc4ccb95ea55e1ba36470f3eab8775
Author: Richard Levitte <levitte at openssl.org>
Date:   Sat Feb 27 16:51:34 2016 +0100

    Configure - Get rid of the special thread_cflag, replace with thread_scheme
    
    The thread_cflag setting filled a double role, as kinda sorta an
    indicator of thread scheme, and as cflags.  Some configs also added
    lflags and ex_libs for multithreading regardless of if threading would
    be enabled or not.
    
    Instead of this, add threading cflags among in the cflag setting,
    threading lflags in the lflag setting and so on if and only if threads
    are enabled (which they are by default).
    
    Also, for configs where there are no special cflags for threading (the
    VMS configs are of that kind), this makes it possible to still clearly
    mention what thread scheme is used.
    
    The exact value of thread scheme is currently ignored except when it's
    "(unknown)", and thereby only serves as a flag to tell if we know how
    to build for multi-threading in a particular config.  Yet, the
    currently used values are "(unknown)", "pthreads", "uithreads" (a.k.a
    solaris threads) and "winthreads".
    
    Reviewed-by: Andy Polyakov <appro at openssl.org>

commit 8864f0de7b491b4c7f724f58200d843700c82e98
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Mar 2 19:13:26 2016 +0100

    Configure - get rid of the special debug_ and release_ settings
    
    Instead, make the build type ("debug" or "release") available through
    $config{build_type} and let the configs themselves figure out what the
    usual settings (such as "cflags", "lflags" and so on) should be
    accordingly.
    
    The benefit with this is that we can now have debug and release
    variants of any setting, not just those Configure supports, and may
    also involve other factors (the MSVC flags /MD[d] and /MT[d] involve
    both build type and whether threading is enabled or not)
    
    Reviewed-by: Andy Polyakov <appro at openssl.org>

commit 940a09bad42c673b0dccd725ae590025c9749735
Author: Richard Levitte <levitte at openssl.org>
Date:   Sat Feb 27 11:42:13 2016 +0100

    Minimize copied config settings
    
    $target{lflags} and $target{plib_flag} were copied to %config for no
    good reason.
    
    Reviewed-by: Andy Polyakov <appro at openssl.org>

commit 98fdbce09144a8addc6682a0ffd8ac92b2ce70b1
Author: Richard Levitte <levitte at openssl.org>
Date:   Sat Feb 27 11:37:33 2016 +0100

    Configure - move the addition of the zlib / libz lib to configs
    
    Configure had the Unix centric addition of -lz when linking with zlib
    is enabled, which doesn't work on other platforms.  Therefore, we move
    it to the BASE_unix config template and add corresponding ones in the
    other BASE_* config templates.  The Windows one is probably incomplete,
    but that doesn't matter for the moment, as mk1mf does it's own thing
    anyway.
    
    This required making the %withargs table global, so perl snippets in
    the configs can use it.
    
    Reviewed-by: Andy Polyakov <appro at openssl.org>

commit d2b2221a04053578911d34a45026543e4c39ce0c
Author: Richard Levitte <levitte at openssl.org>
Date:   Sat Feb 27 11:25:33 2016 +0100

    Configure - Rename BASE to DEFAULTS and add a few inheritable BASEs
    
    These BASE templates are intended to hold values that are common for
    all configuration variants for whole families of configurations.
    
    So far, three "families" are identified: Unix, Windows and VMS, mostly
    characterised by the build system they currently use.
    
    Reviewed-by: Andy Polyakov <appro at openssl.org>

commit b0b92a5bb5b40e9ee7ca751b4d9218ed8726bda0
Author: Richard Levitte <levitte at openssl.org>
Date:   Sat Feb 27 11:08:21 2016 +0100

    Configure - Allow CODErefs and ARRAYrefs in configuration setting arrays
    
    This provides for more powerful lazy evaluation and buildup of the
    setting contents.  For example, something like this becomes possible:
    
        defines => [ sub { $config{thisorthat} ? "FOO" : () } ]
    
    Any undefined result of such functions (such as 'undef' or the empty
    list) will be ignored.
    
    Reviewed-by: Andy Polyakov <appro at openssl.org>

-----------------------------------------------------------------------

Summary of changes:
 Configurations/00-base-templates.conf   |  84 +++-
 Configurations/10-main.conf             | 690 ++++++++++++++++++--------------
 Configurations/90-team.conf             |  65 +--
 Configurations/99-personal-ben.conf     |  34 +-
 Configurations/99-personal-bodo.conf    |   7 +-
 Configurations/99-personal-geoff.conf   |  14 +-
 Configurations/99-personal-levitte.conf |  16 +-
 Configurations/99-personal-rse.conf     |   2 +-
 Configurations/99-personal-steve.conf   |  21 +-
 Configurations/README                   |  37 +-
 Configurations/descrip.mms.tmpl         |   6 +-
 Configurations/unix-Makefile.tmpl       |  10 +-
 Configure                               | 247 ++++++------
 Makefile.in                             |   6 +-
 14 files changed, 707 insertions(+), 532 deletions(-)

diff --git a/Configurations/00-base-templates.conf b/Configurations/00-base-templates.conf
index 4251a6c..cf50785 100644
--- a/Configurations/00-base-templates.conf
+++ b/Configurations/00-base-templates.conf
@@ -1,15 +1,11 @@
 # -*- Mode: perl -*-
 %targets=(
-    BASE => {
+    DEFAULTS => {
 	template	=> 1,
 
 	cflags		=> "",
 	defines		=> [],
-	debug_cflags	=> "",
-	debug_defines	=> [],
-	release_cflags	=> "",
-	release_defines => [],
-	thread_cflags	=> "",
+	thread_scheme	=> "(unknown)", # Assume we don't know
 	thread_defines	=> [],
 
 	apps_aux_src	=> "",
@@ -39,8 +35,82 @@
 	shared_ldflag	=> "",
 	shared_rcflag	=> "",
 	shared_extension	=> "",
+
 	build_scheme	=> "unixmake",
-	build_file      => "Makefile",
+	build_file	=> "Makefile",
+    },
+
+    BASE_common => {
+	template	=> 1,
+	defines		=>
+	    [ sub {
+		unless ($disabled{zlib}) {
+		    if (defined($disabled{"zlib-dynamic"})) {
+			return "ZLIB";
+		    } else {
+			return "ZLIB_SHARED";
+		    }
+		}
+		return (); }
+	    ],
+    },
+
+    BASE_unix => {
+        inherit_from    => [ "BASE_common" ],
+        template        => 1,
+
+        ex_libs         =>
+            sub {
+                unless ($disabled{zlib}) {
+                    if (defined($disabled{"zlib-dynamic"})) {
+                        if (defined($withargs{zlib_lib})) {
+                            return "-L".$withargs{zlib_lib}." -lz";
+                        } else {
+                            return "-lz";
+                        }
+                    }
+                }
+                return (); },
+
+        build_scheme    => "unixmake",
+        build_file      => "Makefile",
+    },
+
+    BASE_Windows => {
+        inherit_from    => [ "BASE_common" ],
+        template        => 1,
+
+        ex_libs         =>
+            sub {
+                unless ($disabled{zlib}) {
+                    if (defined($disabled{"zlib-dynamic"})) {
+                        return "zlib1.lib";
+                    }
+                }
+                return (); },
+
+        build_scheme    => [ "mk1mf" ],
+    },
+
+    BASE_VMS => {
+        inherit_from    => [ "BASE_common" ],
+        template        => 1,
+
+        ex_libs          =>
+            sub {
+                unless ($disabled{zlib}) {
+                    if (defined($disabled{"zlib-dynamic"})) {
+                        if (defined($withargs{zlib_lib})) {
+                            return $withargs{zlib_lib}.'GNV$LIBZSHR.EXE/SHARED'
+                        } else {
+                            return 'GNV$LIBZSHR/SHARE';
+                        }
+                    }
+                }
+                return (); },
+
+        build_file       => "descrip.mms",
+        build_scheme     => [ "unified", "VMS" ],
     },
 
     uplink_common => {
diff --git a/Configurations/10-main.conf b/Configurations/10-main.conf
index ecfbc9a..6fade98 100644
--- a/Configurations/10-main.conf
+++ b/Configurations/10-main.conf
@@ -1,30 +1,46 @@
 ## -*- mode: perl; -*-
 ## Standard openssl configuration targets.
 
+sub picker {
+    my %opts = @_;
+    return sub { add($opts{default} || (),
+                     $opts{$config{build_type}} || ())->(); }
+}
+
+sub threads {
+    my @flags = @_;
+    return sub { add($disabled{threads} ? () : @flags)->(); }
+}
+
+sub combine {
+    my @stuff = @_;
+    return sub { add(@stuff)->(); }
+}
+
 %targets = (
 
 #### Basic configs that should work on any 32-bit box
     "gcc" => {
         cc               => "gcc",
-        cflags           => "",
-        debug_cflags     => "-O0 -g",
-        release_cflags   => "-O3",
-        thread_cflag     => "(unknown)",
+        cflags           => picker(debug   => "-O0 -g",
+                                   release => "-O3"),
+        thread_scheme    => "(unknown)",
         bn_ops           => "BN_LLONG",
     },
     "cc" => {
         cc               => "cc",
         cflags           => "-O",
-        thread_cflag     => "(unknown)",
+        thread_scheme    => "(unknown)",
     },
 
 #### VOS Configurations
     "vos-gcc" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "gcc",
-        cflags           => "-Wall -DOPENSSL_SYS_VOS -D_POSIX_C_SOURCE=200112L -D_BSD -D_VOS_EXTENDED_NAMES -DB_ENDIAN",
-        debug_cflags     => "-O0 -g -DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG",
-        release_cflags   => "-O3",
-        thread_cflag     => "(unknown)",
+        cflags           => picker(default => "-Wall -DOPENSSL_SYS_VOS -D_POSIX_C_SOURCE=200112L -D_BSD -D_VOS_EXTENDED_NAMES -DB_ENDIAN",
+                                   debug   => "-O0 -g -DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG",
+                                   release => "-O3"),
+        thread_scheme    => "(unknown)",
         sys_id           => "VOS",
         lflags           => "-Wl,-map",
         bn_ops           => "BN_LLONG",
@@ -33,10 +49,12 @@
 
 #### Solaris configurations
     "solaris-common" => {
+        inherit_from     => [ "BASE_unix" ],
         template         => 1,
         cflags           => "-DFILIO_H",
-        ex_libs          => "-lresolv -lsocket -lnsl -ldl",
+        ex_libs          => add("-lresolv -lsocket -lnsl -ldl"),
         dso_scheme       => "dlfcn",
+        thread_scheme    => "pthreads",
         shared_target    => "solaris-shared",
         shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
     },
@@ -49,10 +67,10 @@
         # with "Illegal mnemonic" error message.
         inherit_from     => [ "solaris-common", asm("x86_elf_asm") ],
         cc               => "gcc",
-        cflags           => add_before("-Wall -DL_ENDIAN -DOPENSSL_NO_INLINE_ASM"),
-        debug_cflags     => "-O0 -g",
-        release_cflags   => "-O3 -fomit-frame-pointer",
-        thread_cflag     => "-pthread",
+        cflags           => add_before(picker(default => "-Wall -DL_ENDIAN -DOPENSSL_NO_INLINE_ASM",
+                                              debug   => "-O0 -g",
+                                              release => "-O3 -fomit-frame-pointer"),
+                                       threads("-pthread")),
         bn_ops           => "BN_LLONG",
         shared_cflag     => "-fPIC",
         shared_ldflag    => "-shared",
@@ -68,10 +86,10 @@
         #					<appro at fy.chalmers.se>
         inherit_from     => [ "solaris-common", asm("x86_64_asm") ],
         cc               => "gcc",
-        cflags           => add_before("-m64 -Wall -DL_ENDIAN"),
-        debug_cflags     => "-O0 -g",
-        release_cflags   => "-O3",
-        thread_cflag     => "-pthread",
+        cflags           => add_before(picker(default => "-m64 -Wall -DL_ENDIAN",
+                                              debug   => "-O0 -g",
+                                              release => "-O3"),
+                                       threads("-pthread")),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
         perlasm_scheme   => "elf",
         shared_cflag     => "-fPIC",
@@ -83,12 +101,12 @@
     "solaris-x86-cc" => {
         inherit_from     => [ "solaris-common" ],
         cc               => "cc",
-        cflags           => add_before("-xarch=generic -xstrconst -Xa -DL_ENDIAN"),
-        debug_cflags     => "-g",
-        release_cflags   => "-xO5 -xregs=frameptr -xdepend -xbuiltin",
-        thread_cflag     => "-D_REENTRANT",
-        lflags           => add("-mt"),
-        ex_libs          => add("-lpthread"),
+        cflags           => add_before(picker(default => "-xarch=generic -xstrconst -Xa -DL_ENDIAN",
+                                              debug   => "-g",
+                                              release => "-xO5 -xregs=frameptr -xdepend -xbuiltin"),
+                                       threads("-D_REENTRANT")),
+        lflags           => add(threads("-mt")),
+        ex_libs          => add(threads("-lpthread")),
         bn_ops           => "BN_LLONG RC4_CHAR",
         shared_cflag     => "-KPIC",
         shared_ldflag    => "-G -dy -z text",
@@ -96,12 +114,13 @@
     "solaris64-x86_64-cc" => {
         inherit_from     => [ "solaris-common", asm("x86_64_asm") ],
         cc               => "cc",
-        cflags           => add_before("-xarch=generic64 -xstrconst -Xa -DL_ENDIAN"),
-        debug_cflags     => "-g",
-        release_cflags   => "-xO5 -xdepend -xbuiltin",
-        thread_cflag     => "-D_REENTRANT",
-        lflags           => add("-mt"),
-        ex_libs          => add("-lpthread"),
+        cflags           => add_before(picker(default => "-xarch=generic64 -xstrconst -Xa -DL_ENDIAN",
+                                              debug   => "-g",
+                                              release => "-xO5 -xdepend -xbuiltin"),
+                                       threads("-D_REENTRANT")),
+        thread_scheme    => "pthreads",
+        lflags           => add(threads("-mt")),
+        ex_libs          => add(threads("-lpthread")),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
         perlasm_scheme   => "elf",
         shared_cflag     => "-KPIC",
@@ -113,10 +132,10 @@
     "solaris-sparcv7-gcc" => {
         inherit_from     => [ "solaris-common" ],
         cc               => "gcc",
-        cflags           => add_before("-Wall -DB_ENDIAN -DBN_DIV2W"),
-        debug_cflags     => "-O0 -g",
-        release_cflags   => "-O3",
-        thread_cflag     => "-pthread",
+        cflags           => add_before(picker(default => "-Wall -DB_ENDIAN -DBN_DIV2W",
+                                              debug   => "-O0 -g",
+                                              release => "-O3"),
+                                       threads("-pthread")),
         bn_ops           => "BN_LLONG RC4_CHAR",
         shared_cflag     => "-fPIC",
         shared_ldflag    => "-shared",
@@ -129,8 +148,8 @@
         # -m32 should be safe to add as long as driver recognizes
         # -mcpu=ultrasparc
         inherit_from     => [ "solaris-sparcv7-gcc", asm("sparcv9_asm") ],
-        cflags           => add_before("-m32 -mcpu=ultrasparc"),
-        debug_cflags     => "-DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG -DBN_CTX_DEBUG -DPEDANTIC -O -g -pedantic -ansi -Wshadow -Wno-long-long -D__EXTENSIONS__",
+        cflags           => add_before(picker(default => "-m32 -mcpu=ultrasparc",
+                                              debug   => "-DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG -DBN_CTX_DEBUG -DPEDANTIC -O -g -pedantic -ansi -Wshadow -Wno-long-long -D__EXTENSIONS__")),
     },
     "solaris64-sparcv9-gcc" => {
         inherit_from     => [ "solaris-sparcv9-gcc" ],
@@ -147,12 +166,12 @@
     "solaris-sparcv7-cc" => {
         inherit_from     => [ "solaris-common" ],
         cc               => "cc",
-        cflags           => add_before("-xstrconst -Xa -DB_ENDIAN -DBN_DIV2W"),
-        debug_cflags     => "-g -DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG -DBN_CTX_DEBUG",
-        release_cflags   => "-xO5 -xdepend",
-        thread_cflag     => "-D_REENTRANT",
-        lflags           => add("-mt"),
-        ex_libs          => add("-lpthread"),
+        cflags           => add_before(picker(default => "-xstrconst -Xa -DB_ENDIAN -DBN_DIV2W",
+                                              debug   => "-g -DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG -DBN_CTX_DEBUG",
+                                              release => "-xO5 -xdepend"),
+                                       threads("-D_REENTRANT")),
+        lflags           => add(threads("-mt")),
+        ex_libs          => add(threads("-lpthread")),
         bn_ops           => "BN_LLONG RC4_CHAR",
         shared_cflag     => "-KPIC",
         shared_ldflag    => "-G -dy -z text",
@@ -177,26 +196,26 @@
 #### IRIX 5.x configs
 # -mips2 flag is added by ./config when appropriate.
     "irix-gcc" => {
-        inherit_from     => [ asm("mips32_asm") ],
+        inherit_from     => [ "BASE_unix", asm("mips32_asm") ],
         cc               => "gcc",
-        cflags           => "-DB_ENDIAN",
-        debug_cflags     => "-g -O0",
-        release_cflags   => "-O3",
-        thread_cflag     => "(unknown)",
+        cflags           => picker(default => "-DB_ENDIAN",
+                                   debug   => "-g -O0",
+                                   release => "-O3"),
         bn_ops           => "BN_LLONG RC4_CHAR",
+        thread_scheme    => "(unknown)",
         perlasm_scheme   => "o32",
         dso_scheme       => "dlfcn",
         shared_target    => "irix-shared",
         shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
     },
     "irix-cc" => {
-        inherit_from     => [ asm("mips32_asm") ],
+        inherit_from     => [ "BASE_unix", asm("mips32_asm") ],
         cc               => "cc",
-        cflags           => "-use_readonly_const -DB_ENDIAN",
-        debug_cflags     => "-g -O0",
-        release_cflags   => "-O2",
-        thread_cflag     => "(unknown)",
+        cflags           => picker(default => "-use_readonly_const -DB_ENDIAN",
+                                   debug   => "-g -O0",
+                                   release => "-O2"),
         bn_ops           => "BN_LLONG RC4_CHAR",
+        thread_scheme    => "(unknown)",
         perlasm_scheme   => "o32",
         dso_scheme       => "dlfcn",
         shared_target    => "irix-shared",
@@ -206,13 +225,14 @@
 # Only N32 and N64 ABIs are supported. If you need O32 ABI build, invoke
 # './Configure irix-cc -o32' manually.
     "irix-mips3-gcc" => {
-        inherit_from     => [ asm("mips64_asm") ],
+        inherit_from     => [ "BASE_unix", asm("mips64_asm") ],
         cc               => "gcc",
-        cflags           => "-mabi=n32 -DB_ENDIAN -DBN_DIV3W",
-        debug_cflags     => "-g -O0",
-        release_cflags   => "-O3",
-        thread_cflag     => "-D_SGI_MP_SOURCE -pthread",
+        cflags           => combine(picker(default => "-mabi=n32 -DB_ENDIAN -DBN_DIV3W",
+                                           debug   => "-g -O0",
+                                           release => "-O3"),
+                                    threads("-D_SGI_MP_SOURCE -pthread")),
         bn_ops           => "RC4_CHAR SIXTY_FOUR_BIT",
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "n32",
         dso_scheme       => "dlfcn",
         shared_target    => "irix-shared",
@@ -221,14 +241,15 @@
         multilib         => "32",
     },
     "irix-mips3-cc" => {
-        inherit_from     => [ asm("mips64_asm") ],
+        inherit_from     => [ "BASE_unix", asm("mips64_asm") ],
         cc               => "cc",
-        cflags           => "-n32 -mips3 -use_readonly_const -G0 -rdata_shared -DB_ENDIAN -DBN_DIV3W",
-        debug_cflags     => "-g -O0",
-        release_cflags   => "-O2",
-        thread_cflag     => "-D_SGI_MP_SOURCE",
-        ex_libs          => "-lpthread",
+        cflags           => combine(picker(default => "-n32 -mips3 -use_readonly_const -G0 -rdata_shared -DB_ENDIAN -DBN_DIV3W",
+                                           debug   => "-g -O0",
+                                           release => "-O2"),
+                                    threads("-D_SGI_MP_SOURCE")),
+        ex_libs          => add(threads("-lpthread")),
         bn_ops           => "RC4_CHAR SIXTY_FOUR_BIT",
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "n32",
         dso_scheme       => "dlfcn",
         shared_target    => "irix-shared",
@@ -238,13 +259,14 @@
     },
     # N64 ABI builds.
     "irix64-mips4-gcc" => {
-        inherit_from     => [ asm("mips64_asm") ],
+        inherit_from     => [ "BASE_unix", asm("mips64_asm") ],
         cc               => "gcc",
-        cflags           => "-mabi=64 -mips4 -DB_ENDIAN -DBN_DIV3W",
-        debug_cflags     => "-g -O0",
-        release_cflags   => "-O3",
-        thread_cflag     => "-D_SGI_MP_SOURCE",
+        cflags           => combine(picker(default => "-mabi=64 -mips4 -DB_ENDIAN -DBN_DIV3W",
+                                           debug   => "-g -O0",
+                                           release => "-O3"),
+                                    threads("-D_SGI_MP_SOURCE")),
         bn_ops           => "RC4_CHAR SIXTY_FOUR_BIT_LONG",
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "64",
         dso_scheme       => "dlfcn",
         shared_target    => "irix-shared",
@@ -253,14 +275,15 @@
         multilib         => "64",
     },
     "irix64-mips4-cc" => {
-        inherit_from     => [ asm("mips64_asm") ],
+        inherit_from     => [ "BASE_unix", asm("mips64_asm") ],
         cc               => "cc",
-        cflags           => "-64 -mips4 -use_readonly_const -G0 -rdata_shared -DB_ENDIAN -DBN_DIV3W",
-        debug_cflags     => "-g -O0",
-        release_cflags   => "-O2",
-        thread_cflag     => "-D_SGI_MP_SOURCE",
-        ex_libs          => "-lpthread",
+        cflags           => combine(picker(default => "-64 -mips4 -use_readonly_const -G0 -rdata_shared -DB_ENDIAN -DBN_DIV3W",
+                                           debug   => "-g -O0",
+                                           release => "-O2"),
+                                    threads("-D_SGI_MP_SOURCE")),
+        ex_libs          => add(threads("-lpthread")),
         bn_ops           => "RC4_CHAR SIXTY_FOUR_BIT_LONG",
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "64",
         dso_scheme       => "dlfcn",
         shared_target    => "irix-shared",
@@ -298,13 +321,15 @@
 #   provided. 
 #					<appro at fy.chalmers.se>
     "hpux-parisc-gcc" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "gcc",
-        cflags           => "-DB_ENDIAN -DBN_DIV2W",
-        debug_cflags     => "-O0 -g",
-        release_cflags   => "-O3",
-        thread_cflag     => "-pthread",
-        ex_libs          => "-Wl,+s -ldld",
+        cflags           => combine(picker(default => "-DB_ENDIAN -DBN_DIV2W",
+                                           debug   => "-O0 -g",
+                                           release => "-O3"),
+                                    threads("-pthread")),
+        ex_libs          => add("-Wl,+s -ldld"),
         bn_ops           => "BN_LLONG",
+        thread_scheme    => "pthreads",
         dso_scheme       => "dl",
         shared_target    => "hpux-shared",
         shared_cflag     => "-fPIC",
@@ -316,14 +341,15 @@
         multilib         => "/pa1.1",
     },
     "hpux64-parisc2-gcc" => {
-        inherit_from     => [ asm("parisc20_64_asm") ],
+        inherit_from     => [ "BASE_unix", asm("parisc20_64_asm") ],
         cc               => "gcc",
-        cflags           => "-DB_ENDIAN",
-        debug_cflags     => "-O0 -g",
-        release_cflags   => "-O3",
-        thread_cflag     => "-D_REENTRANT",
-        ex_libs          => "-ldl",
+        cflags           => combine(picker(default => "-DB_ENDIAN",
+                                           debug   => "-O0 -g",
+                                           release => "-O3"),
+                                    threads("-D_REENTRANT")),
+        ex_libs          => add("-ldl"),
         bn_ops           => "SIXTY_FOUR_BIT_LONG RC4_CHAR",
+        thread_scheme    => "pthreads",
         dso_scheme       => "dlfcn",
         shared_target    => "hpux-shared",
         shared_cflag     => "-fpic",
@@ -337,13 +363,15 @@
     # Chris Ruemmler <ruemmler at cup.hp.com>
     # Kevin Steves <ks at hp.se>
     "hpux-parisc-cc" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "cc",
-        cflags           => "+Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DBN_DIV2W -DMD32_XARRAY",
-        debug_cflags      => "+O0 +d -g",
-        release_cflags   => "+O3",
-        thread_cflag     => "-D_REENTRANT",
-        ex_libs          => "-Wl,+s -ldld -lpthread",
+        cflags           => combine(picker(default => "+Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DBN_DIV2W -DMD32_XARRAY",
+                                           debug   => "+O0 +d -g",
+                                           release => "+O3"),
+                                    threads("-D_REENTRANT")),
+        ex_libs          => add("-Wl,+s -ldld",threads("-lpthread")),
         bn_ops           => "RC4_CHAR",
+        thread_scheme    => "pthreads",
         dso_scheme       => "dl",
         shared_target    => "hpux-shared",
         shared_cflag     => "+Z",
@@ -356,14 +384,15 @@
         multilib         => "/pa1.1",
     },
     "hpux64-parisc2-cc" => {
-        inherit_from     => [ asm("parisc20_64_asm") ],
+        inherit_from     => [ "BASE_unix", asm("parisc20_64_asm") ],
         cc               => "cc",
-        cflags           => "+DD64 +Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DMD32_XARRAY",
-        debug_cflags      => "+O0 +d -g",
-        release_cflags   => "+O3",
-        thread_cflag     => "-D_REENTRANT",
-        ex_libs          => "-ldl -lpthread",
+        cflags           => combine(picker(default => "+DD64 +Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DMD32_XARRAY",
+                                           debug   => "+O0 +d -g",
+                                           release => "+O3"),
+                                    threads("-D_REENTRANT")),
+        ex_libs          => add("-ldl",threads("-lpthread")),
         bn_ops           => "SIXTY_FOUR_BIT_LONG RC4_CHAR",
+        thread_scheme    => "pthreads",
         dso_scheme       => "dlfcn",
         shared_target    => "hpux-shared",
         shared_cflag     => "+Z",
@@ -374,14 +403,15 @@
 
     # HP/UX IA-64 targets
     "hpux-ia64-cc" => {
-        inherit_from     => [ asm("ia64_asm") ],
+        inherit_from     => [ "BASE_unix", asm("ia64_asm") ],
         cc               => "cc",
-        cflags           => "-Ae +DD32 +Olit=all -z -DB_ENDIAN",
-        debug_cflags     => "+O0 +d -g",
-        release_cflags   => "+O2",
-        thread_cflag     => "-D_REENTRANT",
-        ex_libs          => "-ldl -lpthread",
+        cflags           => combine(picker(default => "-Ae +DD32 +Olit=all -z -DB_ENDIAN",
+                                           debug   => "+O0 +d -g",
+                                           release => "+O2"),
+                                    threads("-D_REENTRANT")),
+        ex_libs          => add("-ldl",threads("-lpthread")),
         bn_ops           => "SIXTY_FOUR_BIT",
+        thread_scheme    => "pthreads",
         dso_scheme       => "dlfcn",
         shared_target    => "hpux-shared",
         shared_cflag     => "+Z",
@@ -392,14 +422,15 @@
     # Frank Geurts <frank.geurts at nl.abnamro.com> has patiently assisted
     # with debugging of the following config.
     "hpux64-ia64-cc" => {
-        inherit_from     => [ asm("ia64_asm") ],
+        inherit_from     => [ "BASE_unix", asm("ia64_asm") ],
         cc               => "cc",
-        cflags           => "-Ae +DD64 +Olit=all -z -DB_ENDIAN",
-        debug_cflags     => "+O0 +d -g",
-        release_cflags   => "+O3",
-        thread_cflag     => "-D_REENTRANT",
-        ex_libs          => "-ldl -lpthread",
+        cflags           => combine(picker(default => "-Ae +DD64 +Olit=all -z -DB_ENDIAN",
+                                           debug   => "+O0 +d -g",
+                                           release => "+O3"),
+                                    threads("-D_REENTRANT")),
+        ex_libs          => add("-ldl", threads("-lpthread")),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
+        thread_scheme    => "pthreads",
         dso_scheme       => "dlfcn",
         shared_target    => "hpux-shared",
         shared_cflag     => "+Z",
@@ -409,14 +440,15 @@
     },
     # GCC builds...
     "hpux-ia64-gcc" => {
-        inherit_from     => [ asm("ia64_asm") ],
+        inherit_from     => [ "BASE_unix", asm("ia64_asm") ],
         cc               => "gcc",
-        cflags           => "-DB_ENDIAN",
-        debug_cflags     => "-O0 -g",
-        release_cflags   => "-O3",
-        thread_cflag     => "-pthread",
-        ex_libs          => "-ldl",
+        cflags           => combine(picker(default => "-DB_ENDIAN",
+                                           debug   => "-O0 -g",
+                                           release => "-O3"),
+                                    threads("-pthread")),
+        ex_libs          => add("-ldl"),
         bn_ops           => "SIXTY_FOUR_BIT",
+        thread_scheme    => "pthreads",
         dso_scheme       => "dlfcn",
         shared_target    => "hpux-shared",
         shared_cflag     => "-fpic",
@@ -425,14 +457,15 @@
         multilib         => "/hpux32",
     },
     "hpux64-ia64-gcc" => {
-        inherit_from     => [ asm("ia64_asm") ],
+        inherit_from     => [ "BASE_unix", asm("ia64_asm") ],
         cc               => "gcc",
-        cflags           => "-mlp64 -DB_ENDIAN",
-        debug_cflags     => "-O0 -g",
-        release_cflags   => "-O3",
-        thread_cflag     => "-pthread",
-        ex_libs          => "-ldl",
+        cflags           => picker(default => "-mlp64 -DB_ENDIAN",
+                                   debug   => "-O0 -g",
+                                   release => "-O3",
+                                   threads("-pthread")),
+        ex_libs          => add("-ldl"),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
+        thread_scheme    => "pthreads",
         dso_scheme       => "dlfcn",
         shared_target    => "hpux-shared",
         shared_cflag     => "-fpic",
@@ -443,41 +476,43 @@
 
 #### HP MPE/iX http://jazz.external.hp.com/src/openssl/
     "MPE/iX-gcc" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "gcc",
         cflags           => "-D_ENDIAN -DBN_DIV2W -O3 -D_POSIX_SOURCE -D_SOCKET_SOURCE -I/SYSLOG/PUB",
-        thread_cflag     => "(unknown)",
         sys_id           => "MPE",
-        ex_libs          => "-L/SYSLOG/PUB -lsyslog -lsocket -lcurses",
+        ex_libs          => add("-L/SYSLOG/PUB -lsyslog -lsocket -lcurses"),
+        thread_scheme    => "(unknown)",
         bn_ops           => "BN_LLONG",
     },
 
 #### DEC Alpha OSF/1/Tru64 targets.
     "osf1-alpha-gcc" => {
-        inherit_from     => [ asm("alpha_asm") ],
+        inherit_from     => [ "BASE_unix", asm("alpha_asm") ],
         cc               => "gcc",
         cflags           => "-O3",
-        thread_cflag     => "(unknown)",
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
+        thread_scheme    => "(unknown)",
         dso_scheme       => "dlfcn",
         shared_target    => "alpha-osf1-shared",
         shared_extension => ".so",
     },
     "osf1-alpha-cc" => {
-        inherit_from     => [ asm("alpha_asm") ],
+        inherit_from     => [ "BASE_unix", asm("alpha_asm") ],
         cc               => "cc",
         cflags           => "-std1 -tune host -O4 -readonly_strings",
-        thread_cflag     => "(unknown)",
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
+        thread_scheme    => "(unknown)",
         dso_scheme       => "dlfcn",
         shared_target    => "alpha-osf1-shared",
         shared_extension => ".so",
     },
     "tru64-alpha-cc" => {
-        inherit_from     => [ asm("alpha_asm") ],
+        inherit_from     => [ "BASE_unix", asm("alpha_asm") ],
         cc               => "cc",
-        cflags           => "-std1 -tune host -fast -readonly_strings",
-        thread_cflag     => "-pthread",
+        cflags           => combine("-std1 -tune host -fast -readonly_strings",
+                                    threads("-pthread")),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
+        thread_scheme    => "pthreads",
         dso_scheme       => "dlfcn",
         shared_target    => "alpha-osf1-shared",
         shared_ldflag    => "-msym",
@@ -490,13 +525,15 @@
 # *-generic* is endian-neutral target, but ./config is free to
 # throw in -D[BL]_ENDIAN, whichever appropriate...
     "linux-generic32" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "gcc",
-        cflags           => "-Wall",
-        debug_cflags     => "-O0 -g -DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG",
-        release_cflags   => "-O3",
-        thread_cflag     => "-pthread",
-        ex_libs          => "-ldl",
+        cflags           => combine(picker(default => "-Wall",
+                                           debug   => "-O0 -g -DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG",
+                                           release => "-O3"),
+                                    threads("-pthread")),
+        ex_libs          => add("-ldl"),
         bn_ops           => "BN_LLONG RC4_CHAR",
+        thread_scheme    => "pthreads",
         dso_scheme       => "dlfcn",
         shared_target    => "linux-shared",
         shared_cflag     => "-fPIC",
@@ -513,14 +550,14 @@
     },
     "linux-ppc64" => {
         inherit_from     => [ "linux-generic64", asm("ppc64_asm") ],
-        cflags           => "-m64 -Wall -DB_ENDIAN",
+        cflags           => add("-m64 -DB_ENDIAN"),
         perlasm_scheme   => "linux64",
         shared_ldflag    => "-m64",
         multilib         => "64",
     },
     "linux-ppc64le" => {
         inherit_from     => [ "linux-generic64", asm("ppc64_asm") ],
-        cflags           => "-m64 -Wall -DL_ENDIAN",
+        cflags           => add("-m64 -DL_ENDIAN"),
         perlasm_scheme   => "linux64le",
         shared_ldflag    => "-m64",
     },
@@ -566,7 +603,7 @@
     },
     "linux-arm64ilp32" => {  # https://wiki.linaro.org/Platform/arm64-ilp32
         inherit_from     => [ "linux-generic32", asm("aarch64_asm") ],
-        cflags           => "-mabi=ilp32 -Wall",
+        cflags           => add("-mabi=ilp32"),
         bn_ops           => "SIXTY_FOUR_BIT RC4_CHAR",
         perlasm_scheme   => "linux64",
         shared_ldflag    => "-mabi=ilp32",
@@ -576,7 +613,7 @@
         # Configure script adds minimally required -march for assembly
         # support, if no -march was specified at command line.
         inherit_from     => [ "linux-generic32", asm("mips32_asm") ],
-        cflags           => "-mabi=32 -Wall -DBN_DIV3W",
+        cflags           => add("-mabi=32 -DBN_DIV3W"),
         perlasm_scheme   => "o32",
         shared_ldflag    => "-mabi=32",
     },
@@ -584,7 +621,7 @@
     # specifications, MIPS32 and MIPS64, rather than to kernel bitness.
     "linux-mips64" => {
         inherit_from     => [ "linux-generic32", asm("mips64_asm") ],
-        cflags           => "-mabi=n32 -Wall -DBN_DIV3W",
+        cflags           => add("-mabi=n32 -DBN_DIV3W"),
         bn_ops           => "SIXTY_FOUR_BIT RC4_CHAR",
         perlasm_scheme   => "n32",
         shared_ldflag    => "-mabi=n32",
@@ -592,7 +629,7 @@
     },
     "linux64-mips64" => {
         inherit_from     => [ "linux-generic64", asm("mips64_asm") ],
-        cflags           => "-mabi=64 -O3 -Wall -DBN_DIV3W",
+        cflags           => add("-mabi=64 -DBN_DIV3W"),
         perlasm_scheme   => "64",
         shared_ldflag    => "-mabi=64",
         multilib         => "64",
@@ -601,27 +638,25 @@
     #### IA-32 targets...
     "linux-elf" => {
         inherit_from     => [ "linux-generic32", asm("x86_elf_asm") ],
-        cc               => "gcc",
-        cflags           => "-DL_ENDIAN -Wall",
-        debug_cflags     => "-O0 -g -DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG -DBN_CTX_DEBUG",
-        release_cflags   => "-O3 -fomit-frame-pointer",
-        debug_ex_libs    => "-lefence",
+        cflags           => add(picker(default => "-DL_ENDIAN",
+                                       release => "-fomit-frame-pointer")),
+        ex_libs          => add(picker(debug => "-lefence")),
         bn_ops           => "BN_LLONG",
     },
     "linux-aout" => {
-        inherit_from     => [ asm("x86_asm") ],
+        inherit_from     => [ "BASE_unix", asm("x86_asm") ],
         cc               => "gcc",
-        cflags           => "-DL_ENDIAN -Wall",
-        debug_cflags     => "-O0 -g",
-        release_cflags   => "-O3 -fomit-frame-pointer",
-        thread_cflag     => "(unknown)",
+        cflags           => add(picker(default => "-DL_ENDIAN -Wall",
+                                       debug   => "-O0 -g",
+                                       release => "-O3 -fomit-frame-pointer")),
         bn_ops           => "BN_LLONG",
+        thread_scheme    => "(unknown)",
         perlasm_scheme   => "a.out",
     },
 
     "linux-x86_64" => {
         inherit_from     => [ "linux-generic64", asm("x86_64_asm") ],
-        cflags           => "-m64 -DL_ENDIAN -Wall",
+        cflags           => add("-m64 -DL_ENDIAN"),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
         perlasm_scheme   => "elf",
         shared_ldflag    => "-m64",
@@ -630,11 +665,11 @@
     "linux-x86_64-clang" => {
         inherit_from     => [ "linux-x86_64" ],
         cc               => "clang",
-        cflags           => "-m64 -DL_ENDIAN -Wall -Wextra -Qunused-arguments",
+        cflags           => add("-Wextra -Qunused-arguments"),
     },
     "linux-x32" => {
         inherit_from     => [ "linux-generic32", asm("x86_64_asm") ],
-        cflags           => "-mx32 -DL_ENDIAN -Wall",
+        cflags           => add("-mx32 -DL_ENDIAN"),
         bn_ops           => "SIXTY_FOUR_BIT",
         perlasm_scheme   => "elf",
         shared_ldflag    => "-mx32",
@@ -648,7 +683,7 @@
 
     "linux64-s390x" => {
         inherit_from     => [ "linux-generic64", asm("s390x_asm") ],
-        cflags           => "-m64 -Wall -DB_ENDIAN",
+        cflags           => add("-m64 -DB_ENDIAN"),
         perlasm_scheme   => "64",
         shared_ldflag    => "-m64",
         multilib         => "64",
@@ -671,7 +706,7 @@
         # sysdeps/s390/dl-procinfo.c affecting ldconfig and ld.so.1...
         #
         inherit_from     => [ "linux-generic32", asm("s390x_asm") ],
-        cflags           => "-m31 -Wall -Wa,-mzarch -DB_ENDIAN",
+        cflags           => add("-m31 -Wa,-mzarch -DB_ENDIAN"),
         bn_obj           => sub { my $r=join(" ", at _); $r=~s/bn\-s390x/bn_asm/; $r; },
         perlasm_scheme   => "31",
         shared_ldflag    => "-m31",
@@ -683,19 +718,19 @@
     # patiently assisted with debugging of following two configs.
     "linux-sparcv8" => {
         inherit_from     => [ "linux-generic32", asm("sparcv8_asm") ],
-        cflags           => "-mcpu=v8 -Wall -DB_ENDIAN -DBN_DIV2W",
+        cflags           => add("-mcpu=v8 -DB_ENDIAN -DBN_DIV2W"),
     },
     "linux-sparcv9" => {
         # it's a real mess with -mcpu=ultrasparc option under Linux,
         # but -Wa,-Av8plus should do the trick no matter what.
         inherit_from     => [ "linux-generic32", asm("sparcv9_asm") ],
-        cflags           => "-m32 -mcpu=ultrasparc -Wall -Wa,-Av8plus -DB_ENDIAN -DBN_DIV2W",
+        cflags           => add("-m32 -mcpu=ultrasparc -Wa,-Av8plus -DB_ENDIAN -DBN_DIV2W"),
         shared_ldflag    => "-m32",
     },
     "linux64-sparcv9" => {
         # GCC 3.1 is a requirement
         inherit_from     => [ "linux-generic64", asm("sparcv9_asm") ],
-        cflags           => "-m64 -mcpu=ultrasparc -Wall -DB_ENDIAN",
+        cflags           => add("-m64 -mcpu=ultrasparc -DB_ENDIAN"),
         bn_ops           => "BN_LLONG RC4_CHAR",
         shared_ldflag    => "-m64",
         multilib         => "64",
@@ -703,14 +738,15 @@
 
     "linux-alpha-gcc" => {
         inherit_from     => [ "linux-generic64", asm("alpha_asm") ],
-        cflags           => "-DL_ENDIAN",
+        cflags           => add("-DL_ENDIAN"),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
     },
     "linux-c64xplus" => {
+        inherit_from     => [ "BASE_unix" ],
         # TI_CGT_C6000_7.3.x is a requirement
         cc               => "cl6x",
-        cflags           => "--linux -ea=.s -eo=.o -mv6400+ -o2 -ox -ms -pden -DOPENSSL_SMALL_FOOTPRINT",
-        thread_cflag     => "-D_REENTRANT",
+        cflags           => combine("--linux -ea=.s -eo=.o -mv6400+ -o2 -ox -ms -pden -DOPENSSL_SMALL_FOOTPRINT",
+                                    threads("-D_REENTRANT")),
         bn_ops           => "BN_LLONG",
         cpuid_asm_src    => "c64xpluscpuid.s",
         bn_asm_src       => "asm/bn-c64xplus.asm c64xplus-gf2m.s",
@@ -720,6 +756,7 @@
         modes_asm_src    => "ghash-c64xplus.s",
         chacha_asm_src   => "chacha-c64xplus.s",
         poly1305_asm_src => "poly1305-c64xplus.s",
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "void",
         dso_scheme       => "dlfcn",
         shared_target    => "linux-shared",
@@ -755,15 +792,15 @@
         # systems are perfectly capable of executing binaries targeting
         # Froyo. Keep in mind that in the nutshell Android builds are
         # about JNI, i.e. shared libraries, not applications.
-        cflags           => "-mandroid -fPIC --sysroot=\$(CROSS_SYSROOT) -Wa,--noexecstack -Wall",
-        debug_cflags     => "-O0 -g",
+        cflags           => picker(default => "-mandroid -fPIC --sysroot=\$(CROSS_SYSROOT) -Wa,--noexecstack -Wall",
+                                   debug   => "-O0 -g",
+                                   release => "-O3"),
         lflags           => "-pie",
-        ex_libs          => "-ldl",
         shared_cflag     => "",
     },
     "android-x86" => {
         inherit_from     => [ "android", asm("x86_asm") ],
-        release_cflags   => "-O3 -fomit-frame-pointer",
+        cflags           => add(picker(release => "-fomit-frame-pointer")),
         bn_ops           => "BN_LLONG",
         perlasm_scheme   => "android",
     },
@@ -798,10 +835,10 @@
 
     "android64" => {
         inherit_from     => [ "linux-generic64" ],
-        cflags           => "-mandroid -fPIC --sysroot=\$(CROSS_SYSROOT) -Wa,--noexecstack -Wall",
-        debug_cflags     => "-O0 -g",
+        cflags           => picker(default => "-mandroid -fPIC --sysroot=\$(CROSS_SYSROOT) -Wa,--noexecstack -Wall",
+                                   debug   => "-O0 -g",
+                                   release => "-O3"),
         lflags           => "-pie",
-        ex_libs          => "-ldl",
         shared_cflag     => "",
     },
     "android64-aarch64" => {
@@ -811,19 +848,21 @@
 
 #### *BSD
     "BSD-generic32" => {
-        # As for thread_cflag. Idea is to maintain "collective" set of
+        # As for thread cflag. Idea is to maintain "collective" set of
         # flags, which would cover all BSD flavors. -pthread applies
         # to them all, but is treated differently. OpenBSD expands is
         # as -D_POSIX_THREAD -lc_r, which is sufficient. FreeBSD 4.x
         # expands it as -lc_r, which has to be accompanied by explicit
         # -D_THREAD_SAFE and sometimes -D_REENTRANT. FreeBSD 5.x
         # expands it as -lc_r, which seems to be sufficient?
+        inherit_from     => [ "BASE_unix" ],
         cc               => "cc",
-        cflags           => "-Wall",
-        debug_cflags     => "-O0 -g",
-        release_cflags   => "-O3",
-        thread_cflag     => "-pthread -D_THREAD_SAFE -D_REENTRANT",
+        cflags           => combine(picker(default => "-Wall",
+                                           debug   => "-O0 -g",
+                                           release => "-O3"),
+                                    threads("-pthread -D_THREAD_SAFE -D_REENTRANT")),
         bn_ops           => "BN_LLONG",
+        thread_scheme    => "pthreads",
         dso_scheme       => "dlfcn",
         shared_target    => "bsd-gcc-shared",
         shared_cflag     => "-fPIC",
@@ -836,8 +875,8 @@
 
     "BSD-x86" => {
         inherit_from     => [ "BSD-generic32", asm("x86_asm") ],
-        cflags           => "-DL_ENDIAN -Wall",
-        release_cflags   => "-O3 -fomit-frame-pointer",
+        cflags           => add(picker(default => "-DL_ENDIAN",
+                                       release => "-fomit-frame-pointer")),
         bn_ops           => "BN_LLONG",
         shared_target    => "bsd-shared",
         perlasm_scheme   => "a.out",
@@ -849,37 +888,37 @@
 
     "BSD-sparcv8" => {
         inherit_from     => [ "BSD-generic32", asm("sparcv8_asm") ],
-        cflags           => "-mcpu=v8 -Wall -DB_ENDIAN",
+        cflags           => add("-mcpu=v8 -DB_ENDIAN"),
     },
     "BSD-sparc64" => {
         # -DMD32_REG_T=int doesn't actually belong in sparc64 target, it
         # simply *happens* to work around a compiler bug in gcc 3.3.3,
         # triggered by RIPEMD160 code.
         inherit_from     => [ "BSD-generic64", asm("sparcv9_asm") ],
-        cflags           => "-DB_ENDIAN -DMD32_REG_T=int -Wall",
+        cflags           => add("-DB_ENDIAN -DMD32_REG_T=int"),
         bn_ops           => "BN_LLONG",
     },
 
     "BSD-ia64" => {
         inherit_from     => [ "BSD-generic64", asm("ia64_asm") ],
-        cflags           => "-DL_ENDIAN -Wall",
+        cflags           => add_before("-DL_ENDIAN"),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
     },
 
     "BSD-x86_64" => {
         inherit_from     => [ "BSD-generic64", asm("x86_64_asm") ],
-        cflags           => "-DL_ENDIAN -Wall",
+        cflags           => add_before("-DL_ENDIAN"),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
         perlasm_scheme   => "elf",
     },
 
     "bsdi-elf-gcc" => {
-        inherit_from     => [ asm("x86_elf_asm") ],
+        inherit_from     => [ "BASE_unix", asm("x86_elf_asm") ],
         cc               => "gcc",
         cflags           => "-DPERL5 -DL_ENDIAN -fomit-frame-pointer -O3 -Wall",
-        thread_cflag     => "(unknown)",
-        ex_libs          => "-ldl",
+        ex_libs          => add("-ldl"),
         bn_ops           => "BN_LLONG",
+        thread_scheme    => "(unknown)",
         dso_scheme       => "dlfcn",
         shared_target    => "bsd-gcc-shared",
         shared_cflag     => "-fPIC",
@@ -887,39 +926,43 @@
     },
 
     "nextstep" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "cc",
         cflags           => "-O -Wall",
         unistd           => "<libc.h>",
-        thread_cflag     => "(unknown)",
         bn_ops           => "BN_LLONG",
+        thread_scheme    => "(unknown)",
     },
     "nextstep3.3" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "cc",
         cflags           => "-O3 -Wall",
         unistd           => "<libc.h>",
-        thread_cflag     => "(unknown)",
         bn_ops           => "BN_LLONG",
+        thread_scheme    => "(unknown)",
     },
 
 # QNX
     "qnx4" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "cc",
         cflags           => "-DL_ENDIAN -DTERMIO",
-        thread_cflag     => "(unknown)",
+        thread_scheme    => "(unknown)",
     },
     "QNX6" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "gcc",
-        ex_libs          => "-lsocket",
+        ex_libs          => add("-lsocket"),
         dso_scheme       => "dlfcn",
         shared_target    => "bsd-gcc-shared",
         shared_cflag     => "-fPIC",
         shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
     },
     "QNX6-i386" => {
-        inherit_from     => [ asm("x86_elf_asm") ],
+        inherit_from     => [ "BASE_unix", asm("x86_elf_asm") ],
         cc               => "gcc",
         cflags           => "-DL_ENDIAN -O2 -Wall",
-        ex_libs          => "-lsocket",
+        ex_libs          => add("-lsocket"),
         dso_scheme       => "dlfcn",
         shared_target    => "bsd-gcc-shared",
         shared_cflag     => "-fPIC",
@@ -939,23 +982,28 @@
 #
 # UnixWare 2.0x fails destest with -O.
     "unixware-2.0" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "cc",
-        cflags           => "-DFILIO_H -DNO_STRINGS_H",
-        thread_cflag     => "-Kthread",
-        ex_libs          => "-lsocket -lnsl -lresolv -lx",
+        cflags           => combine("-DFILIO_H -DNO_STRINGS_H",
+                                    threads("-Kthread")),
+        ex_libs          => add("-lsocket -lnsl -lresolv -lx"),
+        thread_scheme    => "uithreads",
     },
     "unixware-2.1" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "cc",
-        cflags           => "-O -DFILIO_H",
-        thread_cflag     => "-Kthread",
-        ex_libs          => "-lsocket -lnsl -lresolv -lx",
+        cflags           => combine("-O -DFILIO_H",
+                                    threads("-Kthread")),
+        ex_libs          => add("-lsocket -lnsl -lresolv -lx"),
+        thread_scheme    => "uithreads",
     },
     "unixware-7" => {
-        inherit_from     => [ asm("x86_elf_asm") ],
+        inherit_from     => [ "BASE_unix", asm("x86_elf_asm") ],
         cc               => "cc",
-        cflags           => "-O -DFILIO_H -Kalloca",
-        thread_cflag     => "-Kthread",
-        ex_libs          => "-lsocket -lnsl",
+        cflags           => combine("-O -DFILIO_H -Kalloca",
+                                    threads("-Kthread")),
+        ex_libs          => add("-lsocket -lnsl"),
+        thread_scheme    => "uithreads",
         bn_ops           => "BN_LLONG",
         perlasm_scheme   => "elf-1",
         dso_scheme       => "dlfcn",
@@ -964,12 +1012,13 @@
         shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
     },
     "unixware-7-gcc" => {
-        inherit_from     => [ asm("x86_elf_asm") ],
+        inherit_from     => [ "BASE_unix", asm("x86_elf_asm") ],
         cc               => "gcc",
-        cflags           => "-DL_ENDIAN -DFILIO_H -O3 -fomit-frame-pointer -Wall",
-        thread_cflag     => "-D_REENTRANT",
-        ex_libs          => "-lsocket -lnsl",
+        cflags           => combine("-DL_ENDIAN -DFILIO_H -O3 -fomit-frame-pointer -Wall",
+                                    threads("-D_REENTRANT")),
+        ex_libs          => add("-lsocket -lnsl"),
         bn_ops           => "BN_LLONG",
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "elf-1",
         dso_scheme       => "dlfcn",
         shared_target    => "gnu-shared",
@@ -978,11 +1027,11 @@
     },
 # SCO 5 - Ben Laurie <ben at algroup.co.uk> says the -O breaks the SCO cc.
     "sco5-cc" => {
-        inherit_from     => [ asm("x86_elf_asm") ],
+        inherit_from     => [ "BASE_unix", asm("x86_elf_asm") ],
         cc               => "cc",
         cflags           => "-belf",
-        thread_cflag     => "(unknown)",
-        ex_libs          => "-lsocket -lnsl",
+        ex_libs          => add("-lsocket -lnsl"),
+        thread_scheme    => "(unknown)",
         perlasm_scheme   => "elf-1",
         dso_scheme       => "dlfcn",
         shared_target    => "svr3-shared",
@@ -990,12 +1039,12 @@
         shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
     },
     "sco5-gcc" => {
-        inherit_from     => [ asm("x86_elf_asm") ],
+        inherit_from     => [ "BASE_unix", asm("x86_elf_asm") ],
         cc               => "gcc",
         cflags           => "-O3 -fomit-frame-pointer",
-        thread_cflag     => "(unknown)",
-        ex_libs          => "-lsocket -lnsl",
+        ex_libs          => add("-lsocket -lnsl"),
         bn_ops           => "BN_LLONG",
+        thread_scheme    => "(unknown)",
         perlasm_scheme   => "elf-1",
         dso_scheme       => "dlfcn",
         shared_target    => "svr3-shared",
@@ -1005,14 +1054,15 @@
 
 #### IBM's AIX.
     "aix-gcc" => {
-        inherit_from     => [ asm("ppc32_asm") ],
+        inherit_from     => [ "BASE_unix", asm("ppc32_asm") ],
         cc               => "gcc",
-        cflags           => "-DB_ENDIAN",
-        debug_cflags     => "-O0 -g",
-        release_cflags   => "-O",
-        thread_cflag     => "-pthread",
+        cflags           => combine(picker(default => "-DB_ENDIAN",
+                                           debug   => "-O0 -g",
+                                           release => "-O"),
+                                    threads("-pthread")),
         sys_id           => "AIX",
         bn_ops           => "BN_LLONG RC4_CHAR",
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "aix32",
         dso_scheme       => "dlfcn",
         shared_target    => "aix-shared",
@@ -1021,14 +1071,15 @@
         arflags          => "-X32",
     },
     "aix64-gcc" => {
-        inherit_from     => [ asm("ppc64_asm") ],
+        inherit_from     => [ "BASE_unix", asm("ppc64_asm") ],
         cc               => "gcc",
-        cflags           => "-maix64 -DB_ENDIAN",
-        debug_cflags     => "-O0 -g",
-        release_cflags   => "-O",
-        thread_cflag     => "-pthread",
+        cflags           => combine(picker(default => "-maix64 -DB_ENDIAN",
+                                           debug   => "-O0 -g",
+                                           release => "-O"),
+                                    threads("-pthread")),
         sys_id           => "AIX",
         bn_ops           => "SIXTY_FOUR_BIT_LONG RC4_CHAR",
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "aix64",
         dso_scheme       => "dlfcn",
         shared_target    => "aix-shared",
@@ -1040,14 +1091,15 @@
     # $OBJECT_MODE at build time. $OBJECT_MODE is respected at
     # ./config stage!
     "aix-cc" => {
-        inherit_from     => [ asm("ppc32_asm") ],
+        inherit_from     => [ "BASE_unix", asm("ppc32_asm") ],
         cc               => "cc",
-        cflags           => "-q32 -DB_ENDIAN -qmaxmem=16384 -qro -qroconst",
-        debug_cflags     => "",
-        release_cflags   => "-O",
-        thread_cflag     => "-qthreaded -D_THREAD_SAFE",
+        cflags           => combine(picker(default => "-q32 -DB_ENDIAN -qmaxmem=16384 -qro -qroconst",
+                                           debug   => "-O0 -g",
+                                           release => "-O"),
+                                    threads("-qthreaded -D_THREAD_SAFE")),
         sys_id           => "AIX",
         bn_ops           => "BN_LLONG RC4_CHAR",
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "aix32",
         dso_scheme       => "dlfcn",
         shared_target    => "aix-shared",
@@ -1056,14 +1108,15 @@
         arflags          => "-X 32",
     },
     "aix64-cc" => {
-        inherit_from     => [ asm("ppc64_asm") ],
+        inherit_from     => [ "BASE_unix", asm("ppc64_asm") ],
         cc               => "cc",
-        cflags           => "-q64 -DB_ENDIAN -qmaxmem=16384 -qro -qroconst",
-        debug_cflags     => "",
-        release_cflags   => "-O",
-        thread_cflag     => "-qthreaded -D_THREAD_SAFE",
+        cflags           => combine(picker(default => "-q64 -DB_ENDIAN -qmaxmem=16384 -qro -qroconst",
+                                           debug   => "-O0 -g",
+                                           release => "-O"),
+                                    threads("-qthreaded -D_THREAD_SAFE")),
         sys_id           => "AIX",
         bn_ops           => "SIXTY_FOUR_BIT_LONG RC4_CHAR",
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "aix64",
         dso_scheme       => "dlfcn",
         shared_target    => "aix-shared",
@@ -1074,11 +1127,12 @@
 
 # SIEMENS BS2000/OSD: an EBCDIC-based mainframe
     "BS2000-OSD" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "c89",
         cflags           => "-O -XLLML -XLLMK -XL -DB_ENDIAN -DCHARSET_EBCDIC",
-        thread_cflag     => "(unknown)",
-        ex_libs          => "-lsocket -lnsl",
+        ex_libs          => add("-lsocket -lnsl"),
         bn_ops           => "THIRTY_TWO_BIT RC4_CHAR",
+        thread_scheme    => "(unknown)",
     },
 
 # OS/390 Unix an EBCDIC-based Unix system on IBM mainframe
@@ -1086,10 +1140,11 @@
 # IBM compiler does not like the -L switch after any object modules.
 #
     "OS390-Unix" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "c89.sh",
         cflags           => "-O -DB_ENDIAN -DCHARSET_EBCDIC -DNO_SYS_PARAM_H  -D_ALL_SOURCE",
-        thread_cflag     => "(unknown)",
         bn_ops           => "THIRTY_TWO_BIT RC4_CHAR",
+        thread_scheme    => "(unknown)",
     },
 
 #### Visual C targets
@@ -1101,12 +1156,12 @@
 # legitimate and false cases, but as we compile on multiple platforms,
 # we rely on other compilers to catch legitimate cases.
     "VC-common" => {
+        inherit_from     => [ "BASE_Windows" ],
         template         => 1,
         cc               => "cl",
         cflags           => "-W3 -wd4090 -Gs0 -GF -Gy -nologo -DOPENSSL_SYS_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -D_CRT_SECURE_NO_DEPRECATE",
         shared_target    => "win-shared", # meaningless except it gives Configure a hint
         dso_scheme       => "win32",
-	build_scheme     => "mk1mf",
     },
     "VC-WIN64I" => {
         inherit_from     => [ "VC-common", asm("ia64_asm") ],
@@ -1116,7 +1171,7 @@
         bn_obj           => sub { my $r=join(" ", at _); $r=~s/bn\-//; $r; },
         rc4_obj          => "",
         perlasm_scheme   => "ias",
-	build_scheme     => [ "mk1mf", "VC-W64" ],
+        build_scheme     => add("VC-W64", { separator => undef }),
     },
     "VC-WIN64A" => {
         inherit_from     => [ "VC-common", asm("x86_64_asm") ],
@@ -1125,7 +1180,7 @@
         bn_ops           => "SIXTY_FOUR_BIT EXPORT_VAR_AS_FN",
         bn_obj           => sub { my $r=join(" ", at _); $r=~s/x86_64\-gcc/bn_asm/; $r; },
         perlasm_scheme   => "auto",
-	build_scheme     => [ "mk1mf", "VC-W64" ],
+        build_scheme     => add("VC-W64", { separator => undef }),
     },
     "VC-WIN32" => {
         # x86 Win32 target defaults to ANSI API, if you want UNICODE,
@@ -1134,37 +1189,40 @@
         sys_id           => "WIN32",
         bn_ops           => "BN_LLONG EXPORT_VAR_AS_FN",
         perlasm_scheme   => "win32n",
-	build_scheme     => [ "mk1mf", "VC-W32" ],
+        build_scheme     => add("VC-W32", { separator => undef }),
     },
     "VC-CE" => {
+        inherit_from     => [ "BASE_Windows" ],
         cc               => "cl",
         sys_id           => "WINCE",
         bn_ops           => "BN_LLONG EXPORT_VAR_AS_FN",
         dso_scheme       => "win32",
-	build_scheme     => [ "mk1mf", "VC-WCE" ],
+        build_scheme     => add("VC-WCE", { separator => undef }),
     },
 
 #### Borland C++ 4.5
     "BC-32" => {
+        inherit_from     => [ "BASE_Windows" ],
         cc               => "bcc32",
         sys_id           => "WIN32",
         bn_ops           => "BN_LLONG EXPORT_VAR_AS_FN",
         dso_scheme       => "win32",
-	build_scheme     => [ "mk1mf", "BC" ],
+        build_scheme     => add("BC", { separator => undef }),
     },
 
 #### MinGW
     "mingw" => {
-        inherit_from     => [ asm("x86_asm"),
+        inherit_from     => [ "BASE_unix", asm("x86_asm"),
                               sub { $disabled{shared} ? () : "x86_uplink" } ],
         cc               => "gcc",
-        cflags           => "-DL_ENDIAN -DWIN32_LEAN_AND_MEAN -DUNICODE -D_UNICODE -m32 -Wall",
-        debug_cflags     => "-g -O0",
-        release_cflags   => "-O3 -fomit-frame-pointer",
-        thread_cflag     => "-D_MT",
+        cflags           => combine(picker(default => "-DL_ENDIAN -DWIN32_LEAN_AND_MEAN -DUNICODE -D_UNICODE -m32 -Wall",
+                                           debug   => "-g -O0",
+                                           release => "-O3 -fomit-frame-pointer"),
+                                    threads("-D_MT")),
         sys_id           => "MINGW32",
-        ex_libs          => "-lws2_32 -lgdi32 -lcrypt32",
+        ex_libs          => add("-lws2_32 -lgdi32 -lcrypt32"),
         bn_ops           => "BN_LLONG EXPORT_VAR_AS_FN",
+        thread_scheme    => "winthreads",
         perlasm_scheme   => "coff",
         dso_scheme       => "win32",
         shared_target    => "mingw-shared",
@@ -1183,15 +1241,16 @@
         # consider its binaries for using with non-mingw64 run-time
         # environment. And as mingw64 is always consistent with itself,
         # Applink is never engaged and can as well be omitted.
-        inherit_from     => [ asm("x86_64_asm") ],
+        inherit_from     => [ "BASE_unix", asm("x86_64_asm") ],
         cc               => "gcc",
-        cflags           => "-DL_ENDIAN -DWIN32_LEAN_AND_MEAN -DUNICODE -D_UNICODE -m64 -Wall",
-        debug_cflags     => "-g -O0",
-        release_cflags   => "-O3",
-        thread_cflag     => "-D_MT",
+        cflags           => combine(picker(default => "-DL_ENDIAN -DWIN32_LEAN_AND_MEAN -DUNICODE -D_UNICODE -m64 -Wall",
+                                           debug   => "-g -O0",
+                                           release => "-O3"),
+                                    threads("-D_MT")),
         sys_id           => "MINGW64",
-        ex_libs          => "-lws2_32 -lgdi32 -lcrypt32",
+        ex_libs          => add("-lws2_32 -lgdi32 -lcrypt32"),
         bn_ops           => "SIXTY_FOUR_BIT EXPORT_VAR_AS_FN",
+        thread_scheme    => "winthreads",
         perlasm_scheme   => "mingw64",
         dso_scheme       => "win32",
         shared_target    => "mingw-shared",
@@ -1204,6 +1263,7 @@
 
 #### UEFI
     "UEFI" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "cc",
         cflags           => "-DL_ENDIAN -O",
         sys_id           => "UEFI",
@@ -1211,6 +1271,7 @@
 
 #### UWIN
     "UWIN" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "cc",
         cflags           => "-DTERMIOS -DL_ENDIAN -O -Wall",
         sys_id           => "UWIN",
@@ -1220,11 +1281,11 @@
 
 #### Cygwin
     "Cygwin-x86" => {
-        inherit_from     => [ asm("x86_asm") ],
+        inherit_from     => [ "BASE_unix", asm("x86_asm") ],
         cc               => "gcc",
-        cflags           => "-DTERMIOS -DL_ENDIAN -Wall",
-        debug_cflags     => "-g -O0",
-        release_cflags   => "-O3 -fomit-frame-pointer",
+        cflags           => picker(default => "-DTERMIOS -DL_ENDIAN -Wall",
+                                   debug   => "-g -O0",
+                                   release => "-O3 -fomit-frame-pointer"),
         sys_id           => "CYGWIN",
         bn_ops           => "BN_LLONG",
         perlasm_scheme   => "coff",
@@ -1235,11 +1296,11 @@
         shared_extension => ".dll",
     },
     "Cygwin-x86_64" => {
-        inherit_from     => [ asm("x86_64_asm") ],
+        inherit_from     => [ "BASE_unix", asm("x86_64_asm") ],
         cc               => "gcc",
-        cflags           => "-DTERMIOS -DL_ENDIAN -Wall",
-        debug_cflags     => "-g -O0",
-        release_cflags   => "-O3",
+        cflags           => picker(default => "-DTERMIOS -DL_ENDIAN -Wall",
+                                   debug   => "-g -O0",
+                                   release => "-O3"),
         sys_id           => "CYGWIN",
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
         perlasm_scheme   => "mingw64",
@@ -1273,38 +1334,46 @@
 # the builds can be configured to use BSD sockets instead.
 # netware-clib => legacy CLib c-runtime support
     "netware-clib" => {
+        inherit_from     => [ "BASE_Windows" ],
         cc               => "mwccnlm",
-	build_scheme     => [ "mk1mf", "netware" ],
+        build_scheme     => add("netware", { separator => undef }),
     },
     "netware-clib-bsdsock" => {
+        inherit_from     => [ "BASE_Windows" ],
         cc               => "mwccnlm",
-	build_scheme     => [ "mk1mf", "netware" ],
+        build_scheme     => add("netware", { separator => undef }),
     },
     "netware-clib-gcc" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "i586-netware-gcc",
         cflags           => "-nostdinc -I/ndk/nwsdk/include/nlm -I/ndk/ws295sdk/include -DL_ENDIAN -DNETWARE_CLIB -DOPENSSL_SYS_NETWARE -O2 -Wall",
     },
     "netware-clib-bsdsock-gcc" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "i586-netware-gcc",
         cflags           => "-nostdinc -I/ndk/nwsdk/include/nlm -DNETWARE_BSDSOCK -DNETDB_USE_INTERNET -DL_ENDIAN -DNETWARE_CLIB -DOPENSSL_SYS_NETWARE -O2 -Wall",
     },
     # netware-libc => LibC/NKS support
     "netware-libc" => {
+        inherit_from     => [ "BASE_Windows" ],
         cc               => "mwccnlm",
         bn_ops           => "BN_LLONG",
-	build_scheme     => [ "mk1mf", "netware" ],
+        build_scheme     => add("netware", { separator => undef }),
     },
     "netware-libc-bsdsock" => {
+        inherit_from     => [ "BASE_Windows" ],
         cc               => "mwccnlm",
         bn_ops           => "BN_LLONG",
-	build_scheme     => [ "mk1mf", "netware" ],
+        build_scheme     => add("netware", { separator => undef }),
     },
     "netware-libc-gcc" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "i586-netware-gcc",
         cflags           => "-nostdinc -I/ndk/libc/include -I/ndk/libc/include/winsock -DL_ENDIAN -DNETWARE_LIBC -DOPENSSL_SYS_NETWARE -DTERMIO -O2 -Wall",
         bn_ops           => "BN_LLONG",
     },
     "netware-libc-bsdsock-gcc" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "i586-netware-gcc",
         cflags           => "-nostdinc -I/ndk/libc/include -DNETWARE_BSDSOCK -DL_ENDIAN -DNETWARE_LIBC -DOPENSSL_SYS_NETWARE -DTERMIO -O2 -Wall",
         bn_ops           => "BN_LLONG",
@@ -1316,37 +1385,41 @@
         cc               => "gcc",
         cflags           => "-I/dev/env/WATT_ROOT/inc -DTERMIO -DL_ENDIAN -fomit-frame-pointer -O2 -Wall",
         sys_id           => "MSDOS",
-        ex_libs          => "-L/dev/env/WATT_ROOT/lib -lwatt",
+        ex_libs          => add("-L/dev/env/WATT_ROOT/lib -lwatt"),
         bn_ops           => "BN_LLONG",
         perlasm_scheme   => "a.out",
     },
 
 #### Ultrix from Bernhard Simon <simon at zid.tuwien.ac.at>
     "ultrix-cc" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "cc",
         cflags           => "-std1 -O -Olimit 2500 -DL_ENDIAN",
-        thread_cflag     => "(unknown)",
+        thread_scheme    => "(unknown)",
     },
     "ultrix-gcc" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "gcc",
         cflags           => "-O3 -DL_ENDIAN",
-        thread_cflag     => "(unknown)",
         bn_ops           => "BN_LLONG",
+        thread_scheme    => "(unknown)",
     },
 # K&R C is no longer supported; you need gcc on old Ultrix installations
 ##"ultrix","cc:-O2 -DNOPROTO -DNOCONST -DL_ENDIAN::(unknown):::::::",
 
 ##### MacOS X (a.k.a. Darwin) setup
     "darwin-common" => {
+        inherit_from     => [ "BASE_unix" ],
         template         => 1,
         cc               => "cc",
-        cflags           => "",
-        debug_cflags     => "-g -O0",
-        release_cflags   => "-O3",
-        thread_cflag     => "-D_REENTRANT",
+        cflags           => combine(picker(default => "",
+                                           debug   => "-g -O0",
+                                           release => "-O3"),
+                                   threads("-D_REENTRANT")),
         sys_id           => "MACOSX",
         plib_lflags      => "-Wl,-search_paths_first",
         bn_ops           => "BN_LLONG RC4_CHAR",
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "osx32",
         dso_scheme       => "dlfcn",
         shared_target    => "darwin-shared",
@@ -1356,28 +1429,28 @@
     },
     "darwin-ppc-cc" => {
         inherit_from     => [ "darwin-common", asm("ppc32_asm") ],
-        cflags           => "-arch ppc -DB_ENDIAN -Wa,-force_cpusubtype_ALL",
+        cflags           => add("-arch ppc -DB_ENDIAN -Wa,-force_cpusubtype_ALL"),
         perlasm_scheme   => "osx32",
         shared_ldflag    => "-arch ppc -dynamiclib",
     },
     "darwin64-ppc-cc" => {
         inherit_from     => [ "darwin-common", asm("ppc64_asm") ],
-        cflags           => "-arch ppc64 -DB_ENDIAN",
+        cflags           => add("-arch ppc64 -DB_ENDIAN"),
         bn_ops           => "SIXTY_FOUR_BIT_LONG RC4_CHAR",
         perlasm_scheme   => "osx64",
         shared_ldflag    => "-arch ppc64 -dynamiclib",
     },
     "darwin-i386-cc" => {
         inherit_from     => [ "darwin-common", asm("x86_asm") ],
-        cflags           => "-arch i386 -DL_ENDIAN",
-        release_cflags   => "-O3 -fomit-frame-pointer",
+        cflags           => add(picker(default => "-arch i386 -DL_ENDIAN",
+                                       release => "-fomit-frame-pointer")),
         bn_ops           => "BN_LLONG RC4_INT",
         perlasm_scheme   => "macosx",
         shared_ldflag    => "-arch i386 -dynamiclib",
     },
     "darwin64-x86_64-cc" => {
         inherit_from     => [ "darwin-common", asm("x86_64_asm") ],
-        cflags           => "-arch x86_64 -DL_ENDIAN -Wall",
+        cflags           => add("-arch x86_64 -DL_ENDIAN -Wall"),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
         perlasm_scheme   => "macosx",
         shared_ldflag    => "-arch x86_64 -dynamiclib",
@@ -1400,7 +1473,7 @@
 #
     "iphoneos-cross" => {
         inherit_from     => [ "darwin-common" ],
-        cflags           => "-isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fno-common",
+        cflags           => add("-isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fno-common"),
         sys_id           => "iOS",
     },
     "ios-cross" => {
@@ -1408,13 +1481,13 @@
         # It should be possible to go below iOS 6 and even add -arch armv6,
         # thus targeting iPhone pre-3GS, but it's assumed to be irrelevant
         # at this point.
-        cflags           => "-arch armv7 -mios-version-min=6.0.0 -isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fno-common",
+        cflags           => add("-arch armv7 -mios-version-min=6.0.0 -isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fno-common"),
         sys_id           => "iOS",
         perlasm_scheme   => "ios32",
     },
     "ios64-cross" => {
         inherit_from     => [ "darwin-common", asm("aarch64_asm") ],
-        cflags           => "-arch arm64 -mios-version-min=7.0.0 -isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fno-common",
+        cflags           => add("-arch arm64 -mios-version-min=7.0.0 -isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fno-common"),
         sys_id           => "iOS",
         bn_ops           => "SIXTY_FOUR_BIT_LONG RC4_CHAR",
         perlasm_scheme   => "ios64",
@@ -1422,12 +1495,14 @@
 
 ##### GNU Hurd
     "hurd-x86" => {
+        inherit_from     => [ "BASE_unix" ],
         inherit_from     => [ asm("x86_elf_asm") ],
         cc               => "gcc",
-        cflags           => "-DL_ENDIAN -O3 -fomit-frame-pointer -Wall",
-        thread_cflag     => "-pthread",
-        ex_libs          => "-ldl",
+        cflags           => combine("-DL_ENDIAN -O3 -fomit-frame-pointer -Wall",
+                                    threads("-pthread")),
+        ex_libs          => add("-ldl"),
         bn_ops           => "BN_LLONG",
+        thread_scheme    => "pthreads",
         dso_scheme       => "dlfcn",
         shared_target    => "linux-shared",
         shared_cflag     => "-fPIC",
@@ -1435,47 +1510,55 @@
 
 ##### OS/2 EMX
     "OS2-EMX" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "gcc",
     },
 
 ##### VxWorks for various targets
     "vxworks-ppc60x" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "ccppc",
         cflags           => "-D_REENTRANT -mrtp -mhard-float -mstrict-align -fno-implicit-fp -DPPC32_fp60x -O2 -fstrength-reduce -fno-builtin -fno-strict-aliasing -Wall -DCPU=PPC32 -DTOOL_FAMILY=gnu -DTOOL=gnu -I\$(WIND_BASE)/target/usr/h -I\$(WIND_BASE)/target/usr/h/wrn/coreip",
         sys_id           => "VXWORKS",
-        ex_libs          => "-Wl,--defsym,__wrs_rtp_base=0xe0000000 -L \$(WIND_BASE)/target/usr/lib/ppc/PPC32/common",
+        ex_libs          => add("-Wl,--defsym,__wrs_rtp_base=0xe0000000 -L \$(WIND_BASE)/target/usr/lib/ppc/PPC32/common"),
     },
     "vxworks-ppcgen" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "ccppc",
         cflags           => "-D_REENTRANT -mrtp -msoft-float -mstrict-align -O1 -fno-builtin -fno-strict-aliasing -Wall -DCPU=PPC32 -DTOOL_FAMILY=gnu -DTOOL=gnu -I\$(WIND_BASE)/target/usr/h -I\$(WIND_BASE)/target/usr/h/wrn/coreip",
         sys_id           => "VXWORKS",
-        ex_libs          => "-Wl,--defsym,__wrs_rtp_base=0xe0000000 -L \$(WIND_BASE)/target/usr/lib/ppc/PPC32/sfcommon",
+        ex_libs          => add("-Wl,--defsym,__wrs_rtp_base=0xe0000000 -L \$(WIND_BASE)/target/usr/lib/ppc/PPC32/sfcommon"),
     },
     "vxworks-ppc405" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "ccppc",
         cflags           => "-g -msoft-float -mlongcall -DCPU=PPC405 -I\$(WIND_BASE)/target/h",
         sys_id           => "VXWORKS",
         lflags           => "-r",
     },
     "vxworks-ppc750" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "ccppc",
         cflags           => "-ansi -nostdinc -DPPC750 -D_REENTRANT -fvolatile -fno-builtin -fno-for-scope -fsigned-char -Wall -msoft-float -mlongcall -DCPU=PPC604 -I\$(WIND_BASE)/target/h \$(DEBUG_FLAG)",
         sys_id           => "VXWORKS",
         lflags           => "-r",
     },
     "vxworks-ppc750-debug" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "ccppc",
         cflags           => "-ansi -nostdinc -DPPC750 -D_REENTRANT -fvolatile -fno-builtin -fno-for-scope -fsigned-char -Wall -msoft-float -mlongcall -DCPU=PPC604 -I\$(WIND_BASE)/target/h -DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG -DBN_CTX_DEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DDEBUG -g",
         sys_id           => "VXWORKS",
         lflags           => "-r",
     },
     "vxworks-ppc860" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "ccppc",
         cflags           => "-nostdinc -msoft-float -DCPU=PPC860 -DNO_STRINGS_H -I\$(WIND_BASE)/target/h",
         sys_id           => "VXWORKS",
         lflags           => "-r",
     },
     "vxworks-simlinux" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "ccpentium",
         cflags           => "-B\$(WIND_BASE)/host/\$(WIND_HOST_TYPE)/lib/gcc-lib/ -D_VSB_CONFIG_FILE=\"\$(WIND_BASE)/target/lib/h/config/vsbConfig.h\" -DL_ENDIAN -DCPU=SIMLINUX -DTOOL_FAMILY=gnu -DTOOL=gnu -fno-builtin -fno-defer-pop -DNO_STRINGS_H -I\$(WIND_BASE)/target/h -I\$(WIND_BASE)/target/h/wrn/coreip -DOPENSSL_NO_HW_PADLOCK",
         sys_id           => "VXWORKS",
@@ -1483,24 +1566,27 @@
         ranlib           => "ranlibpentium",
     },
     "vxworks-mips" => {
-        inherit_from     => [ asm("mips32_asm") ],
+        inherit_from     => [ "BASE_unix", asm("mips32_asm") ],
         cc               => "ccmips",
-        cflags           => "-mrtp -mips2 -O -G 0 -B\$(WIND_BASE)/host/\$(WIND_HOST_TYPE)/lib/gcc-lib/ -D_VSB_CONFIG_FILE=\"\$(WIND_BASE)/target/lib/h/config/vsbConfig.h\" -DCPU=MIPS32 -msoft-float -mno-branch-likely -DTOOL_FAMILY=gnu -DTOOL=gnu -fno-builtin -fno-defer-pop -DNO_STRINGS_H -I\$(WIND_BASE)/target/usr/h -I\$(WIND_BASE)/target/h/wrn/coreip",
-        thread_cflag     => "-D_REENTRANT",
+        cflags           => combine("-mrtp -mips2 -O -G 0 -B\$(WIND_BASE)/host/\$(WIND_HOST_TYPE)/lib/gcc-lib/ -D_VSB_CONFIG_FILE=\"\$(WIND_BASE)/target/lib/h/config/vsbConfig.h\" -DCPU=MIPS32 -msoft-float -mno-branch-likely -DTOOL_FAMILY=gnu -DTOOL=gnu -fno-builtin -fno-defer-pop -DNO_STRINGS_H -I\$(WIND_BASE)/target/usr/h -I\$(WIND_BASE)/target/h/wrn/coreip",
+                                    threads("-D_REENTRANT")),
         sys_id           => "VXWORKS",
-        ex_libs          => "-Wl,--defsym,__wrs_rtp_base=0xe0000000 -L \$(WIND_BASE)/target/usr/lib/mips/MIPSI32/sfcommon",
+        ex_libs          => add("-Wl,--defsym,__wrs_rtp_base=0xe0000000 -L \$(WIND_BASE)/target/usr/lib/mips/MIPSI32/sfcommon"),
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "o32",
         ranlib           => "ranlibmips",
     },
 
 #### uClinux
     "uClinux-dist" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "$ENV{'CC'}",
-        cflags           => "\$(CFLAGS)",
-        thread_cflag     => "-D_REENTRANT",
+        cflags           => combine("\$(CFLAGS)",
+                                    threads("-D_REENTRANT")),
         plib_lflags      => "\$(LDFLAGS)",
-        ex_libs          => "\$(LDLIBS)",
+        ex_libs          => add("\$(LDLIBS)"),
         bn_ops           => "BN_LLONG",
+        thread_scheme    => "pthreads",
         dso_scheme       => "$ENV{'LIBSSL_dlfcn'}",
         shared_target    => "linux-shared",
         shared_cflag     => "-fPIC",
@@ -1509,12 +1595,14 @@
         ranlib           => "$ENV{'RANLIB'}",
     },
     "uClinux-dist64" => {
+        inherit_from     => [ "BASE_unix" ],
         cc               => "$ENV{'CC'}",
-        cflags           => "\$(CFLAGS)",
-        thread_cflag     => "-D_REENTRANT",
+        cflags           => combine("\$(CFLAGS)",
+                                    threads("-D_REENTRANT")),
         plib_lflags      => "\$(LDFLAGS)",
-        ex_libs          => "\$(LDLIBS)",
+        ex_libs          => add("\$(LDLIBS)"),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
+        thread_scheme    => "pthreads",
         dso_scheme       => "$ENV{'LIBSSL_dlfcn'}",
         shared_target    => "linux-shared",
         shared_cflag     => "-fPIC",
@@ -1525,19 +1613,19 @@
 
     ##### VMS
     "vms-generic" => {
+        inherit_from     => [ "BASE_VMS" ],
         template         => 1,
         cc               => "CC/DECC",
-        cflags           => "/STANDARD=RELAXED/NOLIST/PREFIX=ALL/NAMES=(AS_IS,SHORTENED)",
-        debug_cflags     => "/NOOPTIMIZE/DEBUG",
-        release_cflags   => "/OPTIMIZE/NODEBUG",
-        lflags           => "/MAP",
-        debug_lflags     => "/DEBUG/TRACEBACK",
-        release_lflags   => "/NODEBUG/NOTRACEBACK",
+        cflags           => picker(default => "/STANDARD=RELAXED/NOLIST/PREFIX=ALL/NAMES=(AS_IS,SHORTENED)",
+                                   debug   => "/NOOPTIMIZE/DEBUG",
+                                   release => "/OPTIMIZE/NODEBUG"),
+        lflags           => picker(default => "/MAP",
+                                   debug   => "/DEBUG/TRACEBACK",
+                                   release => "/NODEBUG/NOTRACEBACK"),
         shared_target    => "vms-shared",
+        thread_scheme    => "pthreads",
 
         apps_aux_src     => "vms_decc_init.c",
-        build_file       => "descrip.mms",
-        build_scheme     => [ "unified", "VMS" ],
     },
 
     # VMS on VAX is *unsupported*
@@ -1562,10 +1650,12 @@
     "vms-alpha-P32" => {
 	inherit_from	 => [ "vms-alpha" ],
 	cflags		 => add("/POINTER_SIZE=32"),
+	ex_libs		 => sub { join(",", map { s|SHR([\./])|SHR32$1|g; $_ } @_) },
     },
     "vms-alpha-P64" => {
 	inherit_from	 => [ "vms-alpha" ],
 	cflags		 => add("/POINTER_SIZE=64"),
+	ex_libs		 => sub { join(",", map { s|SHR([\./])|SHR64$1|g; $_ } @_) },
     },
     "vms-ia64" => {
         inherit_from     => [ "vms-generic" ],
@@ -1577,10 +1667,12 @@
     "vms-ia64-P32" => {
 	inherit_from	 => [ "vms-ia64" ],
 	cflags		 => add("/POINTER_SIZE=32"),
+	ex_libs		 => sub { join(",", map { s|SHR([\./])|SHR32$1|g; $_ } @_) },
     },
     "vms-ia64-P64" => {
 	inherit_from	 => [ "vms-ia64" ],
 	cflags		 => add("/POINTER_SIZE=64"),
+	ex_libs		 => sub { join(",", map { s|SHR([\./])|SHR64$1|g; $_ } @_) },
     },
 
 );
diff --git a/Configurations/90-team.conf b/Configurations/90-team.conf
index 7667464..c7f287f 100644
--- a/Configurations/90-team.conf
+++ b/Configurations/90-team.conf
@@ -1,26 +1,37 @@
 ## -*- mode: perl; -*-
 ## Build configuration targets for openssl-team members
 
+sub threads {
+    my @flags = @_;
+    return sub { add($disabled{threads} ? () : @flags)->(); }
+}
+
+sub combine {
+    my @stuff = @_;
+    return sub { add(@stuff)->(); }
+}
+
 %targets = (
     "purify" => {
         cc               => "purify gcc",
         cflags           => "-g -Wall",
-        thread_cflag     => "(unknown)",
-        ex_libs          => "-lsocket -lnsl",
+        thread_scheme    => "(unknown)",
+        ex_libs          => add(" ","-lsocket -lnsl"),
     },
     "debug" => {
         cc               => "gcc",
         cflags           => "-DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG -DBN_CTX_DEBUG -DOPENSSL_NO_ASM -ggdb -g2 -Wformat -Wshadow -Wmissing-prototypes -Wmissing-declarations -Werror",
-        thread_cflag     => "(unknown)",
-        ex_libs          => "-lefence",
+        thread_scheme    => "(unknown)",
+        ex_libs          => add(" ","-lefence"),
     },
     "debug-erbridge" => {
         inherit_from     => [ "x86_64_asm" ],
         cc               => "gcc",
-        cflags           => "$gcc_devteam_warn -DBN_DEBUG -DCONF_DEBUG -m64 -DL_ENDIAN -DTERMIO -g",
-        thread_cflag     => "-D_REENTRANT",
-        ex_libs          => "-ldl",
+        cflags           => combine("$gcc_devteam_warn -DBN_DEBUG -DCONF_DEBUG -m64 -DL_ENDIAN -DTERMIO -g",
+                                    threads("-D_REENTRANT")),
+        ex_libs          => add(" ","-ldl"),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "elf",
         dso_scheme       => "dlfcn",
         shared_target    => "linux-shared",
@@ -32,28 +43,31 @@
     "debug-linux-pentium" => {
         inherit_from     => [ "x86_elf_asm" ],
         cc               => "gcc",
-        cflags           => "-DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG -DBN_CTX_DEBUG -DL_ENDIAN -g -mcpu=pentium -Wall",
-        thread_cflag     => "-D_REENTRANT",
-        ex_libs          => "-ldl",
+        cflags           => combine("-DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG -DBN_CTX_DEBUG -DL_ENDIAN -g -mcpu=pentium -Wall",
+                                    threads("-D_REENTRANT")),
+        ex_libs          => add(" ","-ldl"),
         bn_ops           => "BN_LLONG",
+        thread_scheme    => "pthreads",
         dso_scheme       => "dlfcn",
     },
     "debug-linux-ppro" => {
         inherit_from     => [ "x86_elf_asm" ],
         cc               => "gcc",
-        cflags           => "-DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG -DBN_CTX_DEBUG -DL_ENDIAN -g -mcpu=pentiumpro -Wall",
-        thread_cflag     => "-D_REENTRANT",
-        ex_libs          => "-ldl",
+        cflags           => combine("-DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG -DBN_CTX_DEBUG -DL_ENDIAN -g -mcpu=pentiumpro -Wall",
+                                    threads("-D_REENTRANT")),
+        ex_libs          => add(" ","-ldl"),
         bn_ops           => "BN_LLONG",
+        thread_scheme    => "pthreads",
         dso_scheme       => "dlfcn",
     },
     "debug-linux-elf-noefence" => {
         inherit_from     => [ "x86_elf_asm" ],
         cc               => "gcc",
-        cflags           => "-DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG -DBN_CTX_DEBUG -DL_ENDIAN -g -Wall",
-        thread_cflag     => "-D_REENTRANT",
-        ex_libs          => "-ldl",
+        cflags           => combine("-DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG -DBN_CTX_DEBUG -DL_ENDIAN -g -Wall",
+                                    threads("-D_REENTRANT")),
+        ex_libs          => add(" ","-ldl"),
         bn_ops           => "BN_LLONG",
+        thread_scheme    => "pthreads",
         dso_scheme       => "dlfcn",
         shared_target    => "linux-shared",
         shared_cflag     => "-fPIC",
@@ -61,9 +75,9 @@
     },
     "debug-linux-ia32-aes" => {
         cc               => "gcc",
-        cflags           => "-DL_ENDIAN -O3 -fomit-frame-pointer -Wall",
-        thread_cflag     => "-D_REENTRANT",
-        ex_libs          => "-ldl",
+        cflags           => combine("-DL_ENDIAN -O3 -fomit-frame-pointer -Wall",
+                                    threads("-D_REENTRANT")),
+        ex_libs          => add(" ","-ldl"),
         bn_ops           => "BN_LLONG",
         cpuid_asm_src    => "x86cpuid.s",
         bn_asm_src       => "bn-586.s co-586.s x86-mont.s",
@@ -79,6 +93,7 @@
         wp_asm_src       => "wp_block.s wp-mmx.s",
         modes_asm_src    => "ghash-x86.s",
         padlock_asm_src  => "e_padlock-x86.s",
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "elf",
         dso_scheme       => "dlfcn",
         shared_target    => "linux-shared",
@@ -88,14 +103,15 @@
     "dist" => {
         cc               => "cc",
         cflags           => "-O",
-        thread_cflag     => "(unknown)",
+        thread_scheme    => "(unknown)",
     },
     "debug-test-64-clang" => {
         inherit_from     => [ "x86_64_asm" ],
         cc               => "clang",
-        cflags           => "$gcc_devteam_warn -Wno-error=overlength-strings -Wno-error=extended-offsetof -Wno-error=language-extension-token -Wno-error=unused-const-variable -Wstrict-overflow -Qunused-arguments -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -g3 -O3 -pipe",
-        thread_cflag     => "${BSDthreads}",
+        cflags           => combine("$gcc_devteam_warn -Wno-error=overlength-strings -Wno-error=extended-offsetof -Wno-error=language-extension-token -Wno-error=unused-const-variable -Wstrict-overflow -Qunused-arguments -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -g3 -O3 -pipe",
+                                    threads("${BSDthreads}")),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "elf",
         dso_scheme       => "dlfcn",
         shared_target    => "bsd-gcc-shared",
@@ -105,10 +121,11 @@
     "darwin64-debug-test-64-clang" => {
         inherit_from     => [ "x86_64_asm" ],
         cc               => "clang",
-        cflags           => "-arch x86_64 -DL_ENDIAN $gcc_devteam_warn -Wno-error=overlength-strings -Wno-error=extended-offsetof -Wno-error=language-extension-token -Wno-error=unused-const-variable -Wstrict-overflow -Qunused-arguments -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -g3 -O3 -pipe",
-        thread_cflag     => "${BSDthreads}",
+        cflags           => combine("-arch x86_64 -DL_ENDIAN $gcc_devteam_warn -Wno-error=overlength-strings -Wno-error=extended-offsetof -Wno-error=language-extension-token -Wno-error=unused-const-variable -Wstrict-overflow -Qunused-arguments -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -g3 -O3 -pipe",
+                                    threads("${BSDthreads}")),
         sys_id           => "MACOSX",
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "macosx",
         dso_scheme       => "dlfcn",
         shared_target    => "darwin-shared",
diff --git a/Configurations/99-personal-ben.conf b/Configurations/99-personal-ben.conf
index 611e3de..50b9315 100644
--- a/Configurations/99-personal-ben.conf
+++ b/Configurations/99-personal-ben.conf
@@ -5,29 +5,30 @@
     "debug-ben" => {
         cc               => "gcc",
         cflags           => "$gcc_devteam_warn -DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG -DBN_CTX_DEBUG -DDEBUG_SAFESTACK -O2 -pipe",
-        thread_cflag     => "(unknown)",
+        thread_scheme    => "(unknown)",
     },
     "debug-ben-openbsd" => {
         cc               => "gcc",
         cflags           => "-DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG -DBN_CTX_DEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DOPENSSL_OPENBSD_DEV_CRYPTO -DOPENSSL_NO_ASM -O2 -pedantic -Wall -Wshadow -Werror -pipe",
-        thread_cflag     => "(unknown)",
+        thread_scheme    => "(unknown)",
     },
     "debug-ben-openbsd-debug" => {
         cc               => "gcc",
         cflags           => "-DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG -DBN_CTX_DEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DOPENSSL_OPENBSD_DEV_CRYPTO -DOPENSSL_NO_ASM -g3 -O2 -pedantic -Wall -Wshadow -Werror -pipe",
-        thread_cflag     => "(unknown)",
+        thread_scheme    => "(unknown)",
     },
     "debug-ben-debug" => {
         cc               => "gcc",
         cflags           => "$gcc_devteam_warn -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DOPENSSL_NO_HW_PADLOCK -g3 -O2 -pipe",
-        thread_cflag     => "(unknown)",
+        thread_scheme    => "(unknown)",
     },
     "debug-ben-debug-64" => {
         inherit_from     => [ "x86_64_asm" ],
         cc               => "gcc",
-        cflags           => "$gcc_devteam_warn -Wno-error=overlength-strings -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -g3 -O3 -pipe",
-        thread_cflag     => "${BSDthreads}",
+        cflags           => combine("$gcc_devteam_warn -Wno-error=overlength-strings -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -g3 -O3 -pipe",
+                                    threads("${BSDthreads}")),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "elf",
         dso_scheme       => "dlfcn",
         shared_target    => "bsd-gcc-shared",
@@ -37,9 +38,10 @@
     "debug-ben-debug-64-clang" => {
         inherit_from     => [ "x86_64_asm" ],
         cc               => "clang",
-        cflags           => "$gcc_devteam_warn -Wno-error=overlength-strings -Wno-error=extended-offsetof -Wno-error=language-extension-token -Wstrict-overflow -Qunused-arguments -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -g3 -O3 -pipe",
-        thread_cflag     => "${BSDthreads}",
+        cflags           => combine("$gcc_devteam_warn -Wno-error=overlength-strings -Wno-error=extended-offsetof -Wno-error=language-extension-token -Wstrict-overflow -Qunused-arguments -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -g3 -O3 -pipe",
+                                    threads("${BSDthreads}")),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "elf",
         dso_scheme       => "dlfcn",
         shared_target    => "bsd-gcc-shared",
@@ -49,9 +51,10 @@
     "debug-ben-debug-64-noopt" => {
         inherit_from     => [ "x86_64_asm" ],
         cc               => "gcc",
-        cflags           => "$gcc_devteam_warn -Wno-error=overlength-strings -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -g3 -pipe",
-        thread_cflag     => "${BSDthreads}",
+        cflags           => combine("$gcc_devteam_warn -Wno-error=overlength-strings -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -g3 -pipe",
+                                    threads("${BSDthreads}")),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "elf",
         dso_scheme       => "dlfcn",
         shared_target    => "bsd-gcc-shared",
@@ -61,26 +64,27 @@
     "debug-ben-macos" => {
         cc               => "cc",
         cflags           => "$gcc_devteam_warn -DOPENSSL_NO_ASM -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -arch i386 -O3 -DL_ENDIAN -g3 -pipe",
-        thread_cflag     => "(unknown)",
+        thread_scheme    => "(unknown)",
     },
     "debug-ben-no-opt" => {
         cc               => "gcc",
         cflags           => " -Wall -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -DDEBUG_SAFESTACK -Werror -DL_ENDIAN -Wall -g3",
-        thread_cflag     => "(unknown)",
+        thread_scheme    => "(unknown)",
     },
     "debug-ben-strict" => {
         cc               => "gcc",
         cflags           => "-DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG -DBN_CTX_DEBUG -DCONST_STRICT -O2 -Wall -Wshadow -Werror -Wpointer-arith -Wcast-qual -Wwrite-strings -pipe",
-        thread_cflag     => "(unknown)",
+        thread_scheme    => "(unknown)",
     },
     "debug-ben-darwin64" => {
         inherit_from     => [ "x86_64_asm" ],
         cc               => "cc",
-        cflags           => "$gcc_devteam_warn -Wno-language-extension-token -Wno-extended-offsetof -arch x86_64 -O3 -DL_ENDIAN -DMD32_REG_T=int -Wall",
-        thread_cflag     => "-D_REENTRANT",
+        cflags           => combine("$gcc_devteam_warn -Wno-language-extension-token -Wno-extended-offsetof -arch x86_64 -O3 -DL_ENDIAN -DMD32_REG_T=int -Wall",
+                                    threads("-D_REENTRANT")),
         sys_id           => "MACOSX",
         plib_lflags      => "-Wl,-search_paths_first",
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "macosx",
         dso_scheme       => "dlfcn",
         shared_target    => "darwin-shared",
diff --git a/Configurations/99-personal-bodo.conf b/Configurations/99-personal-bodo.conf
index 24c0e1e..df9b49c 100644
--- a/Configurations/99-personal-bodo.conf
+++ b/Configurations/99-personal-bodo.conf
@@ -5,10 +5,11 @@
     "debug-bodo" => {
         inherit_from     => [ "x86_64_asm" ],
         cc               => "gcc",
-        cflags           => "$gcc_devteam_warn -Wno-error=overlength-strings -DBN_DEBUG -DBN_DEBUG_RAND -DCONF_DEBUG -m64 -DL_ENDIAN -DTERMIO -g -DMD32_REG_T=int",
-        thread_cflag     => "-D_REENTRANT",
-        ex_libs          => "-ldl",
+        cflags           => combine("$gcc_devteam_warn -Wno-error=overlength-strings -DBN_DEBUG -DBN_DEBUG_RAND -DCONF_DEBUG -m64 -DL_ENDIAN -DTERMIO -g -DMD32_REG_T=int",
+                                    threads("-D_REENTRANT")),
+        ex_libs          => add(" ","-ldl"),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "elf",
         dso_scheme       => "dlfcn",
         shared_target    => "linux-shared",
diff --git a/Configurations/99-personal-geoff.conf b/Configurations/99-personal-geoff.conf
index 89ba499..5bddfae 100644
--- a/Configurations/99-personal-geoff.conf
+++ b/Configurations/99-personal-geoff.conf
@@ -4,10 +4,11 @@
 %targets = (
     "debug-geoff32" => {
         cc               => "gcc",
-        cflags           => "-DBN_DEBUG -DBN_DEBUG_RAND -DBN_STRICT -DOPENSSL_NO_DEPRECATED -DOPENSSL_NO_ASM -DOPENSSL_NO_INLINE_ASM -DL_ENDIAN -DTERMIO -DPEDANTIC -O1 -ggdb2 -Wall -Werror -Wundef -pedantic -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare -Wmissing-prototypes -Wmissing-declarations -Wno-long-long",
-        thread_cflag     => "-D_REENTRANT",
-        ex_libs          => "-ldl",
+        cflags           => combine("-DBN_DEBUG -DBN_DEBUG_RAND -DBN_STRICT -DOPENSSL_NO_DEPRECATED -DOPENSSL_NO_ASM -DOPENSSL_NO_INLINE_ASM -DL_ENDIAN -DTERMIO -DPEDANTIC -O1 -ggdb2 -Wall -Werror -Wundef -pedantic -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare -Wmissing-prototypes -Wmissing-declarations -Wno-long-long",
+                                    threads("-D_REENTRANT")),
+        ex_libs          => add(" ","-ldl"),
         bn_ops           => "BN_LLONG",
+        thread_scheme    => "pthreads",
         dso_scheme       => "dlfcn",
         shared_target    => "linux-shared",
         shared_cflag     => "-fPIC",
@@ -15,10 +16,11 @@
     },
     "debug-geoff64" => {
         cc               => "gcc",
-        cflags           => "-DBN_DEBUG -DBN_DEBUG_RAND -DBN_STRICT -DOPENSSL_NO_DEPRECATED -DOPENSSL_NO_ASM -DOPENSSL_NO_INLINE_ASM -DL_ENDIAN -DTERMIO -DPEDANTIC -O1 -ggdb2 -Wall -Werror -Wundef -pedantic -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare -Wmissing-prototypes -Wmissing-declarations -Wno-long-long",
-        thread_cflag     => "-D_REENTRANT",
-        ex_libs          => "-ldl",
+        cflags           => combine("-DBN_DEBUG -DBN_DEBUG_RAND -DBN_STRICT -DOPENSSL_NO_DEPRECATED -DOPENSSL_NO_ASM -DOPENSSL_NO_INLINE_ASM -DL_ENDIAN -DTERMIO -DPEDANTIC -O1 -ggdb2 -Wall -Werror -Wundef -pedantic -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare -Wmissing-prototypes -Wmissing-declarations -Wno-long-long",
+                                    threads("-D_REENTRANT")),
+        ex_libs          => add(" ","-ldl"),
         bn_ops           => "SIXTY_FOUR_BIT_LONG RC4_CHAR",
+        thread_scheme    => "pthreads",
         dso_scheme       => "dlfcn",
         shared_target    => "linux-shared",
         shared_cflag     => "-fPIC",
diff --git a/Configurations/99-personal-levitte.conf b/Configurations/99-personal-levitte.conf
index 9db343e..d1ddf2e 100644
--- a/Configurations/99-personal-levitte.conf
+++ b/Configurations/99-personal-levitte.conf
@@ -1,18 +1,26 @@
 ## -*- mode: perl; -*-
 ## Personal configuration targets
 
+sub picker {
+    my %opts = @_;
+    return sub { add($opts{default} || (),
+                     $opts{$config{build_type}} || ())->(); }
+}
+
 %targets = (
     "levitte-linux-elf" => {
         inherit_from     => [ "linux-elf" ],
-        debug_cflags     => add("-ggdb -g3"),
-        debug_defines    => add("LEVITTE_DEBUG", { separator => undef }),
+        cflags           => add(picker(debug => "-ggdb -g3")),
+        defines          => add(picker(debug => "LEVITTE_DEBUG"),
+                                { separator => undef }),
         build_scheme     => [ "unified", "unix" ],
         build_file       => "Makefile",
     },
     "levitte-linux-x86_64" => {
         inherit_from     => [ "linux-x86_64" ],
-        debug_cflags     => add("-ggdb -g3"),
-        debug_defines    => add("LEVITTE_DEBUG", { separator => undef }),
+        cflags           => add(picker(debug => "-ggdb -g3")),
+        defines          => add(picker(debug => "LEVITTE_DEBUG"),
+                                { separator => undef }),
         build_scheme     => [ "unified", "unix" ],
         build_file       => "Makefile",
     },
diff --git a/Configurations/99-personal-rse.conf b/Configurations/99-personal-rse.conf
index ecb4742..9999fcd 100644
--- a/Configurations/99-personal-rse.conf
+++ b/Configurations/99-personal-rse.conf
@@ -6,7 +6,7 @@
         inherit_from     => [ "x86_elf_asm" ],
         cc               => "cc",
         cflags           => "-DL_ENDIAN -pipe -O -g -ggdb3 -Wall",
-        thread_cflag     => "(unknown)",
+        thread_scheme    => "(unknown)",
         bn_ops           => "BN_LLONG",
     },
 );
diff --git a/Configurations/99-personal-steve.conf b/Configurations/99-personal-steve.conf
index bf9dbf4..473fd24 100644
--- a/Configurations/99-personal-steve.conf
+++ b/Configurations/99-personal-steve.conf
@@ -5,10 +5,11 @@
     "debug-steve64" => {
         inherit_from     => [ "x86_64_asm" ],
         cc               => "gcc",
-        cflags           => "$gcc_devteam_warn -pthread -m64 -DL_ENDIAN -DTERMIO -DCONF_DEBUG -g",
-        thread_cflag     => "-D_REENTRANT",
-        ex_libs          => "-ldl",
+        cflags           => combine("$gcc_devteam_warn -pthread -m64 -DL_ENDIAN -DTERMIO -DCONF_DEBUG -g",
+                                    threads("-D_REENTRANT")),
+        ex_libs          => add(" ","-ldl"),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "elf",
         dso_scheme       => "dlfcn",
         shared_target    => "linux-shared",
@@ -19,11 +20,12 @@
     "debug-steve32" => {
         inherit_from     => [ "x86_elf_asm" ],
         cc               => "gcc",
-        cflags           => "$gcc_devteam_warn -pthread -m32 -DL_ENDIAN -DCONF_DEBUG -g",
-        thread_cflag     => "-D_REENTRANT",
+        cflags           => combine("$gcc_devteam_warn -pthread -m32 -DL_ENDIAN -DCONF_DEBUG -g",
+                                    threads("-D_REENTRANT")),
         lflags           => "-rdynamic",
-        ex_libs          => "-ldl",
+        ex_libs          => add(" ","-ldl"),
         bn_ops           => "BN_LLONG",
+        thread_scheme    => "pthreads",
         dso_scheme       => "dlfcn",
         shared_target    => "linux-shared",
         shared_cflag     => "-fPIC",
@@ -33,10 +35,11 @@
     "debug-steve-opt" => {
         inherit_from     => [ "x86_64_asm" ],
         cc               => "gcc",
-        cflags           => "$gcc_devteam_warn -pthread -m64 -O3 -DL_ENDIAN -DTERMIO -DCONF_DEBUG -g",
-        thread_cflag     => "-D_REENTRANT",
-        ex_libs          => "-ldl",
+        cflags           => combine("$gcc_devteam_warn -pthread -m64 -O3 -DL_ENDIAN -DTERMIO -DCONF_DEBUG -g",
+                                    threads("-D_REENTRANT")),
+        ex_libs          => add(" ","-ldl"),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
+        thread_scheme    => "pthreads",
         perlasm_scheme   => "elf",
         dso_scheme       => "dlfcn",
         shared_target    => "linux-shared",
diff --git a/Configurations/README b/Configurations/README
index 1885157..afc6004 100644
--- a/Configurations/README
+++ b/Configurations/README
@@ -28,30 +28,6 @@ In each table entry, the following keys are significant:
                            given here, they MUST be as an array of the
                            string such as "MACRO=value", or just
                            "MACRO" for definitions without value.
-        debug_cflags    => Extra compilation flags used when making a
-                           debug build (when Configure receives the
-                           --debug option).  Typically something like
-                           "-g -O0".
-        debug_defines   => Similarly to `debug_cflags', this gets
-                           combined with `defines' during a debug
-                           build.  The value here MUST also be an
-                           array of the same form as for `defines'.
-        release_cflags  => Extra compilation flags used when making a
-                           release build (when Configure receives the
-                           --release option, or doesn't receive the
-                           --debug option).  Typically something like
-                           "-O" or "-O3".
-        release_defines => Similarly to `release_cflags', this gets
-                           combined with `defines' during a release
-                           build.  The value here MUST also be an
-                           array of the same form as for `defines'.
-        thread_cflags   => Extra compilation flags used when
-                           compiling with threading enabled.
-                           Explained further below.  [2]
-        thread_defines  => Similarly to `thread_cflags', this gets
-                           combined with `defines' when threading is
-                           enabled.  The value here MUST also be an
-                           array of the same form as for `defines'.
         shared_cflag    => Extra compilation flags used when
                            compiling for shared libraries, typically
                            something like "-fPIC".
@@ -70,9 +46,6 @@ In each table entry, the following keys are significant:
         ex_libs         => Extra libraries that are needed when
                            linking.
 
-        debug_lflags    => Like debug_cflags, but used when linking.
-        release_lflags  => Like release_cflags, but used when linking.
-
         ar              => The library archive command, the default is
                            "ar".
                            (NOTE: this is here for future use, it's
@@ -97,6 +70,14 @@ In each table entry, the following keys are significant:
                            this is here for future use, it's not
                            implemented yet)
 
+        thread_scheme   => The type of threads is used on the
+                           configured platform.  Currently known
+                           values are "(unknown)", "pthreads",
+                           "uithreads" (a.k.a solaris threads) and
+                           "winthreads".  Except for "(unknown)", the
+                           actual value is currently ignored but may
+                           be used in the future.  See further notes
+                           below [2].
         dso_scheme      => The type of dynamic shared objects to build
                            for.  This mostly comes into play with
                            engines, but can be used for other purposes
@@ -265,7 +246,7 @@ In each table entry, the following keys are significant:
         }
 
 [2] OpenSSL is built with threading capabilities unless the user
-    specifies 'no-threads'.  The value of the key 'thread_cflags' may
+    specifies 'no-threads'.  The value of the key 'thread_scheme' may
     be "(unknown)", in which case the user MUST give some compilation
     flags to Configure.
 
diff --git a/Configurations/descrip.mms.tmpl b/Configurations/descrip.mms.tmpl
index 5c575d0..ef59d42 100644
--- a/Configurations/descrip.mms.tmpl
+++ b/Configurations/descrip.mms.tmpl
@@ -126,10 +126,10 @@ OPENSSLDIR={- catdir($config{openssldir}) ||
 ENGINESDIR={- $osslprefix -}ENGINES:
 
 CC= {- $target{cc} -}
-CFLAGS= /DEFINE=({- join(",", @{$config{defines}},"OPENSSLDIR=\"\"\"\$(OPENSSLDIR)\"\"\"","ENGINESDIR=\"\"\"\$(ENGINESDIR)\"\"\"") -}) {- $config{cflags} -}
+CFLAGS= /DEFINE=({- join(",", @{$target{defines}}, @{$config{defines}},"OPENSSLDIR=\"\"\"\$(OPENSSLDIR)\"\"\"","ENGINESDIR=\"\"\"\$(ENGINESDIR)\"\"\"") -}) {- $target{cflags} -} {- $config{cflags} -}
 DEPFLAG= /DEFINE=({- join(",", @{$config{depdefines}}) -})
-LDFLAGS= {- $config{lflags} -}
-EX_LIBS= {- $config{ex_libs} ? ",".$config{ex_libs} : "" -}
+LDFLAGS= {- $target{lflags} -}
+EX_LIBS= {- $target{ex_libs} ? ",".$target{ex_libs} : "" -}{- $config{ex_libs} ? ",".$config{ex_libs} : "" -}
 
 PERL={- $config{perl} -}
 
diff --git a/Configurations/unix-Makefile.tmpl b/Configurations/unix-Makefile.tmpl
index 066f3d7..8ccadbb 100644
--- a/Configurations/unix-Makefile.tmpl
+++ b/Configurations/unix-Makefile.tmpl
@@ -144,13 +144,13 @@ HTMLSUFFIX=html
 
 CROSS_COMPILE= {- $config{cross_compile_prefix} -}
 CC= $(CROSS_COMPILE){- $target{cc} -}
-CFLAGS={- our $cflags2 = join(" ",(map { "-D".$_} @{$config{defines}}),"-DOPENSSLDIR=\"\\\"\$(OPENSSLDIR)\\\"\"","-DENGINESDIR=\"\\\"\$(ENGINESDIR)\\\"\"") -} {- $config{cflags} -}
+CFLAGS={- our $cflags2 = join(" ",(map { "-D".$_} @{$target{defines}}, @{$config{defines}}),"-DOPENSSLDIR=\"\\\"\$(OPENSSLDIR)\\\"\"","-DENGINESDIR=\"\\\"\$(ENGINESDIR)\\\"\"") -} {- $target{cflags} -} {- $config{cflags} -}
 CFLAGS_Q={- $cflags2 =~ s|([\\"])|\\$1|g; $cflags2 -} {- $config{cflags} -}
-LDFLAGS= {- $config{lflags} -}
-PLIB_LDFLAGS= {- $config{plib_lflags} -}
-EX_LIBS= {- $config{ex_libs} -}
+LDFLAGS= {- $target{lflags} -}
+PLIB_LDFLAGS= {- $target{plib_lflags} -}
+EX_LIBS= {- $target{ex_libs} -} {- $config{ex_libs} -}
 SHARED_CFLAGS={- $target{shared_cflag} || "" -}
-SHARED_LDFLAGS={- $target{shared_ldflag}
+SHARED_LDFLAGS={- $target{shared_ldflag}." ".$config{shared_ldflag}
                   # Unlike other OSes (like Solaris, Linux, Tru64,
                   # IRIX) BSD run-time linkers (tested OpenBSD, NetBSD
                   # and FreeBSD) "demand" RPATH set on .so objects.
diff --git a/Configure b/Configure
index 96be541..28339f1 100755
--- a/Configure
+++ b/Configure
@@ -124,7 +124,7 @@ my $strict_warnings = 0;
 # which has to be accompanied by explicit -D_THREAD_SAFE and
 # sometimes -D_REENTRANT. FreeBSD 5.x expands it as -lc_r, which
 # seems to be sufficient?
-my $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT";
+our $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT";
 
 #
 # API compability name to version number mapping.
@@ -136,9 +136,9 @@ my $apitable = {
     "0.9.8" => "0x00908000L",
 };
 
-my $base_target = "BASE";   # The template that all other inherit from
 our %table = ();
 our %config = ();
+our %withargs = ();
 
 # Forward declarations ###############################################
 
@@ -208,7 +208,7 @@ $config{cross_compile_prefix}="";
 $config{fipslibdir}="/usr/local/ssl/fips-2.0/lib/";
 my $nofipscanistercheck=0;
 $config{baseaddr}="0xFB00000";
-my $threads=0;
+my $auto_threads=1;    # enable threads automatically? true by default
 my $default_ranlib;
 $config{fips}=0;
 
@@ -438,8 +438,7 @@ $config{openssl_other_defines}=[];
 my $libs="";
 my $target="";
 $config{options}="";
-my %withargs=();
-my $build_prefix = "release_";
+$config{build_type} = "release";
 
 my @argvcopy=@ARGV;
 
@@ -570,6 +569,8 @@ foreach (@argvcopy)
                         {
                         $disabled{$1} = "option";
                         }
+		# No longer an automatic choice
+		$auto_threads = 0 if ($1 eq "threads");
 		}
 	elsif (/^enable-(.+)$/)
 		{
@@ -584,7 +585,8 @@ foreach (@argvcopy)
 		my $algo = $1;
 		delete $disabled{$algo};
 
-		$threads = 1 if ($algo eq "threads");
+		# No longer an automatic choice
+		$auto_threads = 0 if ($1 eq "threads");
 		}
 	elsif (/^--strict-warnings$/)
 		{
@@ -592,11 +594,11 @@ foreach (@argvcopy)
 		}
 	elsif (/^--debug$/)
 		{
-		$build_prefix = "debug_";
+		$config{build_type} = "debug";
 		}
 	elsif (/^--release$/)
 		{
-		$build_prefix = "release_";
+		$config{build_type} = "release";
 		}
 	elsif (/^386$/)
 		{ $config{processor}=386; }
@@ -827,7 +829,7 @@ print "Configuring for $target\n";
 # Support for legacy targets having a name starting with 'debug-'
 my ($d, $t) = $target =~ m/^(debug-)?(.*)$/;
 if ($d) {
-    $build_prefix = "debug_";
+    $config{build_type} = "debug";
 
     # If we do not find debug-foo in the table, the target is set to foo.
     if (!$table{$target}) {
@@ -835,13 +837,11 @@ if ($d) {
     }
 }
 $config{target} = $target;
-delete $table{$base_target}->{template}; # or the next test will fail.
 my %target = resolve_config($target);
 
 &usage if (!%target || $target{template});
 
-# Set up defaults
-my %target = ( %{$table{$base_target}}, %target );
+%target = ( %{$table{DEFAULTS}}, %target );
 
 $target{exe_extension}="";
 $target{exe_extension}=".exe" if ($config{target} eq "DJGPP"
@@ -869,20 +869,10 @@ $target{nm} =      $ENV{'NM'}      || $target{nm}      || "nm";
 # For cflags, lflags, plib_lflags, ex_libs and defines, add the debug_
 # or release_ attributes.
 # Do it in such a way that no spurious space is appended (hence the grep).
-$config{defines} = [ @{$target{defines}},
-                     @{$target{$build_prefix."defines"}} ];
-$config{cflags} = join(" ",
-		       grep { $_ ne "" } ($target{cflags},
-					  $target{$build_prefix."cflags"}));
-$config{lflags} = join(" ",
-		       grep { $_ ne "" } ($target{lflags},
-					  $target{$build_prefix."lflags"}));
-$config{plib_lflags} = join(" ",
-			    grep { $_  ne "" } ($target{plib_lflags},
-					        $target{$build_prefix."plib_lflags"}));
-$config{ex_libs} = join(" ",
-			grep { $_  ne "" } ($target{ex_libs},
-					    $target{$build_prefix."ex_libs"}));
+$config{defines} = [];
+$config{cflags} = "";
+$config{ex_libs} = "";
+$config{shared_ldflag} = "";
 
 # Make sure build_scheme is consistent.
 $target{build_scheme} = [ $target{build_scheme} ]
@@ -904,7 +894,7 @@ my ($builder, $builder_platform, @builder_opts) =
 if ($target =~ /^mingw/ && `$target{cc} --target-help 2>&1` =~ m/-mno-cygwin/m)
 	{
 	$config{cflags} .= " -mno-cygwin";
-	$target{shared_ldflag} .= " -mno-cygwin";
+	$config{shared_ldflag} .= " -mno-cygwin";
 	}
 
 if ($target =~ /linux.*-mips/ && !$disabled{asm} && $user_cflags !~ /-m(ips|arch=)/) {
@@ -928,81 +918,61 @@ if (!$disabled{dso} && $target{dso_scheme} ne "")
 	$target{dso_scheme} =~ tr/[a-z]/[A-Z]/;
 	if ($target{dso_scheme} eq "DLFCN")
 		{
-		$config{defines} = [ "DSO_DLFCN", "HAVE_DLFCN_H",
-				     @{$config{defines}} ]
+		unshift @{$config{defines}}, "DSO_DLFCN", "HAVE_DLFCN_H";
 		}
 	elsif ($target{dso_scheme} eq "DLFCN_NO_H")
 		{
-		$config{defines} = [ "DSO_DLFCN", @{$config{defines}} ]
+		unshift @{$config{defines}}, "DSO_DLFCN";
 		}
 	else
 		{
-		$config{defines} = [ "DSO_$target{dso_scheme}",
-				     @{$config{defines}} ]
+		unshift @{$config{defines}}, "DSO_$target{dso_scheme}";
 		}
 	}
 
-my $thread_cflags = "";
-my @thread_defines;
-if ($target{thread_cflag} ne "(unknown)" && !$disabled{threads})
-	{
-	# If we know how to do it, support threads by default.
-	$threads = 1;
-	}
-if ($target{thread_cflag} eq "(unknown)" && $threads)
-	{
-	# If the user asked for "threads", [s]he is also expected to
-	# provide any system-dependent compiler options that are
-	# necessary.
-	if ($no_user_cflags && $no_user_defines)
-		{
-		print "You asked for multi-threading support, but didn't\n";
-		print "provide any system-specific compiler options\n";
-		exit(1);
-		}
-	push @thread_defines, "OPENSSL_THREADS";
-	}
-else
-	{
-	$thread_cflags=" $target{thread_cflag}";
-	push @thread_defines, @{$target{thread_defines}}, "OPENSSL_THREADS";
-	}
-
 $config{ex_libs}="$libs$config{ex_libs}" if ($libs ne "");
 
 if ($disabled{asm})
 	{
-	@{$config{defines}} = grep !/^[BL]_ENDIAN$/, @{$config{defines}}
-	    if ($config{fips});
-	}
-
-if ($threads)
-	{
-	$config{cflags} = "$thread_cflags $config{cflags}" if $thread_cflags;
-	push @{$config{defines}}, @thread_defines;
-	push @{$config{openssl_thread_defines}}, @thread_defines;
-	}
-
-unless ($disabled{zlib})
-	{
-	push @{$config{defines}}, "ZLIB";
-	if (defined($disabled{"zlib-dynamic"}))
-		{
-		if (defined($withargs{zlib_lib}))
-			{
-			$config{ex_libs} .= " -L" . $withargs{zlib_lib} . " -lz";
-			}
-		else
-			{
-			$config{ex_libs} .= " -lz";
-			}
-		}
-	else
+	if ($config{fips})
 		{
-		push @{$config{defines}}, "ZLIB_SHARED";
+		@{$config{defines}} = grep !/^[BL]_ENDIAN$/, @{$config{defines}};
+		@{$target{defines}} = grep !/^[BL]_ENDIAN$/, @{$target{defines}};
 		}
 	}
 
+# If threads aren't disabled, check how possible they are
+unless ($disabled{threads}) {
+    if ($auto_threads) {
+        # Enabled by default, disable it forcibly if unavailable
+        if ($target{thread_scheme} eq "(unknown)") {
+            $disabled{threads} = "unavailable";
+        }
+    } else {
+        # The user chose to enable threads explicitely, let's see
+        # if there's a chance that's possible
+        if ($target{thread_scheme} eq "(unknown)") {
+            # If the user asked for "threads" and we don't have internal
+            # knowledge how to do it, [s]he is expected to provide any
+            # system-dependent compiler options that are necessary.  We
+            # can't truly check that the given options are correct, but
+            # we expect the user to know what [s]He is doing.
+            if ($no_user_cflags && $no_user_defines) {
+                die "You asked for multi-threading support, but didn't\n"
+                    ,"provide any system-specific compiler options\n";
+            }
+        }
+    }
+}
+
+# If threads still aren't disabled, add a C macro to ensure the source
+# code knows about it.  Any other flag is taken care of by the configs.
+unless($disabled{threads}) {
+    foreach (("defines", "openssl_thread_defines")) {
+        push @{$config{$_}}, "OPENSSL_THREADS";
+    }
+}
+
 # With "deprecated" disable all deprecated features.
 if (defined($disabled{"deprecated"})) {
         $config{api} = $maxapi;
@@ -1047,7 +1017,7 @@ if ($target{sys_id} ne "")
 	}
 
 unless ($disabled{asm}) {
-    $target{cpuid_asm_src}=$table{BASE}->{cpuid_asm_src} if ($config{processor} eq "386");
+    $target{cpuid_asm_src}=$table{DEFAULTS}->{cpuid_asm_src} if ($config{processor} eq "386");
     $target{bn_asm_src} =~ s/\w+-gf2m.c// if (defined($disabled{ec2m}));
 
     # bn-586 is the only one implementing bn_*_part_words
@@ -1070,7 +1040,7 @@ unless ($disabled{asm}) {
     if ($target{md5_asm_src}) {
 	push @{$config{defines}}, "MD5_ASM";
     }
-    $target{cast_asm_src}=$table{BASE}->{cast_asm_src} unless $disabled{pic}; # CAST assembler is not PIC
+    $target{cast_asm_src}=$table{DEFAULTS}->{cast_asm_src} unless $disabled{pic}; # CAST assembler is not PIC
     if ($target{rmd160_asm_src}) {
 	push @{$config{defines}}, "RMD160_ASM";
     }
@@ -1087,9 +1057,9 @@ unless ($disabled{asm}) {
     }
     if ($target{wp_asm_src} =~ /mmx/) {
         if ($config{processor} eq "386") {
-	    $target{wp_asm_src}=$table{BASE}->{wp_asm_src};
+	    $target{wp_asm_src}=$table{DEFAULTS}->{wp_asm_src};
 	} elsif (!$disabled{"whirlpool"}) {
-	    $config{cflags}.=" -DWHIRLPOOL_ASM";
+	    push @{$config{defines}}, "WHIRLPOOL_ASM";
 	}
     }
     if ($target{modes_asm_src} =~ /ghash-/) {
@@ -1703,11 +1673,11 @@ close(OUT);
 
 print "IsMK1MF       =", ($builder eq "mk1mf" ? "yes" : "no"), "\n";
 print "CC            =$target{cc}\n";
-print "CFLAG         =$config{cflags}\n";
-print "DEFINES       =",join(" ", @{$config{defines}}),"\n";
-print "LFLAG         =$config{lflags}\n";
-print "PLIB_LFLAG    =$config{plib_lflags}\n";
-print "EX_LIBS       =$config{ex_libs}\n";
+print "CFLAG         =$target{cflags} $config{cflags}\n";
+print "DEFINES       =",join(" ", @{$target{defines}}, @{$config{defines}}),"\n";
+print "LFLAG         =$target{lflags}\n";
+print "PLIB_LFLAG    =$target{plib_lflags}\n";
+print "EX_LIBS       =$target{ex_libs} $config{ex_libs}\n";
 print "APPS_OBJ      =$target{apps_obj}\n";
 print "CPUID_OBJ     =$target{cpuid_obj}\n";
 print "UPLINK_OBJ    =$target{uplink_obj}\n";
@@ -1867,7 +1837,7 @@ print <<"EOF";
 Configured for $target.
 EOF
 
-print <<"EOF" if (!$disabled{threads} && !$threads);
+print <<"EOF" if ($disabled{threads} eq "unavailable");
 
 The library could not be configured for supporting multi-threaded
 applications as the compiler options required on this system are not known.
@@ -1937,6 +1907,7 @@ sub asm {
     }
 }
 
+our $add_called = 0;
 # Helper function to implement adding values to already existing configuration
 # values.  It handles elements that are ARRAYs, CODEs and scalars
 sub _add {
@@ -1949,18 +1920,28 @@ sub _add {
 
     my @values =
 	map {
-	    if (ref($_) eq "ARRAY") {
-		$found_array = 1;
-		@$_;
+	    my $res = $_;
+	    while (ref($res) eq "CODE") {
+		$res = $res->();
+	    }
+	    if (defined($res)) {
+		if (ref($res) eq "ARRAY") {
+		    $found_array = 1;
+		    @$res;
+		} else {
+		    $res;
+		}
 	    } else {
-		$_;
+		();
 	    }
     } (@_);
 
+    $add_called = 1;
+
     if ($found_array) {
 	[ @values ];
     } else {
-	join($separator, @values);
+	join($separator, grep { defined($_) && $_ ne "" } @values);
     }
 }
 sub add_before {
@@ -2025,6 +2006,8 @@ sub resolve_config {
     my $target = shift;
     my @breadcrumbs = @_;
 
+    my $extra_checks = defined($ENV{CONFIGURE_EXTRA_CHECKS});
+
     if (grep { $_ eq $target } @breadcrumbs) {
 	die "inherit_from loop!  target backtrace:\n  "
 	    ,$target,"\n  ",join("\n  ", @breadcrumbs),"\n";
@@ -2080,7 +2063,35 @@ sub resolve_config {
     my %all_keys =
 	map { $_ => 1 } (keys %combined_inheritance,
 			 keys %{$table{$target}});
+
+    sub process_values {
+	my $object    = shift;
+	my $inherited = shift;  # Always a [ list ]
+	my $target    = shift;
+	my $entry     = shift;
+
+        $add_called = 0;
+
+        while(ref($object) eq "CODE") {
+            $object = $object->(@$inherited);
+        }
+        if (!defined($object)) {
+            return ();
+        }
+        elsif (ref($object) eq "ARRAY") {
+            local $add_called;  # To make sure recursive calls don't affect it
+            return [ map { process_values($_, $inherited, $target, $entry) }
+                     @$object ];
+        } elsif (ref($object) eq "") {
+            return $object;
+        } else {
+            die "cannot handle reference type ",ref($object)
+                ," found in target ",$target," -> ",$entry,"\n";
+        }
+    }
+
     foreach (sort keys %all_keys) {
+        my $previous = $combined_inheritance{$_};
 
 	# Current target doesn't have a value for the current key?
 	# Assign it the default combiner, the rest of this loop body
@@ -2089,20 +2100,16 @@ sub resolve_config {
 	    $table{$target}->{$_} = $default_combiner;
 	}
 
-	my $valuetype = ref($table{$target}->{$_});
-	if ($valuetype eq "CODE") {
-	    # CODE reference, execute it with the inherited values as
-	    # arguments.
-	    $table{$target}->{$_} =
-		$table{$target}->{$_}->(@{$combined_inheritance{$_}});
-	} elsif ($valuetype eq "ARRAY" || $valuetype eq "") {
-	    # ARRAY or Scalar, just leave it as is.
-	} else {
-	    # Some other type of reference that we don't handle.
-	    # Better to abort at this point.
-	    die "cannot handle reference type $valuetype,"
-		," found in target $target -> $_\n";
-	}
+	$table{$target}->{$_} = process_values($table{$target}->{$_},
+					       $combined_inheritance{$_},
+					       $target, $_);
+        unless(defined($table{$target}->{$_})) {
+            delete $table{$target}->{$_};
+        }
+        if ($extra_checks &&
+            $previous && !($add_called ||  $previous ~~ $table{$target}->{$_})) {
+            warn "$_ got replaced in $target\n";
+        }
     }
 
     # Finally done, return the result.
@@ -2177,22 +2184,11 @@ sub print_table_entry
 	"cc",
 	"cflags",
 	"defines",
-	"debug_cflags",
-	"debug_defines",
-	"release_cflags",
-	"release_defines",
-	"thread_cflag",
 	"unistd",
 	"ld",
 	"lflags",
 	"plib_lflags",
 	"ex_libs",
-	"debug_lflags",
-	"debug_plib_lflags",
-	"debug_ex_libs",
-	"release_lflags",
-	"release_plib_lflags",
-	"release_ex_libs",
 	"bn_ops",
 	"cpuid_obj",
 	"bn_obj",
@@ -2210,6 +2206,7 @@ sub print_table_entry
 	"cmll_obj",
 	"modes_obj",
 	"padlock_obj",
+	"thread_scheme",
 	"perlasm_scheme",
 	"dso_scheme",
 	"shared_target",
diff --git a/Makefile.in b/Makefile.in
index bddbfdb..4286eb9 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -93,11 +93,11 @@ ENGINESDIR={- use File::Spec::Functions;
 
 CROSS_COMPILE= {- $config{cross_compile_prefix} -}
 CC= $(CROSS_COMPILE){- $target{cc} -}
-CFLAG={- our $cflags2 = join(" ",(map { "-D".$_} @{$config{defines}},"OPENSSLDIR=\"\\\"\$(OPENSSLDIR)\\\"\"","ENGINESDIR=\"\\\"\$(ENGINESDIR)\\\"\"")) -} {- $config{cflags} -}
+CFLAG={- our $cflags2 = join(" ",(map { "-D".$_} @{$target{defines}}, @{$config{defines}}),"-DOPENSSLDIR=\"\\\"\$(OPENSSLDIR)\\\"\"","-DENGINESDIR=\"\\\"\$(ENGINESDIR)\\\"\"") -} {- $target{cflags} -} {- $config{cflags} -}
 CFLAG_Q={- $cflags2 =~ s|([\\"])|\\$1|g; $cflags2 -} {- $config{cflags} -}
 LDFLAG= {- $config{lflags} -}
 PLIB_LDFLAG= {- $config{plib_lflags} -}
-EX_LIBS= {- $config{ex_libs} -}
+EX_LIBS= {- $target{ex_libs} -} {- $config{ex_libs} -}
 EXE_EXT= {- $target{exe_extension} -}
 ARFLAGS= {- $target{arflags} -}
 AR=$(CROSS_COMPILE){- $target{ar} -} $(ARFLAGS) r
@@ -196,7 +196,7 @@ SHARED_CRYPTO=libcrypto$(SHLIB_EXT)
 SHARED_SSL=libssl$(SHLIB_EXT)
 SHARED_LIBS={- $disabled{shared} ? '' : '$(SHARED_CRYPTO) $(SHARED_SSL)'  -}
 SHARED_CFLAG={- $target{shared_cflag} -}
-SHARED_LDFLAG={- $target{shared_ldflag}
+SHARED_LDFLAG={- $target{shared_ldflag}." ".$config{shared_ldflag}
                  # Unlike other OSes (like Solaris, Linux, Tru64,
                  # IRIX) BSD run-time linkers (tested OpenBSD, NetBSD
                  # and FreeBSD) "demand" RPATH set on .so objects.


More information about the openssl-commits mailing list