diff --git a/PGBuild/Modules/CheckHeaders.pm b/PGBuild/Modules/CheckHeaders.pm index bd64c21..ed77806 100644 --- a/PGBuild/Modules/CheckHeaders.pm +++ b/PGBuild/Modules/CheckHeaders.pm @@ -36,6 +36,8 @@ sub setup return if $branch ne 'HEAD'; + return if $conf->{using_meson}; # no support yet + # could even set up several of these (e.g. for different branches) my $self = { buildroot => $buildroot, diff --git a/PGBuild/Modules/CheckIndent.pm b/PGBuild/Modules/CheckIndent.pm new file mode 100644 index 0000000..80b6291 --- /dev/null +++ b/PGBuild/Modules/CheckIndent.pm @@ -0,0 +1,93 @@ + +# Package Namespace is hardcoded. Modules must live in +# PGBuild::Modules + +=comment + +Copyright (c) 2003-2022, Andrew Dunstan + +See accompanying License file for license details + +=cut + +package PGBuild::Modules::CheckIndent; + +use PGBuild::Options; +use PGBuild::SCM; +use PGBuild::Utils; +use PGBuild::Log; + +use Cwd qw(abs_path getcwd); + +use strict; +use warnings; + +our ($VERSION); $VERSION = 'REL_16'; + +my $hooks = { 'build' => \&build, }; + +sub setup +{ + my $class = __PACKAGE__; + + my $buildroot = shift; # where we're building + my $branch = shift; # The branch of Postgres that's being built. + my $conf = shift; # ref to the whole config object + my $pgsql = shift; # postgres build dir + + return unless $branch eq 'HEAD'; + + # could even set up several of these (e.g. for different branches) + my $self = { + buildroot => $buildroot, + pgbranch => $branch, + bfconf => $conf, + pgsql => $pgsql + }; + bless($self, $class); + + register_module_hooks($self, $hooks); + return; +} + + + +sub build +{ + # note - we run this in the source directory, not the build directory + # even if it's a vpath build + + my $self = shift; + + return unless step_wanted('indent-check'); + + print time_str(), "checking for pgindent diffs ...\n" if $verbose; + + my $pgsql = abs_path($self->{pgsql}); + + local $ENV{PATH} = "$pgsql/src/tools/pg_bsd_indent:$ENV{PATH}"; + + my $status; + my @diffs; + + my $cmd = "src/tools/pgindent/pgindent --show-diff ."; + + @diffs = run_log("cd pgsql && $cmd"); + $status = $? >> 8; + + my $log = PGBuild::Log->new("indent-check"); + $log->add_log_lines("indent.diff",\@diffs); + + # --show-diff doesn't exit with error, unlike --silent-diff + $status ||= 1 if @diffs; + + @diffs = ("============ pgindent check ======\n", + $log->log_string); + + writelog("indent-check", \@diffs); + print @diffs if ($verbose > 1); + send_result("indent-check", $status, \@diffs) if $status; + return; +} + +1; diff --git a/PGBuild/Modules/TestCollateLinuxUTF8.pm b/PGBuild/Modules/TestCollateLinuxUTF8.pm index 3017962..b778ed8 100644 --- a/PGBuild/Modules/TestCollateLinuxUTF8.pm +++ b/PGBuild/Modules/TestCollateLinuxUTF8.pm @@ -80,7 +80,7 @@ sub installcheck return unless step_wanted("installcheck-collate-$locale"); - print time_str(), "installchecking $locale", __PACKAGE__, "\n" + print time_str(), "installchecking $locale ", __PACKAGE__, "\n" if $verbose; (my $buildport = $ENV{EXTRA_REGRESS_OPTS}) =~ s/--port=//; diff --git a/PGBuild/Modules/TestDecoding.pm b/PGBuild/Modules/TestDecoding.pm index 8e0d2ca..3a3e601 100644 --- a/PGBuild/Modules/TestDecoding.pm +++ b/PGBuild/Modules/TestDecoding.pm @@ -32,7 +32,8 @@ sub setup my $pgsql = shift; # postgres build dir # for now do nothing on MSVC - return if $conf->{using_msvc}; + # meson runs the test on its own + return if $conf->{using_msvc} || $conf->{using_meson}; # only for supported branches return unless $branch eq 'HEAD' || $branch ge 'REL9_4_STABLE'; diff --git a/PGBuild/Modules/TestICU.pm b/PGBuild/Modules/TestICU.pm index 899373c..a60c3b4 100644 --- a/PGBuild/Modules/TestICU.pm +++ b/PGBuild/Modules/TestICU.pm @@ -34,16 +34,24 @@ sub setup my $branch = shift; # The branch of Postgres that's being built. my $conf = shift; # ref to the whole config object my $pgsql = shift; # postgres build dir + my @opts; + foreach my $k ('config_opts','meson_opts') + { + next unless exists $conf->{$k}; + push @opts, @{ $conf->{$k} } + } - return unless grep { $_ eq '--with-icu' } @{ $conf->{config_opts} }, + # for autoconf, we require --with-icu to be explicit even if it's the + # default + return unless grep { $_ eq '--with-icu' || $_ eq '-Dicu=enabled' } @opts; - # could even set up several of these (e.g. for different branches) - my $self = { + # could even set up several of these (e.g. for different branches) + my $self = { buildroot => $buildroot, pgbranch => $branch, bfconf => $conf, pgsql => $pgsql - }; + }; bless($self, $class); # for each instance you create, do: diff --git a/PGBuild/Modules/TestMyTap.pm b/PGBuild/Modules/TestMyTap.pm index 5079ad8..a80a9ef 100644 --- a/PGBuild/Modules/TestMyTap.pm +++ b/PGBuild/Modules/TestMyTap.pm @@ -40,9 +40,9 @@ sub setup return unless $branch eq 'HEAD'; - my @opts = @{ $conf->{config_opts} }; + my @opts = (@{ $conf->{config_opts} }, @{ $conf->{meson_opts} }); - return unless grep { /enable-tap-tests/ } @opts; + return unless grep { /enable-tap-tests|-Dtap_tests=enabled/ } @opts; my $tests = $conf->{my_tap_tests}; diff --git a/PGBuild/Modules/TestUpgrade.pm b/PGBuild/Modules/TestUpgrade.pm index 85d7c47..9d51454 100644 --- a/PGBuild/Modules/TestUpgrade.pm +++ b/PGBuild/Modules/TestUpgrade.pm @@ -46,6 +46,8 @@ sub setup my $conf = shift; # ref to the whole config object my $pgsql = shift; # postgres build dir + # this obviates the need of any meson support in this module, as + # this has been in since release 15 return if -d "$buildroot/$branch/pgsql/src/bin/pg_upgrade/t"; die diff --git a/PGBuild/Modules/TestUpgradeXversion.pm b/PGBuild/Modules/TestUpgradeXversion.pm index c4e2c97..5ea18dd 100644 --- a/PGBuild/Modules/TestUpgradeXversion.pm +++ b/PGBuild/Modules/TestUpgradeXversion.pm @@ -99,6 +99,22 @@ sub run_psql ## no critic (Subroutines::ProhibitManyArgs) return; # callers can check $? } +sub dbnames +{ + my $loc = shift; + # collect names of databases. + my $sql = 'select datname from pg_database'; + + run_psql("psql", "-A -t", $sql, "postgres", "$loc-dbnames.data"); + my @dbnames = file_lines("$loc-dbnames.data"); + + chomp @dbnames; + my %dbnames; + do { s/\r$//; $dbnames{$_} = 1; } + foreach @dbnames; + return %dbnames; +} + sub get_lock { my $self = shift; @@ -292,6 +308,8 @@ sub save_for_testing # fix the regression database so its functions point to $libdir rather than # the source directory, which won't persist past this build. + my %dbnames = dbnames("$upgrade_loc/save"); + my $sql = 'select distinct probin::text from pg_proc ' . 'where probin not like $$$libdir%$$'; @@ -325,11 +343,14 @@ sub save_for_testing return if $?; + my $dblink = (grep { /_dblink$/ } keys %dbnames)[0]; + if (($this_branch ge 'REL9_5' || $this_branch eq 'HEAD') - && !$self->{bfconf}->{using_msvc}) + && !$self->{bfconf}->{using_msvc} + && $dblink) { run_psql("$installdir/bin/psql", "-A -t -e", $sql, - "contrib_regression_dblink", "$upgrade_loc/fix.log", 1); + $dblink, "$upgrade_loc/fix.log", 1); return if $?; } @@ -383,11 +404,18 @@ sub test_upgrade ## no critic (Subroutines::ProhibitManyArgs) ); return if $?; + # is the old version using unix sockets or localhost? + + my $oldconf = file_contents("$other_branch/inst/$upgrade_test/postgresql.conf"); + my $using_localhost = $oldconf =~ /^listen_addresses = 'localhost'/m; + + local $ENV{PGHOST} = $using_localhost ? "localhost" : $ENV{PGHOST}; + # The old version will have the unix sockets point to tmpdir from the # run in which it was set up, which will be gone by now, so we repoint # it to the current run's tmpdir. # listen_addresses will be set correctly and requires no adjustment. - unless ($self->{bfconf}->{using_msvc} || $^O eq 'msys') + if (! $using_localhost) { open(my $opgconf, ">>", "$other_branch/inst/$upgrade_test/postgresql.conf") @@ -418,16 +446,7 @@ sub test_upgrade ## no critic (Subroutines::ProhibitManyArgs) $sport = $sport + 0; # collect names of databases present in old installation. - my $sql = 'select datname from pg_database'; - - run_psql("psql", "-A -t", $sql, "postgres", - "$upgrade_loc/$oversion-dbnames.data"); - my @dbnames = file_lines("$upgrade_loc/$oversion-dbnames.data"); - - chomp @dbnames; - my %dbnames; - do { s/\r$//; $dbnames{$_} = 1; } - foreach @dbnames; + my %dbnames = dbnames("$upgrade_loc/$oversion"); if ($oversion ne $this_branch) { @@ -473,7 +492,7 @@ sub test_upgrade ## no critic (Subroutines::ProhibitManyArgs) . qq{> "$upgrade_loc/$oversion-initdb.log" 2>&1}); return if $?; - unless ($self->{bfconf}->{using_msvc} || $^O eq 'msys') + unless ($using_localhost) { open(my $pgconf, ">>", "$installdir/$oversion-upgrade/postgresql.conf") || die "opening $installdir/$oversion-upgrade/postgresql.conf: $!"; @@ -685,7 +704,11 @@ sub installcheck local %ENV = %ENV; - if ($self->{bfconf}->{using_msvc} || $^O eq 'msys') + if ($ENV{PG_TEST_USE_UNIX_SOCKETS}) + { + $ENV{PGHOST} = $tmpdir; + } + elsif ($self->{bfconf}->{using_msvc} || $^O eq 'msys') { $ENV{PGHOST} = 'localhost'; } @@ -738,8 +761,11 @@ sub installcheck # ok, we now have the persistent copy of all branches we can use # to test upgrading from - my $dconfig = `$installdir/bin/pg_config --configure`; - my $dport = $dconfig =~ /--with-pgport=(\d+)/ ? $1 : 5432; + my $dport; + { + no warnings 'once'; + $dport = $main::buildport; + } # for other branches ignore the from-source root if it's being used my $stable_root = $self->{upgrade_install_root}; diff --git a/PGBuild/Options.pm b/PGBuild/Options.pm index 39bfa3f..80c615d 100644 --- a/PGBuild/Options.pm +++ b/PGBuild/Options.pm @@ -26,7 +26,7 @@ BEGIN @option_list = qw( $forcerun $buildconf $keepall $help $quiet $from_source $from_source_clean $testmode - $skip_steps $only_steps $find_typedefs + $skip_steps $only_steps $skip_suites $find_typedefs $nosend $nostatus $verbose @config_set $schedule $tests $check_warnings $delay_check $show_error_log $avoid_ts_collisions @@ -49,6 +49,7 @@ our ( $nostatus, $verbose, @config_set, $schedule, $tests, $check_warnings, $delay_check, $show_error_log, $avoid_ts_collisions, + $skip_suites ); my (%standard_options); @@ -68,6 +69,7 @@ my (%standard_options); 'quiet' => \$quiet, 'skip-steps=s' => \$skip_steps, 'only-steps=s' => \$only_steps, + 'skip-suites=s' => \$skip_suites, 'config-set=s' => \@config_set, 'schedule=s' => \$schedule, 'tests=s' => \$tests, diff --git a/PGBuild/Utils.pm b/PGBuild/Utils.pm index d08225d..a0f3226 100644 --- a/PGBuild/Utils.pm +++ b/PGBuild/Utils.pm @@ -409,7 +409,16 @@ sub check_install_is_complete my $suffix = '.dll'; # adjust settings for non-MSVC - if (-e "$build_dir/src/Makefile.global") # i.e. not msvc + + # use a simplified test for meson - where we always install everything + if (-e "$build_dir/meson-private") + { + $tmp_loc = "$tmp_loc/$install_dir"; + $bindir = "$tmp_loc/bin"; + $libdir = "$tmp_loc/lib/postgresql"; + return (-d $bindir && -d $libdir); + } + elsif (-e "$build_dir/src/Makefile.global") # i.e. not msvc { no warnings qw(once); my $make = $PGBuild::conf{make}; diff --git a/build-farm.conf.sample b/build-farm.conf.sample index 36a8145..6186fa3 100644 --- a/build-farm.conf.sample +++ b/build-farm.conf.sample @@ -225,6 +225,9 @@ my $confdir = File::Spec->rel2abs(File::Basename::dirname(__FILE__)); # These are the ones omitted without the setting # on a secure single user system it makes sense to enable these # PG_TEST_EXTRA => "ssl ldap kerberos", + + # Where to put port locks. Default is the buildroot + # PG_TEST_PORT_DIR => 'some path', }, # env settings to pass to configure. These settings will only be seen by @@ -233,6 +236,7 @@ my $confdir = File::Spec->rel2abs(File::Basename::dirname(__FILE__)); # comment out if not using ccache # ccache is known to cause issues sometimes on msys2 + # don't set CC at all if using MSVC, especially with meson CC => 'ccache gcc', # If using vpath builds, this makes it use true symbolic links @@ -249,6 +253,12 @@ my $confdir = File::Spec->rel2abs(File::Basename::dirname(__FILE__)); # This example makes the regression tests run with extra # checking of user names created by the tests # CPPFLAGS => '-DENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS', + + # where to find a usable pkg-config or equivalent + # see for example https://github.com/pkgconf/pkgconf + # PKG_CONFIG => 'c:/path/to/pkg-config.exe', + # PATH-style list of extra directories to search for .pc files + # PKG_CONFIG_PATH => 'c:/path/to/libxml/pkgconfig', }, # settings added to those in config_env if valgrind is being used @@ -266,6 +276,19 @@ my $confdir = File::Spec->rel2abs(File::Basename::dirname(__FILE__)); # see below for MSVC config + # set true if running with meson + # will be ignored for branches older than 16 + using_meson => undef, + + # similar to make_jobs above - how much parallelism do you want for + # meson's build and test stages. undef says use meson's default. (1?) + meson_jobs => undef, + + # timeout multiplier for meson test jobs. + # default if value is undefined is 3, 0 means no timeout + meson_test_timeout => undef, + + # options used with configure (and not for meson) config_opts => [ qw( --enable-cassert @@ -282,7 +305,31 @@ my $confdir = File::Spec->rel2abs(File::Basename::dirname(__FILE__)); ), # could also add for example --enable-tap-tests - ], + ], + + # Note, for meson we turn off all the auto options and then selectively + # re-enable them using these options, so zlib and readline have to be + # explicitly enabled here. + # see meson docs re interaction of buildtype, debug and + # optimization settings. debugoptimised = debug:on + optimisation:2 + meson_opts => [ + qw( + -Dcassert=true + -Dbuildtype=debugoptimized + -Dnls=enabled + -Dplperl=enabled + -Dplpython=enabled + -Dpltcl=enabled + -Dgssapi=enabled + -Dssl=openssl + -Dldap=enabled + -Dlibxml=enabled + -Dlibxslt=enabled + -Dzlib=enabled + -Dreadline=enabled + ), + # could for example add -Dtap_tests=enabled + ], # per-branch contents of extra config for check stages. # each branch has an array of setting lines (no \n required) @@ -388,10 +435,13 @@ if ($conf{using_msvc}) %{ $conf{build_env} } = (%{ $conf{build_env} }, %$vsenv); - # MSVC needs a somewhat different style of config opts (why??) + # MSVC non-meson needs a somewhat different style of config opts (why??) # What we write here will be literally (via Data::Dumper) put into # the config.pl file for the MSVC build. + # This will be ignored for meson builds, which use meson_opts rather + # than config_opts. See above for meson_opts. + $conf{config_opts} = { asserts => 1, # --enable-cassert integer_datetimes => 1, # --enable-integer-datetimes diff --git a/run_build.pl b/run_build.pl index 92919a6..06af491 100755 --- a/run_build.pl +++ b/run_build.pl @@ -138,11 +138,19 @@ BEGIN if ($skip_steps =~ /\S/) { %skip_steps = map { $_ => 1 } split(/\s+/, $skip_steps); + $skip_steps{make} = 1 if $skip_steps{build}; } $only_steps ||= ""; if ($only_steps =~ /\S/) { %only_steps = map { $_ => 1 } split(/\s+/, $only_steps); + $only_steps{make} = 1 if $only_steps{build}; +} +our %skip_suites; +$skip_suites ||= ""; +if ($skip_suites =~ /\S/) +{ + %skip_suites = map { $_ => 1 } split(/\s+/, $skip_suites); } our ($branch); @@ -185,7 +193,9 @@ BEGIN $wait_timeout, $use_accache, $use_valgrind, $valgrind_options, $use_installcheck_parallel, $max_load_avg, - $use_discard_caches, $archive_reports + $use_discard_caches, $archive_reports, + $using_meson, $meson_jobs, + $meson_test_timeout ) = @PGBuild::conf{ qw(build_root target animal aux_path trigger_exclude @@ -193,9 +203,13 @@ BEGIN use_vpath tar_log_cmd using_msvc extra_config make_jobs core_file_glob ccache_failure_remove wait_timeout use_accache use_valgrind valgrind_options use_installcheck_parallel max_load_avg - use_discard_caches archive_reports) + use_discard_caches archive_reports using_meson meson_jobs + meson_test_timeout) }; +$using_meson = undef unless $branch eq 'HEAD' || $branch ge 'REL_16_STABLE'; +$meson_test_timeout //= 3; + $ts_prefix = sprintf('%s:%-13s ', $animal, $branch); if ($max_load_avg) @@ -245,15 +259,27 @@ BEGIN print scalar(localtime()), ": buildfarm run for $animal:$branch starting\n" if $verbose; +$use_vpath ||= $using_meson; + die "cannot use vpath with MSVC" - if ($using_msvc and $use_vpath); + if ($using_msvc && $use_vpath && !$using_meson); if (ref($force_every) eq 'HASH') { $force_every = $force_every->{$branch} || $force_every->{default}; } -my $config_opts = $PGBuild::conf{config_opts}; +my ($config_opts, $meson_opts); +if ($using_meson) +{ + $meson_opts = $PGBuild::conf{meson_opts}; + delete $PGBuild::conf{config_opts}; +} +else +{ + $config_opts = $PGBuild::conf{config_opts}; + delete $PGBuild::conf{meson_opts}; +} our ($buildport); @@ -365,14 +391,20 @@ BEGIN $devnull = $using_msvc ? "nul" : "/dev/null"; -$st_prefix = "$animal."; +$st_prefix = $testmode ? "$animal-test." : "$animal."; # set environment from config while (my ($envkey, $envval) = each %{ $PGBuild::conf{build_env} }) { + # ignore this setting for branches older than 13 + next if $envkey eq 'PG_TEST_USE_UNIX_SOCKETS' && + $branch lt "REL_13_STABLE" && $branch ne 'HEAD'; $ENV{$envkey} = $envval; } +# default directory for port locks in TAP tests +$ENV{PG_TEST_PORT_DIR} ||= $buildroot; + # default value - supply unless set via the config file # or calling environment $ENV{PGCTLTIMEOUT} = 120 unless exists $ENV{PGCTLTIMEOUT}; @@ -403,6 +435,13 @@ BEGIN ); umask $oldmask unless $using_msvc; +my $vtmpdir = $tmpdir; +if ($Config{osname} =~ /msys/i) +{ + $tmpdir = `cygpath -a -m $tmpdir`; + chomp $tmpdir; +} + my $scm = PGBuild::SCM->new(\%PGBuild::conf); if (!$from_source) { @@ -428,11 +467,11 @@ BEGIN } else { - $pgsql = $scm->get_build_path($use_vpath); + $pgsql = $scm->get_build_path($use_vpath || $using_meson); } # make sure we are using GNU make (except for MSVC) -unless ($using_msvc) +unless ($using_msvc || $using_meson) { die "$make is not GNU Make - please fix config file" unless check_make(); @@ -489,9 +528,12 @@ BEGIN # recursively fix any permissions that might stop us removing the directories # then remove old run artefacts if any, die if not possible my $fix_perms = sub { chmod 0700, $_ unless -l $_; }; -File::Find::find($fix_perms, "inst") if -d "inst"; -rmtree("inst"); -die "$installdir exists!" if -e "inst"; +if (step_wanted('install')) +{ + File::Find::find($fix_perms, "inst") if -d "inst"; + rmtree("inst"); + die "$installdir exists!" if -e "inst"; +} unless ($from_source && !$use_vpath) { File::Find::find($fix_perms, "$pgsql") if -d $pgsql; @@ -512,7 +554,8 @@ BEGIN # if it's not a regular run, make sure we force the next run # this run could defeat the up-to-date checks -if (($nosend || $nostatus) && !$from_source) +# unless it's in testmode, which uses a different prefix +if (($nosend || $nostatus) && !$from_source && !$testmode) { open(my $fh, '>', $forcefile) || die "opening $forcefile: $!"; close($fh); @@ -699,8 +742,8 @@ END if ($extra_config && $extra_config->{$branch}) { - my $tmpname = "$tmpdir/bfextra.conf"; - open($extraconf, ">", "$tmpname") || die 'opening $tmpname $!'; + my $tmpname = "$vtmpdir/bfextra.conf"; + open($extraconf, ">", "$tmpname") || die "opening $tmpname $!"; $ENV{TEMP_CONFIG} = $tmpname; foreach my $line (@{ $extra_config->{$branch} }) { @@ -760,7 +803,8 @@ END } } - print time_str(), "checking if build run needed ...\n" if $verbose; + print time_str(), "checking if build run needed ...\n" + if $verbose && !($testmode || $from_source); # transition to new time processing unlink "last.success"; @@ -843,7 +887,8 @@ END if ($use_vpath) { - print time_str(), "creating vpath build dir $pgsql ...\n" if $verbose; + my $str = $using_meson ? "meson" : "vpath"; + print time_str(), "creating $str build dir $pgsql ...\n" if $verbose; mkdir $pgsql || die "making $pgsql: $!"; } elsif (!$from_source && $scm->copy_source_required()) @@ -869,33 +914,40 @@ END if (step_wanted('configure')) { - print time_str(), "running configure ...\n" if $verbose; + my $str = $using_meson ? "meson setup" : "configure"; + print time_str(), "running $str ...\n" if $verbose; configure(); } +# force this on to avoid meson errors on build +local $ENV{MSYS} = $ENV{MSYS} || ""; +$ENV{MSYS} .= " winjitdebug" if ($using_meson); + # module configure has to wait until we have built and installed the base # so see below make(); +meson_test_setup() if $using_meson; + make_check() unless $delay_check; # contrib is built under the standard build step for msvc -make_contrib() unless ($using_msvc); +make_contrib() unless ($using_msvc || $using_meson); make_testmodules() - unless ($using_msvc || ($branch ne 'HEAD' && $branch lt 'REL9_5')); + unless ($using_msvc || $using_meson || ($branch ne 'HEAD' && $branch lt 'REL9_5')); make_doc() if (check_optional_step('build_docs')); make_install(); # contrib is installed under standard install for msvc -make_contrib_install() unless ($using_msvc); +make_contrib_install() unless ($using_msvc || $using_meson); make_testmodules_install() - unless ($using_msvc || ($branch ne 'HEAD' && $branch lt 'REL9_5')); + unless ($branch ne 'HEAD' && $branch lt 'REL9_5'); make_check() if $delay_check; @@ -909,11 +961,18 @@ END process_module_hooks("check") if $delay_check; -make_misc_check(); +if ($using_meson) +{ + run_meson_noninst_checks(); +} +else +{ + make_misc_check(); -run_bin_tests(); + run_bin_tests(); -run_misc_tests(); + run_misc_tests(); +} foreach my $locale (@locales) { @@ -923,6 +982,8 @@ END initdb($locale); + $locale =~ s/\s/-/g; + do { # silence warning about uninitialized value, on e.g. frogmouth. @@ -933,6 +994,10 @@ END { $ENV{PGHOST} = $tmpdir; } + elsif ($ENV{PG_TEST_USE_UNIX_SOCKETS}) + { + $ENV{PGHOST} = $tmpdir; + } else { $ENV{PGHOST} = 'localhost'; @@ -947,80 +1012,90 @@ END process_module_hooks('installcheck', $locale) if step_wanted('install-check'); - if ( -d "$pgsql/src/test/isolation" - && $locale eq 'C' - && step_wanted('isolation-check')) + if ($using_meson) { - # restart the db to clear the log file print time_str(), "restarting db ($locale)...\n" if $verbose; stop_db($locale); start_db($locale); - print time_str(), "running make isolation check ...\n" if $verbose; - - make_isolation_check($locale); + run_meson_install_checks($locale); } - - if ( - step_wanted('pl-install-check') - && ( - ( - !$using_msvc - && (grep { /--with-(perl|python|tcl)/ } @$config_opts) - ) - || ( - $using_msvc - && ( defined($config_opts->{perl}) - || defined($config_opts->{python}) - || defined($config_opts->{tcl})) - ) - ) - ) + else { + if ( -d "$pgsql/src/test/isolation" + && $locale eq 'C' + && step_wanted('isolation-check')) + { + # restart the db to clear the log file + print time_str(), "restarting db ($locale)...\n" if $verbose; - # restart the db to clear the log file - print time_str(), "restarting db ($locale)...\n" if $verbose; + stop_db($locale); + start_db($locale); - stop_db($locale); - start_db($locale); + print time_str(), "running make isolation check ...\n" + if $verbose; + make_isolation_check($locale); + } - print time_str(), "running make PL installcheck ($locale)...\n" - if $verbose; + if ( + step_wanted('pl-install-check') + && ( + ( + !$using_msvc + && (grep { /--with-(perl|python|tcl)/ } @$config_opts) + ) + || ( + $using_msvc + && ( defined($config_opts->{perl}) + || defined($config_opts->{python}) + || defined($config_opts->{tcl})) + ) + ) + ) + { + # restart the db to clear the log file + print time_str(), "restarting db ($locale)...\n" if $verbose; - make_pl_install_check($locale); - } + stop_db($locale); + start_db($locale); - if (step_wanted('contrib-install-check')) - { + print time_str(), "running make PL installcheck ($locale)...\n" + if $verbose; - # restart the db to clear the log file - print time_str(), "restarting db ($locale)...\n" if $verbose; + make_pl_install_check($locale); + } - stop_db($locale); - start_db($locale); + if (step_wanted('contrib-install-check')) + { + # restart the db to clear the log file + print time_str(), "restarting db ($locale)...\n" if $verbose; - print time_str(), "running make contrib installcheck ($locale)...\n" - if $verbose; + stop_db($locale); + start_db($locale); - make_contrib_install_check($locale); - } + print time_str(), "running make contrib installcheck ($locale)...\n" + if $verbose; - unless (!step_wanted('testmodules-install-check') - || ($branch ne 'HEAD' && $branch lt 'REL9_5')) - { - print time_str(), "restarting db ($locale)...\n" if $verbose; + make_contrib_install_check($locale); + } - stop_db($locale); - start_db($locale); + unless (!step_wanted('testmodules-install-check') + || ($branch ne 'HEAD' && $branch lt 'REL9_5')) + { + print time_str(), "restarting db ($locale)...\n" if $verbose; - print time_str(), - "running make test-modules installcheck ($locale)...\n" - if $verbose; + stop_db($locale); + start_db($locale); - make_testmodules_install_check($locale); - } + print time_str(), + "running make test-modules installcheck ($locale)...\n" + if $verbose; + + make_testmodules_install_check($locale); + } + } # end of non-meson block print time_str(), "stopping db ($locale)...\n" if $verbose; @@ -1034,7 +1109,7 @@ END unless $keepall; } -if (step_wanted('ecpg-check')) +if (!$using_meson && step_wanted('ecpg-check')) { print time_str(), "running make ecpg check ...\n" if $verbose; @@ -1179,49 +1254,66 @@ sub check_make sub make { return unless step_wanted('make'); - print time_str(), "running make ...\n" if $verbose; + print time_str(), "running build ...\n" if $verbose; my (@makeout); - unless ($using_msvc) + if ($using_meson) { - my $make_cmd = $make; - $make_cmd = "$make -j $make_jobs" - if ($make_jobs > 1); - @makeout = run_log("cd $pgsql && $make_cmd"); + my $jflag = defined($meson_jobs) ? " --jobs=$meson_jobs" : ""; + @makeout = run_log("meson compile -C $pgsql --verbose $jflag"); + move "$pgsql/meson-logs/meson-log.txt", "$pgsql/meson-logs/compile.log"; + if (-s "$pgsql/meson-logs/compile.log") + { + my $log = PGBuild::Log->new("compile"); + $log->add_log("$pgsql/meson-logs/compile.log"); + push(@makeout,$log->log_string); + } } - else + elsif ($using_msvc) { chdir "$pgsql/src/tools/msvc"; @makeout = run_log("perl build.pl"); chdir $branch_root; } + else + { + my $make_cmd = $make; + $make_cmd = "$make -j $make_jobs" + if ($make_jobs > 1); + @makeout = run_log("cd $pgsql && $make_cmd"); + } my $status = $? >> 8; - writelog('make', \@makeout); + writelog('build', \@makeout); print "======== make log ===========\n", @makeout if ($verbose > 1); - $status ||= check_make_log_warnings('make', $verbose) if $check_warnings; - send_result('Make', $status, \@makeout) if $status; - $steps_completed .= " Make"; + $status ||= check_make_log_warnings('build', $verbose) if $check_warnings; + send_result('Build', $status, \@makeout) if $status; + $steps_completed .= " Build"; return; } sub make_doc { return unless step_wanted('make-doc'); - print time_str(), "running make doc ...\n" if $verbose; + print time_str(), "building docs ...\n" if $verbose; my (@makeout); - unless ($using_msvc) + if ($using_meson) { my $extra_targets = $PGBuild::conf{extra_doc_targets} || ""; - @makeout = - run_log("cd $pgsql/doc/src/sgml && $make html $extra_targets"); + @makeout = run_log("meson compile -C $pgsql html $extra_targets"); } - else + elsif ($using_msvc) { chdir "$pgsql/src/tools/msvc"; @makeout = run_log("perl builddoc.pl"); chdir $branch_root; } + else + { + my $extra_targets = $PGBuild::conf{extra_doc_targets} || ""; + @makeout = + run_log("cd $pgsql/doc/src/sgml && $make html $extra_targets"); + } my $status = $? >> 8; writelog('make-doc', \@makeout); print "======== make doc log ===========\n", @makeout if ($verbose > 1); @@ -1233,19 +1325,30 @@ sub make_doc sub make_install { return unless step_wanted('install'); - print time_str(), "running make install ...\n" if $verbose; + print time_str(), "running install ...\n" if $verbose; my @makeout; - unless ($using_msvc) + if($using_meson) { - @makeout = run_log("cd $pgsql && $make install"); + @makeout = run_log("meson install -C $pgsql "); + move "$pgsql/meson-logs/meson-log.txt","$pgsql/meson-logs/install.log"; + my $log = PGBuild::Log->new("install"); + if (-s "$pgsql/meson-logs/install.log") + { + $log->add_file("$pgsql/meson-logs/install.log"); + push(@makeout, $log->log_string); + } } - else + elsif ($using_msvc) { chdir "$pgsql/src/tools/msvc"; @makeout = run_log(qq{perl install.pl "$installdir"}); chdir $branch_root; } + else + { + @makeout = run_log("cd $pgsql && $make install"); + } my $status = $? >> 8; writelog('make-install', \@makeout); print "======== make install log ===========\n", @makeout if ($verbose > 1); @@ -1358,21 +1461,36 @@ sub make_contrib_install sub make_testmodules_install { + return if $using_msvc && ! $using_meson; return unless (step_wanted('testmodules') and step_wanted('install')); - print time_str(), "running make testmodules install ...\n" + print time_str(), "running testmodules install ...\n" if $verbose; - my $tmp_inst = abs_path($pgsql) . "/tmp_install"; - my $cmd = "cd $pgsql/src/test/modules && " - . "$make install && $make DESTDIR=$tmp_inst install"; - my @makeout = run_log($cmd); + my @out; + if ($using_meson) + { + # for meson, the test setup installs these in the tmp_dir but + # the install procedure doesn't install them in $installdir, so + # do that using a special "compile" target + my $cmd = "meson compile -C $pgsql install-test-files"; + @out = run_log($cmd); + } + else + { + # for autoconf, we need to install them in both $tmp_install + # and $installdir + my $tmp_inst = abs_path($pgsql) . "/tmp_install"; + my $cmd = "cd $pgsql/src/test/modules && " + . "$make install && $make DESTDIR=$tmp_inst install"; + @out = run_log($cmd); + } my $status = $? >> 8; - writelog('install-testmodules', \@makeout); - print "======== make testmodules install log ===========\n", @makeout + writelog('install-testmodules', \@out); + print "======== testmodules install log ===========\n", @out if ($verbose > 1); - send_result('TestModulesInstall', $status, \@makeout) if $status; + send_result('TestModulesInstall', $status, \@out) if $status; $steps_completed .= " TestModulesInstall"; return; } @@ -1387,7 +1505,9 @@ sub initdb chdir $installdir; - my $initdbopts = qq{-A trust -U buildfarm --locale=$locale}; + my $initdbopts = qq{-A trust -U buildfarm --locale="$locale"}; + + $locale =~ s/\s/-/g; if ($use_discard_caches && ($branch eq 'HEAD' || $branch ge 'REL_14')) { @@ -1406,13 +1526,16 @@ sub initdb print $handle "\n# Configuration added by buildfarm client\n\n"; - if (!$using_msvc && $Config{osname} !~ /msys|MSWin/) + if ($ENV{PG_TEST_USE_UNIX_SOCKETS} || (!$using_msvc && $Config{osname} !~ /msys|MSWin/)) { + # postgres treats backslash as escape + my $tmpd = $tmpdir; + $tmpd =~ s!\\!/!g; my $param = - $branch eq 'REL9_2_STABLE' + ($branch le 'REL9_2_STABLE' && $branch ne 'HEAD') ? "unix_socket_directory" : "unix_socket_directories"; - print $handle "$param = '$tmpdir'\n"; + print $handle "$param = '$tmpd'\n"; print $handle "listen_addresses = ''\n"; } else @@ -1426,11 +1549,11 @@ sub initdb } close($handle); - if ($using_msvc || $Config{osname} =~ /msys|MSWin/) + if (!$ENV{PG_TEST_USE_UNIX_SOCKETS} && ($using_msvc || $Config{osname} =~ /msys|MSWin/)) { my $pg_regress; - if ($using_msvc) + if ($using_msvc && !$using_meson) { $pg_regress = "$abspgsql/Release/pg_regress/pg_regress"; unless (-e "$pg_regress.exe") @@ -1464,6 +1587,27 @@ sub initdb return; } + +sub _meson_env +{ + my %env; + # these should be safe to appear on the log and could be required + # for running tests + my @safe_set = qw( + PATH + PGUSER PGHOST PG_TEST_PORT_DIR PG_TEST_EXTRA + PG_TEST_USE_UNIX_SOCKETS PG_REGRESS_SOCK_DIR + SystemRoot TEMP TMP MSYS + TEMP_CONFIG PGCTLTIMEOUT + USER USERNAME USERDOMAIN); + foreach my $setting (@safe_set) + { + my $v = $ENV{$setting}; + $env{$setting} = $v if $v; + } + return %env; +} + sub start_valgrind_db { # run the postmaster under valgrind. @@ -1539,9 +1683,10 @@ sub start_db # clear log file each time we start # seem to need an intermediate file here to get round Windows bogosity + # we need to redirect input from devnull to avoid issues on msys2 chdir($installdir); my $cmd = - qq{"bin/pg_ctl" -D data-$locale -l logfile -w start >startlog 2>&1}; + qq{"bin/pg_ctl" -D data-$locale -l logfile -w start <$devnull >startlog 2>&1}; system($cmd); } @@ -1622,10 +1767,23 @@ sub make_install_check { my $locale = shift; return unless step_wanted('install-check'); - print time_str(), "running make installcheck ($locale)...\n" if $verbose; + print time_str(), "running installcheck ($locale)...\n" if $verbose; my @checklog; - unless ($using_msvc) + if ($using_meson) + { + local %ENV = _meson_env(); + my $jflag = defined($meson_jobs) ? " --num-processes=$meson_jobs" : ""; + @checklog = run_log("meson test -t $meson_test_timeout $jflag -v -C $pgsql --no-rebuild --print-errorlogs --setup running --suite regress-running --logbase regress-installcheck-$locale"); + } + elsif ($using_msvc) + { + my $parallel = $use_installcheck_parallel ? "parallel" : ""; + chdir "$pgsql/src/tools/msvc"; + @checklog = run_log("perl vcregress.pl installcheck $parallel"); + chdir $branch_root; + } + else { my $chktarget = $use_installcheck_parallel @@ -1642,12 +1800,6 @@ sub make_install_check } @checklog = run_log("cd $pgsql/src/test/regress && $make $chktarget"); } - else - { - chdir "$pgsql/src/tools/msvc"; - @checklog = run_log("perl vcregress.pl installcheck"); - chdir $branch_root; - } my $status = $? >> 8; my @logfiles = ("$pgsql/src/test/regress/regression.diffs", "inst/logfile"); my $log = PGBuild::Log->new("check"); @@ -1707,6 +1859,196 @@ sub make_contrib_install_check return; } +sub meson_test_setup +{ + # we run test setup separately so we can pass test arguments + # in the check stage + local %ENV = _meson_env(); + my @log = run_log("meson test -C $pgsql --no-rebuild --suite setup"); + # XXX fixme: logging etc. + return; +} + +# run tests for all the installcheck suites meson knows about +sub run_meson_install_checks +{ + my $locale = shift; + return unless step_wanted('misc-install-check'); + local %ENV = _meson_env(); + print time_str(), "running meson misc installchecks ($locale) ...\n" if $verbose; + + # clean out old logs etc + unlink "$pgsql/meson-logs/installcheckworld.txt"; + rmtree $_ foreach glob("$pgsql/testrun/*-running"); + + my $jflag = defined($meson_jobs) ? " --num-processes=$meson_jobs" : ""; + + # skip regress, done by make_installcheck + # skip isolation and ecpg, done with misc checks + my $skip = "--no-suite regress-running --no-suite isolation-running --no-suite ecpg-running"; + foreach my $sk (keys %skip_suites) + { + $skip .= " --no-suite $sk-running"; + } + + my @checklog=run_log("meson test -t $meson_test_timeout $jflag -C $pgsql --setup running --print-errorlogs --no-rebuild --logbase installcheckworld $skip"); + + my @fails = glob("$pgsql/testrun/*/*/test.fail"); + + my $status = (0 < @fails); + + my @faildirs = map { dirname $_ } @fails; + my (@miscdirs,@moddirs,@contribdirs,@otherdirs); + foreach my $dir (@faildirs) + { + my $sname = basename (dirname ($dir)); + $sname =~ s/-running$//; + if (-e "pgsql/src/test/$sname") + { + push @miscdirs, $dir; + } + elsif (-e "pgsql/src/test/modules/$sname") + { + push @moddirs, $dir; + } + elsif (-e "pgsql/contrib/$sname") + { + push @contribdirs, $dir; + } + else + { + push @otherdirs, $dir; + } + } + + @miscdirs = sort @miscdirs; + @moddirs = sort @moddirs; + @contribdirs = sort @contribdirs; + @otherdirs = sort @otherdirs; + + @faildirs = (@miscdirs, @moddirs, @contribdirs, @otherdirs); + + my $log = PGBuild::Log->new("misc-installcheck-$locale"); + $log->add_log("$pgsql/meson-logs/installcheckworld.txt"); + foreach my $dir (@faildirs) + { + $log->add_log($_) + foreach ("$dir/regression.diffs", glob("$dir/log/*")); + } + push(@checklog, $log->log_string); + + if ($status) + { + my $first = $faildirs[0]; + $first = basename (dirname $first); + $first =~ s/-running$//; + writelog("$first-installcheck-$locale", \@checklog); + print @checklog if ($verbose > 1); + send_result("${first}InstallCheck-$locale", $status, \@checklog); + } + else + { + writelog("misc-installcheck-$locale", \@checklog); + print @checklog if ($verbose > 1); + $steps_completed .= " MiscInstallCheck-$locale"; + } + return; +} + +# run tests for all the non-installcheck suites meson knows about +sub run_meson_noninst_checks +{ + return unless step_wanted('misc-check'); + local %ENV = _meson_env(); + + print time_str(), "running meson misc tests ...\n" if $verbose; + + # move windows executables aside so that the TAP tests find them from + # the tmp_install rather than where they are built. + foreach my $file (glob("$pgsql/src/bin/*/*.exe")) + { + my $exe = basename $file; + next if $exe =~ /built-/; + (my $dest = $file) =~ s/$exe/built-$exe/; + move $file, $dest; + } + + my $jflag = defined($meson_jobs) ? " --num-processes $meson_jobs" : ""; + + # skip setup, already done + # skip regress, done by make_check + my $skip = "--no-suite setup --no-suite regress"; + foreach my $sk (keys %skip_suites) + { + $skip .= " --no-suite $sk"; + } + my @checklog=run_log("meson test -t $meson_test_timeout $jflag -C $pgsql --print-errorlogs --no-rebuild --logbase checkworld $skip"); + + my @fails = glob("$pgsql/testrun/*/*/test.fail"); + + my $status = (0 < @fails); + + my @faildirs = map { dirname $_ } @fails; + my (@bindirs,@miscdirs,@moddirs,@contribdirs,@otherdirs); + foreach my $dir (@faildirs) + { + my $sname = basename (dirname ($dir)); + if (-e "pgsql/src/bin/$sname") + { + push @bindirs,$dir; + } + elsif (-e "pgsql/src/test/$sname") + { + push @miscdirs, $dir; + } + elsif (-e "pgsql/src/test/modules/$sname") + { + push @moddirs, $dir; + } + elsif (-e "pgsql/contrib/$sname") + { + push @contribdirs, $dir; + } + else + { + push @otherdirs, $dir; + } + } + + @bindirs = sort @bindirs; + @miscdirs = sort @miscdirs; + @moddirs = sort @moddirs; + @contribdirs = sort @contribdirs; + @otherdirs = sort @otherdirs; + + @faildirs = (@bindirs, @miscdirs, @moddirs, @contribdirs, @otherdirs); + + my $log = PGBuild::Log->new("misc-check"); + $log->add_log("$pgsql/meson-logs/checkworld.txt"); + foreach my $dir (@faildirs) + { + $log->add_log($_) + foreach ("$dir/regression.diffs", glob("$dir/log/*")); + } + push(@checklog, $log->log_string); + + if ($status) + { + my $first = $faildirs[0]; + $first = basename (dirname $first); + writelog("$first-check", \@checklog); + print @checklog if ($verbose > 1); + send_result("${first}Check", $status, \@checklog); + } + else + { + writelog("misc-check", \@checklog); + print @checklog if ($verbose > 1); + $steps_completed .= " MiscCheck"; + } + return; +} + # run the modules that can't be run with installcheck sub make_misc_check { @@ -2019,6 +2361,7 @@ sub run_misc_tests my $testname = basename($testdir); next if $testname =~ /ssl/ && !$using_ssl; next unless -d "$testdir/t"; + next if $using_msvc && $testname eq 'pg_bsd_indent'; next unless step_wanted("module-$testname"); print time_str(), "running misc test module-$testname ...\n" if $verbose; @@ -2040,10 +2383,32 @@ sub run_misc_tests sub make_check { return unless step_wanted('check'); - print time_str(), "running make check ...\n" if $verbose; + print time_str(), "running basic regression tests ...\n" if $verbose; my @makeout; - unless ($using_msvc) + if ($using_meson) + { + # prevent meson from logging the whole environment, + # see its issue 5328 + local %ENV = _meson_env(); + if ($using_msvc) + { + # not sure why we need to do this for msvc, but it works + my $inst = $installdir; + $inst =~ s/^[a-z]://i; + my $abs_pgsql = abs_path($pgsql); + $ENV{PATH} = "$abs_pgsql/tmp_install$inst/bin;$ENV{PATH}"; + } + my $jflag = defined($meson_jobs) ? " --num-processes=$meson_jobs" : ""; + @makeout=run_log("meson test -t $meson_test_timeout $jflag -C $pgsql --logbase checklog --print-errorlogs --no-rebuild --suite regress --test-args=--no-locale"); + } + elsif ($using_msvc) + { + chdir "$pgsql/src/tools/msvc"; + @makeout = run_log("perl vcregress.pl check"); + chdir $branch_root; + } + else { my $chktarget = "check"; if ($schedule && -s $schedule) @@ -2059,12 +2424,6 @@ sub make_check @makeout = run_log("cd $pgsql/src/test/regress && $make NO_LOCALE=1 $chktarget"); } - else - { - chdir "$pgsql/src/tools/msvc"; - @makeout = run_log("perl vcregress.pl check"); - chdir $branch_root; - } my $status = $? >> 8; @@ -2072,9 +2431,9 @@ sub make_check # get the log files and the regression diffs my @logs = - glob("$pgsql/src/test/regress/log/*.log $pgsql/tmp_install/log/*"); - unshift(@logs, "$pgsql/src/test/regress/regression.diffs") - if (-e "$pgsql/src/test/regress/regression.diffs"); + glob("$pgsql/src/test/regress/log/*.log $pgsql/tmp_install/log/* $pgsql/*/checklog.txt $pgsql/testrun/regress/regress/log/*"); + unshift @logs, "$_/regression.diffs" + foreach ("$pgsql/src/test/regress","$pgsql/testrun/regress/regress"); $log->add_log($_) foreach (@logs); my $base = "$pgsql/src/test/regress/tmp_check"; if ($status) @@ -2147,8 +2506,29 @@ sub make_ecpg_check return; } +# replace previous use of external egrep -A +sub _dump_filter +{ + my ($lines, $tag, $context) = @_; + my @output; + while (@$lines) + { + my $line = shift @$lines; + if (index($line,$tag) > -1) + { + push(@output, splice(@$lines,0,$context)); + } + } + return @output; +} + sub find_typedefs { + # work around the fact that ucrt/binutils objdump is far slower + # than the one in msys/binutils + local $ENV{PATH} = $ENV{PATH}; + $ENV{PATH} = "/usr/bin:$ENV{PATH}" if $Config{osname} eq 'msys'; + my ($hostobjdump) = grep { /--host=/ } @$config_opts; $hostobjdump ||= ""; $hostobjdump =~ s/--host=(.*)/$1-objdump/; @@ -2201,12 +2581,14 @@ sub find_typedefs { next if $bin =~ m!bin/(ipcclean|pltcl_)!; next unless -f $bin; - next if -l $bin; # ignore symlinks to plain files (e.g. postmaster) + next if -l $bin; # ignore symlinks to plain files + next if $bin =~ m!/postmaster.exe$!; # sometimes a copy not a link + if ($using_osx) { # no run_log due to redirections. - @dumpout = - `dwarfdump $bin 2>/dev/null | egrep -A2 TAG_typedef 2>/dev/null`; + @dumpout = `dwarfdump $bin 2>/dev/null`; + @dumpout = _dump_filter(\@dumpout,'TAG_typedef',2); foreach (@dumpout) { ## no critic (RegularExpressions::ProhibitCaptureWithoutTest) @@ -2229,9 +2611,9 @@ sub find_typedefs } elsif (@err == 1) # Linux and sometimes windows { - my $cmd = "$objdump -Wi $bin 2>/dev/null | " - . "egrep -A3 DW_TAG_typedef 2>/dev/null"; + my $cmd = "$objdump -Wi $bin 2>/dev/null"; @dumpout = `$cmd`; # no run_log because of redirections + @dumpout = _dump_filter(\@dumpout,'DW_TAG_typedef',3); foreach (@dumpout) { @flds = split; @@ -2246,10 +2628,10 @@ sub find_typedefs { # FreeBSD, similar output to Linux - my $cmd = "readelf -w $bin 2>/dev/null | " - . "egrep -A3 DW_TAG_typedef 2>/dev/null"; - + my $cmd = "readelf -w $bin 2>/dev/null"; @dumpout = ` $cmd`; # no run_log due to redirections + @dumpout = _dump_filter(\@dumpout,'DW_TAG_typedef',3); + foreach (@dumpout) { @flds = split; @@ -2314,37 +2696,123 @@ sub find_typedefs return; } -sub configure +# meson setup for all platforms +sub meson_setup { + my $env = $PGBuild::conf{config_env}; + $env = { %$env }; # clone it + delete $env->{CC} if $using_msvc; # this can confuse meson in this case + local %ENV = (%ENV, %$env); + $ENV{MSYS2_ARG_CONV_EXCL} = "-Dextra"; - if ($using_msvc) + my @quoted_opts; + foreach my $c_opt (@$meson_opts) { - my $lconfig = { %$config_opts, "--with-pgport" => $buildport }; - my $conf = Data::Dumper->Dump([$lconfig], ['config']); - my @text = ( - "# Configuration arguments for vcbuild.\n", - "# written by buildfarm client \n", - "use strict; \n", - "use warnings;\n", - "our $conf \n", - "1;\n" - ); + if ($c_opt =~ /['"]/) + { + push(@quoted_opts, $c_opt); + } + elsif ($using_msvc) + { + push(@quoted_opts,qq{"$c_opt"}); + } + else + { + push(@quoted_opts, "'$c_opt'"); + } + } - my $handle; - open($handle, ">", "$pgsql/src/tools/msvc/config.pl") - || die "opening $pgsql/src/tools/msvc/config.pl: $!"; - print $handle @text; - close($handle); + my $docs_opts=""; + $docs_opts = "-Ddocs=enabled" + if defined($PGBuild::conf{optional_steps}->{build_docs}); + $docs_opts .= " -Ddocs_pdf=enabled" + if $docs_opts && ($PGBuild::conf{extra_doc_targets} || "") =~ /[.]pdf/; + + my $confstr = join(" ", + "-Dauto_features=disabled", + @quoted_opts, + $docs_opts, + "-Dlibdir=lib", + qq{-Dprefix="$installdir"}, + "-Dpgport=$buildport"); + + my $srcdir = $from_source || 'pgsql'; - push(@text, "# no configure step for MSCV - config file shown\n"); + # use default ninja backend on all platforms + my @confout = run_log("meson setup $confstr $pgsql $srcdir"); - writelog('configure', \@text); + my $status = $? >> 8; + + move "$pgsql/meson-logs/meson-log.txt", "$pgsql/meson-logs/setup.log"; + + if (-s "$pgsql/meson-logs/setup.log") + { + my $log = PGBuild::Log->new("setup"); + $log->add_log("$pgsql/meson-logs/setup.log"); + push(@confout,$log->log_string); + } + + print "======== setup output ===========\n", @confout + if ($verbose > 1); + + writelog('configure', \@confout); + + if ($status) + { + send_result('Configure', $status, \@confout); + } + $steps_completed .= " Configure"; + + return; + +} + +# non-meson MSVC setup +sub msvc_setup +{ + my $lconfig = { %$config_opts, "--with-pgport" => $buildport }; + my $conf = Data::Dumper->Dump([$lconfig], ['config']); + my @text = ( + "# Configuration arguments for vcbuild.\n", + "# written by buildfarm client \n", + "use strict; \n", + "use warnings;\n", + "our $conf \n", + "1;\n" + ); + + my $handle; + open($handle, ">", "$pgsql/src/tools/msvc/config.pl") + || die "opening $pgsql/src/tools/msvc/config.pl: $!"; + print $handle @text; + close($handle); + + push(@text, "# no configure step for MSCV - config file shown\n"); + + writelog('configure', \@text); + + $steps_completed .= " Configure"; + return; +} - $steps_completed .= " Configure"; +# setup entry, directly implements autoconf setup, +# calls above for meson / msvc +sub configure +{ + if ($using_meson) + { + meson_setup(); + return; + } + if ($using_msvc) + { + msvc_setup(); return; } + # autoconf/configure setup + my @quoted_opts; foreach my $c_opt (@$config_opts) { @@ -2479,9 +2947,9 @@ sub configure if (-s "$pgsql/config.log") { - push(@confout, - "\n\n================= config.log ================\n\n", - file_lines("$pgsql/config.log")); + my $log = PGBuild::Log->new("configure"); + $log->add_log("$pgsql/config.log"); + push(@confout,$log->log_string); } writelog('configure', \@confout);