X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=Configure;h=3604ba4f73eaed8b89d8b4bb4dc7ac6c78a55bee;hp=215ffb87f2c7f300599f6e51a86b245163552d38;hb=216e8d91033d237880cff7da0d02d46d47bae41b;hpb=050a36a9a1af1e00003f76597df7cf9ff33f8101 diff --git a/Configure b/Configure index 215ffb87f2..3604ba4f73 100755 --- a/Configure +++ b/Configure @@ -14,7 +14,7 @@ use strict; use File::Basename; use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/; use File::Path qw/mkpath/; -use IPC::Cmd qw/can_run/; +use if $^O ne "VMS", 'File::Glob' => qw/glob/; # see INSTALL for instructions. @@ -79,7 +79,7 @@ my $usage="Usage: Configure [no- ...] [enable- ...] [-Dxxx] [-lx # RMD160_ASM use some extra ripemd160 assembler, # SHA256_ASM sha256_block is implemented in assembler # SHA512_ASM sha512_block is implemented in assembler -# AES_ASM ASE_[en|de]crypt is implemented in assembler +# AES_ASM AES_[en|de]crypt is implemented in assembler # Minimum warning options... any contributions to OpenSSL should at least get # past these. @@ -87,7 +87,7 @@ my $usage="Usage: Configure [no- ...] [enable- ...] [-Dxxx] [-lx # DEBUG_UNUSED enables __owur (warn unused result) checks. my $gcc_devteam_warn = "-DDEBUG_UNUSED" # -DPEDANTIC complements -pedantic and is meant to mask code that - # is not strictly standard-compliant and/or implementation-specifc, + # is not strictly standard-compliant and/or implementation-specific, # e.g. inline assembly, disregards to alignment requirements, such # that -pedantic would complain about. Incidentally -DPEDANTIC has # to be used even in sanitized builds, because sanitizer too is @@ -144,7 +144,7 @@ my $strict_warnings = 0; our $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT"; # -# API compability name to version number mapping. +# API compatibility name to version number mapping. # my $maxapi = "1.1.0"; # API for "no-deprecated" builds my $apitable = { @@ -211,7 +211,7 @@ die "erroneous version information in opensslv.h: ", # Collect target configurations my $pattern = catfile(dirname($0), "Configurations", "*.conf"); -foreach (sort glob($pattern) ) { +foreach (sort glob($pattern)) { &read_config($_); } @@ -224,7 +224,7 @@ if (defined $ENV{$local_config_envname}) { $pattern = catfile($ENV{$local_config_envname}, '*.conf'); } - foreach (sort glob($pattern) ) { + foreach (sort glob($pattern)) { &read_config($_); } } @@ -245,7 +245,7 @@ my $default_ranlib; $config{fips}=0; # Top level directories to build -$config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "tools" ]; +$config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "tools", "fuzz" ]; # crypto/ subdirectories to build $config{sdirs} = [ "objects", @@ -301,7 +301,8 @@ my @disablables = ( "engine", "err", "filenames", - "fuzz", + "fuzz-libfuzzer", + "fuzz-afl", "gost", "heartbeats", "hw(-.+)?", @@ -310,6 +311,7 @@ my @disablables = ( "md2", "md4", "mdc2", + "msan", "multiblock", "nextprotoneg", "ocb", @@ -323,7 +325,6 @@ my @disablables = ( "rc5", "rdrand", "rfc3779", - "ripemd", "rmd160", "scrypt", "sctp", @@ -354,19 +355,25 @@ foreach my $proto ((@tls, @dtls)) push(@disablables, "$proto-method"); } -my @deprecated_disablables = ( - "ssl2", - "buf-freelists", +my %deprecated_disablables = ( + "ssl2" => undef, + "buf-freelists" => undef, + "ripemd" => "rmd160" ); # All of the following is disabled by default (RC5 was enabled before 0.9.8): our %disabled = ( # "what" => "comment" "asan" => "default", + "crypto-mdebug" => "default", + "crypto-mdebug-backtrace" => "default", "ec_nistp_64_gcc_128" => "default", "egd" => "default", - "fuzz" => "default", + "fuzz-libfuzzer" => "default", + "fuzz-afl" => "default", + "heartbeats" => "default", "md2" => "default", + "msan" => "default", "rc5" => "default", "sctp" => "default", "ssl-trace" => "default", @@ -377,8 +384,6 @@ our %disabled = ( # "what" => "comment" "weak-ssl-ciphers" => "default", "zlib" => "default", "zlib-dynamic" => "default", - "crypto-mdebug" => "default", - "heartbeats" => "default", ); # Note: => pair form used for aesthetics, not to truly make a hash table @@ -432,10 +437,12 @@ my @disable_cascades = ( # no-autoalginit is only useful when building non-shared "autoalginit" => [ "shared", "apps" ], - "stdio" => [ "apps" ], + "stdio" => [ "apps", "capieng" ], "apps" => [ "tests" ], "comp" => [ "zlib" ], sub { !$disabled{"unit-test"} } => [ "heartbeats" ], + + sub { !$disabled{"msan"} } => [ "asm" ], ); # Avoid protocol support holes. Also disable all versions below N, if version @@ -460,17 +467,6 @@ while ((my $first, my $second) = (shift @list, shift @list)) { # To remove something from %disabled, use "enable-foo". # For symmetry, "disable-foo" is a synonym for "no-foo". -my @generated_headers = ( - "include/openssl/opensslconf.h", - "crypto/include/internal/bn_conf.h", - "crypto/include/internal/dso_conf.h" - ); - -my @generated_by_make_headers = ( - "crypto/buildinf.h" - ); - - my $no_sse2=0; &usage if ($#ARGV < 0); @@ -504,7 +500,7 @@ if (grep /^reconf(igure)?$/, @argvcopy) { if (grep(/^reconf/,@argvcopy)); $ENV{CROSS_COMPILE} = $configdata::config{cross_compile_prefix} if defined($configdata::config{cross_compile_prefix}); - $ENV{CROSS_COMPILE} = $configdata::config{cc} + $ENV{CC} = $configdata::config{cc} if defined($configdata::config{cc}); print "Reconfiguring with: ", join(" ",@argvcopy), "\n"; @@ -560,21 +556,17 @@ foreach (@argvcopy) s /^zlib-dynamic$/enable-zlib-dynamic/; if (/^(no|disable|enable)-(.+)$/) - { - my $word = $2; - if (grep { $word =~ /^${_}$/ } @deprecated_disablables) - { - $deprecated_options{$_} = 1; - next; - } - elsif (!grep { $word =~ /^${_}$/ } @disablables) - { - $unsupported_options{$_} = 1; - next; - } - } - if (/^no-(.+)$/ || /^disable-(.+)$/) - { + { + my $word = $2; + if (!exists $deprecated_disablables{$word} + && !grep { $word =~ /^${_}$/ } @disablables) + { + $unsupported_options{$_} = 1; + next; + } + } + if (/^no-(.+)$/ || /^disable-(.+)$/) + { foreach my $proto ((@tls, @dtls)) { if ($1 eq "$proto-method") @@ -613,6 +605,14 @@ foreach (@argvcopy) { $disabled{"dynamic-engine"} = "option"; } + elsif (exists $deprecated_disablables{$1}) + { + $deprecated_options{$_} = 1; + if (defined $deprecated_disablables{$1}) + { + $disabled{$deprecated_disablables{$1}} = "option"; + } + } else { $disabled{$1} = "option"; @@ -697,6 +697,14 @@ foreach (@argvcopy) { $withargs{zlib_include}=$1; } + elsif (/^--with-fuzzer-lib=(.*)$/) + { + $withargs{fuzzer_lib}=$1; + } + elsif (/^--with-fuzzer-include=(.*)$/) + { + $withargs{fuzzer_include}=$1; + } elsif (/^--with-fipslibdir=(.*)$/) { $config{fipslibdir}="$1/"; @@ -717,6 +725,13 @@ foreach (@argvcopy) { $libs.=$_." "; } + elsif (/^-static$/) + { + $libs.=$_." "; + $disabled{"pic"} = "forced"; + $disabled{"shared"} = "forced"; + $disabled{"threads"} = "forced"; + } elsif (/^-D(.*)$/) { push @user_defines, $1; @@ -909,16 +924,23 @@ $config{cross_compile_prefix} = $ENV{'CROSS_COMPILE'} if $config{cross_compile_prefix} eq ""; # Allow overriding the names of some tools. USE WITH CARE +# Note: only Unix cares about HASHBANGPERL... that explains +# the default string. $config{perl} = $ENV{'PERL'} || ($^O ne "VMS" ? $^X : "perl"); +$config{hashbangperl} = + $ENV{'HASHBANGPERL'} || $ENV{'PERL'} || "/usr/bin/env perl"; $target{cc} = $ENV{'CC'} || $target{cc} || "cc"; $target{ranlib} = $ENV{'RANLIB'} || $target{ranlib} || - (scalar can_run("$config{cross_compile_prefix}ranlib") ? + (which("$config{cross_compile_prefix}ranlib") ? "\$(CROSS_COMPILE)ranlib" : "true"); $target{ar} = $ENV{'AR'} || $target{ar} || "ar"; $target{nm} = $ENV{'NM'} || $target{nm} || "nm"; $target{rc} = $ENV{'RC'} || $ENV{'WINDRES'} || $target{rc} || "windres"; +# Cache the C compiler command for reconfiguration +$config{cc} = $target{cc}; + # 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). @@ -1041,8 +1063,7 @@ if ($disabled{"dynamic-engine"}) { $config{dynamic_engines} = 1; } -unless ($disabled{fuzz}) { - push @{$config{dirs}}, "fuzz"; +unless ($disabled{"fuzz-libfuzzer"}) { $config{cflags} .= "-fsanitize-coverage=edge,indirect-calls "; } @@ -1051,12 +1072,17 @@ unless ($disabled{asan}) { } unless ($disabled{ubsan}) { - # -DPEDANTIC or -fnosanitize=aligmnent may also be required on some + # -DPEDANTIC or -fnosanitize=alignment may also be required on some # platforms. $config{cflags} .= "-fsanitize=undefined -fno-sanitize-recover=all "; } -unless ($disabled{fuzz} && $disabled{asan} && $disabled{ubsan}) { +unless ($disabled{msan}) { + $config{cflags} .= "-fsanitize=memory "; +} + +unless ($disabled{"fuzz-libfuzzer"} && $disabled{"fuzz-afl"} + && $disabled{asan} && $disabled{ubsan} && $disabled{msan}) { $config{cflags} .= "-fno-omit-frame-pointer -g "; } # @@ -1100,6 +1126,9 @@ unless ($disabled{asm}) { push @{$config{defines}}, "SHA256_ASM" if ($target{sha1_asm_src} =~ /sha256/); push @{$config{defines}}, "SHA512_ASM" if ($target{sha1_asm_src} =~ /sha512/); } + if ($target{rc4_asm_src} ne $table{DEFAULTS}->{rc4_asm_src}) { + push @{$config{defines}}, "RC4_ASM"; + } if ($target{md5_asm_src}) { push @{$config{defines}}, "MD5_ASM"; } @@ -1157,7 +1186,7 @@ if ($^O ne "VMS" && !$disabled{makedepend}) { } close(PIPE); - $config{makedepprog} = scalar can_run('makedepend') unless $config{makedepprog}; + $config{makedepprog} = which('makedepend') unless $config{makedepprog}; $disabled{makedepend} = "unavailable" unless $config{makedepprog}; } @@ -1352,9 +1381,13 @@ if ($builder eq "unified") { my $f = $_->[1]; # The basic things we're trying to build my @programs = (); + my @programs_install = (); my @libraries = (); + my @libraries_install = (); my @engines = (); + my @engines_install = (); my @scripts = (); + my @scripts_install = (); my @extra = (); my @overrides = (); my @intermediates = (); @@ -1378,6 +1411,7 @@ if ($builder eq "unified") { $template->fill_in(HASH => { config => \%config, target => \%target, disabled => \%disabled, + withargs => \%withargs, builddir => abs2rel($buildd, $blddir), sourcedir => abs2rel($sourced, $blddir), buildtop => abs2rel($blddir, $blddir), @@ -1417,48 +1451,72 @@ if ($builder eq "unified") { 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*PROGRAMS(_NO_INST)?\s*=\s*(.*)\s*$/ + => sub { + if (!@skip || $skip[$#skip] > 0) { + my $install = $1; + my @x = tokenize($2); + push @programs, @x; + push @programs_install, @x unless $install; + } + }, + qr/^\s*LIBS(_NO_INST)?\s*=\s*(.*)\s*$/ + => sub { + if (!@skip || $skip[$#skip] > 0) { + my $install = $1; + my @x = tokenize($2); + push @libraries, @x; + push @libraries_install, @x unless $install; + } + }, + qr/^\s*ENGINES(_NO_INST)?\s*=\s*(.*)\s*$/ + => sub { + if (!@skip || $skip[$#skip] > 0) { + my $install = $1; + my @x = tokenize($2); + push @engines, @x; + push @engines_install, @x unless $install; + } + }, + qr/^\s*SCRIPTS(_NO_INST)?\s*=\s*(.*)\s*$/ + => sub { + if (!@skip || $skip[$#skip] > 0) { + my $install = $1; + my @x = tokenize($2); + push @scripts, @x; + push @scripts_install, @x unless $install; + } + }, qr/^\s*EXTRA\s*=\s*(.*)\s*$/ - => sub { push @extra, split(/\s+/, $1) + => sub { push @extra, tokenize($1) if !@skip || $skip[$#skip] > 0 }, qr/^\s*OVERRIDES\s*=\s*(.*)\s*$/ - => sub { push @overrides, split(/\s+/, $1) + => sub { push @overrides, tokenize($1) if !@skip || $skip[$#skip] > 0 }, qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/, - => sub { push @{$ordinals{$1}}, split(/\s+/, $2) + => sub { push @{$ordinals{$1}}, tokenize($2) if !@skip || $skip[$#skip] > 0 }, qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ - => sub { push @{$sources{$1}}, split(/\s+/, $2) + => sub { push @{$sources{$1}}, tokenize($2) if !@skip || $skip[$#skip] > 0 }, qr/^\s*SHARED_SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ - => sub { push @{$shared_sources{$1}}, split(/\s+/, $2) + => sub { push @{$shared_sources{$1}}, tokenize($2) if !@skip || $skip[$#skip] > 0 }, qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ - => sub { push @{$includes{$1}}, split(/\s+/, $2) + => sub { push @{$includes{$1}}, tokenize($2) if !@skip || $skip[$#skip] > 0 }, - qr/^\s*DEPEND\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ - => sub { push @{$depends{$1}}, split(/\s+/, $2) + qr/^\s*DEPEND\[((?:\\.|[^\\\]])*)\]\s*=\s*(.*)\s*$/ + => sub { push @{$depends{$1}}, tokenize($2) if !@skip || $skip[$#skip] > 0 }, qr/^\s*GENERATE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ => sub { push @{$generate{$1}}, $2 if !@skip || $skip[$#skip] > 0 }, qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ - => sub { push @{$renames{$1}}, split(/\s+/, $2) + => sub { push @{$renames{$1}}, tokenize($2) if !@skip || $skip[$#skip] > 0 }, qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ - => sub { push @{$sharednames{$1}}, split(/\s+/, $2) + => sub { push @{$sharednames{$1}}, tokenize($2) if !@skip || $skip[$#skip] > 0 }, qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/ => sub { @@ -1514,6 +1572,14 @@ if ($builder eq "unified") { $unified_info{programs}->{$program} = 1; } + foreach (@programs_install) { + my $program = cleanfile($buildd, $_, $blddir); + if ($unified_info{rename}->{$program}) { + $program = $unified_info{rename}->{$program}; + } + $unified_info{install}->{programs}->{$program} = 1; + } + foreach (@libraries) { my $library = cleanfile($buildd, $_, $blddir); if ($unified_info{rename}->{$library}) { @@ -1522,6 +1588,14 @@ if ($builder eq "unified") { $unified_info{libraries}->{$library} = 1; } + foreach (@libraries_install) { + my $library = cleanfile($buildd, $_, $blddir); + if ($unified_info{rename}->{$library}) { + $library = $unified_info{rename}->{$library}; + } + $unified_info{install}->{libraries}->{$library} = 1; + } + die <<"EOF" if scalar @engines and !$config{dynamic_engines}; ENGINES can only be used if configured with 'dynamic-engine'. This is usually a fault in a build.info file. @@ -1534,6 +1608,14 @@ EOF $unified_info{engines}->{$library} = 1; } + foreach (@engines_install) { + my $library = cleanfile($buildd, $_, $blddir); + if ($unified_info{rename}->{$library}) { + $library = $unified_info{rename}->{$library}; + } + $unified_info{install}->{engines}->{$library} = 1; + } + foreach (@scripts) { my $script = cleanfile($buildd, $_, $blddir); if ($unified_info{rename}->{$script}) { @@ -1542,6 +1624,14 @@ EOF $unified_info{scripts}->{$script} = 1; } + foreach (@scripts_install) { + my $script = cleanfile($buildd, $_, $blddir); + if ($unified_info{rename}->{$script}) { + $script = $unified_info{rename}->{$script}; + } + $unified_info{install}->{scripts}->{$script} = 1; + } + foreach (@extra) { my $extra = cleanfile($buildd, $_, $blddir); $unified_info{extra}->{$extra} = 1; @@ -1672,11 +1762,11 @@ EOF foreach (keys %depends) { my $dest = $_; - my $ddest = cleanfile($sourced, $_, $blddir); + my $ddest = $dest eq "" ? "" : cleanfile($sourced, $_, $blddir); # If the destination doesn't exist in source, it can only be # a generated file in the build tree. - if (! -f $ddest) { + if ($ddest ne "" && ! -f $ddest) { $ddest = cleanfile($buildd, $_, $blddir); if ($unified_info{rename}->{$ddest}) { $ddest = $unified_info{rename}->{$ddest}; @@ -1693,7 +1783,7 @@ EOF if (! -f $d || (grep { $d eq $_ } map { cleanfile($srcdir, $_, $blddir) } - (@generated_headers, @generated_by_make_headers))) { + grep { /\.h$/ } keys %{$unified_info{generate}})) { $d = cleanfile($buildd, $_, $blddir); } # Take note if the file to depend on is being renamed @@ -1703,10 +1793,10 @@ EOF $unified_info{depends}->{$ddest}->{$d} = 1; # If we depend on a header file or a perl module, let's make # sure it can get included - if ($d =~ /\.(h|pm)$/) { + if ($dest ne "" && $d =~ /\.(h|pm)$/) { my $i = dirname($d); - push @{$unified_info{includes}->{$ddest}}, $i - unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}}; + push @{$unified_info{includes}->{$ddest}->{source}}, $i + unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}->{source}}; } } } @@ -1724,9 +1814,12 @@ EOF } } foreach (@{$includes{$dest}}) { - my $i = cleandir($sourced, $_, $blddir); - push @{$unified_info{includes}->{$ddest}}, $i - unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}}; + my $is = cleandir($sourced, $_, $blddir); + my $ib = cleandir($buildd, $_, $blddir); + push @{$unified_info{includes}->{$ddest}->{source}}, $is + unless grep { $_ eq $is } @{$unified_info{includes}->{$ddest}->{source}}; + push @{$unified_info{includes}->{$ddest}->{build}}, $ib + unless grep { $_ eq $ib } @{$unified_info{includes}->{$ddest}->{build}}; } } } @@ -1737,12 +1830,28 @@ EOF $unified_info{$_} = [ sort keys %{$unified_info{$_}} ]; } # Two level structures - foreach my $l1 (("sources", "shared_sources", "ldadd", "depends")) { + foreach my $l1 (("install", "sources", "shared_sources", "ldadd", "depends")) { foreach my $l2 (sort keys %{$unified_info{$l1}}) { $unified_info{$l1}->{$l2} = [ sort keys %{$unified_info{$l1}->{$l2}} ]; } } + # Includes + foreach my $dest (sort keys %{$unified_info{includes}}) { + if (defined($unified_info{includes}->{$dest}->{build})) { + my @source_includes = + ( @{$unified_info{includes}->{$dest}->{source}} ); + $unified_info{includes}->{$dest} = + [ @{$unified_info{includes}->{$dest}->{build}} ]; + foreach my $inc (@source_includes) { + push @{$unified_info{includes}->{$dest}}, $inc + unless grep { $_ eq $inc } @{$unified_info{includes}->{$dest}}; + } + } else { + $unified_info{includes}->{$dest} = + [ @{$unified_info{includes}->{$dest}->{source}} ]; + } + } } # For the schemes that need it, we provide the old *_obj configs @@ -1919,59 +2028,12 @@ print "THIRTY_TWO_BIT mode\n" if $config{b32}; print "BN_LLONG mode\n" if $config{bn_ll}; print "RC4 uses $config{rc4_int}\n" if $config{rc4_int} ne $def_int; -for (@generated_headers) { - mkpath(catdir($blddir, dirname($_))); - run_dofile(catfile($blddir, $_), - catfile($srcdir, $_.".in")); -} - -### -### 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")); }, - unixmake => sub { - build_Makefile(); - - run_dofile("util/domd", "util/domd.in"); - chmod 0755, "util/domd"; - }, ); $builders{$builder}->($builder_platform, @builder_opts); @@ -2332,13 +2394,34 @@ sub run_dofile foreach (@templates) { die "Can't open $_, $!" unless -f $_; } - my $cmd = "$config{perl} \"-I.\" \"-Mconfigdata\" $dofile -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\""; + 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, $!"; } +sub which +{ + my ($name)=@_; + + if (eval { require IPC::Cmd; 1; }) { + IPC::Cmd->import(); + return scalar IPC::Cmd::can_run($name); + } else { + # if there is $directories component in splitpath, + # then it's not something to test with $PATH... + return $name if (File::Spec->splitpath($name))[1]; + + foreach (File::Spec->path()) { + my $fullpath = catfile($_, "$name$target{exe_extension}"); + if (-f $fullpath and -x $fullpath) { + return $fullpath; + } + } + } +} + # Configuration printer ############################################## sub print_table_entry @@ -2569,3 +2652,41 @@ sub collect_information { } } } + +# tokenize($line) +# $line is a line of text to split up into tokens +# returns a list of tokens +# +# Tokens are divided by spaces. If the tokens include spaces, they +# have to be quoted with single or double quotes. Double quotes +# inside a double quoted token must be escaped. Escaping is done +# with backslash. +# Basically, the same quoting rules apply for " and ' as in any +# Unix shell. +sub tokenize { + my $line = my $debug_line = shift; + my @result = (); + + while ($line =~ s|^\s+||, $line ne "") { + my $token = ""; + while ($line ne "" && $line !~ m|^\s|) { + if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) { + $token .= $1; + $line = $'; + } elsif ($line =~ m/^'([^']*)'/) { + $token .= $1; + $line = $'; + } elsif ($line =~ m/^(\S+)/) { + $token .= $1; + $line = $'; + } + } + push @result, $token; + } + + if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) { + print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n"; + print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n"; + } + return @result; +}