X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=Configure;h=d78066b25bfbfd30031f956d06ee8d1991214a23;hp=ea00e8d96d1dfaffe95e8958f114ea53a2287c36;hb=fce1b86f61e183d3b73a51d2077ec2719291b756;hpb=e431bcfabd72163b0ee89674e2face26a349ba9c diff --git a/Configure b/Configure index ea00e8d96d..d78066b25b 100755 --- a/Configure +++ b/Configure @@ -226,11 +226,6 @@ if (grep /^reconf(igure)?$/, @argvcopy) { die "Incorrect data to reconfigure, please do a normal configuration\n" if (grep(/^reconf/,@argvcopy)); $config{perlenv} = $configdata::config{perlenv} // {}; - - print "Reconfiguring with: ", join(" ",@argvcopy), "\n"; - foreach (sort keys %{$config{perlenv}}) { - print " $_ = $config{perlenv}->{$_}\n"; - } } else { die "Insufficient data to reconfigure, please do a normal configuration\n"; } @@ -283,11 +278,15 @@ if (defined env($local_config_envname)) { } } +# Save away perl command information +$config{perl_cmd} = $^X; +$config{perl_version} = $Config{version}; +$config{perl_archname} = $Config{archname}; + $config{prefix}=""; $config{openssldir}=""; $config{processor}=""; $config{libdir}=""; -$config{cross_compile_prefix}=""; my $auto_threads=1; # enable threads automatically? true by default my $default_ranlib; @@ -440,8 +439,6 @@ our %disabled = ( # "what" => "comment" "ssl3" => "default", "ssl3-method" => "default", "ubsan" => "default", - #TODO(TLS1.3): Temporarily disabled while this is a WIP - "tls1_3" => "default", "tls13downgrade" => "default", "unit-test" => "default", "weak-ssl-ciphers" => "default", @@ -515,22 +512,79 @@ 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 $no_sse2=0; - &usage if ($#ARGV < 0); -my $user_cflags=""; -my @user_defines=(); +# For the "make variables" CINCLUDES and CDEFINES, we support lists with +# platform specific list separators. Users from those platforms should +# recognise those separators from how you set up the PATH to find executables. +# The default is the Unix like separator, :, but as an exception, we also +# support the space as separator. +my $list_separator_re = + { VMS => qr/(? qr/(? {$^O} // qr/(? undef, + ARFLAGS => [], + AS => undef, + ASFLAGS => [], + CC => undef, + CFLAGS => [], + CXX => undef, + CXXFLAGS => [], + CPP => undef, + CPPFLAGS => [], # -D, -I, -Wp, + CPPDEFINES => [], # Alternative for -D + CPPINCLUDES => [], # Alternative for -I + CROSS_COMPILE => undef, + HASHBANGPERL=> undef, + LD => undef, + LDFLAGS => [], # -L, -Wl, + LDLIBS => [], # -l + MT => undef, + MTFLAGS => [], + RANLIB => undef, + RC => undef, + RCFLAGS => [], + RM => undef, + ); +# Info about what "make variables" may be prefixed with the cross compiler +# prefix. This should NEVER mention any such variable with a list for value. +my @user_crossable = qw ( AR AS CC CXX CPP LD MT RANLIB RC ); +# The same but for flags given as Configure options. These are *additional* +# input, as opposed to the VAR=string option that override the corresponding +# config target attributes +my %useradd = ( + CPPDEFINES => [], + CPPINCLUDES => [], + CPPFLAGS => [], + CFLAGS => [], + CXXFLAGS => [], + LDFLAGS => [], + LDLIBS => [], + ); + +my %user_synonyms = ( + HASHBANGPERL=> 'PERL', + RC => 'WINDRES', + ); +my %user_to_target = ( + # If not given here, the value is the lc of the key + CPPDEFINES => 'defines', + CPPINCLUDES => 'includes', + CROSS_COMPILE => 'cross_compile_prefix', + LDFLAGS => 'lflags', + LDLIBS => 'ex_libs', + ); + $config{openssl_api_defines}=[]; $config{openssl_algorithm_defines}=[]; $config{openssl_thread_defines}=[]; $config{openssl_sys_defines}=[]; $config{openssl_other_defines}=[]; -my $ldflags=""; -my $libs=""; -my $target=""; $config{options}=""; $config{build_type} = "release"; +my $target=""; my %unsupported_options = (); my %deprecated_options = (); @@ -545,6 +599,16 @@ while (@argvcopy) if (m|^(\w+)=(.+)?$|) { $config{perlenv}->{$1} = $2; + # Every time a variable is given as a configuration argument, + # it acts as a reset if the variable. + if (exists $user{$1}) + { + $user{$1} = ref $user{$1} eq "ARRAY" ? [] : undef; + } + if (exists $useradd{$1}) + { + $useradd{$1} = []; + } next; } @@ -724,7 +788,7 @@ while (@argvcopy) } elsif (/^--cross-compile-prefix=(.*)$/) { - $config{cross_compile_prefix}=$1; + $user{CROSS_COMPILE}=$1; } elsif (/^--config=(.*)$/) { @@ -732,15 +796,15 @@ while (@argvcopy) } elsif (/^-L(.*)$/) { - $ldflags.=$_." "; + push @{$useradd{LDFLAGS}}, $_; } elsif (/^-l(.*)$/ or /^-Wl,/) { - $libs.=$_." "; + push @{$useradd{LDLIBS}}, $_; } elsif (/^-framework$/) { - $libs.=$_." ".shift(@argvcopy)." "; + push @{$useradd{LDLIBS}}, $_, shift(@argvcopy); } elsif (/^-rpath$/ or /^-R$/) # -rpath is the OSF1 rpath flag @@ -748,11 +812,11 @@ while (@argvcopy) { my $rpath = shift(@argvcopy) || ""; $rpath .= " " if $rpath ne ""; - $libs.=$_." ".$rpath; + push @{$useradd{LDFLAGS}}, $_, $rpath; } elsif (/^-static$/) { - $libs.=$_." "; + push @{$useradd{LDFLAGS}}, $_; $disabled{"dso"} = "forced"; $disabled{"pic"} = "forced"; $disabled{"shared"} = "forced"; @@ -760,12 +824,21 @@ while (@argvcopy) } elsif (/^-D(.*)$/) { - push @user_defines, $1; + push @{$useradd{CPPDEFINES}}, $1; + } + elsif (/^-I(.*)$/) + { + push @{$useradd{CPPINCLUDES}}, $1; + } + elsif (/^-Wp,$/) + { + push @{$useradd{CPPFLAGS}}, $1; } else # common if (/^[-+]/), just pass down... { $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei; - $user_cflags.=" ".$_; + push @{$useradd{CFLAGS}}, $_; + push @{$useradd{CXXFLAGS}}, $_; } } else @@ -802,24 +875,26 @@ while (@argvcopy) } } -if ($libs =~ /(^|\s)-Wl,-rpath,/ +foreach (keys %user) { + my $value = env($_); + $value //= defined $user_synonyms{$_} ? env($user_synonyms{$_}) : undef; + + if (defined $value) { + if (ref $user{$_} eq 'ARRAY') { + $user{$_} = [ split /$list_separator_re/, $value ]; + } elsif (!defined $user{$_}) { + $user{$_} = $value; + } + } +} + +if (grep { $_ =~ /(^|\s)-Wl,-rpath,/ } ($user{LDLIBS} ? @{$user{LDLIBS}} : ()) && !$disabled{shared} && !($disabled{asan} && $disabled{msan} && $disabled{ubsan})) { die "***** Cannot simultaneously use -rpath, shared libraries, and\n", "***** any of asan, msan or ubsan\n"; } -if (scalar(@seed_sources) == 0) { - print "Using implicit seed configuration\n"; - push @seed_sources, 'os'; -} -die "Cannot seed with none and anything else" - if scalar(grep { $_ eq 'none' } @seed_sources) > 0 - && scalar(@seed_sources) > 1; -push @{$config{openssl_other_defines}}, - map { (my $x = $_) =~ tr|[\-a-z]|[_A-Z]|; "OPENSSL_RAND_SEED_$x" } - @seed_sources; - my @tocheckfor = (keys %disabled); while (@tocheckfor) { my %new_tocheckfor = (); @@ -860,9 +935,20 @@ if ($target eq "HASH") { exit 0; } -print "Configuring OpenSSL version $config{version} ($config{version_num})\n"; +print "Configuring OpenSSL version $config{version} ($config{version_num}) "; print "for $target\n"; +if (scalar(@seed_sources) == 0) { + print "Using os-specific seed configuration\n"; + push @seed_sources, 'os'; +} +die "Cannot seed with none and anything else" + if scalar(grep { $_ eq 'none' } @seed_sources) > 0 + && scalar(@seed_sources) > 1; +push @{$config{openssl_other_defines}}, + map { (my $x = $_) =~ tr|[\-a-z]|[_A-Z]|; "OPENSSL_RAND_SEED_$x" } + @seed_sources; + # Backward compatibility? if ($target =~ m/^CygWin32(-.*)$/) { $target = "Cygwin".$1; @@ -945,71 +1031,7 @@ foreach my $feature (@{$target{enable}}) { } } -foreach (sort (keys %disabled)) - { - $config{options} .= " no-$_"; - - printf " no-%-12s %-10s", $_, "[$disabled{$_}]"; - - if (/^dso$/) - { } - elsif (/^threads$/) - { } - elsif (/^shared$/) - { } - elsif (/^pic$/) - { } - elsif (/^zlib$/) - { } - elsif (/^dynamic-engine$/) - { } - elsif (/^makedepend$/) - { } - elsif (/^zlib-dynamic$/) - { } - elsif (/^sse2$/) - { $no_sse2 = 1; } - elsif (/^engine$/) - { - @{$config{dirs}} = grep !/^engines$/, @{$config{dirs}}; - @{$config{sdirs}} = grep !/^engine$/, @{$config{sdirs}}; - push @{$config{openssl_other_defines}}, "OPENSSL_NO_ENGINE"; - print " OPENSSL_NO_ENGINE (skip engines)"; - } - else - { - my ($WHAT, $what); - - ($WHAT = $what = $_) =~ tr/[\-a-z]/[_A-Z]/; - - # Fix up C macro end names - $WHAT = "RMD160" if $what eq "ripemd"; - - # fix-up crypto/directory name(s) - $what = "ripemd" if $what eq "rmd160"; - $what = "whrlpool" if $what eq "whirlpool"; - - if ($what ne "async" && $what ne "err" - && grep { $_ eq $what } @{$config{sdirs}}) - { - push @{$config{openssl_algorithm_defines}}, "OPENSSL_NO_$WHAT"; - @{$config{sdirs}} = grep { $_ ne $what} @{$config{sdirs}}; - - print " OPENSSL_NO_$WHAT (skip dir)"; - } - else - { - push @{$config{openssl_other_defines}}, "OPENSSL_NO_$WHAT"; - print " OPENSSL_NO_$WHAT"; - - if (/^err$/) { push @user_defines, "OPENSSL_NO_ERR"; } - } - } - - print "\n"; - } - -$target{cxxflags}=$target{cflags} unless defined $target{cxxflags}; +$target{cxxflags}//=$target{cflags} if $target{cxx}; $target{exe_extension}=""; $target{exe_extension}=".exe" if ($config{target} eq "DJGPP" || $config{target} =~ /^(?:Cygwin|mingw)/); @@ -1021,43 +1043,83 @@ $target{dso_extension}=$target{shared_extension_simple}; ($target{shared_import_extension}=$target{shared_extension_simple}.".a") if ($config{target} =~ /^(?:Cygwin|mingw)/); - -$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} = ($^O ne "VMS" ? $^X : "perl"); -$config{hashbangperl} = - env('HASHBANGPERL') || env('PERL') || "/usr/bin/env perl"; -$target{cc} = env('CC') || $target{cc} || "cc"; -$target{cxx} = env('CXX') || $target{cxx} || "c++"; -$target{ranlib} = env('RANLIB') || $target{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"; +foreach (keys %user) { + my $target_key = $user_to_target{$_} // lc $_; + my $ref_type = ref $user{$_}; + + # Temporary function. Takes an intended ref type (empty string or "ARRAY") + # and a value that's to be coerced into that type. + my $mkvalue = sub { + my $type = shift; + my $value = shift; + my $undef_p = shift; + + die "Too many arguments for \$mkvalue" if @_; + + while (ref $value eq 'CODE') { + $value = $value->(); + } + + if ($type eq 'ARRAY') { + return undef unless defined $value; + return undef if ref $value ne 'ARRAY' && !$value; + return undef if ref $value eq 'ARRAY' && !@$value; + return [ $value ] unless ref $value eq 'ARRAY'; + } + return undef unless $value; + return $value; + }; + + $config{$target_key} = + $mkvalue->($ref_type, $user{$_}) + || $mkvalue->($ref_type, $target{$target_key}); + delete $config{$target_key} unless defined $config{$target_key}; +} +$config{plib_lflags} = [ $target{plib_lflags} ]; # Allow overriding the build file name -$target{build_file} = env('BUILDFILE') || $target{build_file} || "Makefile"; - -# Cache information necessary for reconfiguration -$config{cc} = $target{cc}; -$config{cxx} = $target{cxx}; -$config{build_file} = $target{build_file}; - -# 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} = []; -$config{cflags} = ""; -$config{cxxflags} = ""; -$config{lflags} = ""; -$config{ex_libs} = ""; -$config{shared_ldflag} = ""; +$config{build_file} = env('BUILDFILE') || $target{build_file} || "Makefile"; + +my %disabled_info = (); # For configdata.pm +foreach my $what (sort keys %disabled) { + $config{options} .= " no-$what"; + + if (!grep { $what eq $_ } ( 'dso', 'threads', 'shared', 'pic', + 'dynamic-engine', 'makedepend', + 'zlib-dynamic', 'zlib', 'sse2' )) { + (my $WHAT = uc $what) =~ s|-|_|g; + + # Fix up C macro end names + $WHAT = "RMD160" if $what eq "ripemd"; + + # fix-up crypto/directory name(s) + $what = "ripemd" if $what eq "rmd160"; + $what = "whrlpool" if $what eq "whirlpool"; + + my $macro = $disabled_info{$what}->{macro} = "OPENSSL_NO_$WHAT"; + + if ((grep { $what eq $_ } @{$config{sdirs}}) + && $what ne 'async' && $what ne 'err') { + @{$config{sdirs}} = grep { $what ne $_} @{$config{sdirs}}; + $disabled_info{$what}->{skipped} = [ catdir('crypto', $what) ]; + + if ($what ne 'engine') { + push @{$config{openssl_algorithm_defines}}, $macro; + } else { + @{$config{dirs}} = grep !/^engines$/, @{$config{dirs}}; + push @{$disabled_info{engine}->{skipped}}, catdir('engines'); + push @{$config{openssl_other_defines}}, $macro; + } + } else { + push @{$config{openssl_other_defines}}, $macro; + } + + } +} # Make sure build_scheme is consistent. $target{build_scheme} = [ $target{build_scheme} ] @@ -1087,22 +1149,24 @@ foreach my $checker (($builder_platform."-".$target{build_file}."-checker.pm", push @{$config{defines}}, "NDEBUG" if $config{build_type} eq "release"; -if ($target =~ /^mingw/ && `$target{cc} --target-help 2>&1` =~ m/-mno-cygwin/m) +if ($target =~ /^mingw/ && `$config{cc} --target-help 2>&1` =~ m/-mno-cygwin/m) { - $config{cflags} .= " -mno-cygwin"; - $config{shared_ldflag} .= " -mno-cygwin"; + push @{$config{cflags}}, "-mno-cygwin"; + push @{$config{cxxflags}}, "-mno-cygwin" if $config{cxx}; + push @{$config{shared_ldflag}}, "-mno-cygwin"; } -if ($target =~ /linux.*-mips/ && !$disabled{asm} && $user_cflags !~ /-m(ips|arch=)/) { +if ($target =~ /linux.*-mips/ && !$disabled{asm} + && !grep { $_ !~ /-m(ips|arch=)/ } (@{$user{CFLAGS}}, + @{$useradd{CFLAGS}})) { # minimally required architecture flags for assembly modules - $config{cflags}="-mips2 $config{cflags}" if ($target =~ /mips32/); - $config{cflags}="-mips3 $config{cflags}" if ($target =~ /mips64/); + my $value; + $value = '-mips2' if ($target =~ /mips32/); + $value = '-mips3' if ($target =~ /mips64/); + unshift @{$config{cflags}}, $value; + unshift @{$config{cxxflags}}, $value if $config{cxx}; } -my $no_shared_warn=0; -my $no_user_cflags=0; -my $no_user_defines=0; - # The DSO code currently always implements all functions so that no # applications will have to worry about that from a compilation point # of view. However, the "method"s may return zero unless that platform @@ -1126,9 +1190,6 @@ if (!$disabled{dso} && $target{dso_scheme} ne "") } } -$config{ex_libs}="$libs$config{ex_libs}" if ($libs ne ""); -$config{lflags}="$config{lflags}$ldflags" if ($ldflags ne ""); - # If threads aren't disabled, check how possible they are unless ($disabled{threads}) { if ($auto_threads) { @@ -1145,7 +1206,8 @@ unless ($disabled{threads}) { # 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) { + if (!@{$user{CFLAGS}} && !@{$useradd{CFLAGS}} + && !@{$user{CPPDEFINES}} && !@{$useradd{CPPDEFINES}}) { die "You asked for multi-threading support, but didn't\n" ,"provide any system-specific compiler options\n"; } @@ -1156,9 +1218,7 @@ unless ($disabled{threads}) { # 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"; - } + push @{$config{openssl_thread_defines}}, "OPENSSL_THREADS"; } # With "deprecated" disable all deprecated features. @@ -1166,6 +1226,7 @@ if (defined($disabled{"deprecated"})) { $config{api} = $maxapi; } +my $no_shared_warn=0; if ($target{shared_target} eq "") { $no_shared_warn = 1 @@ -1184,22 +1245,27 @@ if ($disabled{"dynamic-engine"}) { } unless ($disabled{asan}) { - $config{cflags} .= "-fsanitize=address "; + push @{$config{cflags}}, "-fsanitize=address"; + push @{$config{cxxflags}}, "-fsanitize=address" if $config{cxx}; } unless ($disabled{ubsan}) { # -DPEDANTIC or -fnosanitize=alignment may also be required on some # platforms. - $config{cflags} .= "-fsanitize=undefined -fno-sanitize-recover=all "; + push @{$config{cflags}}, "-fsanitize=undefined", "-fno-sanitize-recover=all"; + push @{$config{cxxflags}}, "-fsanitize=undefined", "-fno-sanitize-recover=all" + if $config{cxx}; } unless ($disabled{msan}) { - $config{cflags} .= "-fsanitize=memory "; + push @{$config{cflags}}, "-fsanitize=memory"; + push @{$config{cxxflags}}, "-fsanitize=memory" if $config{cxx}; } unless ($disabled{"fuzz-libfuzzer"} && $disabled{"fuzz-afl"} && $disabled{asan} && $disabled{ubsan} && $disabled{msan}) { - $config{cflags} .= "-fno-omit-frame-pointer -g "; + push @{$config{cflags}}, "-fno-omit-frame-pointer", "-g"; + push @{$config{cxxflags}}, "-fno-omit-frame-pointer", "-g" if $config{cxx}; } # # Platform fix-ups @@ -1208,9 +1274,12 @@ unless ($disabled{"fuzz-libfuzzer"} && $disabled{"fuzz-afl"} # This saves the build files from having to check if ($disabled{pic}) { - foreach (qw(shared_cflag shared_cxxflag shared_ldflag - dso_cflags dso_cxxflags dso_lflags)) + foreach (qw(shared_cflag shared_cxxflag shared_cppflag + shared_defines shared_includes shared_ldflag + dso_cflags dso_cxxflags dso_cppflags + dso_defines dso_includes dso_lflags)) { + delete $config{$_}; $target{$_} = ""; } } @@ -1226,11 +1295,13 @@ if ($target{sys_id} ne "") unless ($disabled{asm}) { $target{cpuid_asm_src}=$table{DEFAULTS}->{cpuid_asm_src} if ($config{processor} eq "386"); + push @{$config{defines}}, "OPENSSL_CPUID_OBJ" if ($target{cpuid_asm_src} ne "mem_clr.c"); + $target{bn_asm_src} =~ s/\w+-gf2m.c// if (defined($disabled{ec2m})); # bn-586 is the only one implementing bn_*_part_words push @{$config{defines}}, "OPENSSL_BN_ASM_PART_WORDS" if ($target{bn_asm_src} =~ /bn-586/); - push @{$config{defines}}, "OPENSSL_IA32_SSE2" if (!$no_sse2 && $target{bn_asm_src} =~ /86/); + push @{$config{defines}}, "OPENSSL_IA32_SSE2" if (!$disabled{sse2} && $target{bn_asm_src} =~ /86/); push @{$config{defines}}, "OPENSSL_BN_ASM_MONT" if ($target{bn_asm_src} =~ /-mont/); push @{$config{defines}}, "OPENSSL_BN_ASM_MONT5" if ($target{bn_asm_src} =~ /-mont5/); @@ -1258,7 +1329,7 @@ unless ($disabled{asm}) { push @{$config{defines}}, "AES_CTR_ASM" if ($target{aes_asm_src} =~ s/\s*aes-ctr\.fake//); # aes-xts.fake indicates presence of AES_xts_[en|de]crypt... push @{$config{defines}}, "AES_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); + $target{aes_asm_src} =~ s/\s*(vpaes|aesni)-x86\.s//g if ($disabled{sse2}); push @{$config{defines}}, "VPAES_ASM" if ($target{aes_asm_src} =~ m/vpaes/); push @{$config{defines}}, "BSAES_ASM" if ($target{aes_asm_src} =~ m/bsaes/); } @@ -1275,6 +1346,9 @@ unless ($disabled{asm}) { if ($target{ec_asm_src} =~ /ecp_nistz256/) { push @{$config{defines}}, "ECP_NISTZ256_ASM"; } + if ($target{ec_asm_src} =~ /x25519/) { + push @{$config{defines}}, "X25519_ASM"; + } if ($target{padlock_asm_src} ne $table{DEFAULTS}->{padlock_asm_src}) { push @{$config{defines}}, "PADLOCK_ASM"; } @@ -1283,7 +1357,7 @@ unless ($disabled{asm}) { } } -my %predefined = compiler_predefined($target{cc}); +my %predefined = compiler_predefined($config{cc}); # Check for makedepend capabilities. if (!$disabled{makedepend}) { @@ -1294,7 +1368,7 @@ if (!$disabled{makedepend}) { } elsif ($predefined{__GNUC__} >= 3) { # We know that GNU C version 3 and up as well as all clang # versions support dependency generation - $config{makedepprog} = "\$(CROSS_COMPILE)$target{cc}"; + $config{makedepprog} = "\$(CROSS_COMPILE)$config{cc}"; } else { # In all other cases, we look for 'makedepend', and disable the # capability if not found. @@ -1331,9 +1405,12 @@ die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set # Hack cflags for better warnings (dev option) ####################### -# "Stringify" the C flags string. This permits it to be made part of a string -# and works as well on command lines. -$config{cflags} =~ s/([\\\"])/\\$1/g; +# "Stringify" the C and C++ flags string. This permits it to be made part of +# a string and works as well on command lines. +$config{cflags} = [ map { (my $x = $_) =~ s/([\\\"])/\\$1/g; $x } + @{$config{cflags}} ]; +$config{cxxflags} = [ map { (my $x = $_) =~ s/([\\\"])/\\$1/g; $x } + @{$config{cxxflags}} ] if $config{cxx}; if (defined($config{api})) { $config{openssl_api_defines} = [ "OPENSSL_MIN_API=".$apitable->{$config{api}} ]; @@ -1342,7 +1419,8 @@ if (defined($config{api})) { } if (defined($predefined{__clang__}) && !$disabled{asm}) { - $config{cflags} .= " -Qunused-arguments"; + push @{$config{cflags}}, "-Qunused-arguments"; + push @{$config{cxxflags}}, "-Qunused-arguments" if $config{cxx}; } if ($strict_warnings) @@ -1355,13 +1433,21 @@ if ($strict_warnings) $gcc_devteam_warn .= " -Wmisleading-indentation" if $gccver >= 6; foreach $wopt (split /\s+/, $gcc_devteam_warn) { - $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/) + push @{$config{cflags}}, $wopt + unless grep { $_ eq $wopt } @{$config{cflags}}; + push @{$config{cxxflags}}, $wopt + if ($config{cxx} + && !grep { $_ eq $wopt } @{$config{cxxflags}}); } if (defined($predefined{__clang__})) { foreach $wopt (split /\s+/, $clang_devteam_warn) { - $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/) + push @{$config{cflags}}, $wopt + unless grep { $_ eq $wopt } @{$config{cflags}}; + push @{$config{cxxflags}}, $wopt + if ($config{cxx} + && !grep { $_ eq $wopt } @{$config{cxxflags}}); } } } @@ -1370,21 +1456,18 @@ unless ($disabled{"crypto-mdebug-backtrace"}) { foreach my $wopt (split /\s+/, $memleak_devteam_backtrace) { - $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/) + push @{$config{cflags}}, $wopt + unless grep { $_ eq $wopt } @{$config{cflags}}; + push @{$config{cxxflags}}, $wopt + if ($config{cxx} + && !grep { $_ eq $wopt } @{$config{cxxflags}}); } if ($target =~ /^BSD-/) { - $config{ex_libs} .= " -lexecinfo"; + push @{$config{ex_libs}}, "-lexecinfo"; } } -if ($user_cflags ne "") { $config{cflags}="$config{cflags}$user_cflags"; $config{cxxflags}="$config{cxxflags}$user_cflags";} -else { $no_user_cflags=1; } -if (@user_defines) { $config{defines}=[ @{$config{defines}}, @user_defines ]; } -else { $no_user_defines=1; } - -# ALL MODIFICATIONS TO %config and %target MUST BE DONE FROM HERE ON - unless ($disabled{afalgeng}) { $config{afalgeng}=""; if ($target =~ m/^linux/) { @@ -1409,6 +1492,24 @@ unless ($disabled{afalgeng}) { push @{$config{openssl_other_defines}}, "OPENSSL_NO_AFALGENG" if ($disabled{afalgeng}); +# Finish up %config by appending things the user gave us on the command line +# apart from "make variables" +foreach (keys %useradd) { + # The must all be lists, so we assert that here + die "internal error: \$useradd{$_} isn't an ARRAY\n" + unless ref $useradd{$_} eq 'ARRAY'; + + my $target_key = $user_to_target{$_} // lc $_; + + if (defined $config{$target_key}) { + push @{$config{$target_key}}, @{$useradd{$_}}; + } else { + $config{$target_key} = [ @{$useradd{$_}} ]; + } +} + +# ALL MODIFICATIONS TO %config and %target MUST BE DONE FROM HERE ON + # If we use the unified build, collect information from build.info files my %unified_info = (); @@ -1836,7 +1937,7 @@ EOF # If it isn't in the source tree, we assume it's generated # in the build tree - if (! -f $s) { + if (! -f $s || $generate{$_}) { $s = cleanfile($buildd, $_, $blddir); } # We recognise C++, C and asm files @@ -1864,7 +1965,7 @@ EOF # If it isn't in the source tree, we assume it's generated # in the build tree - if (! -f $s) { + if (! -f $s || $generate{$_}) { $s = cleanfile($buildd, $_, $blddir); } @@ -2064,8 +2165,11 @@ foreach (grep /_(asm|aux)_src$/, keys %target) { # Write down our configuration where it fits ######################### +print "Creating configdata.pm\n"; open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n"; print OUT <<"EOF"; +#! $config{hashbangperl} + package configdata; use strict; @@ -2200,29 +2304,299 @@ if ($builder eq "unified") { EOF } -print OUT "1;\n"; -close(OUT); +print OUT + "# The following data is only used when this files is use as a script\n"; +print OUT "my \%makevars = (\n"; +foreach (sort keys %user) { + print OUT ' ',$_,' ' x (20 - length $_),'=> ', + "'",$user_to_target{$_} || lc $_,"',\n"; +} +print OUT ");\n"; +print OUT "my \%disabled_info = (\n"; +foreach my $what (sort keys %disabled_info) { + print OUT " '$what' => {\n"; + foreach my $info (sort keys %{$disabled_info{$what}}) { + if (ref $disabled_info{$what}->{$info} eq 'ARRAY') { + print OUT " $info => [ ", + join(', ', map { "'$_'" } @{$disabled_info{$what}->{$info}}), + " ],\n"; + } else { + print OUT " $info => '", $disabled_info{$what}->{$info}, + "',\n"; + } + } + print OUT " },\n"; +} +print OUT ");\n"; +print OUT 'my @user_crossable = qw( ', join (' ', @user_crossable), " );\n"; +print OUT << 'EOF'; +# If run directly, we can give some answers, and even reconfigure +unless (caller) { + use Getopt::Long; + use File::Spec::Functions; + use File::Basename; + use Pod::Usage; + + my $here = dirname($0); + + my $dump = undef; + my $cmdline = undef; + my $options = undef; + my $target = undef; + my $envvars = undef; + my $makevars = undef; + my $buildparams = undef; + my $reconf = undef; + my $verbose = undef; + my $help = undef; + my $man = undef; + GetOptions('dump|d' => \$dump, + 'command-line|c' => \$cmdline, + 'options|o' => \$options, + 'target|t' => \$target, + 'environment|e' => \$envvars, + 'make-variables|m' => \$makevars, + 'build-parameters|b' => \$buildparams, + 'reconfigure|reconf|r' => \$reconf, + 'verbose|v' => \$verbose, + 'help' => \$help, + 'man' => \$man) + or die "Errors in command line arguments\n"; + + unless ($dump || $cmdline || $options || $target || $envvars || $makevars + || $buildparams || $reconf || $verbose || $help || $man) { + print STDERR <<"_____"; +You must give at least one option. +For more information, do '$0 --help' +_____ + exit(2); + } + + if ($help) { + pod2usage(-exitval => 0, + -verbose => 1); + } + if ($man) { + pod2usage(-exitval => 0, + -verbose => 2); + } + if ($dump || $cmdline) { + print "\nCommand line (with current working directory = $here):\n\n"; + print ' ',join(' ', + $config{perl}, + catfile($config{sourcedir}, 'Configure'), + @{$config{perlargv}}), "\n"; + print "\nPerl information:\n\n"; + print ' ',$config{perl_cmd},"\n"; + print ' ',$config{perl_version},' for ',$config{perl_archname},"\n"; + } + if ($dump || $options) { + my $longest = 0; + my $longest2 = 0; + foreach my $what (@disablables) { + $longest = length($what) if $longest < length($what); + $longest2 = length($disabled{$what}) + if $disabled{$what} && $longest2 < length($disabled{$what}); + } + print "\nEnabled features:\n\n"; + foreach my $what (@disablables) { + print " $what\n" unless $disabled{$what}; + } + print "\nDisabled features:\n\n"; + foreach my $what (@disablables) { + if ($disabled{$what}) { + print " $what", ' ' x ($longest - length($what) + 1), + "[$disabled{$what}]", ' ' x ($longest2 - length($disabled{$what}) + 1); + print $disabled_info{$what}->{macro} + if $disabled_info{$what}->{macro}; + print ' (skip ', + join(', ', @{$disabled_info{$what}->{skipped}}), + ')' + if $disabled_info{$what}->{skipped}; + print "\n"; + } + } + } + if ($dump || $target) { + print "\nConfig target attributes:\n\n"; + foreach (sort keys %target) { + next if $_ =~ m|^_| || $_ eq 'template'; + my $quotify = sub { + map { (my $x = $_) =~ s|([\\\$\@"])|\\$1|g; "\"$x\""} @_; + }; + print ' ', $_, ' => '; + if (ref($target{$_}) eq "ARRAY") { + print '[ ', join(', ', $quotify->(@{$target{$_}})), " ],\n"; + } else { + print $quotify->($target{$_}), ",\n" + } + } + } + if ($dump || $envvars) { + print "\nRecorded environment:\n\n"; + foreach (sort keys %{$config{perlenv}}) { + print ' ',$_,' = ',($config{perlenv}->{$_} || ''),"\n"; + } + } + if ($dump || $makevars) { + print "\nMakevars:\n\n"; + foreach my $var (sort keys %makevars) { + my $prefix = ''; + $prefix = $config{cross_compile_prefix} + if grep { $var eq $_ } @user_crossable; + $prefix //= ''; + print ' ',$var,' ' x (16 - length $var),'= ', + (ref $config{$makevars{$var}} eq 'ARRAY' + ? join(' ', @{$config{$makevars{$var}}}) + : $prefix.$config{$makevars{$var}}), + "\n" + if defined $config{$makevars{$var}}; + } + + my @buildfile = ($config{builddir}, $config{build_file}); + unshift @buildfile, $here + unless file_name_is_absolute($config{builddir}); + my $buildfile = canonpath(catdir(@buildfile)); + print <<"_____"; + +NOTE: These variables only represent the configuration view. The build file +template may have processed these variables further, please have a look at the +build file for more exact data: + $buildfile +_____ + } + if ($dump || $buildparams) { + my @buildfile = ($config{builddir}, $config{build_file}); + unshift @buildfile, $here + unless file_name_is_absolute($config{builddir}); + print "\nbuild file:\n\n"; + print " ", canonpath(catfile(@buildfile)),"\n"; + + print "\nbuild file templates:\n\n"; + foreach (@{$config{build_file_templates}}) { + my @tmpl = ($_); + unshift @tmpl, $here + unless file_name_is_absolute($config{sourcedir}); + print ' ',canonpath(catfile(@tmpl)),"\n"; + } + } + if ($reconf) { + if ($verbose) { + print 'Reconfiguring with: ', join(' ',@{$config{perlargv}}), "\n"; + foreach (sort keys %{$config{perlenv}}) { + print ' ',$_,' = ',($config{perlenv}->{$_} || ""),"\n"; + } + } + + chdir $here; + exec $^X,catfile($config{sourcedir}, 'Configure'),'reconf'; + } +} + +1; + +__END__ + +=head1 NAME -print "\n"; -print "PROCESSOR =$config{processor}\n" if $config{processor}; -print "PERL =$config{perl}\n"; -print "PERLVERSION =$Config{version} for $Config{archname}\n"; -print "HASHBANGPERL =$config{hashbangperl}\n"; -print "CC =$config{cross_compile_prefix}$target{cc}\n"; -print "CFLAG =$target{cflags} $config{cflags}\n"; -print "CXX =$config{cross_compile_prefix}$target{cxx}\n" - if defined $target{cxx}; -print "CXXFLAG =$target{cxxflags} $config{cxxflags}\n" - if defined $target{cxx}; -print "DEFINES =",join(" ", @{$target{defines}}, @{$config{defines}}),"\n"; -#print "RANLIB =", $target{ranlib} eq '$(CROSS_COMPILE)ranlib' ? -# "$config{cross_compile_prefix}ranlib" : -# "$target{ranlib}", "\n"; -print "LDFLAGS =$config{lflags} $target{lflags}\n"; -print "EX_LIBS =$target{ex_libs} $config{ex_libs}\n"; +configdata.pm - configuration data for OpenSSL builds + +=head1 SYNOPSIS + +Interactive: + + perl configdata.pm [options] + +As data bank module: + + use configdata; + +=head1 DESCRIPTION + +This module can be used in two modes, interactively and as a module containing +all the data recorded by OpenSSL's Configure script. + +When used interactively, simply run it as any perl script, with at least one +option, and you will get the information you ask for. See L below. + +When loaded as a module, you get a few databanks with useful information to +perform build related tasks. The databanks are: + + %config Configured things. + %target The OpenSSL config target with all inheritances + resolved. + %disabled The features that are disabled. + @disablables The list of features that can be disabled. + %withargs All data given through --with-THING options. + %unified_info All information that was computed from the build.info + files. + +=head1 OPTIONS + +=over 4 + +=item B<--help> + +Print a brief help message and exit. + +=item B<--man> + +Print the manual page and exit. + +=item B<--dump> | B<-d> + +Print all relevant configuration data. This is equivalent to B<--command-line> +B<--options> B<--target> B<--environment> B<--make-variables> +B<--build-parameters>. + +=item B<--command-line> | B<-c> + +Print the current configuration command line. + +=item B<--options> | B<-o> + +Print the features, both enabled and disabled, and display defined macro and +skipped directories where applicable. + +=item B<--target> | B<-t> + +Print the config attributes for this config target. + +=item B<--environment> | B<-e> + +Print the environment variables and their values at the time of configuration. + +=item B<--make-variables> | B<-m> + +Print the main make variables generated in the current configuration + +=item B<--build-parameters> | B<-b> + +Print the build parameters, i.e. build file and build file templates. + +=item B<--reconfigure> | B<--reconf> | B<-r> + +Redo the configuration. + +=item B<--verbose> | B<-v> + +Verbose output. + +=back + +=cut + +EOF +close(OUT); +if ($builder_platform eq 'unix') { + my $mode = (0755 & ~umask); + chmod $mode, 'configdata.pm' + or warn sprintf("WARNING: Couldn't change mode for 'configdata.pm' to 0%03o: %s\n",$mode,$!); +} my %builders = ( unified => sub { + print 'Creating ',$target{build_file},"\n"; run_dofile(catfile($blddir, $target{build_file}), @{$config{build_file_templates}}); }, @@ -2254,6 +2628,18 @@ safest course of action is to clean the source directory and redo this configuration. EOF +print <<"EOF"; + +********************************************************************** +*** *** +*** If you want to report a building issue, please include the *** +*** output from this command: *** +*** *** +*** perl configdata.pm --dump *** +*** *** +********************************************************************** +EOF + exit(0); ###################################################################### @@ -2689,9 +3075,12 @@ sub print_table_entry my @sequence = ( "sys_id", + "cpp", + "cppflags", + "defines", + "includes", "cc", "cflags", - "defines", "unistd", "ld", "lflags",