From: Heiko Schlittermann (HS12-RIPE) Date: Thu, 3 Nov 2016 23:08:59 +0000 (+0100) Subject: Introduce EXIM_BUILD_SUFFIX for src/Makefile and testsuite X-Git-Tag: exim-4_88_RC4~10 X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=fefe59d9280bc0b33fb9e1e89d0d664db8078542;p=exim.git Introduce EXIM_BUILD_SUFFIX for src/Makefile and testsuite This enables parallel builds in a shared directory, if they have the same os-type and arch-type. Think about EXIM_BUILD_SUFFIX as 'name of your linux distro' --- diff --git a/src/Makefile b/src/Makefile index adda7ceb3..ccaca1c13 100644 --- a/src/Makefile +++ b/src/Makefile @@ -19,8 +19,14 @@ RM_COMMAND=/bin/rm # provide an override for the OS type and architecture type; they still have # to be used for the OS-specific files. To override them, you can set the # shell variables OSTYPE and ARCHTYPE when running make. - -buildname=$${build:-`$(SHELL) scripts/os-type`-`$(SHELL) scripts/arch-type`} +# +# EXIM_BUILD_SUFFIX should be used to enable parallel builds on a file +# system shared among different Linux distros (same os-type, same +# arch-type). The ../test/runtest script is expected to honour the +# EXIM_BUILD_SUFFIX when searching the Exim binary. +# NOTE: EXIM_BUILD_SUFFIX is considered *experimental*. + +buildname=$${build:-`$(SHELL) scripts/os-type`-`$(SHELL) scripts/arch-type`}$${EXIM_BUILD_SUFFIX:+.$$EXIM_BUILD_SUFFIX} # The default target checks for the existence of Local/Makefile, that the main # makefile is built and up-to-date, and then it runs it. diff --git a/test/lib/Exim/Runtest.pm b/test/lib/Exim/Runtest.pm index 851c29d3b..1677ae3e6 100644 --- a/test/lib/Exim/Runtest.pm +++ b/test/lib/Exim/Runtest.pm @@ -3,10 +3,11 @@ use 5.010; use strict; use warnings; use IO::Socket::INET; +use Cwd; use Carp; use parent 'Exporter'; -our @EXPORT_OK = qw(mailgroup dynamic_socket); +our @EXPORT_OK = qw(mailgroup dynamic_socket exim_binary); our %EXPORT_TAGS = ( all => \@EXPORT_OK, ); @@ -57,6 +58,53 @@ sub dynamic_socket { croak 'Can not allocate a free port.'; } +sub exim_binary { + + # two simple cases, absolute path or relative path and executable + return @_ if $_[0] =~ /^\//; + return Cwd::abs_path(shift), @_ if -x $_[0]; + + # so we're still here, if the simple approach didn't help. + + # if there is '../exim-snapshot//exim', use this + # if there is '../exim4//exim', use this + # if there is '../exim-*.*//exim', use the one with the highest version + # 4.84 < 4.85RC1 < 4.85RC2 < 4.85 < 4.86RC1 < … < 4.86 + # if there is '../src/', use this + # + + my $prefix = '..'; # was intended for testing. + + # get a list of directories having the "scripts/{os,arch}-type" + # scripts + my @candidates = grep { -x "$_/scripts/os-type" and -x "$_/scripts/arch-type" } + "$prefix/exim-snapshot", "$prefix/exim4", # highest priority + (reverse sort { # list of exim-*.* directories + # split version number from RC number + my @a = ($a =~ /(\d+\.\d+)(?:RC(\d+))?/); + my @b = ($b =~ /(\d+\.\d+)(?:RC(\d+))?/); + # if the versions are not equal, we're fine, + # but otherwise we've to compare the RC number, where an + # empty RC number is better than a non-empty + ($a[0] cmp $b[0]) || (defined $a[1] ? defined $b[1] ? $a[1] cmp $b[1] : -1 : 1) + } glob "$prefix/exim-*.*"), + "$prefix/src"; # the "normal" source + + # binaries should be found now depending on the os-type and + # arch-type in the directories we got above + my @binaries = grep { -x } + map { ("$_/exim", "$_/exim4") } + map { + my $os = `$_/scripts/os-type`; + my $arch = `$_/scripts/arch-type`; + chomp($os, $arch); + "$_/build-$os-$arch" . ($ENV{EXIM_BUILD_SUFFIX} ? ".$ENV{EXIM_BUILD_SUFFIX}" : ''); + } @candidates; + + return $binaries[0], @_; +} + + 1; __END__ @@ -75,6 +123,14 @@ group name or some other random but existing group. Return a dynamically allocated listener socket in the range between 1024 and 65534; +=item ($binary, @argv) = B(I<@argv>) + +Find the Exim binary. Consider the first element of I<@argv> +and remove it from I<@argv>, if it is an executable binary. +Otherwise search the binary (while honouring C, +C<../scripts/os-type> and C<../os-arch>) and return the +the path to the binary and the unmodified I<@argv>. + =back =cut diff --git a/test/runtest b/test/runtest index 38047b1eb..8b735c1ff 100755 --- a/test/runtest +++ b/test/runtest @@ -17,6 +17,7 @@ #use strict; use 5.010; +use feature 'state'; # included in 5.010 use warnings; use Errno; @@ -2444,7 +2445,7 @@ else # as the path to the binary. If the first argument does not start with a # '/' but exists in the file system, it's assumed to be the Exim binary. -$parm_exim = (@ARGV > 0 && (-x $ARGV[0] or $ARGV[0] =~ m?^/?))? Cwd::abs_path(shift @ARGV) : ""; +($parm_exim, @ARGV) = Exim::Runtest::exim_binary(@ARGV); print "Exim binary is $parm_exim\n" if $parm_exim ne ""; @@ -2511,55 +2512,6 @@ $parm_cwd = Cwd::getcwd(); # takes precedence; otherwise exim-snapshot takes precedence over any numbered # releases. -if ($parm_exim eq "") - { - my($use_srcdir) = ""; - - opendir DIR, ".." || die "** Failed to opendir \"..\": $!\n"; - while ($f = readdir(DIR)) - { - my($srcdir); - - # Try this directory if it is "exim4" or if it is exim-snapshot or exim-n.m - # possibly followed by -RCx where n.m is greater than any previously tried - # directory. Thus, we should choose the highest version of Exim that has - # been compiled. - - if ($f eq "exim4" || $f eq "exim-snapshot" || $f eq 'src') - { $srcdir = $f; } - else - { $srcdir = $f - if ($f =~ /^exim-\d+\.\d+(-RC\d+)?$/ && $f gt $use_srcdir); } - - # Look for a build directory with a binary in it. If we find a binary, - # accept this source directory. - - if ($srcdir) - { - opendir SRCDIR, "../$srcdir" || - die "** Failed to opendir \"$cwd/../$srcdir\": $!\n"; - while ($f = readdir(SRCDIR)) - { - if ($f =~ /^build-/ && -e "../$srcdir/$f/exim") - { - $use_srcdir = $srcdir; - $parm_exim = "$cwd/../$srcdir/$f/exim"; - $parm_exim =~ s'/[^/]+/\.\./'/'; - last; - } - } - closedir(SRCDIR); - } - - # If we have found "exim4" or "exim-snapshot", that takes precedence. - # Otherwise, continue to see if there's a later version. - - last if $use_srcdir eq "exim4" || $use_srcdir eq "exim-snapshot"; - } - closedir(DIR); - print "Exim binary found in $parm_exim\n" if $parm_exim ne ""; - } - # If $parm_exim is still empty, ask the caller if ($parm_exim eq "") @@ -2612,7 +2564,13 @@ while() $version =~ s/^\d+\K\./_/; $git =~ s/^exim-//i; $git =~ s/.*-\Kg([[:xdigit:]]+(?:-XX)?)/$1/; - print "\n*** Version mismatch (Exim: $version vs. GIT: $git). ***\n\n" + print <<___ + +*** Version mismatch +*** Exim binary: $version +*** Git : $git + +___ if not $version eq $git; } } diff --git a/test/t/00-basic.t b/test/t/00-basic.t index 99a3e5fbd..ae8eff77d 100644 --- a/test/t/00-basic.t +++ b/test/t/00-basic.t @@ -5,7 +5,7 @@ use Test::Exception; use lib 'lib'; use_ok 'Exim::Runtest', qw(:all) or BAIL_OUT 'Can not load the module'; -can_ok 'Exim::Runtest', qw(mailgroup dynamic_socket); +can_ok 'Exim::Runtest', qw(mailgroup dynamic_socket exim_binary); pod_coverage_ok 'Exim::Runtest' => 'docs complete'; subtest 'mailgroup' => sub { @@ -31,5 +31,12 @@ subtest 'dynamic_socket' => sub { $socket->close; }; +subtest 'exim_binary' => sub { + my @argv1 = qw(/bin/sh a b); + my @argv2 = qw(t/samples/foo a b); + chomp(my $cwd = `pwd`); # don't use Cwd, as we use Cwd in the tested module already + is_deeply [exim_binary(@argv1)], \@argv1 => 'got the binary as abs path from argv'; + is_deeply [exim_binary(@argv2)], ["$cwd/t/samples/foo", @argv2[1,$#argv2]] => 'got the binary as rel path from argv'; +}; done_testing; diff --git a/test/t/samples/foo b/test/t/samples/foo new file mode 100755 index 000000000..0e748db3f --- /dev/null +++ b/test/t/samples/foo @@ -0,0 +1,2 @@ +# this file solely exists to be tested as +# an executable from one of the tests in t/ diff --git a/test/t/samples/src/.directory b/test/t/samples/src/.directory new file mode 100644 index 000000000..e69de29bb