require 5.000;
use strict;
use File::Basename;
-use File::Spec::Functions;
+use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/;
+use File::Path qw/mkpath/;
# see INSTALL for instructions.
# DEBUG_SAFESTACK use type-safe stacks to enforce type-safety on stack items
# provided to stack calls. Generates unique stack functions for
# each possible stack type.
-# DES_PTR use pointer lookup vs arrays in the DES in crypto/des/des_locl.h
-# DES_RISC1 use different DES_ENCRYPT macro that helps reduce register
-# dependancies but needs to more registers, good for RISC CPU's
-# DES_RISC2 A different RISC variant.
-# DES_UNROLL unroll the inner DES loop, sometimes helps, somtimes hinders.
-# DES_INT use 'int' instead of 'long' for DES_LONG in crypto/des/des.h
-# This is used on the DEC Alpha where long is 8 bytes
-# and int is 4
# BN_LLONG use the type 'long long' in crypto/bn/bn.h
-# MD2_CHAR use 'char' instead of 'int' for MD2_INT in crypto/md2/md2.h
-# MD2_LONG use 'long' instead of 'int' for MD2_INT in crypto/md2/md2.h
-# IDEA_SHORT use 'short' instead of 'int' for IDEA_INT in crypto/idea/idea.h
-# IDEA_LONG use 'long' instead of 'int' for IDEA_INT in crypto/idea/idea.h
-# RC2_SHORT use 'short' instead of 'int' for RC2_INT in crypto/rc2/rc2.h
-# RC2_LONG use 'long' instead of 'int' for RC2_INT in crypto/rc2/rc2.h
# RC4_CHAR use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
-# RC4_LONG use 'long' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
-# RC4_INDEX define RC4_INDEX in crypto/rc4/rc4_locl.h. This turns on
-# array lookups instead of pointer use.
-# RC4_CHUNK enables code that handles data aligned at long (natural CPU
-# word) boundary.
-# RC4_CHUNK_LL enables code that handles data aligned at long long boundary
-# (intended for 64-bit CPUs running 32-bit OS).
-# BF_PTR use 'pointer arithmatic' for Blowfish (unsafe on Alpha).
-# BF_PTR2 intel specific version (generic version is more efficient).
-#
# Following are set automatically by this script
#
# MD5_ASM use some extra md5 assember,
# This adds backtrace information to the memory leak info.
my $memleak_devteam_backtrace = "-rdynamic -DCRYPTO_MDEBUG_BACKTRACE";
-
my $strict_warnings = 0;
-my $x86_gcc_des="DES_PTR DES_RISC1 DES_UNROLL";
-
-# MD2_CHAR slags pentium pros
-my $x86_gcc_opts="RC4_INDEX MD2_INT";
-
# As for $BSDthreads. 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
# Information collection #############################################
+# Unified build supports separate build dir
+my $srcdir = catdir(absolutedir(dirname($0))); # catdir ensures local syntax
+my $blddir = catdir(absolutedir(".")); # catdir ensures local syntax
+my $dofile = abs2rel(catfile($srcdir, "util/dofile.pl"));
+
+$config{sourcedir} = abs2rel($srcdir);
+$config{builddir} = abs2rel($blddir);
+
# Collect version numbers
$config{version} = "unknown";
$config{version_num} = "unknown";
$config{shlib_version_history} = "unknown";
collect_information(
- '<include/openssl/opensslv.h',
- undef,
+ collect_from_file(catfile($srcdir,'include/openssl/opensslv.h')),
qr/OPENSSL.VERSION.TEXT.*OpenSSL (\S+) / => sub { $config{version} = $1; },
qr/OPENSSL.VERSION.NUMBER.*(0x\S+)/ => sub { $config{version_num}=$1 },
qr/SHLIB_VERSION_NUMBER *"([^"]+)"/ => sub { $config{shlib_version_number}=$1 },
# Collect target configurations
-my ($vol, $dir, $dummy) = File::Spec->splitpath($0);
-my $pattern = File::Spec->catpath($vol, $dir, "Configurations/*.conf");
+my $pattern = catfile(dirname($0), "Configurations", "*.conf");
foreach (sort glob($pattern) ) {
&read_config($_);
}
my $no_rfc3779=0;
my $no_asm=0;
my $no_dso=0;
-my $Makefile="Makefile";
my $default_ranlib;
$config{fips}=0;
my @disablables = (
"aes",
"asm",
+ "async",
+ "autoalginit",
+ "autoerrinit",
"bf",
"camellia",
"capieng",
"ecdh",
"ecdsa",
"ec_nistp_64_gcc_128",
+ "egd",
"engine",
"err", # Really???
"heartbeats",
}
elsif (/^--with-zlib-lib=(.*)$/)
{
- $withargs{"zlib-lib"}=$1;
+ $withargs{zlib_lib}=$1;
}
elsif (/^--with-zlib-include=(.*)$/)
{
- $withargs{"zlib-include"}="-I$1";
+ $withargs{zlib_include}="-I$1";
}
elsif (/^--with-fipslibdir=(.*)$/)
{
my ($ALGO, $algo);
($ALGO = $algo = $_) =~ tr/[\-a-z]/[_A-Z]/;
- if (/^asm$/ || /^err$/ || /^hw$/ || /^hw-/)
+ if (/^asm$/ || /^err$/ || /^hw$/ || /^hw-/ || /^async$/
+ || /^autoalginit/ || /^autoerrinit/)
{
push @{$config{openssl_other_defines}}, "OPENSSL_NO_$ALGO";
print " OPENSSL_NO_$ALGO";
# Allow environment CC to override compiler...
$target{cc} = $ENV{CC} || $target{cc};
-# For cflags and lflags, add the debug_ or release_ attributes
+# For cflags, lflags, plib_lflags and ex_libs, add the debug_ or release_
+# attributes.
# Do it in such a way that no spurious space is appended (hence the grep).
$config{cflags} = join(" ",
grep { $_ ne "" } ($target{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"}));
$target{ranlib} = $ENV{'RANLIB'} || $target{ranlib} || $default_ranlib;
$target{ar} = $ENV{'AR'} || "ar";
$target{build_scheme} = [ $target{build_scheme} ]
if ref($target{build_scheme}) ne "ARRAY";
+my ($builder, $builder_platform, @builder_opts) =
+ @{$target{build_scheme}};
+
# if $config{prefix}/lib$target{multilib} is not an existing directory, then
# assume that it's not searched by linker automatically, in
# which case adding $target{multilib} suffix causes more grief than
$config{cflags} .= "$exp_cflags";
-# '%' in $config{lflags} is used to split flags to "pre-" and post-flags
-my ($pre,$post)=split('%',$config{lflags});
-if (defined($post)) { $config{prelflags}=$pre; $config{lflags}=$post; }
-else { $config{prelflags}=""; $config{lflags}=$pre; }
-
if ($target =~ /^mingw/ && `$target{cc} --target-help 2>&1` !~ m/-mno-cygwin/m)
{
$config{cflags} =~ s/-mno-cygwin\s*//;
$config{cflags} = "$dso_cflags $config{cflags}";
}
-my $thread_cflags;
+my $thread_cflags = "";
my @thread_defines;
if ($target{thread_cflag} ne "(unknown)" && !$no_threads)
{
print "provide any system-specific compiler options\n";
exit(1);
}
- $thread_cflags="-DOPENSSL_THREADS $config{cflags}" ;
+ $thread_cflags="-DOPENSSL_THREADS" ;
push @thread_defines, "OPENSSL_THREADS";
}
else
{
- $thread_cflags="-DOPENSSL_THREADS $target{thread_cflag} $config{cflags}";
+ $thread_cflags="-DOPENSSL_THREADS $target{thread_cflag}";
push @thread_defines, "OPENSSL_THREADS";
-# my $def;
-# foreach $def (split ' ',$target{thread_cflag})
-# {
-# if ($def =~ s/^-D// && $def !~ /^_/)
-# {
-# push @thread_defines, "$def";
-# }
-# }
}
-$config{lflags}="$libs$config{lflags}" if ($libs ne "");
+$config{ex_libs}="$libs$config{ex_libs}" if ($libs ne "");
if ($no_asm)
{
$config{cflags}=~s/-D[BL]_ENDIAN// if ($config{fips});
- $thread_cflags=~s/-D[BL]_ENDIAN// if ($config{fips});
}
if ($threads)
{
- $config{cflags}=$thread_cflags;
+ $config{cflags} = "$thread_cflags $config{cflags}" if $thread_cflags;
push @{$config{openssl_thread_defines}}, @thread_defines;
}
$config{cflags} = "-DZLIB $config{cflags}";
if (defined($disabled{"zlib-dynamic"}))
{
- if (defined($withargs{"zlib-lib"}))
+ if (defined($withargs{zlib_lib}))
{
- $config{lflags} .= " -L" . $withargs{"zlib-lib"} . " -lz";
+ $config{ex_libs} .= " -L" . $withargs{zlib_lib} . " -lz";
}
else
{
- $config{lflags} .= " -lz";
+ $config{ex_libs} .= " -lz";
}
}
else
}
}
-if ($target{build_scheme}->[0] ne "mk1mf")
+if ($builder ne "mk1mf")
{
# add {no-}static-engine to options to allow mkdef.pl to work without extra arguments
if ($config{no_shared})
#
# Platform fix-ups
#
-if ($target =~ /-icc$/) # Intel C compiler
- {
- my $iccver=0;
- if (open(FD,"$target{cc} -V 2>&1 |"))
- {
- while(<FD>) { $iccver=$1 if (/Version ([0-9]+)\./); }
- close(FD);
- }
- if ($iccver>=8)
- {
- $config{cflags}=~s/-KPIC/-fPIC/;
- # Eliminate unnecessary dependency from libirc.a. This is
- # essential for shared library support, as otherwise
- # apps/openssl can end up in endless loop upon startup...
- $config{cflags}.=" -Dmemcpy=__builtin_memcpy -Dmemset=__builtin_memset";
- }
- if ($iccver>=9)
- {
- $config{lflags}.=" -i-static";
- $config{lflags}=~s/-no_cpprt/-no-cpprt/;
- }
- if ($iccver>=10)
- {
- $config{lflags}=~s/-i-static/-static-intel/;
- }
- if ($iccver>=11)
- {
- $config{cflags}.=" -no-intel-extensions"; # disable Cilk
- $config{lflags}=~s/-no-cpprt/-no-cxxlib/;
- }
- }
-
# Unlike other OSes (like Solaris, Linux, Tru64, IRIX) BSD run-time
# linkers (tested OpenBSD, NetBSD and FreeBSD) "demand" RPATH set on
# .so objects. Apparently application RPATH is not global and does
}
if (!$no_asm) {
- $target{cpuid_obj}=$table{BASE}->{cpuid_obj} if ($config{processor} eq "386");
- $target{cpuid_obj}.=" uplink.o uplink-x86.o" if ($config{cflags} =~ /-DOPENSSL_USE_APPLINK/);
+ $target{cpuid_asm_src}=$table{BASE}->{cpuid_asm_src} if ($config{processor} eq "386");
+ $target{cpuid_asm_src}.=" uplink.c uplink-x86.s" if ($config{cflags} =~ /-DOPENSSL_USE_APPLINK/);
- $target{bn_obj} =~ s/\w+-gf2m.o// if (defined($disabled{ec2m}));
+ $target{bn_asm_src} =~ s/\w+-gf2m.c// if (defined($disabled{ec2m}));
# bn-586 is the only one implementing bn_*_part_words
- $config{cflags}.=" -DOPENSSL_BN_ASM_PART_WORDS" if ($target{bn_obj} =~ /bn-586/);
- $config{cflags}.=" -DOPENSSL_IA32_SSE2" if (!$no_sse2 && $target{bn_obj} =~ /86/);
+ $config{cflags}.=" -DOPENSSL_BN_ASM_PART_WORDS" if ($target{bn_asm_src} =~ /bn-586/);
+ $config{cflags}.=" -DOPENSSL_IA32_SSE2" if (!$no_sse2 && $target{bn_asm_src} =~ /86/);
- $config{cflags}.=" -DOPENSSL_BN_ASM_MONT" if ($target{bn_obj} =~ /-mont/);
- $config{cflags}.=" -DOPENSSL_BN_ASM_MONT5" if ($target{bn_obj} =~ /-mont5/);
- $config{cflags}.=" -DOPENSSL_BN_ASM_GF2m" if ($target{bn_obj} =~ /-gf2m/);
+ $config{cflags}.=" -DOPENSSL_BN_ASM_MONT" if ($target{bn_asm_src} =~ /-mont/);
+ $config{cflags}.=" -DOPENSSL_BN_ASM_MONT5" if ($target{bn_asm_src} =~ /-mont5/);
+ $config{cflags}.=" -DOPENSSL_BN_ASM_GF2m" if ($target{bn_asm_src} =~ /-gf2m/);
if ($config{fips}) {
push @{$config{openssl_other_defines}}, "OPENSSL_FIPS";
}
- if ($target{sha1_obj} =~ /\.o$/) {
- $config{cflags}.=" -DSHA1_ASM" if ($target{sha1_obj} =~ /sx86/ || $target{sha1_obj} =~ /sha1/);
- $config{cflags}.=" -DSHA256_ASM" if ($target{sha1_obj} =~ /sha256/);
- $config{cflags}.=" -DSHA512_ASM" if ($target{sha1_obj} =~ /sha512/);
- if ($target{sha1_obj} =~ /sse2/) {
- if ($no_sse2) {
- $target{sha1_obj} =~ s/\S*sse2\S+//;
- } elsif ($config{cflags} !~ /OPENSSL_IA32_SSE2/) {
- $config{cflags}.=" -DOPENSSL_IA32_SSE2";
- }
- }
+ if ($target{sha1_asm_src}) {
+ $config{cflags}.=" -DSHA1_ASM" if ($target{sha1_asm_src} =~ /sx86/ || $target{sha1_asm_src} =~ /sha1/);
+ $config{cflags}.=" -DSHA256_ASM" if ($target{sha1_asm_src} =~ /sha256/);
+ $config{cflags}.=" -DSHA512_ASM" if ($target{sha1_asm_src} =~ /sha512/);
}
- if ($target{md5_obj} =~ /\.o$/) {
+ if ($target{md5_asm_src}) {
$config{cflags}.=" -DMD5_ASM";
}
- $target{cast_obj}=$table{BASE}->{cast_obj} if (!$config{no_shared}); # CAST assembler is not PIC
- if ($target{rmd160_obj} =~ /\.o$/) {
+ $target{cast_asm_src}=$table{BASE}->{cast_asm_src} if (!$config{no_shared}); # CAST assembler is not PIC
+ if ($target{rmd160_asm_src}) {
$config{cflags}.=" -DRMD160_ASM";
}
- if ($target{aes_obj} =~ /\.o$/) {
- $config{cflags}.=" -DAES_ASM" if ($target{aes_obj} =~ m/\baes-/);;
- # aes-ctr.o is not a real file, only indication that assembler
+ if ($target{aes_asm_src}) {
+ $config{cflags}.=" -DAES_ASM" if ($target{aes_asm_src} =~ m/\baes-/);;
+ # aes-ctr.fake is not a real file, only indication that assembler
# module implements AES_ctr32_encrypt...
- $config{cflags}.=" -DAES_CTR_ASM" if ($target{aes_obj} =~ s/\s*aes-ctr\.o//);
- # aes-xts.o indicates presence of AES_xts_[en|de]crypt...
- $config{cflags}.=" -DAES_XTS_ASM" if ($target{aes_obj} =~ s/\s*aes-xts\.o//);
- $target{aes_obj} =~ s/\s*(vpaes|aesni)-x86\.o//g if ($no_sse2);
- $config{cflags}.=" -DVPAES_ASM" if ($target{aes_obj} =~ m/vpaes/);
- $config{cflags}.=" -DBSAES_ASM" if ($target{aes_obj} =~ m/bsaes/);
+ $config{cflags}.=" -DAES_CTR_ASM" if ($target{aes_asm_src} =~ s/\s*aes-ctr\.fake//);
+ # aes-xts.fake indicates presence of AES_xts_[en|de]crypt...
+ $config{cflags}.=" -DAES_XTS_ASM" if ($target{aes_asm_src} =~ s/\s*aes-xts\.fake//);
+ $target{aes_asm_src} =~ s/\s*(vpaes|aesni)-x86\.s//g if ($no_sse2);
+ $config{cflags}.=" -DVPAES_ASM" if ($target{aes_asm_src} =~ m/vpaes/);
+ $config{cflags}.=" -DBSAES_ASM" if ($target{aes_asm_src} =~ m/bsaes/);
}
- if ($target{wp_obj} =~ /mmx/ && $config{processor} eq "386") {
- $target{wp_obj}=$table{BASE}->{wp_obj};
- } elsif (!$disabled{"whirlpool"}) {
- $config{cflags}.=" -DWHIRLPOOL_ASM";
+ if ($target{wp_asm_src} =~ /mmx/) {
+ if ($config{processor} eq "386") {
+ $target{wp_asm_src}=$table{BASE}->{wp_asm_src};
+ } elsif (!$disabled{"whirlpool"}) {
+ $config{cflags}.=" -DWHIRLPOOL_ASM";
+ }
}
- if ($target{modes_obj} =~ /ghash-/) {
+ if ($target{modes_asm_src} =~ /ghash-/) {
$config{cflags}.=" -DGHASH_ASM";
}
- if ($target{ec_obj} =~ /ecp_nistz256/) {
+ if ($target{ec_asm_src} =~ /ecp_nistz256/) {
$config{cflags}.=" -DECP_NISTZ256_ASM";
}
- if ($target{poly1305_obj} =~ /\.o$/) {
+ if ($target{poly1305_asm_src} ne "") {
$config{cflags}.=" -DPOLY1305_ASM";
}
}
-$config{makedepprog} = "makedepend";
-if ($target{cc} eq "gcc" || ($target{cc} eq 'cc' && $config{target} =~ /darwin/)) {
- $config{makedepprog} = $target{cc};
+# Is the compiler gcc or clang? $ecc is used below to see if error-checking
+# can be turned on.
+my $ecc = $target{cc};
+my $ccpcc = "$config{cross_compile_prefix}$target{cc}";
+$config{makedepprog} = 'makedepend';
+open(PIPE, "$ccpcc --version 2>&1 | head -2 |");
+while ( <PIPE> ) {
+ $config{makedepprog} = $ccpcc if /clang|gcc/;
+ $ecc = "clang" if /clang/;
+ $ecc = "gcc" if /gcc/;
}
+close(PIPE);
+
$config{depflags} =~ s/^\s*//;
# Deal with bn_ops ###################################################
-$config{des_ptr} =0;
-$config{des_risc1} =0;
-$config{des_risc2} =0;
-$config{des_unroll} =0;
$config{bn_ll} =0;
-$config{rc4_idx} =0;
-$config{bf_ptr} =0;
$config{export_var_as_fn} =0;
my $def_int="unsigned int";
$config{rc4_int} =$def_int;
-$config{rc4_chunk} ="";
-$config{md2_int} =$def_int;
-$config{idea_int} =$def_int;
-$config{rc2_int} =$def_int;
-($config{b64l},$config{b64},$config{b32},$config{b16},$config{b8})=(0,0,1,0,0);
-
-$config{des_int} = "unsigned long";
+($config{b64l},$config{b64},$config{b32})=(0,0,1);
+my $count = 0;
foreach (sort split(/\s+/,$target{bn_ops})) {
- $config{des_ptr}=1 if /DES_PTR/;
- $config{des_risc1}=1 if /DES_RISC1/;
- $config{des_risc2}=1 if /DES_RISC2/;
- $config{des_unroll}=1 if /DES_UNROLL/;
- $config{des_int}="unsigned int" if /DES_INT/;
- $config{bn_ll}=1 if /BN_LLONG/;
- $config{rc4_int}="unsigned char" if /RC4_CHAR/;
- $config{rc4_int}="unsigned long" if /RC4_LONG/;
- $config{rc4_idx}=1 if /RC4_INDEX/;
- $config{rc4_chunk}="unsigned long" if /RC4_CHUNK/;
- $config{rc4_chunk}="unsigned long long" if /RC4_CHUNK_LL/;
- $config{md2_int}="unsigned char" if /MD2_CHAR/;
- $config{md2_int}="unsigned long" if /MD2_LONG/;
- $config{idea_int}="unsigned char" if /IDEA_CHAR/;
- $config{idea_int}="unsigned long" if /IDEA_LONG/;
- $config{rc2_int}="unsigned char" if /RC2_CHAR/;
- $config{rc2_int}="unsigned long" if /RC2_LONG/;
- $config{bf_ptr}=1 if $_ eq "BF_PTR";
- $config{bf_ptr}=2 if $_ eq "BF_PTR2";
- ($config{b64l},$config{b64},$config{b32},$config{b16},$config{b8})
- =(0,1,0,0,0) if /SIXTY_FOUR_BIT/;
- ($config{b64l},$config{b64},$config{b32},$config{b16},$config{b8})
- =(1,0,0,0,0) if /SIXTY_FOUR_BIT_LONG/;
- ($config{b64l},$config{b64},$config{b32},$config{b16},$config{b8})
- =(0,0,1,0,0) if /THIRTY_TWO_BIT/;
- ($config{b64l},$config{b64},$config{b32},$config{b16},$config{b8})
- =(0,0,0,1,0) if /SIXTEEN_BIT/;
- ($config{b64l},$config{b64},$config{b32},$config{b16},$config{b8})
- =(0,0,0,0,1) if /EIGHT_BIT/;
- $config{export_var_as_fn}=1 if /EXPORT_VAR_AS_FN/;
+ $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/;
+ $config{export_var_as_fn}=1 if $_ eq 'EXPORT_VAR_AS_FN';
+ $config{bn_ll}=1 if $_ eq 'BN_LLONG';
+ $config{rc4_int}="unsigned char" if $_ eq 'RC4_CHAR';
+ ($config{b64l},$config{b64},$config{b32})
+ =(0,1,0) if $_ eq 'SIXTY_FOUR_BIT';
+ ($config{b64l},$config{b64},$config{b32})
+ =(1,0,0) if $_ eq 'SIXTY_FOUR_BIT_LONG';
+ ($config{b64l},$config{b64},$config{b32})
+ =(0,0,1) if $_ eq 'THIRTY_TWO_BIT';
}
+die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n"
+ if $count > 1;
# Hack cflags for better warnings (dev option) #######################
$config{cflags} .= " $apiflag";
}
-my $ecc = $target{cc};
-$ecc = "clang" if `$target{cc} --version 2>&1` =~ /clang/;
-
if ($strict_warnings)
{
my $wopt;
- die "ERROR --strict-warnings requires gcc or clang" unless ($ecc =~ /gcc(-\d(\.\d)*)?$/ or $ecc =~ /clang$/);
+ die "ERROR --strict-warnings requires gcc or clang"
+ unless $ecc eq 'gcc' || $ecc eq 'clang';
foreach $wopt (split /\s+/, $gcc_devteam_warn)
{
$config{cflags} .= " $wopt" unless ($config{cflags} =~ /(^|\s)$wopt(\s|$)/)
}
if ($target =~ /^BSD-/)
{
- $config{lflags} .= " -lexecinfo";
+ $config{ex_libs} .= " -lexecinfo";
}
}
}
+# If we use the unified build, collect information from build.info files
+my %unified_info = ();
+
+if ($builder eq "unified") {
+ # Store the name of the template file we will build the build file from
+ # in %config. This may be useful for the build file itself.
+ my $build_file_template =
+ catfile($srcdir, "Configurations",
+ $builder_platform."-".$target{build_file}.".tmpl");
+ $build_file_template =
+ catfile($srcdir, "Configurations", $target{build_file}.".tmpl")
+ if (! -f $build_file_template);
+ $config{build_file_template} = $build_file_template;
+
+ use lib catdir(dirname(__FILE__),"util");
+ use with_fallback qw(Text::Template);
+
+ sub cleandir {
+ my $dir = shift;
+ my $base = shift || ".";
+
+ # Make sure the directories we're building in exists
+ mkpath($dir);
+
+ my $res = abs2rel(absolutedir($dir), rel2abs($base));
+ #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n";
+ return $res;
+ }
+
+ sub cleanfile {
+ my $file = shift;
+ my $base = shift || ".";
+ my $d = dirname($file);
+ my $f = basename($file);
+
+ # Make sure the directories we're building in exists
+ mkpath($d);
+
+ my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($base));
+ #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n";
+ return $res;
+ }
+
+ my @build_infos = ( [ ".", "build.info" ] );
+ foreach (@{$config{dirs}}) {
+ push @build_infos, [ $_, "build.info" ]
+ if (-f catfile($srcdir, $_, "build.info"));
+ }
+ foreach (@{$config{sdirs}}) {
+ push @build_infos, [ catdir("crypto", $_), "build.info" ]
+ if (-f catfile($srcdir, "crypto", $_, "build.info"));
+ }
+ foreach (@{$config{engdirs}}) {
+ push @build_infos, [ catdir("engines", $_), "build.info" ]
+ if (-f catfile($srcdir, "engines", $_, "build.info"));
+ }
+
+ foreach (@build_infos) {
+ my $sourced = catdir($srcdir, $_->[0]);
+ my $buildd = catdir($blddir, $_->[0]);
+
+ mkpath($buildd);
+
+ my $f = $_->[1];
+ # The basic things we're trying to build
+ my @programs = ();
+ my @libraries = ();
+ my @engines = ();
+ my @scripts = ();
+ my @extra = ();
+ my @intermediates = ();
+ my @rawlines = ();
+
+ my %ordinals = ();
+ my %sources = ();
+ my %includes = ();
+ my %depends = ();
+ my %renames = ();
+ my %sharednames = ();
+
+ my $template = Text::Template->new(TYPE => 'FILE',
+ SOURCE => catfile($sourced, $f));
+ die "Something went wrong with $sourced/$f: $!\n" unless $template;
+ my @text =
+ split /^/m,
+ $template->fill_in(HASH => { config => \%config,
+ target => \%target,
+ builddir => abs2rel($buildd, $blddir),
+ sourcedir => abs2rel($sourced, $blddir),
+ buildtop => abs2rel($blddir, $blddir),
+ sourcetop => abs2rel($srcdir, $blddir) },
+ DELIMITERS => [ "{-", "-}" ]);
+
+ # The top item of this stack has the following values
+ # -2 positive already run and we found ELSE (following ELSIF should fail)
+ # -1 positive already run (skip until ENDIF)
+ # 0 negatives so far (if we're at a condition, check it)
+ # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF)
+ # 2 positive ELSE (following ELSIF should fail)
+ my @skip = ();
+ collect_information(
+ collect_from_array([ @text ],
+ qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
+ $l1 =~ s/\\$//; $l1.$l2 }),
+ # Info we're looking for
+ qr/^\s*IF\[((?:\\.|[^\\\]])*)\]\s*$/
+ => sub { push @skip, !! $1; },
+ qr/^\s*ELSIF\[((?:\\.|[^\\\]])*)\]\s*$/
+ => sub { die "ELSIF out of scope" if ! @skip;
+ die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
+ $skip[$#skip] = -1 if $skip[$#skip] != 0;
+ $skip[$#skip] = !! $1
+ if $skip[$#skip] == 0; },
+ qr/^\s*ELSE\s*$/
+ => sub { die "ELSE out of scope" if ! @skip;
+ $skip[$#skip] = -2 if $skip[$#skip] != 0;
+ $skip[$#skip] = 2 if $skip[$#skip] == 0; },
+ qr/^\s*ENDIF\s*$/
+ => sub { die "ENDIF out of scope" if ! @skip;
+ pop @skip; },
+ qr/^\s*PROGRAMS\s*=\s*(.*)\s*$/
+ => sub { push @programs, split(/\s+/, $1)
+ if !@skip || $skip[$#skip] > 0 },
+ qr/^\s*LIBS\s*=\s*(.*)\s*$/
+ => sub { push @libraries, split(/\s+/, $1)
+ if !@skip || $skip[$#skip] > 0 },
+ qr/^\s*ENGINES\s*=\s*(.*)\s*$/
+ => sub { push @engines, split(/\s+/, $1)
+ if !@skip || $skip[$#skip] > 0 },
+ qr/^\s*SCRIPTS\s*=\s*(.*)\s*$/
+ => sub { push @scripts, split(/\s+/, $1)
+ if !@skip || $skip[$#skip] > 0 },
+ qr/^\s*EXTRA\s*=\s*(.*)\s*$/
+ => sub { push @extra, split(/\s+/, $1)
+ if !@skip || $skip[$#skip] > 0 },
+
+ qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/,
+ => sub { push @{$ordinals{$1}}, split(/\s+/, $2)
+ if !@skip || $skip[$#skip] > 0 },
+ qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
+ => sub { push @{$sources{$1}}, split(/\s+/, $2)
+ if !@skip || $skip[$#skip] > 0 },
+ qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
+ => sub { push @{$includes{$1}}, split(/\s+/, $2)
+ if !@skip || $skip[$#skip] > 0 },
+ qr/^\s*DEPEND\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
+ => sub { push @{$depends{$1}}, split(/\s+/, $2)
+ if !@skip || $skip[$#skip] > 0 },
+ qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
+ => sub { push @{$renames{$1}}, split(/\s+/, $2)
+ if !@skip || $skip[$#skip] > 0 },
+ qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
+ => sub { push @{$sharednames{$1}}, split(/\s+/, $2)
+ if !@skip || $skip[$#skip] > 0 },
+ qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/
+ => sub {
+ my $lineiterator = shift;
+ my $target_kind = $1;
+ while (defined $lineiterator->()) {
+ chomp;
+ if (/^\s*ENDRAW\[((?:\\.|[^\\\]])+)\]\s*$/) {
+ die "ENDRAW doesn't match BEGINRAW"
+ if $1 ne $target_kind;
+ last;
+ }
+ next if @skip && $skip[$#skip] <= 0;
+ push @rawlines, $_
+ if ($target_kind eq $target{build_file}
+ || $target_kind eq $target{build_file}."(".$builder_platform.")");
+ }
+ },
+ qr/^(?:#.*|\s*)$/ => sub { },
+ "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" }
+ );
+ die "runaway IF?" if (@skip);
+
+ foreach (keys %renames) {
+ die "$_ renamed to more than one thing: "
+ ,join(" ", @{$renames{$_}}),"\n"
+ if scalar @{$renames{$_}} > 1;
+ my $dest = cleanfile(catfile($buildd, $_), $blddir);
+ my $to = cleanfile(catfile($buildd, $renames{$_}->[0]), $blddir);
+ die "$dest renamed to more than one thing: "
+ ,$unified_info{rename}->{$dest}, $to
+ unless !defined($unified_info{rename}->{$dest})
+ or $unified_info{rename}->{$dest} eq $to;
+ $unified_info{rename}->{$dest} = $to;
+ }
+
+ foreach (@programs) {
+ my $program = cleanfile(catfile($buildd, $_), $blddir);
+ if ($unified_info{rename}->{$program}) {
+ $program = $unified_info{rename}->{$program};
+ }
+ $unified_info{programs}->{$program} = 1;
+ }
+
+ foreach (@libraries) {
+ my $library = cleanfile(catfile($buildd, $_), $blddir);
+ if ($unified_info{rename}->{$library}) {
+ $library = $unified_info{rename}->{$library};
+ }
+ $unified_info{libraries}->{$library} = 1;
+ }
+
+ die <<"EOF" if $config{no_shared} && scalar @engines;
+ENGINES can only be used if configured with 'shared'.
+This is usually a fault in a build.info file.
+EOF
+ foreach (@engines) {
+ my $library = cleanfile(catfile($buildd, $_), $blddir);
+ if ($unified_info{rename}->{$library}) {
+ $library = $unified_info{rename}->{$library};
+ }
+ $unified_info{engines}->{$library} = 1;
+ }
+
+ foreach (@scripts) {
+ my $script = cleanfile(catfile($buildd, $_), $blddir);
+ if ($unified_info{rename}->{$script}) {
+ $script = $unified_info{rename}->{$script};
+ }
+ $unified_info{scripts}->{$script} = 1;
+ }
+
+ foreach (@extra) {
+ my $extra = cleanfile(catfile($buildd, $_), $blddir);
+ $unified_info{extra}->{$extra} = 1;
+ }
+
+ push @{$unified_info{rawlines}}, @rawlines;
+
+ if (!$config{no_shared}) {
+ # Check sharednames.
+ foreach (keys %sharednames) {
+ my $dest = cleanfile(catfile($buildd, $_), $blddir);
+ if ($unified_info{rename}->{$dest}) {
+ $dest = $unified_info{rename}->{$dest};
+ }
+ die "shared_name for $dest with multiple values: "
+ ,join(" ", @{$sharednames{$_}}),"\n"
+ if scalar @{$sharednames{$_}} > 1;
+ my $to = cleanfile(catfile($buildd, $sharednames{$_}->[0]),
+ $blddir);
+ die "shared_name found for a library $dest that isn't defined\n"
+ unless $unified_info{libraries}->{$dest};
+ die "shared_name for $dest with multiple values: "
+ ,$unified_info{sharednames}->{$dest}, ", ", $to
+ unless !defined($unified_info{sharednames}->{$dest})
+ or $unified_info{sharednames}->{$dest} eq $to;
+ $unified_info{sharednames}->{$dest} = $to;
+ }
+
+ # Additionally, we set up sharednames for libraries that don't
+ # have any, as themselves.
+ foreach (keys %{$unified_info{libraries}}) {
+ if (!defined $unified_info{sharednames}->{$_}) {
+ $unified_info{sharednames}->{$_} = $_
+ }
+ }
+ }
+
+ foreach (keys %ordinals) {
+ my $dest = $_;
+ my $ddest = cleanfile(catfile($buildd, $_), $blddir);
+ if ($unified_info{rename}->{$ddest}) {
+ $ddest = $unified_info{rename}->{$ddest};
+ }
+ foreach (@{$ordinals{$dest}}) {
+ my %known_ordinals =
+ (
+ crypto =>
+ cleanfile(catfile($sourced, "util", "libeay.num"), $blddir),
+ ssl =>
+ cleanfile(catfile($sourced, "util", "ssleay.num"), $blddir)
+ );
+ my $o = $known_ordinals{$_};
+ die "Ordinals for $ddest defined more than once\n"
+ if $unified_info{ordinals}->{$ddest};
+ $unified_info{ordinals}->{$ddest} = [ $_, $o ];
+ }
+ }
+
+ foreach (keys %sources) {
+ my $dest = $_;
+ my $ddest = cleanfile(catfile($buildd, $_), $blddir);
+ if ($unified_info{rename}->{$ddest}) {
+ $ddest = $unified_info{rename}->{$ddest};
+ }
+ foreach (@{$sources{$dest}}) {
+ my $s = cleanfile(catfile($sourced, $_), $blddir);
+
+ # If it isn't in the source tree, we assume it's generated
+ # in the build tree
+ if (! -f $s) {
+ $s = cleanfile(catfile($buildd, $_), $blddir);
+ }
+ # We recognise C and asm files
+ if ($s =~ /\.[csS]\b$/) {
+ (my $o = $_) =~ s/\.[csS]\b$/.o/;
+ $o = cleanfile(catfile($buildd, $o), $blddir);
+ $unified_info{sources}->{$ddest}->{$o} = 1;
+ $unified_info{sources}->{$o}->{$s} = 1;
+ } else {
+ $unified_info{sources}->{$ddest}->{$s} = 1;
+ }
+ }
+ }
+
+ foreach (keys %depends) {
+ my $dest = $_;
+ my $ddest = cleanfile(catfile($buildd, $_), $blddir);
+ if ($unified_info{rename}->{$ddest}) {
+ $ddest = $unified_info{rename}->{$ddest};
+ }
+ foreach (@{$depends{$dest}}) {
+ my $d = cleanfile(catfile($sourced, $_), $blddir);
+
+ # If it isn't found in the source, let's assume it's generated
+ # and that the Makefile template has the lines
+ if (! -f $d) {
+ $d = cleanfile(catfile($buildd, $_), $blddir);
+ }
+ # Take note if the file to depend on is being renamed
+ if ($unified_info{rename}->{$d}) {
+ $d = $unified_info{rename}->{$d};
+ }
+ $unified_info{depends}->{$ddest}->{$d} = 1;
+ # If we depend on a header file, let's make sure it
+ # can get included
+ if ($d =~ /\.h$/) {
+ my $i = dirname($d);
+ push @{$unified_info{includes}->{$ddest}}, $i
+ unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}};
+ }
+ }
+ }
+
+ foreach (keys %includes) {
+ my $dest = $_;
+ my $ddest = cleanfile(catfile($buildd, $_), $blddir);
+ if ($unified_info{rename}->{$ddest}) {
+ $ddest = $unified_info{rename}->{$ddest};
+ }
+ foreach (@{$includes{$dest}}) {
+ my $i = cleandir(catdir($sourced, $_), $blddir);
+ push @{$unified_info{includes}->{$ddest}}, $i
+ unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}};
+ }
+ }
+ }
+
+ ### Make unified_info a bit more efficient
+ # One level structures
+ foreach (("programs", "libraries", "engines", "scripts", "extra")) {
+ $unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
+ }
+ # Two level structures
+ foreach my $l1 (("sources", "ldadd", "depends")) {
+ foreach my $l2 (sort keys %{$unified_info{$l1}}) {
+ $unified_info{$l1}->{$l2} =
+ [ sort keys %{$unified_info{$l1}->{$l2}} ];
+ }
+ }
+}
+
+# For the schemes that need it, we provide the old *_obj configs
+# from the *_asm_obj ones
+foreach (grep /_asm_src$/, keys %target) {
+ my $src = $_;
+ (my $obj = $_) =~ s/_asm_src$/_obj/;
+ ($target{$obj} = $target{$src}) =~ s/\.[csS]\b/.o/g;
+}
+
# Write down our configuration where it fits #########################
open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n";
use Exporter;
#use vars qw(\@ISA \@EXPORT);
our \@ISA = qw(Exporter);
-our \@EXPORT = qw(\%config \%target %withargs);
+our \@EXPORT = qw(\%config \%target %withargs %unified_info);
EOF
print OUT "our %config = (\n";
print OUT <<"EOF";
);
-1;
EOF
+if ($builder eq "unified") {
+ my $recurse;
+ $recurse = sub {
+ my $indent = shift;
+ foreach (@_) {
+ if (ref $_ eq "ARRAY") {
+ print OUT " "x$indent, "[\n";
+ foreach (@$_) {
+ $recurse->($indent + 4, $_);
+ }
+ print OUT " "x$indent, "],\n";
+ } elsif (ref $_ eq "HASH") {
+ my %h = %$_;
+ print OUT " "x$indent, "{\n";
+ foreach (sort keys %h) {
+ if (ref $h{$_} eq "") {
+ print OUT " "x($indent + 4), quotify("perl", $_), " => ", quotify("perl", $h{$_}), ",\n";
+ } else {
+ print OUT " "x($indent + 4), quotify("perl", $_), " =>\n";
+ $recurse->($indent + 8, $h{$_});
+ }
+ }
+ print OUT " "x$indent, "},\n";
+ } else {
+ print OUT " "x$indent, quotify("perl", $_), ",\n";
+ }
+ }
+ };
+ print OUT "our %unified_info = (\n";
+ foreach (sort keys %unified_info) {
+ if (ref $unified_info{$_} eq "") {
+ print OUT " "x4, quotify("perl", $_), " => ", quotify("perl", $unified_info{$_}), ",\n";
+ } else {
+ print OUT " "x4, quotify("perl", $_), " =>\n";
+ $recurse->(8, $unified_info{$_});
+ }
+ }
+ print OUT <<"EOF";
+);
+
+EOF
+}
+print OUT "1;\n";
close(OUT);
-print "IsMK1MF =", ($target{build_scheme}->[0] eq "mk1mf" ? "yes" : "no"), "\n";
+die <<"EOF" if $builder ne "unified" && $srcdir ne $blddir;
+
+***** Trying building anywhere else than in the source tree will not
+***** work for target $config{target}. To make it possible, it needs
+***** to use the "unified" build scheme.
+
+EOF
+
+print "IsMK1MF =", ($builder eq "mk1mf" ? "yes" : "no"), "\n";
print "CC =$target{cc}\n";
print "CFLAG =$config{cflags}\n";
-print "EX_LIBS =$config{lflags}\n";
+print "LFLAG =$config{lflags}\n";
+print "PLIB_LFLAG =$config{plib_lflags}\n";
+print "EX_LIBS =$config{ex_libs}\n";
print "CPUID_OBJ =$target{cpuid_obj}\n";
print "BN_ASM =$target{bn_obj}\n";
print "EC_ASM =$target{ec_obj}\n";
print "SIXTY_FOUR_BIT_LONG mode\n" if $config{b64l};
print "SIXTY_FOUR_BIT mode\n" if $config{b64};
print "THIRTY_TWO_BIT mode\n" if $config{b32};
-print "SIXTEEN_BIT mode\n" if $config{b16};
-print "EIGHT_BIT mode\n" if $config{b8};
-print "DES_PTR used\n" if $config{des_ptr};
-print "DES_RISC1 used\n" if $config{des_risc1};
-print "DES_RISC2 used\n" if $config{des_risc2};
-print "DES_UNROLL used\n" if $config{des_unroll};
-print "DES_INT used\n" if $config{des_int} =~ / int$/;
print "BN_LLONG mode\n" if $config{bn_ll};
print "RC4 uses $config{rc4_int}\n" if $config{rc4_int} != $def_int;
-print "RC4_INDEX mode\n" if $config{rc4_idx};
-print "RC4_CHUNK is undefined\n" unless $config{rc4_chunk};
-print "RC4_CHUNK is $config{rc4_chunk}\n" if $config{rc4_chunk};
-print "MD2 uses $config{md2_int}\n" if $config{md2_int} != $def_int;
-print "IDEA uses $config{idea_int}\n" if $config{idea_int} != $def_int;
-print "RC2 uses $config{rc2_int}\n" if $config{rc2_int} != $def_int;
-print "BF_PTR used\n" if $config{bf_ptr} == 1;
-print "BF_PTR2 used\n" if $config{bf_ptr} == 2;
-
-run_dofile("$Makefile.in","$Makefile");
-
-run_dofile("include/openssl/opensslconf.h.in", "include/openssl/opensslconf.h");
-
-foreach my $alg ( 'bf', 'bn', 'des', 'rc4' ) {
- run_dofile("crypto/include/internal/${alg}_conf.h.in",
- "crypto/include/internal/${alg}_conf.h");
+
+mkpath(catdir($blddir, "include/openssl"));
+run_dofile(catfile($blddir, "include/openssl/opensslconf.h"),
+ catfile($srcdir, "include/openssl/opensslconf.h.in"));
+
+mkpath(catdir($blddir, "crypto/include/internal"));
+foreach my $alg ( 'bn' ) {
+ run_dofile(catfile($blddir, "crypto/include/internal/${alg}_conf.h"),
+ catfile($srcdir, "crypto/include/internal/${alg}_conf.h.in"));
}
-# Copy all Makefile.in to Makefile (except top-level)
-use File::Find;
-use IO::File;
-find(sub {
- return if ($_ ne "Makefile.in" || $File::Find::dir eq ".");
- my $in = IO::File->new($_, "r") or
- die sprintf "Error reading Makefile.in in %s: !$\n",
- $File::Find::dir;
- my $out = IO::File->new("Makefile", "w") or
- die sprintf "Error writing Makefile in %s: !$\n",
- $File::Find::dir;
- print $out "# Generated from $_, do not edit\n";
- while (my $line = <$in>) { print $out $line }
- $in->close() or
- die sprintf "Error reading Makefile.in in %s: !$\n",
- $File::Find::dir;
- $out->close() or
- die sprintf "Error writing Makefile in %s: !$\n",
- $File::Find::dir;
- }, ".");
+###
+### When the old "unixmake" scheme goes away, so does this function
+###
+sub build_Makefile {
+ run_dofile("Makefile","Makefile.in");
+
+ # Copy all Makefile.in to Makefile (except top-level)
+ use File::Find;
+ use IO::File;
+ find(
+ {
+ preprocess => sub {
+ grep(!/^\./, @_);
+ },
+ wanted => sub {
+ return if ($_ ne "Makefile.in" || $File::Find::dir eq ".");
+ my $in = IO::File->new($_, "r") or
+ die sprintf "Error reading Makefile.in in %s: !$\n",
+ $File::Find::dir;
+ my $out = IO::File->new("Makefile", "w") or
+ die sprintf "Error writing Makefile in %s: !$\n",
+ $File::Find::dir;
+ print $out "# Generated from $_, do not edit\n";
+ while (my $line = <$in>) { print $out $line }
+ $in->close() or
+ die sprintf "Error reading Makefile.in in %s: !$\n",
+ $File::Find::dir;
+ $out->close() or
+ die sprintf "Error writing Makefile in %s: !$\n",
+ $File::Find::dir;
+ },
+ },
+ ".");
+}
my %builders = (
+ unified => sub {
+ run_dofile(catfile($blddir, $target{build_file}),
+ $config{build_file_template},
+ catfile($srcdir, "Configurations", "common.tmpl"));
+
+ my $make_command = "$make PERL=\'$config{perl}\'";
+ my $make_targets = "";
+ $make_targets .= " depend"
+ if $config{depflags} ne $default_depflags && $make_depend;
+ (system $make_command.$make_targets) == 0
+ or die "make $make_targets failed"
+ if $make_targets ne "";
+ if ($config{depflags} ne $default_depflags && !$make_depend) {
+ $warn_make_depend++;
+ }
+ },
unixmake => sub {
+ build_Makefile();
+
+ run_dofile("util/domd", "util/domd.in");
+ chmod 0755, "util/domd";
+
my $make_command = "$make PERL=\'$config{perl}\'";
my $make_targets = "";
- $make_targets .= " depend" if $config{depflags} ne $default_depflags && $make_depend;
- (system $make_command.$make_targets) == 0 or die "make $make_targets failed"
+ $make_targets .= " depend"
+ if $config{depflags} ne $default_depflags && $make_depend;
+ (system $make_command.$make_targets) == 0
+ or die "make $make_targets failed"
if $make_targets ne "";
+
if ($config{depflags} ne $default_depflags && !$make_depend) {
$warn_make_depend++;
}
},
mk1mf => sub {
+ my $platform = shift;
+ # The only reason we do this is to have something to build MINFO from
+ build_Makefile();
+
open (OUT,">crypto/buildinf.h") || die "Can't open buildinf.h";
printf OUT <<"EOF";
#ifndef MK1MF_BUILD
close(OUT);
# create the ms/version32.rc file if needed
- if (! grep /^netware/, @{$target{build_scheme}}) {
+ if ($platform eq "netware") {
my ($v1, $v2, $v3, $v4);
if ($config{version_num} =~ /^0x([0-9a-f]{1})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{1})L$/i) {
$v1=hex $1;
},
);
-my ($builder, @builder_opts) = @{$target{build_scheme}};
-$builders{$builder}->(@builder_opts);
+$builders{$builder}->($builder_platform, @builder_opts);
print <<"EOF";
sub run_dofile()
{
- my $in = shift;
my $out = shift;
+ my @templates = @_;
- # should we remove $out ?
- system("$config{perl} -I. -Mconfigdata util/dofile.pl -o\"Configure\" $in > $out.new");
+ unlink $out || warn "Can't remove $out, $!"
+ if -f $out;
+ foreach (@templates) {
+ die "Can't open $_, $!" unless -f $_;
+ }
+ my $cmd = "$config{perl} \"-I.\" \"-Mconfigdata\" $dofile -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\"";
+ #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
+ system($cmd);
exit 1 if $? != 0;
rename("$out.new", $out) || die "Can't rename $out.new, $!";
}
"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",
# Utility routines ###################################################
+# Makes a directory absolute and cleans out /../ in paths like foo/../bar
+# On some platforms, this uses rel2abs(), while on others, realpath() is used.
+# realpath() requires that at least all path components except the last is an
+# existing directory. On VMS, the last component of the directory spec must
+# exist.
+sub absolutedir {
+ my $dir = shift;
+
+ # realpath() is quite buggy on VMS. It uses LIB$FID_TO_NAME, which
+ # will return the volume name for the device, no matter what. Also,
+ # it will return an incorrect directory spec if the argument is a
+ # directory that doesn't exist.
+ if ($^O eq "VMS") {
+ return rel2abs($dir);
+ }
+
+ # We use realpath() on Unix, since no other will properly clean out
+ # a directory spec.
+ use Cwd qw/realpath/;
+
+ return realpath($dir);
+}
+
sub which
{
my($name)=@_;
map { $processor->($_); } @_;
}
-# collect_information($filename, $line_continue, $regexp => $CODEref, ...)
-# $filename is the file to read.
-# $line_continue is either undef (which is a noop), or two arguments, where
-# the first is a regexp detecting a line continuation ending, and the
-# following argument is a CODEref that takes care of concatenating two
-# lines.
+# collect_from_file($filename, $line_concat_cond_re, $line_concat)
+# $filename is a file name to read from
+# $line_concat_cond_re is a regexp detecting a line continuation ending
+# $line_concat is a CODEref that takes care of concatenating two lines
+sub collect_from_file {
+ my $filename = shift;
+ my $line_concat_cond_re = shift;
+ my $line_concat = shift;
+
+ open my $fh, $filename || die "unable to read $filename: $!\n";
+ return sub {
+ my $saved_line = "";
+ $_ = "";
+ while (<$fh>) {
+ chomp;
+ if (defined $line_concat) {
+ $_ = $line_concat->($saved_line, $_);
+ $saved_line = "";
+ }
+ if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
+ $saved_line = $_;
+ next;
+ }
+ return $_;
+ }
+ die "$filename ending with continuation line\n" if $_;
+ close $fh;
+ return undef;
+ }
+}
+
+# collect_from_array($array, $line_concat_cond_re, $line_concat)
+# $array is an ARRAYref of lines
+# $line_concat_cond_re is a regexp detecting a line continuation ending
+# $line_concat is a CODEref that takes care of concatenating two lines
+sub collect_from_array {
+ my $array = shift;
+ my $line_concat_cond_re = shift;
+ my $line_concat = shift;
+ my @array = (@$array);
+
+ return sub {
+ my $saved_line = "";
+ $_ = "";
+ while (defined($_ = shift @array)) {
+ chomp;
+ if (defined $line_concat) {
+ $_ = $line_concat->($saved_line, $_);
+ $saved_line = "";
+ }
+ if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
+ $saved_line = $_;
+ next;
+ }
+ return $_;
+ }
+ die "input text ending with continuation line\n" if $_;
+ return undef;
+ }
+}
+
+# collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...)
+# $lineiterator is a CODEref that delivers one line at a time.
# All following arguments are regex/CODEref pairs, where the regexp detects a
# line and the CODEref does something with the result of the regexp.
sub collect_information {
- my $filename = shift;
- my $line_continue_re = shift;
- my $line_concat = defined($line_continue_re) ? shift : undef;
+ my $lineiterator = shift;
my %collectors = @_;
- my $saved_line = "";
- open IN, $filename || die "unable to read $filename: $!\n";
- while(<IN>) {
- chomp;
- if (defined $line_concat) {
- $_ = $line_concat->($saved_line, $_);
- }
- if (defined $line_continue_re && /$line_continue_re/) {
- $saved_line = $_;
- next;
- }
- foreach my $re (keys %collectors) {
- if (/$re/) { $collectors{$re}->() };
- }
+ while(defined($_ = $lineiterator->())) {
+ chomp;
+ my $found = 0;
+ foreach my $re (keys %collectors) {
+ if ($re ne "OTHERWISE" && /$re/) {
+ $collectors{$re}->($lineiterator);
+ $found = 1;
+ };
+ }
+ if ($collectors{"OTHERWISE"}) {
+ $collectors{"OTHERWISE"}->($lineiterator, $_)
+ unless $found || !defined $collectors{"OTHERWISE"};
+ }
}
- close IN;
}